diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 441c1ed6229..02f08a797e1 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -68,6 +68,9 @@ src/System.Management.Automation/engine/remoting @dantraMSFT @mirichmo @PaulHi # Area: Side-By-Side # @mirichmo @charub +# Area: Libpsl-native +src/libpsl-native @dantraMSFT + # Areas: Build # Must be last *.config @daxian-dbw @TravisEz13 @adityapatwardhan diff --git a/src/libpsl-native/src/.gitignore b/src/libpsl-native/src/.gitignore new file mode 100644 index 00000000000..5c8aecc64be --- /dev/null +++ b/src/libpsl-native/src/.gitignore @@ -0,0 +1 @@ +pal_config.h diff --git a/src/libpsl-native/src/getstat.cpp b/src/libpsl-native/src/getstat.cpp index dba95262a7a..2cc6f66ce36 100644 --- a/src/libpsl-native/src/getstat.cpp +++ b/src/libpsl-native/src/getstat.cpp @@ -34,6 +34,10 @@ //! @retval -1 if failed //! +// DO NOT use in managed code +// use externally defined structs in managed code has proven to be buggy +// (memory corruption issues due to layout difference between platforms) +// see https://github.com/dotnet/corefx/issues/29700#issuecomment-389313075 int32_t GetStat(const char* path, struct stat* buf) { assert(path); diff --git a/src/libpsl-native/src/setdate.cpp b/src/libpsl-native/src/setdate.cpp index 97709ad558d..b5d7b70dde1 100644 --- a/src/libpsl-native/src/setdate.cpp +++ b/src/libpsl-native/src/setdate.cpp @@ -15,13 +15,14 @@ //! @brief SetDate sets the date and time on local computer. //! You must be super-user to set the time. +//! See comment in setdate.h about the use of private_tm //! //! SetDate //! //! @retval 0 successfully set date //! @retval -1 if failure occurred. //! -int32_t SetDate(struct tm* time) +int32_t SetDate(struct private_tm* time) { errno = 0; @@ -29,8 +30,29 @@ int32_t SetDate(struct tm* time) setlocale(LC_ALL, ""); struct timeval tv; + int32_t result = GetTimeVal(*time,tv); + if(result != 0) + { + return result; + } + + return settimeofday(&tv, NULL); +} + +static int32_t GetTimeVal(struct private_tm& time, struct timeval& tv) +{ + struct tm nativeTime = 0; + nativeTime.tm_hour = static_cast(time.Hour); + nativeTime.tm_isdst = static_cast(time.IsDst); + nativeTime.tm_mday = static_cast(time.DayOfMonth); + nativeTime.tm_min = static_cast(time.Minutes); + nativeTime.tm_mon = static_cast(time.Month); + nativeTime.tm_sec = static_cast(time.Seconds); + nativeTime.tm_wday = static_cast(time.DayOfWeek); + nativeTime.tm_yday = static_cast(time.DayInYear); + nativeTime.tm_year = static_cast(time.Year); - time_t newTime = mktime(time); + time_t newTime = mktime(&nativeTime); if (newTime == -1) { return -1; @@ -39,5 +61,5 @@ int32_t SetDate(struct tm* time) tv.tv_sec = newTime; tv.tv_usec = 0; - return settimeofday(&tv, NULL); + return 0; } diff --git a/src/libpsl-native/src/setdate.h b/src/libpsl-native/src/setdate.h index 250cf515e59..4d69f1e0a7c 100644 --- a/src/libpsl-native/src/setdate.h +++ b/src/libpsl-native/src/setdate.h @@ -9,6 +9,27 @@ PAL_BEGIN_EXTERNC -int32_t SetDate(struct tm* time); +int32_t SetDate(struct private_tm* time); + +static int32_t GetTimeVal(struct private_tm& time, struct timeval& tv); PAL_END_EXTERNC + +// Using a private struct because theuse externally defined structs +// in managed code has proven to be buggy +// (memory corruption issues due to layout difference between platforms) +// see https://github.com/dotnet/corefx/issues/29700#issuecomment-389313075 +#pragma pack(push, 4) // exact fit - no padding +struct private_tm +{ + int32_t Seconds; /* Seconds (0-60) */ + int32_t Minutes; /* Minutes (0-59) */ + int32_t Hour; /* Hours (0-23) */ + int32_t DayOfMonth;/* Day of the month (1-31) */ + int32_t Month; /* Month (0-11) */ + int32_t Year; /* Year - 1900 */ + int32_t DayOfWeek; /* Day of the week (0-6, Sunday = 0) */ + int32_t DayInYear; /* Day in the year (0-365, 1 Jan = 0) */ + int32_t IsDst; /* Daylight saving time */ +}; +#pragma pack(pop) //back to whatever the previous packing mode was