diff --git a/CMakeLists.txt b/CMakeLists.txt index cfd0e2591..2163e3908 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -129,6 +129,10 @@ else () list(APPEND AWS_COMMON_OS_SRC "${ANDROID_SRC}") list (APPEND AWS_COMMON_OS_SRC "source/platform_fallback_stubs/system_info.c") list (APPEND AWS_COMMON_OS_SRC "source/platform_fallback_stubs/file_direct_io.c") + elseif(CMAKE_SYSTEM_NAME STREQUAL "AIX") + list(APPEND AWS_COMMON_OS_SRC "source/aix/*.c") + list (APPEND AWS_COMMON_OS_SRC "source/platform_fallback_stubs/system_info.c") + list (APPEND AWS_COMMON_OS_SRC "source/platform_fallback_stubs/file_direct_io.c") else() list (APPEND AWS_COMMON_OS_SRC "source/platform_fallback_stubs/system_info.c") list (APPEND AWS_COMMON_OS_SRC "source/platform_fallback_stubs/file_direct_io.c") diff --git a/cmake/AwsCFlags.cmake b/cmake/AwsCFlags.cmake index b9d2f6446..ecd23e34b 100644 --- a/cmake/AwsCFlags.cmake +++ b/cmake/AwsCFlags.cmake @@ -167,7 +167,9 @@ function(aws_set_common_properties target) # loaded at runtime which happens to use libcrypto.so from OpenSSL. # If the symbols from libcrypto.a aren't hidden, then SOME function calls use the libcrypto.a implementation # and SOME function calls use the libcrypto.so implementation, and this mismatch leads to weird crashes. - if (UNIX AND NOT APPLE) + if (CMAKE_SYSTEM_NAME STREQUAL "AIX") + target_link_options(${PROJECT_NAME} PRIVATE -lm -lbsd) + elseif (UNIX AND NOT APPLE) # If we used target_link_options() (CMake 3.13+) we could make these flags PUBLIC set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS " -Wl,--exclude-libs,libcrypto.a") endif() diff --git a/include/aws/common/platform.h b/include/aws/common/platform.h index 9742860fb..4b4616237 100644 --- a/include/aws/common/platform.h +++ b/include/aws/common/platform.h @@ -29,6 +29,8 @@ # endif #elif __linux__ # define AWS_OS_LINUX +#elif _AIX +# define AWS_OS_AIX #endif #if defined(__ANDROID__) diff --git a/source/aix/time.c b/source/aix/time.c new file mode 100644 index 000000000..a3e3afb0e --- /dev/null +++ b/source/aix/time.c @@ -0,0 +1,76 @@ +/* time.c + timegm() implementation for AIX platform. +*/ + +#include +#include +#include +#include +#include + +time_t timegm (struct tm *tm); +time_t timegm (struct tm *tm) +{ + static const int msum [2][12] = { + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}, /* normal years */ + { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335} /* leap years */ + }; + static const int mlen [2][12] = { + { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, + { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} + }; + static const int tmstr_year= 1900; /* base of 'tm_year' in 'struct tm' */ + static const int epoch_year= 1970; /* unix timestamp epoch */ + static const int base_year= -9999; /* start of a 400-year period: used to be 1601, + but this allows larger range (in 64 bit) + mind you, this is proleptic Gregorian */ + int year, ytmp, dtmp, ytmpe, dtmpe; + int isleapyear; + long long t; + + if (!tm) return -1; + + year = tm->tm_year + tmstr_year; + isleapyear= (year%4==0) - (year%100==0) + (year%400==0); + + if (year<-9999 || year>9999 || + tm->tm_mon<0 || tm->tm_mon>11 || + tm->tm_mday<1 || tm->tm_mday>mlen[isleapyear][tm->tm_mon] || + tm->tm_hour<0 || tm->tm_hour>23 || + tm->tm_min<0 || tm->tm_min>59 || + tm->tm_min<0 || tm->tm_sec>59) return -1; + +/* days between 'current year' and 'epoch_year' has to be calculated + in three steps: */ + +/* 1. days between current year and 'base_year' */ + ytmp = year - base_year; + dtmp = ytmp*365 + ytmp/4 - ytmp/100 + ytmp/400; + +/* 2. days between 'epoch year' and 'base_year' */ + ytmpe = epoch_year - base_year; + dtmpe = ytmpe*365 + ytmpe/4 - ytmpe/100 + ytmpe/400; + +/* 3. days between 'current year' and 'epoch_year' */ + t = dtmp - dtmpe; + + t += msum[isleapyear][tm->tm_mon]; + t += tm->tm_mday-1; + + tm->tm_wday = (t+4)%7;/* 0..6=Sun..Sat; adding 4 to adjust 1970.01.01.=Thursday; */ + if (tm->tm_wday<0) tm->tm_wday += 7; + tm->tm_yday = msum[isleapyear][tm->tm_mon] + tm->tm_mday-1; + tm->tm_isdst= 0; + + t = t*24 + tm->tm_hour; + t = t*60 + tm->tm_min; + t = t*60 + tm->tm_sec; + +#if LONG_MAX == 2147483647L + if (tLONG_MAX) { + t= -1; + } +#endif + + return t; +} diff --git a/source/posix/clock.c b/source/posix/clock.c index 4ca0a47ba..0e349ddef 100644 --- a/source/posix/clock.c +++ b/source/posix/clock.c @@ -7,6 +7,12 @@ #include +/* In AIX, time.h provided NS_PER_SEC as macro, which causes compilation + * error, so need to undefine it. + */ +#if defined (AWS_OS_AIX) && defined (NS_PER_SEC) +#undef NS_PER_SEC +#endif static const uint64_t NS_PER_SEC = 1000000000; #if defined(CLOCK_BOOTTIME)