forked from snarfed/libmsntp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
timing.c
120 lines (90 loc) · 3.31 KB
/
timing.c
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/* Copyright (C) 1996 N.M. Maclaren
Copyright (C) 1996 The University of Cambridge
This includes all of the code needed to handle the time. It assumes rather
more than is defined by POSIX, unfortunately. Systems that do not have the
'X/Open' extensions may need changes. */
#include "header.h"
#include <sys/types.h>
#include <sys/time.h>
#define TIMING
#include "kludges.h"
#undef TIMING
#define MILLION_L 1000000l /* For conversion to/from timeval */
#define MILLION_D 1.0e6 /* Must be equal to MILLION_L */
double current_time (double offset) {
/* Get the current UTC time in seconds since the Epoch plus an offset (usually
the time from the beginning of the century to the Epoch!) */
struct timeval current;
errno = 0;
if (gettimeofday(¤t,NULL)) {
fatal(errno,"unable to read current machine/system time",NULL);
exit(errno);
}
return offset+current.tv_sec+1.0e-6*current.tv_usec;
}
time_t convert_time (double value, int *millisecs) {
/* Convert the time to the ANSI C form. */
time_t result = (time_t)value;
if ((*millisecs = (int)(1000.0*(value-result))) >= 1000) {
*millisecs = 0;
++result;
}
return result;
}
int adjust_time (double difference, int immediate, double ignore) {
/* Adjust the current UTC time. This is portable, even if struct timeval uses
an unsigned long for tv_sec. */
struct timeval old, new, adjust, previous;
char text[40];
long n;
/* Start by converting to timeval format. Note that we have to cater for
negative, unsigned values. */
if ((n = (long)difference) > difference) --n;
adjust.tv_sec = n;
adjust.tv_usec = (long)(MILLION_D*(difference-n));
errno = 0;
if (gettimeofday(&old,NULL)) {
fatal(errno,"unable to read machine/system time",NULL);
return errno;
}
new.tv_sec = old.tv_sec+adjust.tv_sec;
new.tv_usec = (n = (long)old.tv_usec+(long)adjust.tv_usec);
if (n < 0) {
new.tv_usec += MILLION_L;
--new.tv_sec;
} else if (n >= MILLION_L) {
new.tv_usec -= MILLION_L;
++new.tv_sec;
}
/* Now diagnose the situation if necessary, and perform the dirty deed. */
if (verbose > 2)
fprintf(stderr,
"Times: old=(%ld,%.6ld) new=(%ld,%.6ld) adjust=(%ld,%.6ld)\n",
(long)old.tv_sec,(long)old.tv_usec,
(long)new.tv_sec,(long)new.tv_usec,
(long)adjust.tv_sec,(long)adjust.tv_usec);
if (immediate) {
errno = 0;
if (settimeofday(&new,NULL)) {
fatal(errno,"unable to reset current system time",NULL);
return errno;
}
} else {
errno = 0;
if (adjtime(&adjust,&previous)) {
fatal(errno,"unable to adjust current system time",NULL);
return errno;
}
if (previous.tv_sec != 0 || previous.tv_usec != 0) {
sprintf(text,"(%ld,%.6ld)",
(long)previous.tv_sec,(long)previous.tv_usec);
if (previous.tv_sec+1.0e-6*previous.tv_usec > ignore) {
fatal(EMSNTP_INTERNAL,"outstanding time adjustment %s",text);
return EMSNTP_INTERNAL;
}
else if (verbose)
fprintf(stderr,"%s: outstanding time adjustment %s\n",
argv0,text);
}
}
}