Added code to detect real OS platform.

This commit is contained in:
2015-02-12 06:21:02 +00:00
parent 80f9722efd
commit 1cff36aec7
6 changed files with 425 additions and 2 deletions

View File

@@ -1,3 +1,12 @@
2015-02-12 Natalia Portillo <claunia@claunia.com>
* Claunia.IO.csproj:
* Tests/Interop.Apple.cs:
* Tests/Interop.DetectOS.cs:
* Interop/Interop.DetectOS.cs:
* Interop/Interop.PlatformID.cs:
Added code to detect real OS platform.
2015-02-12 Natalia Portillo <claunia@claunia.com>
* Interop/Apple/Interop.Apple.Errors.cs:

View File

@@ -45,6 +45,9 @@
<Compile Include="Interop\Apple\Interop.Apple.Libraries.cs" />
<Compile Include="Tests\Interop.Apple.cs" />
<Compile Include="Interop\Apple\Interop.Apple.Errors.cs" />
<Compile Include="Interop\Interop.DetectOS.cs" />
<Compile Include="Interop\Interop.PlatformID.cs" />
<Compile Include="Tests\Interop.DetectOS.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>

View File

@@ -0,0 +1,189 @@
//
// Interop.DetectOS.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2015 © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Runtime.InteropServices;
internal static partial class Interop
{
public static class DetectOS
{
/// <summary>
/// POSIX uname structure, size from OSX, big enough to handle extra fields
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
struct utsname
{
/// <summary>
/// System name
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string sysname;
/// <summary>
/// Node name
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string nodename;
/// <summary>
/// Release level
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string release;
/// <summary>
/// Version level
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string version;
/// <summary>
/// Hardware level
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string machine;
}
[DllImport("libc", SetLastError = true)]
static extern int uname(out utsname name);
[DllImport("libc", SetLastError = true, EntryPoint = "sysctlbyname", CharSet = CharSet.Ansi)]
static extern int OSX_sysctlbyname(string name, IntPtr oldp, IntPtr oldlenp, IntPtr newp, uint newlen);
public static Interop.PlatformID GetRealPlatformID()
{
if ((int)Environment.OSVersion.Platform < 4 ||
(int)Environment.OSVersion.Platform == 5)
{
return (Interop.PlatformID)((int)Environment.OSVersion.Platform);
}
utsname unixname;
int error = uname(out unixname);
if (error != 0)
throw new Exception(String.Format("Unhandled exception calling uname: {0}", Marshal.GetLastWin32Error()));
switch (unixname.sysname)
{
// TODO: Differentiate Linux, Android, Tizen
case "Linux":
{
#if __ANDROID__
return PlatformID.Android;
#else
return PlatformID.Linux;
#endif
}
case "Darwin":
{
int osx_error;
IntPtr pLen = Marshal.AllocHGlobal(sizeof(int));
osx_error = OSX_sysctlbyname("hw.machine", IntPtr.Zero, pLen, IntPtr.Zero, 0);
if (osx_error != 0)
{
Marshal.FreeHGlobal(pLen);
throw new Exception(String.Format("Unhandled exception calling uname: {0}", Marshal.GetLastWin32Error()));
}
int length = Marshal.ReadInt32(pLen);
IntPtr pStr = Marshal.AllocHGlobal(length);
osx_error = OSX_sysctlbyname("hw.machine", pStr, pLen, IntPtr.Zero, 0);
if (osx_error != 0)
{
Marshal.FreeHGlobal(pStr);
Marshal.FreeHGlobal(pLen);
throw new Exception(String.Format("Unhandled exception calling uname: {0}", Marshal.GetLastWin32Error()));
}
string machine = Marshal.PtrToStringAnsi(pStr);
Marshal.FreeHGlobal(pStr);
Marshal.FreeHGlobal(pLen);
if (machine.StartsWith("iPad", StringComparison.Ordinal) ||
machine.StartsWith("iPod", StringComparison.Ordinal) ||
machine.StartsWith("iPhone", StringComparison.Ordinal))
return PlatformID.iOS;
return PlatformID.MacOSX;
}
case "GNU":
return PlatformID.Hurd;
case "FreeBSD":
case "GNU/kFreeBSD":
return PlatformID.FreeBSD;
case "DragonFly":
return PlatformID.DragonFly;
case "Haiku":
return PlatformID.Haiku;
case "HP-UX":
return PlatformID.HPUX;
case "AIX":
return PlatformID.AIX;
case "OS400":
return PlatformID.OS400;
case "IRIX":
case "IRIX64":
return PlatformID.IRIX;
case "Minix":
return PlatformID.Minix;
case "NetBSD":
return PlatformID.NetBSD;
case "NONSTOP_KERNEL":
return PlatformID.NonStop;
case "OpenBSD":
return PlatformID.OpenBSD;
case "QNX":
return PlatformID.QNX;
case "SINIX-Y":
return PlatformID.SINIX;
case "SunOS":
return PlatformID.Solaris;
case "OSF1":
return PlatformID.Tru64;
case "ULTRIX":
return PlatformID.Ultrix;
case "SCO_SV":
return PlatformID.OpenServer;
case "UnixWare":
return PlatformID.UnixWare;
case "Interix":
case "UWIN-W7":
return PlatformID.Win32NT;
default:
{
if (unixname.sysname.StartsWith("CYGWIN_NT", StringComparison.Ordinal) ||
unixname.sysname.StartsWith("MINGW32_NT", StringComparison.Ordinal) ||
unixname.sysname.StartsWith("MSYS_NT", StringComparison.Ordinal) ||
unixname.sysname.StartsWith("UWIN", StringComparison.Ordinal))
return PlatformID.Win32NT;
return PlatformID.Unknown;
}
}
}
}
}

View File

@@ -0,0 +1,179 @@
//
// Interop.PlatformID.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2015 © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
internal static partial class Interop
{
public enum PlatformID
{
/// <summary>
/// Win32s
/// </summary>
Win32S = 0,
/// <summary>
/// Win32 (Windows 9x)
/// </summary>
Win32Windows = 1,
/// <summary>
/// Windows NT
/// </summary>
Win32NT = 2,
/// <summary>
/// Windows Mobile
/// </summary>
WinCE = 3,
/// <summary>
/// UNIX (do not use, too generic)
/// </summary>
Unix = 4,
/// <summary>
/// Xbox 360
/// </summary>
Xbox = 5,
/// <summary>
/// OS X
/// </summary>
MacOSX = 6,
/// <summary>
/// iOS is not OS X
/// </summary>
iOS = 7,
/// <summary>
/// Linux
/// </summary>
Linux = 8,
/// <summary>
/// Sun Solaris
/// </summary>
Solaris = 9,
/// <summary>
/// NetBSD
/// </summary>
NetBSD = 10,
/// <summary>
/// OpenBSD
/// </summary>
OpenBSD = 11,
/// <summary>
/// FreeBSD
/// </summary>
FreeBSD = 12,
/// <summary>
/// DragonFly BSD
/// </summary>
DragonFly = 13,
/// <summary>
/// Nintendo Wii
/// </summary>
Wii = 14,
/// <summary>
/// Nintendo Wii U
/// </summary>
WiiU = 15,
/// <summary>
/// Sony PlayStation 3
/// </summary>
PlayStation3 = 16,
/// <summary>
/// Sony Playstation 4
/// </summary>
PlayStation4 = 17,
/// <summary>
/// Google Android
/// </summary>
Android = 18,
/// <summary>
/// Samsung Tizen
/// </summary>
Tizen = 19,
/// <summary>
/// Windows Phone
/// </summary>
WindowsPhone = 20,
/// <summary>
/// GNU/Hurd
/// </summary>
Hurd = 21,
/// <summary>
/// Haiku
/// </summary>
Haiku = 22,
/// <summary>
/// HP-UX
/// </summary>
HPUX = 23,
/// <summary>
/// AIX
/// </summary>
AIX = 24,
/// <summary>
/// OS/400
/// </summary>
OS400 = 25,
/// <summary>
/// IRIX
/// </summary>
IRIX = 26,
/// <summary>
/// Minix
/// </summary>
Minix = 27,
/// <summary>
/// NonStop
/// </summary>
NonStop = 28,
/// <summary>
/// QNX
/// </summary>
QNX = 29,
/// <summary>
/// SINIX
/// </summary>
SINIX = 30,
/// <summary>
/// Tru64 UNIX
/// </summary>
Tru64 = 31,
/// <summary>
/// Ultrix
/// </summary>
Ultrix = 32,
/// <summary>
/// SCO OpenServer / SCO UNIX
/// </summary>
OpenServer = 33,
/// <summary>
/// SCO UnixWare
/// </summary>
UnixWare = 34,
/// <summary>
/// IBM z/OS
/// </summary>
zOS = 35,
Unknown = -1
}
}

View File

@@ -37,7 +37,7 @@ namespace Tests
public void TestStat()
{
// Take care, Mono returns UNIX for Mac OS X
if (Environment.OSVersion.Platform == PlatformID.MacOSX || Environment.OSVersion.Platform == PlatformID.Unix)
if (Interop.DetectOS.GetRealPlatformID() == Interop.PlatformID.MacOSX || Interop.DetectOS.GetRealPlatformID() == Interop.PlatformID.iOS)
{
string testFile = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "/.localized";
@@ -80,7 +80,7 @@ namespace Tests
public void TestStat64()
{
// Take care, Mono returns UNIX for Mac OS X
if (Environment.OSVersion.Platform == PlatformID.MacOSX || Environment.OSVersion.Platform == PlatformID.Unix)
if (Interop.DetectOS.GetRealPlatformID() == Interop.PlatformID.MacOSX || Interop.DetectOS.GetRealPlatformID() == Interop.PlatformID.iOS)
{
string testFile = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "/.localized";

View File

@@ -0,0 +1,43 @@
//
// Interop.DetectOS.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2015 © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using NUnit.Framework;
namespace Tests
{
[TestFixture]
public class InteropDetectOS
{
[Test]
public void DetectOS()
{
Interop.PlatformID pid = Interop.DetectOS.GetRealPlatformID();
Assert.AreEqual(Interop.PlatformID.MacOSX, pid, "This test only works on OS X but in the fail you'll see the detected OS");
}
}
}