-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.c
More file actions
99 lines (73 loc) · 1.67 KB
/
main.c
File metadata and controls
99 lines (73 loc) · 1.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <bits/time.h>
#include <sys/time.h>
#include <time.h>
#include <sys/timerfd.h>
#define ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0]))
#define BUF_SIZE 1024
static char buf[BUF_SIZE];
static char time_format[] = "%a %b %d %I:%M:%S %p %Z %Y\n";
static int setup_timerfd(int timer_fd, struct timespec *now) {
assert(timer_fd > 0);
assert(now);
int r;
struct itimerspec tspec = {
.it_value = {.tv_sec = now->tv_sec + 1, .tv_nsec = 0},
.it_interval = {.tv_sec = 1, .tv_nsec = 0}
};
r = timerfd_settime(
timer_fd,
TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET,
&tspec,
0
);
assert(!r);
return timer_fd;
}
static ssize_t write_time_fmt(const struct timespec *t, char *p, size_t p_len) {
assert(t);
assert(p);
struct tm *gm = localtime((const time_t *)t);
assert(gm);
ssize_t n = strftime(p, p_len, time_format, gm);
assert(n > 0);
return n;
}
static void run(int timer_fd, struct timespec *now) {
assert(timer_fd > 0);
assert(now);
int r;
while (1) {
char read_buf[8];
ssize_t n = write_time_fmt(now, buf, BUF_SIZE);
r = write(1, buf, n);
assert(r == n);
n = read(timer_fd, read_buf, 8);
if (n != 8) {
assert(errno == ECANCELED);
return;
}
uint64_t dt = *((uint64_t *)read_buf);
now->tv_sec += dt;
}
}
int main(void) {
int r;
int timer_fd = timerfd_create(CLOCK_REALTIME, 0);
assert(timer_fd > 0);
while (1) {
struct timespec now;
r = clock_gettime(CLOCK_REALTIME, &now);
assert(!r);
now.tv_nsec = 0;
setup_timerfd(timer_fd, &now);
run(timer_fd, &now);
}
r = close(timer_fd);
assert(!r);
return EXIT_SUCCESS;
}