From fc5a1ae6aac3f6357f673daee8ce2f29d1a5e09a Mon Sep 17 00:00:00 2001 From: Andrew Schwartzmeyer Date: Fri, 30 Sep 2016 14:47:24 -0700 Subject: [PATCH] Clean up SetDate Remove pass-by-reference from C API --- .../commands/utility/SetDateCommand.cs | 58 +++++++++---------- .../project.json | 8 +++ .../CoreCLR/CorePsPlatform.cs | 13 +---- src/libpsl-native/src/setdate.cpp | 31 +++------- src/libpsl-native/src/setdate.h | 2 +- 5 files changed, 45 insertions(+), 67 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/SetDateCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/SetDateCommand.cs index b865b197b5..04f0033a37 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/SetDateCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/SetDateCommand.cs @@ -69,42 +69,37 @@ namespace Microsoft.PowerShell.Commands goto case "Date"; } - // - - // build up the SystemTime struct to pass to SetSystemTime - NativeMethods.SystemTime systemTime = new NativeMethods.SystemTime(); - systemTime.Year = (UInt16)dateToUse.Year; - systemTime.Month = (UInt16)dateToUse.Month; - systemTime.Day = (UInt16)dateToUse.Day; - systemTime.Hour = (UInt16)dateToUse.Hour; - systemTime.Minute = (UInt16)dateToUse.Minute; - systemTime.Second = (UInt16)dateToUse.Second; - systemTime.Milliseconds = (UInt16)dateToUse.Millisecond; - if (ShouldProcess(dateToUse.ToString())) { - if (Platform.IsWindows) +#if UNIX + if (!Platform.NonWindowsSetDate(dateToUse)) { + throw new Win32Exception(Marshal.GetLastWin32Error()); + } +#else + // build up the SystemTime struct to pass to SetSystemTime + NativeMethods.SystemTime systemTime = new NativeMethods.SystemTime(); + systemTime.Year = (UInt16)dateToUse.Year; + systemTime.Month = (UInt16)dateToUse.Month; + systemTime.Day = (UInt16)dateToUse.Day; + systemTime.Hour = (UInt16)dateToUse.Hour; + systemTime.Minute = (UInt16)dateToUse.Minute; + systemTime.Second = (UInt16)dateToUse.Second; + systemTime.Milliseconds = (UInt16)dateToUse.Millisecond; #pragma warning disable 56523 - - if (!NativeMethods.SetLocalTime(ref systemTime)) - { - throw new Win32Exception(Marshal.GetLastWin32Error()); - } - - // MSDN says to call this twice to account for changes - // between DST - if (!NativeMethods.SetLocalTime(ref systemTime)) - { - throw new Win32Exception(Marshal.GetLastWin32Error()); - } - -#pragma warning restore 56523 - } - else + if (!NativeMethods.SetLocalTime(ref systemTime)) { - Platform.NonWindowsSetDate(dateToUse); + throw new Win32Exception(Marshal.GetLastWin32Error()); } + + // MSDN says to call this twice to account for changes + // between DST + if (!NativeMethods.SetLocalTime(ref systemTime)) + { + throw new Win32Exception(Marshal.GetLastWin32Error()); + } +#pragma warning restore 56523 +#endif } //output DateTime object wrapped in an PSObject with DisplayHint attached @@ -121,7 +116,8 @@ namespace Microsoft.PowerShell.Commands internal static class NativeMethods { - public struct SystemTime + [StructLayout(LayoutKind.Sequential)] + public class SystemTime { public UInt16 Year; public UInt16 Month; diff --git a/src/Microsoft.PowerShell.Commands.Utility/project.json b/src/Microsoft.PowerShell.Commands.Utility/project.json index a1443bd9a0..6e84936749 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/project.json +++ b/src/Microsoft.PowerShell.Commands.Utility/project.json @@ -12,6 +12,14 @@ "allowUnsafe": true }, + "configurations": { + "Linux": { + "buildOptions": { + "define": [ "UNIX" ] + } + } + }, + "dependencies": { "System.Management.Automation": "1.0.0-*" }, diff --git a/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs b/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs index 34cb42a93c..3733458ebd 100644 --- a/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs +++ b/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs @@ -403,10 +403,10 @@ namespace System.Management.Automation return Unix.CreateHardLink(path, strTargetPath); } - internal static void NonWindowsSetDate(DateTime dateToUse) + internal static bool NonWindowsSetDate(DateTime dateToUse) { Unix.SetDateInfoInternal date = new Unix.SetDateInfoInternal(dateToUse); - Unix.SetDate(date); + return Unix.NativeMethods.SetDate(date) == 0; } internal static string NonWindowsGetDomainName() @@ -526,15 +526,6 @@ namespace System.Management.Automation } } - public static void SetDate(SetDateInfoInternal info) - { - int ret = NativeMethods.SetDate(info); - if (ret == -1) - { - throw new Win32Exception(Marshal.GetLastWin32Error()); - } - } - public static bool CreateHardLink(string path, string strTargetPath) { int ret = NativeMethods.CreateHardLink(path, strTargetPath); diff --git a/src/libpsl-native/src/setdate.cpp b/src/libpsl-native/src/setdate.cpp index 3a2c179d7e..3f350101ff 100644 --- a/src/libpsl-native/src/setdate.cpp +++ b/src/libpsl-native/src/setdate.cpp @@ -4,6 +4,7 @@ #include "setdate.h" +#include #include #include #include @@ -11,8 +12,8 @@ #include #include -//! @brief SetDate sets the date and time on local computer. You must -//! be super-user to set the time. +//! @brief SetDate sets the date and time on local computer. +//! You must be super-user to set the time. //! //! SetDate //! @@ -20,27 +21,17 @@ //! @parblock //! A struct that contains program to execute and its parameters //! -//! @exception errno Passes these errors via errno to GetLastError: -//! - ERROR_BAD_ENVIRONMENT: locale is not UTF-8 -//! - ERROR_INVALID_PARAMETER: time was not passed in correctly -//! - ERROR_ACCESS_DENIED: you must be super-user to set the date -//! //! @retval 0 successfully set date -//! @retval -1 if failure occurred. To get extended error information, call GetLastError. +//! @retval -1 if failure occurred. //! - -int32_t SetDate(const SetDateInfo &info) +int32_t SetDate(const SetDateInfo info) { errno = 0; // Select locale from environment setlocale(LC_ALL, ""); // Check that locale is UTF-8 - if (nl_langinfo(CODESET) != std::string("UTF-8")) - { - errno = ERROR_BAD_ENVIRONMENT; - return -1; - } + assert(nl_langinfo(CODESET) == std::string("UTF-8")); struct tm bdTime; struct timeval tv; @@ -56,19 +47,11 @@ int32_t SetDate(const SetDateInfo &info) time_t newTime = mktime(&bdTime); if (newTime == -1) { - errno = ERROR_INVALID_PARAMETER; return -1; } tv.tv_sec = newTime; tv.tv_usec = 0; - int result = settimeofday(&tv, NULL); - if (result == -1) - { - errno = ERROR_ACCESS_DENIED; - return -1; - } - - return 0; + return settimeofday(&tv, NULL); } diff --git a/src/libpsl-native/src/setdate.h b/src/libpsl-native/src/setdate.h index b55a7d1e7a..bf2bccaed1 100644 --- a/src/libpsl-native/src/setdate.h +++ b/src/libpsl-native/src/setdate.h @@ -17,6 +17,6 @@ typedef struct setDateInfo int32_t DST; } SetDateInfo; -int32_t SetDate(const SetDateInfo &info); +int32_t SetDate(const SetDateInfo info); PAL_END_EXTERNC