Back to index

glibc  2.9
adjtime.c
Go to the documentation of this file.
00001 /* Copyright (C) 1998,2000,2002,2003,2004,2006 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003 
00004    The GNU C Library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Lesser General Public
00006    License as published by the Free Software Foundation; either
00007    version 2.1 of the License, or (at your option) any later version.
00008 
00009    The GNU C Library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Lesser General Public License for more details.
00013 
00014    You should have received a copy of the GNU Lesser General Public
00015    License along with the GNU C Library; if not, write to the Free
00016    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00017    02111-1307 USA.  */
00018 
00019 #include <shlib-compat.h>
00020 #include <sysdep.h>
00021 #include <sys/time.h>
00022 #include <kernel-features.h>
00023 
00024 #if !defined __ASSUME_TIMEVAL64 || SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
00025 struct timeval32
00026 {
00027     int tv_sec, tv_usec;
00028 };
00029 
00030 struct timex32 {
00031        unsigned int modes;  /* mode selector */
00032        long offset;         /* time offset (usec) */
00033        long freq;           /* frequency offset (scaled ppm) */
00034        long maxerror;              /* maximum error (usec) */
00035        long esterror;              /* estimated error (usec) */
00036        int status;          /* clock command/status */
00037        long constant;              /* pll time constant */
00038        long precision;             /* clock precision (usec) (read only) */
00039        long tolerance;             /* clock frequency tolerance (ppm)
00040                              * (read only)
00041                              */
00042        struct timeval32 time;      /* (read only) */
00043        long tick;           /* (modified) usecs between clock ticks */
00044 
00045        long ppsfreq;           /* pps frequency (scaled ppm) (ro) */
00046        long jitter;            /* pps jitter (us) (ro) */
00047        int shift;              /* interval duration (s) (shift) (ro) */
00048        long stabil;            /* pps stability (scaled ppm) (ro) */
00049        long jitcnt;            /* jitter limit exceeded (ro) */
00050        long calcnt;            /* calibration intervals (ro) */
00051        long errcnt;            /* calibration errors (ro) */
00052        long stbcnt;            /* stability limit exceeded (ro) */
00053 
00054        int  :32; int  :32; int  :32; int  :32;
00055        int  :32; int  :32; int  :32; int  :32;
00056        int  :32; int  :32; int  :32; int  :32;
00057 };
00058 
00059 #define TIMEVAL             timeval32
00060 #define TIMEX        timex32
00061 #define ADJTIME             attribute_compat_text_section __adjtime_tv32
00062 #define ADJTIMEX(x)  INLINE_SYSCALL (old_adjtimex, 1, x)
00063 #define ADJTIMEX32(x)       INLINE_SYSCALL (old_adjtimex, 1, x)
00064 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
00065 #define LINKAGE
00066 #else
00067 #define LINKAGE             static
00068 #endif
00069 
00070 LINKAGE int ADJTIME (const struct TIMEVAL *itv, struct TIMEVAL *otv);
00071 
00072 #include <sysdeps/unix/sysv/linux/adjtime.c>
00073 
00074 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
00075 int
00076 attribute_compat_text_section
00077 __adjtimex_tv32 (struct timex32 *tx) { return ADJTIMEX (tx); }
00078 strong_alias (__adjtimex_tv32, __adjtimex_tv32_1);
00079 strong_alias (__adjtimex_tv32, __adjtimex_tv32_2);
00080 compat_symbol (libc, __adjtimex_tv32_1, __adjtimex, GLIBC_2_0);
00081 compat_symbol (libc, __adjtimex_tv32_2, adjtimex, GLIBC_2_0);
00082 compat_symbol (libc, __adjtime_tv32, adjtime, GLIBC_2_0);
00083 #endif
00084 #endif /* !__ASSUME_TIMEVAL64 || SHLIB_COMPAT */
00085 
00086 #undef TIMEVAL
00087 #define TIMEVAL             timeval
00088 #undef TIMEX
00089 #define TIMEX        timex
00090 #undef ADJTIMEX
00091 #define ADJTIMEX(x)  INLINE_SYSCALL (adjtimex, 1, x)
00092 
00093 #undef LINKAGE
00094 #undef ADJTIME
00095 #if !defined __ASSUME_TIMEVAL64
00096 #define LINKAGE             static
00097 #define ADJTIME             __adjtime_tv64
00098 #endif
00099 
00100 #include <sysdeps/unix/sysv/linux/adjtime.c>
00101 #include <stdbool.h>
00102 
00103 #if !defined __ASSUME_TIMEVAL64
00104 static bool missing_adjtimex;
00105 
00106 int
00107 __adjtime (itv, otv)
00108      const struct timeval *itv;
00109      struct timeval *otv;
00110 {
00111   struct timeval32 itv32, otv32;
00112   int ret;
00113 
00114   switch (missing_adjtimex)
00115     {
00116     case false:
00117       ret = __adjtime_tv64 (itv, otv);
00118       if (ret && errno == ENOSYS)
00119        missing_adjtimex = 1;
00120       else
00121        break;
00122 
00123       /* FALLTHRU */
00124 
00125     default:
00126       itv32.tv_sec = itv->tv_sec;
00127       itv32.tv_usec = itv->tv_usec;
00128       ret = __adjtime_tv32 (&itv32, &otv32);
00129       if (ret == 0)
00130        {
00131          otv->tv_sec = otv32.tv_sec;
00132          otv->tv_usec = otv32.tv_usec;
00133        }
00134       break;
00135     }
00136 
00137   return ret;
00138 }
00139 #endif
00140 
00141 versioned_symbol (libc, __adjtime, adjtime, GLIBC_2_1);
00142 
00143 int
00144 __adjtimex_tv64 (struct timex *tx)
00145 {
00146 #if defined __ASSUME_TIMEVAL64
00147   return ADJTIMEX (tx);
00148 #else
00149   struct timex32 tx32;
00150   int ret;
00151 
00152   switch (missing_adjtimex)
00153     {
00154     case false:
00155       ret = ADJTIMEX (tx);
00156       if (ret && errno == ENOSYS)
00157        missing_adjtimex = 1;
00158       else
00159        break;
00160 
00161       /* FALLTHRU */
00162 
00163     default:
00164       tx32.modes = tx->modes;
00165       tx32.offset = tx->offset;
00166       tx32.freq = tx->freq;
00167       tx32.maxerror = tx->maxerror;
00168       tx32.esterror = tx->esterror;
00169       tx32.status = tx->status;
00170       tx32.constant = tx->constant;
00171       tx32.precision = tx->precision;
00172       tx32.tolerance = tx->tolerance;
00173       tx32.time.tv_sec = tx->time.tv_sec;
00174       tx32.time.tv_sec = tx->time.tv_usec;
00175       tx32.tick = tx->tick;
00176       tx32.ppsfreq = tx->ppsfreq;
00177       tx32.jitter = tx->jitter;
00178       tx32.shift = tx->shift;
00179       tx32.stabil = tx->stabil;
00180       tx32.jitcnt = tx->jitcnt;
00181       tx32.calcnt = tx->calcnt;
00182       tx32.errcnt = tx->errcnt;
00183       tx32.stbcnt = tx->stbcnt;
00184 
00185       ret = ADJTIMEX32 (&tx32);
00186       if (ret == 0)
00187        {
00188          tx->modes = tx32.modes;
00189          tx->offset = tx32.offset;
00190          tx->freq = tx32.freq;
00191          tx->maxerror = tx32.maxerror;
00192          tx->esterror = tx32.esterror;
00193          tx->status = tx32.status;
00194          tx->constant = tx32.constant;
00195          tx->precision = tx32.precision;
00196          tx->tolerance = tx32.tolerance;
00197          tx->time.tv_sec = tx32.time.tv_sec;
00198          tx->time.tv_usec = tx32.time.tv_sec;
00199          tx->tick = tx32.tick;
00200          tx->ppsfreq = tx32.ppsfreq;
00201          tx->jitter = tx32.jitter;
00202          tx->shift = tx32.shift;
00203          tx->stabil = tx32.stabil;
00204          tx->jitcnt = tx32.jitcnt;
00205          tx->calcnt = tx32.calcnt;
00206          tx->errcnt = tx32.errcnt;
00207          tx->stbcnt = tx32.stbcnt;
00208        }
00209       break;
00210     }
00211 
00212   return ret;
00213 #endif
00214 }
00215 
00216 strong_alias (__adjtimex_tv64, __adjtimex_internal);
00217 strong_alias (__adjtimex_tv64, __adjtimex_tv64p);
00218 weak_alias (__adjtimex_tv64, ntp_adjtime);
00219 versioned_symbol (libc, __adjtimex_tv64, __adjtimex, GLIBC_2_1);
00220 versioned_symbol (libc, __adjtimex_tv64p, adjtimex, GLIBC_2_1);