Use a struct utsname when calling uname() instead of an 8K buffer
authorJeffrey Stedfast <jeff@xamarin.com>
Wed, 6 Jul 2011 22:06:14 +0000 (18:06 -0400)
committerJeffrey Stedfast <jeff@xamarin.com>
Wed, 6 Jul 2011 22:06:14 +0000 (18:06 -0400)
mcs/class/System/System/Platform.cs

index a953e83a31c4a61d7c8efca7423dced952bf44c6..5d457454987a38ef48172b936f402c737941eaf8 100644 (file)
@@ -27,22 +27,37 @@ using System.Runtime.InteropServices;
 
 namespace System {
        internal static class Platform {
-               [DllImport ("libc")]
-               static extern int uname (IntPtr buf);
-               
                static bool checkedIsMacOS;
                static bool isMacOS;
                
+               // This is the struct layout for MacOSX. Linux has an additional field,
+               // but each field length is only 65 bytes (as opposed to 256 on MacOSX).
+               //
+               // Since we are only using uname() to detect whether or not the system
+               // is MacOSX, we only need .sysname so it doesn't matter if it is too
+               // big for other platforms or not.
+               [StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)]
+               struct utsname {
+                       [MarshalAs (UnmanagedType.ByValTStr, SizeConst = 256)]
+                       public string sysname;
+                       [MarshalAs (UnmanagedType.ByValTStr, SizeConst = 256)]
+                       public string nodename;
+                       [MarshalAs (UnmanagedType.ByValTStr, SizeConst = 256)]
+                       public string release;
+                       [MarshalAs (UnmanagedType.ByValTStr, SizeConst = 256)]
+                       public string version;
+                       [MarshalAs (UnmanagedType.ByValTStr, SizeConst = 256)]
+                       public string machine;
+               }
+               
+               [DllImport ("libc")]
+                static extern int uname (ref utsname buf);
+               
                public static bool IsMacOS {
                        get {
                                if (!checkedIsMacOS) {
-                                       IntPtr buf = Marshal.AllocHGlobal (8192);
-                                       if (uname (buf) == 0) {
-                                               string os = Marshal.PtrToStringAnsi (buf);
-                                               if (os == "Darwin")
-                                                       isMacOS = true;
-                                       }
-                                       Marshal.FreeHGlobal (buf);
+                                       utsname buf = new utsname ();
+                                       isMacOS = uname (ref buf) == 0 && buf.sysname == "Darwin";
                                        checkedIsMacOS = true;
                                }