]> git.proxmox.com Git - wasi-libc.git/blobdiff - libc-top-half/musl/src/linux/clock_adjtime.c
Update to musl 1.1.24.
[wasi-libc.git] / libc-top-half / musl / src / linux / clock_adjtime.c
index 056ad6d34104cfa35064ea293763a94fffbd0372..2f531397c3309618d28186fdfff3ba368559700b 100644 (file)
@@ -1,7 +1,119 @@
 #include <sys/timex.h>
+#include <time.h>
+#include <errno.h>
 #include "syscall.h"
 
+#define IS32BIT(x) !((x)+0x80000000ULL>>32)
+
+struct ktimex64 {
+       unsigned modes;
+       int :32;
+       long long offset, freq, maxerror, esterror;
+       int status;
+       int :32;
+       long long constant, precision, tolerance;
+       long long time_sec, time_usec;
+       long long tick, ppsfreq, jitter;
+       int shift;
+       int :32;
+       long long stabil, jitcnt, calcnt, errcnt, stbcnt;
+       int tai;
+       int __padding[11];
+};
+
+struct ktimex {
+       unsigned modes;
+       long offset, freq, maxerror, esterror;
+       int status;
+       long constant, precision, tolerance;
+       long time_sec, time_usec;
+       long tick, ppsfreq, jitter;
+       int shift;
+       long stabil, jitcnt, calcnt, errcnt, stbcnt;
+       int tai;
+       int __padding[11];
+};
+
 int clock_adjtime (clockid_t clock_id, struct timex *utx)
 {
+       int r = -ENOSYS;
+#ifdef SYS_clock_adjtime64
+       if (SYS_clock_adjtime == SYS_clock_adjtime64 ||
+           (utx->modes & ADJ_SETOFFSET) && !IS32BIT(utx->time.tv_sec)) {
+               struct ktimex64 ktx = {
+                       .modes = utx->modes,
+                       .offset = utx->offset,
+                       .freq = utx->freq,
+                       .maxerror = utx->maxerror,
+                       .esterror = utx->esterror,
+                       .status = utx->status,
+                       .constant = utx->constant,
+                       .precision = utx->precision,
+                       .tolerance = utx->tolerance,
+                       .time_sec = utx->time.tv_sec,
+                       .time_usec = utx->time.tv_usec,
+                       .tick = utx->tick,
+                       .ppsfreq = utx->ppsfreq,
+                       .jitter = utx->jitter,
+                       .shift = utx->shift,
+                       .stabil = utx->stabil,
+                       .jitcnt = utx->jitcnt,
+                       .calcnt = utx->calcnt,
+                       .errcnt = utx->errcnt,
+                       .stbcnt = utx->stbcnt,
+                       .tai = utx->tai,
+               };
+               r = __syscall(SYS_clock_adjtime, clock_id, &ktx);
+               if (r>=0) {
+                       utx->modes = ktx.modes;
+                       utx->offset = ktx.offset;
+                       utx->freq = ktx.freq;
+                       utx->maxerror = ktx.maxerror;
+                       utx->esterror = ktx.esterror;
+                       utx->status = ktx.status;
+                       utx->constant = ktx.constant;
+                       utx->precision = ktx.precision;
+                       utx->tolerance = ktx.tolerance;
+                       utx->time.tv_sec = ktx.time_sec;
+                       utx->time.tv_usec = ktx.time_usec;
+                       utx->tick = ktx.tick;
+                       utx->ppsfreq = ktx.ppsfreq;
+                       utx->jitter = ktx.jitter;
+                       utx->shift = ktx.shift;
+                       utx->stabil = ktx.stabil;
+                       utx->jitcnt = ktx.jitcnt;
+                       utx->calcnt = ktx.calcnt;
+                       utx->errcnt = ktx.errcnt;
+                       utx->stbcnt = ktx.stbcnt;
+                       utx->tai = ktx.tai;
+               }
+       }
+       if (SYS_clock_adjtime == SYS_clock_adjtime64 || r!=-ENOSYS)
+               return __syscall_ret(r);
+       if ((utx->modes & ADJ_SETOFFSET) && !IS32BIT(utx->time.tv_sec))
+               return __syscall_ret(-ENOTSUP);
+#endif
+       if (sizeof(time_t) > sizeof(long)) {
+               union {
+                       struct timex utx;
+                       struct ktimex ktx;
+               } u = { *utx };
+               u.ktx.time_sec = utx->time.tv_sec;
+               u.ktx.time_usec = utx->time.tv_usec;
+#ifdef SYS_adjtimex
+               if (clock_id==CLOCK_REALTIME) r = __syscall(SYS_adjtimex, &u);
+               else
+#endif
+               r = __syscall(SYS_clock_adjtime, clock_id, &u);
+               if (r>=0) {
+                       *utx = u.utx;
+                       utx->time.tv_sec = u.ktx.time_sec;
+                       utx->time.tv_usec = u.ktx.time_usec;
+               }
+               return __syscall_ret(r);
+       }
+#ifdef SYS_adjtimex
+       if (clock_id==CLOCK_REALTIME) return syscall(SYS_adjtimex, utx);
+#endif
        return syscall(SYS_clock_adjtime, clock_id, utx);
 }