13

Something similar to linux

cat /proc/uptime

which returns the uptime in seconds, and preferably not parsing uptime(1).

Mark Harrison
  • 297,451
  • 125
  • 333
  • 465
  • please see: https://stackoverflow.com/questions/12199631/convert-seconds-to-hours-minutes-seconds/48762631#4876263 – splaisan Feb 14 '18 at 13:00

8 Answers8

19

Old question, I know, but I needed to do the same thing so I thought I'd post the code I'm using, which I got from http://cocoadev.com/wiki/FindingUptime

#include <time.h>
#include <errno.h>
#include <sys/sysctl.h>

double uptime()
{
    struct timeval boottime;
    size_t len = sizeof(boottime);
    int mib[2] = { CTL_KERN, KERN_BOOTTIME };
    if( sysctl(mib, 2, &boottime, &len, NULL, 0) < 0 )
    {
        return -1.0;
    }
    time_t bsec = boottime.tv_sec, csec = time(NULL);

    return difftime(csec, bsec);
}
Bleyddyn
  • 388
  • 3
  • 14
17

The Uptime article on Wikipedia has an interesting lead:

Using sysctl

There is also a method of using sysctl to call the system's last boot time: $ sysctl kern.boottime kern.boottime: { sec = 1271934886, usec = 667779 } Thu Apr 22 12:14:46 2010

Which references sysctl(8), which references sysctl(3).

Community
  • 1
  • 1
Shaggy Frog
  • 27,575
  • 16
  • 91
  • 128
  • 2
    and just in case any apple people see this, it sure would be nice to have this wrapped up in /proc!! – Mark Harrison Jul 16 '10 at 23:07
  • 3
    which is not the uptime. Uptime can be calculated from this, given that the system time has not been changed since boot and given that the system does not support any kind of suspend. – lImbus Jan 05 '14 at 15:47
2

If anyone is trying to do this programmatically using sysctl.h and is expecting a string back like what you see in the command line, the returned value that I get is a 16 byte array, not a string:

sysctlbyname("kern.boottime", value, &size, NULL, 0);

An example for what gets put into value in hex starting from the [0] index:

a9 af c6 4e 0 0 0 0 0 0 0 0 28 be 92 55

The first 4 bytes (maybe the first 8, won't know until Jan 2012) is the epoch time in little endian byte order.

Jon
  • 1,379
  • 1
  • 12
  • 32
1

correct way:

CFTimeInterval getSystemUptime(void)
{
    enum { NANOSECONDS_IN_SEC = 1000 * 1000 * 1000 };
    static double multiply = 0;
    if (multiply == 0)
    {
        mach_timebase_info_data_t s_timebase_info;
        kern_return_t result = mach_timebase_info(&s_timebase_info);
        assert(result == noErr);
        // multiply to get value in the nano seconds
        multiply = (double)s_timebase_info.numer / (double)s_timebase_info.denom;
        // multiply to get value in the seconds
        multiply /= NANOSECONDS_IN_SEC;
    }
    return mach_absolute_time() * multiply;
}

also you could use CACurrentMediaTime() from QuartzCore.framework (which has same code probably) - Available since OS X v10.5 and iOS 2.0

Maxim Kholyavkin
  • 4,463
  • 2
  • 37
  • 82
  • I suspect this is a better solution. I would also suggest using `mach_continuous_time()` (in place of `mach_absolute_time()`) if running macOS 10.12 or later. – James Bucanek May 16 '18 at 00:46
1

To add to @Bleyddyn's answer (since it's 11 years and counting)...

I needed a small utility to print the uptime in seconds, so I took that code and slightly altered it to compile on modern macOS.

You can clone the luckman212/uptime_s repo and run ./build.sh to generate your own universal binary that will simply print the uptime in secs.

luckman212
  • 473
  • 1
  • 7
  • 15
0

There is a function UpTime declared in DriverServices.h. I believe this is equivalent to another function mach_absolute_time. Both seem to be undocumented.

JWWalker
  • 22,385
  • 6
  • 55
  • 76
0

Unfortunately the "sysctl kern.boottime" returns the seconds of the timestamp, not elapsed seconds.. Multiple calls do not increase the second count, but must be seconds from epoc of the boot date itself.

Uri
  • 1
  • 2
    Just subtract the system's boot time from the current time to find out how long the system has been up. – Gabe Jul 20 '10 at 22:48
  • 2
    @Gabe - which gives you wrong results if the system time has been modified since bootup. – lImbus Jan 05 '14 at 15:45
  • FYI after trial and error, something like this solved my issue (slightly different than OP) date -r `sysctl -n kern.boottime | awk '{print $4}' | sed 's/,//'` "+%Y%m%d%H%M%S" – JWHardcastle Aug 31 '14 at 13:21
  • please have a look to https://stackoverflow.com/questions/12199631/convert-seconds-to-hours-minutes-seconds/48762631#4876263 – splaisan Feb 14 '18 at 13:01
0

A simple Lua script to do exactly what you ask for:

local now=tonumber(io.popen("date +%s"):read())
local boottime=tonumber(io.popen("sysctl -n kern.boottime"):read():match("sec = (%d+)"))
local uptime=now-boottime
Valerio Schiavoni
  • 1,373
  • 1
  • 12
  • 19