7 /* time(2) with backward time jump protection.
9 /* #include <sane_time.h>
11 /* time_t sane_time(void)
14 /* This module provides time(2) like call for applications
15 /* which need monotonically increasing time function rather
16 /* than the real exact time. It eliminates the need for various
17 /* workarounds all over the application which would handle
18 /* potential problems if time suddenly jumps backward.
19 /* Instead we choose to deal with this problem inside this
20 /* module and let the application focus on its own tasks.
22 /* sane_time() returns the current timestamp as obtained from
23 /* time(2) call, at least most of the time. In case this routine
24 /* detects that time has jumped backward, it keeps returning
25 /* whatever timestamp it returned before, until this timestamp
26 /* and the time(2) timestamp become synchronized again.
27 /* Additionally, the returned timestamp is slowly increased to
28 /* prevent the faked clock from freezing for too long.
30 /* time(2) get current time
32 /* Warning message is logged if backward time jump is detected.
36 /* The Secure Mailer license must be distributed with this software.
40 /* 155 00, Prague, Czech Republic
47 /* Utility library. */
51 /* Application-specific. */
53 #include "sane_time.h"
56 * How many times shall we slow down the real clock when recovering from
61 /* sane_time - get current time, protected against time warping */
63 time_t sane_time(void)
66 static time_t last_time
,
72 now
= time((time_t *) 0);
74 if ((delta
= now
- last_time
) < 0 && last_time
!= 0) {
75 if ((delta
= now
- last_real
) < 0) {
76 msg_warn("%sbackward time jump detected -- slewing clock",
77 warned
++ ? "another " : "");
80 last_time
+= delta
/ SLEW_FACTOR
;
81 fraction
= delta
% SLEW_FACTOR
;
86 msg_warn("backward time jump recovered -- back to normality");
99 * Proof-of-concept test program. Repeatedly print current system time and
100 * time returned by sane_time(). Meanwhile, try stepping your system clock
101 * back and forth to see what happens.
105 #include <msg_vstream.h>
106 #include <iostuff.h> /* doze() */
108 int main(int argc
, char **argv
)
113 msg_vstream_init(argv
[0], VSTREAM_ERR
);
115 if (argc
== 2 && (delay
= atol(argv
[1]) * 1000) > 0)
118 msg_fatal("usage: %s [delay in ms (default 1 second)]", argv
[0]);
121 now
= time((time_t *) 0);
122 vstream_printf("real: %s", ctime(&now
));
124 vstream_printf("fake: %s\n", ctime(&now
));
125 vstream_fflush(VSTREAM_OUT
);