#include #include #include #include #include static const char * as_time_string (time_t tim) { struct tm *gmt = gmtime (&tim); static char timbuf[100]; if (gmt == NULL || strftime (timbuf, sizeof (timbuf), "%Y-%m-%d %H:%M:%S", gmt) == 0) strcpy (timbuf, "---"); return timbuf; } int main () { /* clock() returns the uptime with a resolution of ca. 1 usec. */ struct timespec ts_now; struct timespec up; if (clock_gettime (CLOCK_REALTIME, &ts_now) == 0 && clock_gettime (CLOCK_BOOTTIME, &up) == 0) { struct timespec result = ts_now; if (result.tv_nsec < up.tv_nsec) { result.tv_nsec += 1000000000; result.tv_sec -= 1; } result.tv_sec -= up.tv_sec; result.tv_nsec -= up.tv_nsec; printf ("from clock : %d.%09d = %s.%09d\n", (int) result.tv_sec, (int) result.tv_nsec, as_time_string (result.tv_sec), (int) result.tv_nsec); } /* /proc/uptime contains the uptime with a resolution of 0.01 sec. */ FILE *fp = fopen ("/proc/uptime", "re"); if (fp != NULL) { char buf[32 + 1]; size_t n = fread (buf, 1, sizeof (buf) - 1, fp); fclose (fp); if (n > 0) { buf[n] = '\0'; /* buf now contains two values: the uptime and the idle time. */ char *endptr; double uptime = strtod (buf, &endptr); if (endptr > buf) { struct timespec result; if (clock_gettime (CLOCK_REALTIME, &result) == 0) { time_t uptime_sec = uptime; struct timespec up = { .tv_sec = uptime_sec, .tv_nsec = (uptime - uptime_sec) * 1e9 + 0.5 }; if (result.tv_nsec < up.tv_nsec) { result.tv_nsec += 1000000000; result.tv_sec -= 1; } result.tv_sec -= up.tv_sec; result.tv_nsec -= up.tv_nsec; printf ("from /proc : %d.%09d = %s.%09d\n", (int) result.tv_sec, (int) result.tv_nsec, as_time_string (result.tv_sec), (int) result.tv_nsec); } } } } /* The sysinfo call returns the uptime with a resolution of 1 sec only. */ struct sysinfo info; if (sysinfo (&info) >= 0) { struct timespec result; if (clock_gettime (CLOCK_REALTIME, &result) == 0) { result.tv_sec -= info.uptime; printf ("from sysinfo: %d.%09d = %s.%09d\n", (int) result.tv_sec, (int) result.tv_nsec, as_time_string (result.tv_sec), (int) result.tv_nsec); } } return 0; }