forked from dotnet/runtime
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Return the correct OSVersion on OSX like systems. (dotnet#36029)
* Return the correct OSVersion on OSX like systems. Fix dotnet#34977 * Rename files to not have Linux when they aren't Linux specific. * Assert OSVersion Build number is valid. * PR feedback Move interop code to Common\src\Interop. Specify the full path to libobjc.dylib. Fix objc_msgSend_stret for ARM64. * Specify full path to libproc.dylib. Fix dotnet#24095
- Loading branch information
Showing
10 changed files
with
175 additions
and
67 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
#nullable enable | ||
|
||
using System; | ||
using System.Runtime.InteropServices; | ||
using nint = System.IntPtr; | ||
|
||
internal static partial class Interop | ||
{ | ||
internal static partial class libobjc | ||
{ | ||
#if TARGET_ARM64 | ||
private const string MessageSendStructReturnEntryPoint = "objc_msgSend"; | ||
#else | ||
private const string MessageSendStructReturnEntryPoint = "objc_msgSend_stret"; | ||
#endif | ||
|
||
[StructLayout(LayoutKind.Sequential)] | ||
private struct NSOperatingSystemVersion | ||
{ | ||
public nint majorVersion; | ||
public nint minorVersion; | ||
public nint patchVersion; | ||
} | ||
|
||
[DllImport(Libraries.libobjc)] | ||
private static extern IntPtr objc_getClass(string className); | ||
[DllImport(Libraries.libobjc)] | ||
private static extern IntPtr sel_getUid(string selector); | ||
[DllImport(Libraries.libobjc)] | ||
private static extern IntPtr objc_msgSend(IntPtr basePtr, IntPtr selector); | ||
|
||
internal static Version GetOperatingSystemVersion() | ||
{ | ||
int major = 0; | ||
int minor = 0; | ||
int patch = 0; | ||
|
||
IntPtr processInfo = objc_msgSend(objc_getClass("NSProcessInfo"), sel_getUid("processInfo")); | ||
|
||
if (processInfo != IntPtr.Zero) | ||
{ | ||
NSOperatingSystemVersion osVersion = get_operatingSystemVersion(processInfo, sel_getUid("operatingSystemVersion")); | ||
|
||
major = osVersion.majorVersion.ToInt32(); | ||
minor = osVersion.minorVersion.ToInt32(); | ||
patch = osVersion.patchVersion.ToInt32(); | ||
} | ||
|
||
return new Version(major, minor, patch); | ||
} | ||
|
||
[DllImport(Libraries.libobjc, EntryPoint = MessageSendStructReturnEntryPoint)] | ||
private static extern NSOperatingSystemVersion get_operatingSystemVersion(IntPtr basePtr, IntPtr selector); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
18 changes: 18 additions & 0 deletions
18
src/libraries/System.Private.CoreLib/src/System/Environment.OSVersion.OSX.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
namespace System | ||
{ | ||
public static partial class Environment | ||
{ | ||
private static OperatingSystem GetOSVersion() | ||
{ | ||
Version version = Interop.libobjc.GetOperatingSystemVersion(); | ||
|
||
// For compatibility reasons with Mono, PlatformID.Unix is returned on MacOSX. PlatformID.MacOSX | ||
// is hidden from the editor and shouldn't be used. | ||
return new OperatingSystem(PlatformID.Unix, version); | ||
} | ||
} | ||
} |
67 changes: 67 additions & 0 deletions
67
src/libraries/System.Private.CoreLib/src/System/Environment.OSVersion.Unix.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
namespace System | ||
{ | ||
public static partial class Environment | ||
{ | ||
private static OperatingSystem GetOSVersion() => GetOperatingSystem(Interop.Sys.GetUnixRelease()); | ||
|
||
// Tests exercise this method for corner cases via private reflection | ||
private static OperatingSystem GetOperatingSystem(string release) | ||
{ | ||
int major = 0, minor = 0, build = 0, revision = 0; | ||
|
||
// Parse the uname's utsname.release for the first four numbers found. | ||
// This isn't perfect, but Version already doesn't map exactly to all possible release | ||
// formats, e.g. 2.6.19-1.2895.fc6 | ||
if (release != null) | ||
{ | ||
int i = 0; | ||
major = FindAndParseNextNumber(release, ref i); | ||
minor = FindAndParseNextNumber(release, ref i); | ||
build = FindAndParseNextNumber(release, ref i); | ||
revision = FindAndParseNextNumber(release, ref i); | ||
} | ||
|
||
return new OperatingSystem(PlatformID.Unix, new Version(major, minor, build, revision)); | ||
} | ||
|
||
private static int FindAndParseNextNumber(string text, ref int pos) | ||
{ | ||
// Move to the beginning of the number | ||
for (; pos < text.Length; pos++) | ||
{ | ||
char c = text[pos]; | ||
if ('0' <= c && c <= '9') | ||
{ | ||
break; | ||
} | ||
} | ||
|
||
// Parse the number; | ||
int num = 0; | ||
for (; pos < text.Length; pos++) | ||
{ | ||
char c = text[pos]; | ||
if ('0' > c || c > '9') | ||
break; | ||
|
||
try | ||
{ | ||
num = checked((num * 10) + (c - '0')); | ||
} | ||
// Integer overflow can occur for example with: | ||
// Linux nelknet 4.15.0-24201807041620-generic | ||
// To form a valid Version, num must be positive. | ||
catch (OverflowException) | ||
{ | ||
return int.MaxValue; | ||
} | ||
} | ||
|
||
return num; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters