I would like to get the system uptime from within a C application running on a linux-based system. I don't want to call uptime(1) and parse the output, I'd like to call the underlying C API I suspect exists. Anyone know if there is such a call, or does uptime(1) simply process records obtained from wtmp?
What API do I call to get the system uptime?
is it possible to get uptime in nano seconds ??? Have you tried ? –
Deandeana
To obtain the uptime in a higher resolution see https://mcmap.net/q/425924/-getting-millisecond-or-microsecond-accurate-boot-time-in-linux-c-c/1340631 –
Gardener
The system call you're looking for is sysinfo().
It's defined in sys/sysinfo.h
Its signature is: int sysinfo(struct sysinfo *info)
Since kernel 2.4, the structure has looked like this:
struct sysinfo {
long uptime; /* Seconds since boot */
unsigned long loads[3]; /* 1, 5, and 15 minute load averages */
unsigned long totalram; /* Total usable main memory size */
unsigned long freeram; /* Available memory size */
unsigned long sharedram; /* Amount of shared memory */
unsigned long bufferram; /* Memory used by buffers */
unsigned long totalswap; /* Total swap space size */
unsigned long freeswap; /* swap space still available */
unsigned short procs; /* Number of current processes */
unsigned long totalhigh; /* Total high memory size */
unsigned long freehigh; /* Available high memory size */
unsigned int mem_unit; /* Memory unit size in bytes */
char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding for libc5 */
};
Have fun!
I'd implemented reading /proc/uptime as bdonlan suggested above, but calling an API versus reading a "file" is exactly what I wanted. Thank you! –
Overfeed
Is it possible to get nano seconds level information (for uptime)?? –
Deandeana
That would be something like this.
#include <stdio.h>
#include <errno.h>
#include <linux/unistd.h> /* for _syscallX macros/related stuff */
#include <linux/kernel.h> /* for struct sysinfo */
#include <sys/sysinfo.h>
long get_uptime()
{
struct sysinfo s_info;
int error = sysinfo(&s_info);
if(error != 0)
{
printf("code error = %d\n", error);
}
return s_info.uptime;
}
See "man sysinfo" for more info.
For me only the
sys/sysinfo.h
and stdio.h
includes were needed, so I presume the rest of includes may be safely deleted from the answer. –
Dollfuss Read the file /proc/uptime
and take the first decimal number as the uptime in seconds.
From man 5 proc
:
/proc/uptime
This file contains two numbers: the uptime of the system (sec‐
onds), and the amount of time spent in idle process (seconds).
...and if you
strace
the uptime(1)
command, you'll see that it does just that. –
Louise caf: on linux machines, BSD machines generally uses "current time - syctl kern.boottime" –
Auricula
@caf,
uptime(1)
does a lot more than just that, so it can be a bit hard to find :) –
Nosh @Tarrant: That approach gives wrong results if someone resets the current time using 'date' or settimeofday() API. I am looking for something based on ticks which cannot be affected by time/date settings –
Semiconductor
There's also clock_gettime (probably needs -lrt
). The behavior I've seen (I'm not going to claim it's guaranteed) but given CLOCK_MONOTONIC
as the clk_id
is that it returns the system uptime in the given struct timespec *
parameter.
#include <stdio.h>
#include <time.h>
int main(int argc, char* argv[]) {
struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
printf("tv_sec=%llu tv_nsec=%llu\n",
(unsigned long long)t.tv_sec,
(unsigned long long)t.tv_nsec);
return 0;
}
No it doesn't; the monotonic clock has an arbitrary epoch. The manpage you linked you says just that. –
Tasha
@BoundaryImposition The question is tagged linux and in Linux the behavior was (and still is as I described). POSIX says the epoch is arbitrary, the Linux implementation correlates with uptime. See kernel/time/posix-timers.c and fs/proc/uptime.c. And here is a relevant LKML thread. –
Diploid
You linked to implementation files. This could change at any time. The question is about the API, and the API says that the epoch is arbitrary. Arbitrary doesn't mean that there isn't an epoch, it just means that the choice is not to be relied upon. The LKML thread you linked me to actually states this. –
Tasha
And in my answer I wrote "I'm not going to claim it's guaranteed." The question's text also specifically mentions "linux" as the use case. The LKML thread also states that the behavior is not likely to change any time soon. POSIX helps write code that behaves reliably across compliant platforms. If the use case only covers one platform it seems very reasonable to rely on the platform's behavior. –
Diploid
For the reasons described by Lightness Races In Orbit, I'd say this is a bad answer. There's a working linux-specific api that will fail to compile on other OSes, which is preferable to relying on an os-specific behavior of an os-general api that will silently do the wrong thing on other OSes or in the presence of future changes to the compiler. –
Infielder
works for me on fedora without lrt :) –
Margenemargent
#include <sys/sysinfo.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <grp.h>
int main() {
struct sysinfo sys_info;
struct group* grp;
gid_t gid;
char** users;
int days, hours, mins, x = 1;
system("clear");
printf("\033[4;40m Systems information \033[0;m \n");
if(sysinfo(&sys_info) != 0)
perror("sysinfo");
days = sys_info.uptime / 86400;
hours = (sys_info.uptime / 3600) - (days * 24);
mins = (sys_info.uptime / 60) - (days * 1440) - (hours * 60);
printf("\033[1;33m Uptime: \033[0;36m %ddays, %dhours, %dminutes, %ldseconds \033[0;m \n",
days, hours, mins, sys_info.uptime % 60);
printf("\033[1;33m Load Avgs: \033[0;m 1min(%ld) 5min(%ld) 15min(%ld) \n",
sys_info.loads[0], sys_info.loads[1], sys_info.loads[2]);
printf("\033[1;33m Total Ram: \033[0;m %ldk \t Free: %ldk \n", sys_info.totalram / 1024, sys_info.freeram / 1024);
printf(" \033[1;33m Shared Ram: \033[0;m %ldk ", sys_info.sharedram / 1024);
printf(" Buffered Ram: %ldk \n", sys_info.bufferram / 1024);
printf("\033[1;33m Total Swap: \033[0;m %ldk \t Free swap: %ldk \n", sys_info.totalswap / 1024, sys_info.freeswap / 1024);
printf("\033[1;33m Total High Memory: \033[0;m %ldk Free high memory: %ldk \033[0;m \n", sys_info.totalhigh / 1024, sys_info.freehigh / 1024);
printf(" \n");
printf("\033[1;44m Total Number of processes: %d \033[0;m \n", sys_info.procs);
gid = getgid();
printf(" Group ID: \033[031m %d", gid);
if((grp = getgrgid(gid)) == NULL ) return 1;
printf("\033[0;m Group %s ", grp->gr_name );
printf("\n Users in your group ");
for( users = grp->gr_mem; *users != NULL; users++,++x ); printf( "%d", ++x);
if(strcmp(grp->gr_passwd,"x") == 0) printf(" Password is protected by shadow file. \n");
else printf("Password: %s ", grp->gr_passwd);
return 0;
}
A good answer should include not just code but also some explanation of how it works and why it answers the question. This is particularly true as there is already an accepted answer to the question. –
Lauretta
© 2022 - 2024 — McMap. All rights reserved.