]> git.ipfire.org Git - thirdparty/util-linux.git/blame - lib/monotonic.c
whereis: make "-BMS <dir> -f" more obvious in usage()
[thirdparty/util-linux.git] / lib / monotonic.c
CommitLineData
cd2876d2
KZ
1/*
2 * Please, don't add this file to libcommon because clock_gettime() requires
3 * -lrt on systems with old libc.
4 */
2c5484f7 5#include <time.h>
378543e1 6#include <signal.h>
2c5484f7
KZ
7#include <sys/sysinfo.h>
8#include <sys/time.h>
9
10#include "c.h"
11#include "nls.h"
cd2876d2 12#include "monotonic.h"
2c5484f7
KZ
13
14int get_boot_time(struct timeval *boot_time)
15{
60cb2c37 16#ifdef CLOCK_BOOTTIME
2c5484f7 17 struct timespec hires_uptime;
60cb2c37
RM
18 struct timeval lores_uptime;
19#endif
20 struct timeval now;
88e0f3df 21#ifdef HAVE_SYSINFO
2c5484f7 22 struct sysinfo info;
88e0f3df 23#endif
2c5484f7
KZ
24
25 if (gettimeofday(&now, NULL) != 0) {
26 warn(_("gettimeofday failed"));
27 return -errno;
28 }
29#ifdef CLOCK_BOOTTIME
30 if (clock_gettime(CLOCK_BOOTTIME, &hires_uptime) == 0) {
31 TIMESPEC_TO_TIMEVAL(&lores_uptime, &hires_uptime);
32 timersub(&now, &lores_uptime, boot_time);
33 return 0;
34 }
35#endif
88e0f3df 36#ifdef HAVE_SYSINFO
2c5484f7
KZ
37 /* fallback */
38 if (sysinfo(&info) != 0)
39 warn(_("sysinfo failed"));
40
41 boot_time->tv_sec = now.tv_sec - info.uptime;
42 boot_time->tv_usec = 0;
43 return 0;
88e0f3df
ST
44#else
45 return -ENOSYS;
46#endif
2c5484f7 47}
cd2876d2
KZ
48
49int gettime_monotonic(struct timeval *tv)
50{
51#ifdef CLOCK_MONOTONIC
52 /* Can slew only by ntp and adjtime */
53 int ret;
54 struct timespec ts;
55
56# ifdef CLOCK_MONOTONIC_RAW
57 /* Linux specific, cant slew */
58 if (!(ret = clock_gettime(CLOCK_MONOTONIC_RAW, &ts))) {
59# else
60 if (!(ret = clock_gettime(CLOCK_MONOTONIC, &ts))) {
61# endif
62 tv->tv_sec = ts.tv_sec;
63 tv->tv_usec = ts.tv_nsec / 1000;
64 }
65 return ret;
66#else
67 return gettimeofday(tv, NULL);
68#endif
69}
378543e1
SK
70
71int setup_timer(timer_t * t_id, struct itimerval *timeout,
72 void (*timeout_handler)(void))
73{
74 struct sigaction sig_a;
75 static struct sigevent sig_e = {
76 .sigev_notify = SIGEV_SIGNAL,
77 .sigev_signo = SIGALRM
78 };
79 struct itimerspec val = {
80 .it_value.tv_sec = timeout->it_value.tv_sec,
81 .it_value.tv_nsec = timeout->it_value.tv_usec * 1000,
82 .it_interval.tv_sec = 0,
83 .it_interval.tv_nsec = 0
84 };
85
86 if (sigemptyset(&sig_a.sa_mask))
87 return 1;
88 sig_a.sa_flags = SA_SIGINFO;
89 sig_a.sa_handler = timeout_handler;
90 if (sigaction(SIGALRM, &sig_a, 0))
91 return 1;
92 if (timer_create(CLOCK_MONOTONIC, &sig_e, t_id))
93 return 1;
94 if (timer_settime(*t_id, SA_SIGINFO, &val, NULL))
95 return 1;
96 return 0;
97}
98
99void cancel_timer(timer_t *t_id)
100{
101 timer_delete(*t_id);
102}