• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <sys/timex.h>
2 #include <time.h>
3 #include <errno.h>
4 #include "syscall.h"
5 
6 #define IS32BIT(x) !((x)+0x80000000ULL>>32)
7 
8 struct ktimex64 {
9 	unsigned modes;
10 	int :32;
11 	long long offset, freq, maxerror, esterror;
12 	int status;
13 	int :32;
14 	long long constant, precision, tolerance;
15 	long long time_sec, time_usec;
16 	long long tick, ppsfreq, jitter;
17 	int shift;
18 	int :32;
19 	long long stabil, jitcnt, calcnt, errcnt, stbcnt;
20 	int tai;
21 	int __padding[11];
22 };
23 
24 struct ktimex {
25 	unsigned modes;
26 	long offset, freq, maxerror, esterror;
27 	int status;
28 	long constant, precision, tolerance;
29 	long time_sec, time_usec;
30 	long tick, ppsfreq, jitter;
31 	int shift;
32 	long stabil, jitcnt, calcnt, errcnt, stbcnt;
33 	int tai;
34 	int __padding[11];
35 };
36 
clock_adjtime(clockid_t clock_id,struct timex * utx)37 int clock_adjtime (clockid_t clock_id, struct timex *utx)
38 {
39 	int r = -ENOSYS;
40 #ifdef SYS_clock_adjtime64
41 	if (SYS_clock_adjtime == SYS_clock_adjtime64 ||
42 	    (utx->modes & ADJ_SETOFFSET) && !IS32BIT(utx->time.tv_sec)) {
43 		struct ktimex64 ktx = {
44 			.modes = utx->modes,
45 			.offset = utx->offset,
46 			.freq = utx->freq,
47 			.maxerror = utx->maxerror,
48 			.esterror = utx->esterror,
49 			.status = utx->status,
50 			.constant = utx->constant,
51 			.precision = utx->precision,
52 			.tolerance = utx->tolerance,
53 			.time_sec = utx->time.tv_sec,
54 			.time_usec = utx->time.tv_usec,
55 			.tick = utx->tick,
56 			.ppsfreq = utx->ppsfreq,
57 			.jitter = utx->jitter,
58 			.shift = utx->shift,
59 			.stabil = utx->stabil,
60 			.jitcnt = utx->jitcnt,
61 			.calcnt = utx->calcnt,
62 			.errcnt = utx->errcnt,
63 			.stbcnt = utx->stbcnt,
64 			.tai = utx->tai,
65 		};
66 		r = __syscall(SYS_clock_adjtime, clock_id, &ktx);
67 		if (r>=0) {
68 			utx->modes = ktx.modes;
69 			utx->offset = ktx.offset;
70 			utx->freq = ktx.freq;
71 			utx->maxerror = ktx.maxerror;
72 			utx->esterror = ktx.esterror;
73 			utx->status = ktx.status;
74 			utx->constant = ktx.constant;
75 			utx->precision = ktx.precision;
76 			utx->tolerance = ktx.tolerance;
77 			utx->time.tv_sec = ktx.time_sec;
78 			utx->time.tv_usec = ktx.time_usec;
79 			utx->tick = ktx.tick;
80 			utx->ppsfreq = ktx.ppsfreq;
81 			utx->jitter = ktx.jitter;
82 			utx->shift = ktx.shift;
83 			utx->stabil = ktx.stabil;
84 			utx->jitcnt = ktx.jitcnt;
85 			utx->calcnt = ktx.calcnt;
86 			utx->errcnt = ktx.errcnt;
87 			utx->stbcnt = ktx.stbcnt;
88 			utx->tai = ktx.tai;
89 		}
90 	}
91 	if (SYS_clock_adjtime == SYS_clock_adjtime64 || r!=-ENOSYS)
92 		return __syscall_ret(r);
93 	if ((utx->modes & ADJ_SETOFFSET) && !IS32BIT(utx->time.tv_sec))
94 		return __syscall_ret(-ENOTSUP);
95 #endif
96 	if (sizeof(time_t) > sizeof(long)) {
97 		struct ktimex ktx = {
98 			.modes = utx->modes,
99 			.offset = utx->offset,
100 			.freq = utx->freq,
101 			.maxerror = utx->maxerror,
102 			.esterror = utx->esterror,
103 			.status = utx->status,
104 			.constant = utx->constant,
105 			.precision = utx->precision,
106 			.tolerance = utx->tolerance,
107 			.time_sec = utx->time.tv_sec,
108 			.time_usec = utx->time.tv_usec,
109 			.tick = utx->tick,
110 			.ppsfreq = utx->ppsfreq,
111 			.jitter = utx->jitter,
112 			.shift = utx->shift,
113 			.stabil = utx->stabil,
114 			.jitcnt = utx->jitcnt,
115 			.calcnt = utx->calcnt,
116 			.errcnt = utx->errcnt,
117 			.stbcnt = utx->stbcnt,
118 			.tai = utx->tai,
119 		};
120 #ifdef SYS_adjtimex
121 		if (clock_id==CLOCK_REALTIME) r = __syscall(SYS_adjtimex, &ktx);
122 		else
123 #endif
124 		r = __syscall(SYS_clock_adjtime, clock_id, &ktx);
125 		if (r>=0) {
126 			utx->modes = ktx.modes;
127 			utx->offset = ktx.offset;
128 			utx->freq = ktx.freq;
129 			utx->maxerror = ktx.maxerror;
130 			utx->esterror = ktx.esterror;
131 			utx->status = ktx.status;
132 			utx->constant = ktx.constant;
133 			utx->precision = ktx.precision;
134 			utx->tolerance = ktx.tolerance;
135 			utx->time.tv_sec = ktx.time_sec;
136 			utx->time.tv_usec = ktx.time_usec;
137 			utx->tick = ktx.tick;
138 			utx->ppsfreq = ktx.ppsfreq;
139 			utx->jitter = ktx.jitter;
140 			utx->shift = ktx.shift;
141 			utx->stabil = ktx.stabil;
142 			utx->jitcnt = ktx.jitcnt;
143 			utx->calcnt = ktx.calcnt;
144 			utx->errcnt = ktx.errcnt;
145 			utx->stbcnt = ktx.stbcnt;
146 			utx->tai = ktx.tai;
147 		}
148 		return __syscall_ret(r);
149 	}
150 #ifdef SYS_adjtimex
151 	if (clock_id==CLOCK_REALTIME) return syscall(SYS_adjtimex, utx);
152 #endif
153 	return syscall(SYS_clock_adjtime, clock_id, utx);
154 }
155