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 	struct ktimex64 ktx = {
42 		.modes = utx->modes,
43 		.offset = utx->offset,
44 		.freq = utx->freq,
45 		.maxerror = utx->maxerror,
46 		.esterror = utx->esterror,
47 		.status = utx->status,
48 		.constant = utx->constant,
49 		.precision = utx->precision,
50 		.tolerance = utx->tolerance,
51 		.time_sec = utx->time.tv_sec,
52 		.time_usec = utx->time.tv_usec,
53 		.tick = utx->tick,
54 		.ppsfreq = utx->ppsfreq,
55 		.jitter = utx->jitter,
56 		.shift = utx->shift,
57 		.stabil = utx->stabil,
58 		.jitcnt = utx->jitcnt,
59 		.calcnt = utx->calcnt,
60 		.errcnt = utx->errcnt,
61 		.stbcnt = utx->stbcnt,
62 		.tai = utx->tai,
63 	};
64 	r = __syscall(SYS_clock_adjtime64, clock_id, &ktx);
65 	if (r>=0) {
66 		utx->modes = ktx.modes;
67 		utx->offset = ktx.offset;
68 		utx->freq = ktx.freq;
69 		utx->maxerror = ktx.maxerror;
70 		utx->esterror = ktx.esterror;
71 		utx->status = ktx.status;
72 		utx->constant = ktx.constant;
73 		utx->precision = ktx.precision;
74 		utx->tolerance = ktx.tolerance;
75 		utx->time.tv_sec = ktx.time_sec;
76 		utx->time.tv_usec = ktx.time_usec;
77 		utx->tick = ktx.tick;
78 		utx->ppsfreq = ktx.ppsfreq;
79 		utx->jitter = ktx.jitter;
80 		utx->shift = ktx.shift;
81 		utx->stabil = ktx.stabil;
82 		utx->jitcnt = ktx.jitcnt;
83 		utx->calcnt = ktx.calcnt;
84 		utx->errcnt = ktx.errcnt;
85 		utx->stbcnt = ktx.stbcnt;
86 		utx->tai = ktx.tai;
87 	}
88 	if (SYS_clock_adjtime == SYS_clock_adjtime64 || r!=-ENOSYS)
89 		return __syscall_ret(r);
90 	if ((utx->modes & ADJ_SETOFFSET) && !IS32BIT(utx->time.tv_sec))
91 		return __syscall_ret(-ENOTSUP);
92 #endif
93 	if (sizeof(time_t) > sizeof(long)) {
94 		struct ktimex ktx = {
95 			.modes = utx->modes,
96 			.offset = utx->offset,
97 			.freq = utx->freq,
98 			.maxerror = utx->maxerror,
99 			.esterror = utx->esterror,
100 			.status = utx->status,
101 			.constant = utx->constant,
102 			.precision = utx->precision,
103 			.tolerance = utx->tolerance,
104 			.time_sec = utx->time.tv_sec,
105 			.time_usec = utx->time.tv_usec,
106 			.tick = utx->tick,
107 			.ppsfreq = utx->ppsfreq,
108 			.jitter = utx->jitter,
109 			.shift = utx->shift,
110 			.stabil = utx->stabil,
111 			.jitcnt = utx->jitcnt,
112 			.calcnt = utx->calcnt,
113 			.errcnt = utx->errcnt,
114 			.stbcnt = utx->stbcnt,
115 			.tai = utx->tai,
116 		};
117 #ifdef SYS_adjtimex
118 		if (clock_id==CLOCK_REALTIME) r = __syscall(SYS_adjtimex, &ktx);
119 		else
120 #endif
121 		r = __syscall(SYS_clock_adjtime, clock_id, &ktx);
122 		if (r>=0) {
123 			utx->modes = ktx.modes;
124 			utx->offset = ktx.offset;
125 			utx->freq = ktx.freq;
126 			utx->maxerror = ktx.maxerror;
127 			utx->esterror = ktx.esterror;
128 			utx->status = ktx.status;
129 			utx->constant = ktx.constant;
130 			utx->precision = ktx.precision;
131 			utx->tolerance = ktx.tolerance;
132 			utx->time.tv_sec = ktx.time_sec;
133 			utx->time.tv_usec = ktx.time_usec;
134 			utx->tick = ktx.tick;
135 			utx->ppsfreq = ktx.ppsfreq;
136 			utx->jitter = ktx.jitter;
137 			utx->shift = ktx.shift;
138 			utx->stabil = ktx.stabil;
139 			utx->jitcnt = ktx.jitcnt;
140 			utx->calcnt = ktx.calcnt;
141 			utx->errcnt = ktx.errcnt;
142 			utx->stbcnt = ktx.stbcnt;
143 			utx->tai = ktx.tai;
144 		}
145 		return __syscall_ret(r);
146 	}
147 #ifdef SYS_adjtimex
148 	if (clock_id==CLOCK_REALTIME) return syscall(SYS_adjtimex, utx);
149 #endif
150 	return syscall(SYS_clock_adjtime, clock_id, utx);
151 }
152