Access to sysctl.h

jamiejamie USMember

Is there any way to access sysctl.h's time values? I want to get to the system uptime, like in this post:

http://stackoverflow.com/questions/12488481/getting-ios-system-uptime-that-doesnt-pause-when-asleep

But I don't see a way to do this using Monotouch. The examples I was able to find only work with string values.

Posts

  • jamiejamie USMember

    I tried the example for getting a system string and it doesn't compile, due to the keyword "extern" not being recognized.

  • SKallSKall USMember ✭✭✭✭
    edited July 2014

    Here is a sample usage file: https://github.com/XForms/Xamarin-Forms-Labs/blob/master/src/Xamarin.Forms.Labs/Xamarin.Forms.Labs.iOS/Device/AppleDevice.cs

    DLL import:

        [DllImport(MonoTouch.Constants.SystemLibrary)]
        static internal extern int sysctlbyname([MarshalAs(UnmanagedType.LPStr)] string property, IntPtr output, IntPtr oldLen, IntPtr newp, uint newlen);
    

    Helper function:

        /// <summary>
        /// Gets the system property.
        /// </summary>
        /// <returns>The system property value.</returns>
        /// <param name="property">Property to get.</param>
        public static string GetSystemProperty(string property)
        {
            var pLen = Marshal.AllocHGlobal(sizeof(int));
            sysctlbyname(property, IntPtr.Zero, pLen, IntPtr.Zero, 0);
            var length = Marshal.ReadInt32(pLen);
            var pStr = Marshal.AllocHGlobal(length);
            sysctlbyname(property, pStr, pLen, IntPtr.Zero, 0);
            return Marshal.PtrToStringAnsi(pStr);
        }
    

    Usage:

    var hardwareVersion = GetSystemProperty("hw.machine");
    

    How to get a struct TimeVal (quick hack, you probably have to modify the struct with proper layout):

    1) define time val struct:

        public struct TimeVal
        {
            public long sec;
            public long ms;
        }
    

    2) Change the function to get the system property:

        public static TimeVal GetBoottime()
        {
            var pLen = Marshal.AllocHGlobal(sizeof(int));
            sysctlbyname("kern.boottime", IntPtr.Zero, pLen, IntPtr.Zero, 0);
            var length = Marshal.ReadInt32(pLen);
            var pStr = Marshal.AllocHGlobal(length);
            sysctlbyname("kern.boottime", pStr, pLen, IntPtr.Zero, 0);
            return Marshal.PtrToStructure<TimeVal>(pStr);
        }
    

    3) Usage:

                var uptime = GetBoottime();
    
                System.Diagnostics.Debug.WriteLine("{0} seconds, {1} milliseconds.", uptime.sec, uptime.ms);
    
  • espresso3389espresso3389 JPMember

    I think the GetSystemProperty function illustrated above has several problems. The most critical one is that it does not release the allocated memory blocks.

    The following is a modified version, which does not use Marshal.AllocHGlobal but normal byte array:

    public static string GetSystemProperty(string name)
    {
      var len64 = IntPtr.Zero;
      if (sysctlbyname(name, null, ref len64, IntPtr.Zero, IntPtr.Zero) < 0)
        return null;
      var len = len64.ToInt32();
      if (len == 1)
        return "";
      var buf = new byte[len];
      if (sysctlbyname(name, buf, ref len64, IntPtr.Zero, IntPtr.Zero) < 0)
        return null;
      return Encoding.ASCII.GetString(buf, 0, len - 1); // removing the terminating \0.
    }
    
    [DllImport(ObjCRuntime.Constants.SystemLibrary)]
    static extern int sysctlbyname([MarshalAs(UnmanagedType.LPStr)] string property, byte[] buffer, ref IntPtr oldlenp, IntPtr _null1, IntPtr newlen);
    
    [DllImport(ObjCRuntime.Constants.SystemLibrary)]
    static extern int sysctlbyname([MarshalAs(UnmanagedType.LPStr)] string property, out long value, ref IntPtr oldlenp, IntPtr _null1, IntPtr newlen);
    
  • ShawinderSekhon.4746ShawinderSekhon.4746 USMember
    edited November 9

    I am trying to get GetSystemProperty("hw.cpusubtype") and it's returning special characters. I want to detect the type of processor (Armv7...etc)

Sign In or Register to comment.