Back to index

glibc  2.9
adjtime.c
Go to the documentation of this file.
00001 /* Copyright (C) 1995, 1996, 1997, 1998, 2002, 2004, 2007, 2008
00002    Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #include <errno.h>
00021 #include <limits.h>
00022 #include <sys/time.h>
00023 #include <sys/timex.h>
00024 
00025 #include <kernel-features.h>
00026 
00027 #define MAX_SEC      (INT_MAX / 1000000L - 2)
00028 #define MIN_SEC      (INT_MIN / 1000000L + 2)
00029 
00030 #ifndef MOD_OFFSET
00031 #define modes mode
00032 #endif
00033 
00034 #ifndef TIMEVAL
00035 #define TIMEVAL timeval
00036 #endif
00037 
00038 #ifndef TIMEX
00039 #define TIMEX timex
00040 #endif
00041 
00042 #ifndef ADJTIME
00043 #define ADJTIME __adjtime
00044 #endif
00045 
00046 #ifndef ADJTIMEX
00047 #define NO_LOCAL_ADJTIME
00048 #define ADJTIMEX(x) INTUSE(__adjtimex) (x)
00049 extern int INTUSE(__adjtimex) (struct timex *__ntx);
00050 #endif
00051 
00052 #ifndef LINKAGE
00053 #define LINKAGE
00054 #endif
00055 
00056 LINKAGE int
00057 ADJTIME (const struct TIMEVAL *itv, struct TIMEVAL *otv)
00058 {
00059   struct TIMEX tntx;
00060 
00061   if (itv)
00062     {
00063       struct TIMEVAL tmp;
00064 
00065       /* We will do some check here. */
00066       tmp.tv_sec = itv->tv_sec + itv->tv_usec / 1000000L;
00067       tmp.tv_usec = itv->tv_usec % 1000000L;
00068       if (tmp.tv_sec > MAX_SEC || tmp.tv_sec < MIN_SEC)
00069        {
00070          __set_errno (EINVAL);
00071          return -1;
00072        }
00073       tntx.offset = tmp.tv_usec + tmp.tv_sec * 1000000L;
00074       tntx.modes = ADJ_OFFSET_SINGLESHOT;
00075     }
00076   else
00077     {
00078 #ifdef ADJ_OFFSET_SS_READ
00079       tntx.modes = ADJ_OFFSET_SS_READ;
00080 #else
00081       tntx.modes = 0;
00082 #endif
00083     }
00084 
00085 #if defined ADJ_OFFSET_SS_READ && !defined __ASSUME_ADJ_OFFSET_SS_READ
00086  again:
00087 #endif
00088   if (__builtin_expect (ADJTIMEX (&tntx) < 0, 0))
00089     {
00090 #if defined ADJ_OFFSET_SS_READ && !defined __ASSUME_ADJ_OFFSET_SS_READ
00091       if (itv && errno == EINVAL && tntx.modes == ADJ_OFFSET_SS_READ)
00092        {
00093          tntx.modes = ADJ_OFFSET_SINGLESHOT;
00094          goto again;
00095        }
00096 #endif
00097       return -1;
00098     }
00099 
00100   if (otv)
00101     {
00102       if (tntx.offset < 0)
00103        {
00104          otv->tv_usec = -(-tntx.offset % 1000000);
00105          otv->tv_sec  = -(-tntx.offset / 1000000);
00106        }
00107       else
00108        {
00109          otv->tv_usec = tntx.offset % 1000000;
00110          otv->tv_sec  = tntx.offset / 1000000;
00111        }
00112     }
00113   return 0;
00114 }
00115 
00116 #ifdef NO_LOCAL_ADJTIME
00117 weak_alias (__adjtime, adjtime)
00118 #endif