1  /* adjtime -- adjust the system clock.  Linux/Alpha/tv32 version.
       2     Copyright (C) 2019-2023 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
      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
      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 */