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