1 /* adjtime -- adjust the system clock.  Linux/Alpha/tv32 version.
2    Copyright (C) 2019-2022 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <http://www.gnu.org/licenses/>.  */
18 
19 #include <shlib-compat.h>
20 
21 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
22 
23 #include <time.h>
24 #include <sys/time.h>
25 #include <sys/timex.h>
26 #include <string.h>
27 
28 struct timex32 {
29 	unsigned int modes;	/* mode selector */
30 	long offset;		/* time offset (usec) */
31 	long freq;		/* frequency offset (scaled ppm) */
32 	long maxerror;		/* maximum error (usec) */
33 	long esterror;		/* estimated error (usec) */
34 	int status;		/* clock command/status */
35 	long constant;		/* pll time constant */
36 	long precision;		/* clock precision (usec) (read only) */
37 	long tolerance;		/* clock frequency tolerance (ppm)
38 				 * (read only)
39 				 */
40 	struct __timeval32 time;	/* (read only) */
41 	long tick;		/* (modified) usecs between clock ticks */
42 
43 	long ppsfreq;           /* pps frequency (scaled ppm) (ro) */
44 	long jitter;            /* pps jitter (us) (ro) */
45 	int shift;              /* interval duration (s) (shift) (ro) */
46 	long stabil;            /* pps stability (scaled ppm) (ro) */
47 	long jitcnt;            /* jitter limit exceeded (ro) */
48 	long calcnt;            /* calibration intervals (ro) */
49 	long errcnt;            /* calibration errors (ro) */
50 	long stbcnt;            /* stability limit exceeded (ro) */
51 
52 	int  :32; int  :32; int  :32; int  :32;
53 	int  :32; int  :32; int  :32; int  :32;
54 	int  :32; int  :32; int  :32; int  :32;
55 };
56 
57 int
58 attribute_compat_text_section
__adjtime_tv32(const struct __timeval32 * itv,struct __timeval32 * otv)59 __adjtime_tv32 (const struct __timeval32 *itv, struct __timeval32 *otv)
60 {
61   struct timeval itv64 = valid_timeval32_to_timeval (*itv);
62   struct timeval otv64;
63 
64   if (__adjtime (&itv64, &otv64) == -1)
65     return -1;
66 
67   *otv = valid_timeval_to_timeval32 (otv64);
68   return 0;
69 }
70 
71 int
72 attribute_compat_text_section
__adjtimex_tv32(struct timex32 * tx)73 __adjtimex_tv32 (struct timex32 *tx)
74 {
75   struct timex tx64;
76   memset (&tx64, 0, sizeof tx64);
77   tx64.modes     = tx->modes;
78   tx64.offset    = tx->offset;
79   tx64.freq      = tx->freq;
80   tx64.maxerror  = tx->maxerror;
81   tx64.esterror  = tx->esterror;
82   tx64.status    = tx->status;
83   tx64.constant  = tx->constant;
84   tx64.precision = tx->precision;
85   tx64.tolerance = tx->tolerance;
86   tx64.tick      = tx->tick;
87   tx64.ppsfreq   = tx->ppsfreq;
88   tx64.jitter    = tx->jitter;
89   tx64.shift     = tx->shift;
90   tx64.stabil    = tx->stabil;
91   tx64.jitcnt    = tx->jitcnt;
92   tx64.calcnt    = tx->calcnt;
93   tx64.errcnt    = tx->errcnt;
94   tx64.stbcnt    = tx->stbcnt;
95   tx64.time      = valid_timeval32_to_timeval (tx->time);
96 
97   int status = __adjtimex (&tx64);
98   if (status < 0)
99     return status;
100 
101   memset (tx, 0, sizeof *tx);
102   tx->modes     = tx64.modes;
103   tx->offset    = tx64.offset;
104   tx->freq      = tx64.freq;
105   tx->maxerror  = tx64.maxerror;
106   tx->esterror  = tx64.esterror;
107   tx->status    = tx64.status;
108   tx->constant  = tx64.constant;
109   tx->precision = tx64.precision;
110   tx->tolerance = tx64.tolerance;
111   tx->tick      = tx64.tick;
112   tx->ppsfreq   = tx64.ppsfreq;
113   tx->jitter    = tx64.jitter;
114   tx->shift     = tx64.shift;
115   tx->stabil    = tx64.stabil;
116   tx->jitcnt    = tx64.jitcnt;
117   tx->calcnt    = tx64.calcnt;
118   tx->errcnt    = tx64.errcnt;
119   tx->stbcnt    = tx64.stbcnt;
120   tx->time      = valid_timeval_to_timeval32 (tx64.time);
121 
122   return status;
123 }
124 
125 strong_alias (__adjtimex_tv32, __adjtimex_tv32_1);
126 strong_alias (__adjtimex_tv32, __adjtimex_tv32_2);
127 compat_symbol (libc, __adjtimex_tv32_1, __adjtimex, GLIBC_2_0);
128 compat_symbol (libc, __adjtimex_tv32_2, adjtimex, GLIBC_2_0);
129 compat_symbol (libc, __adjtime_tv32, adjtime, GLIBC_2_0);
130 
131 #endif /* SHLIB_COMPAT */
132