]>
Commit | Line | Data |
---|---|---|
320054e8 | 1 | #include <sys/timex.h> |
79a9b408 DG |
2 | #include <time.h> |
3 | #include <errno.h> | |
320054e8 DG |
4 | #include "syscall.h" |
5 | ||
79a9b408 DG |
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 | ||
320054e8 DG |
37 | int clock_adjtime (clockid_t clock_id, struct timex *utx) |
38 | { | |
79a9b408 DG |
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 | union { | |
98 | struct timex utx; | |
99 | struct ktimex ktx; | |
100 | } u = { *utx }; | |
101 | u.ktx.time_sec = utx->time.tv_sec; | |
102 | u.ktx.time_usec = utx->time.tv_usec; | |
103 | #ifdef SYS_adjtimex | |
104 | if (clock_id==CLOCK_REALTIME) r = __syscall(SYS_adjtimex, &u); | |
105 | else | |
106 | #endif | |
107 | r = __syscall(SYS_clock_adjtime, clock_id, &u); | |
108 | if (r>=0) { | |
109 | *utx = u.utx; | |
110 | utx->time.tv_sec = u.ktx.time_sec; | |
111 | utx->time.tv_usec = u.ktx.time_usec; | |
112 | } | |
113 | return __syscall_ret(r); | |
114 | } | |
115 | #ifdef SYS_adjtimex | |
116 | if (clock_id==CLOCK_REALTIME) return syscall(SYS_adjtimex, utx); | |
117 | #endif | |
320054e8 DG |
118 | return syscall(SYS_clock_adjtime, clock_id, utx); |
119 | } |