Update to LGPL v2.1.
[jlayton/glibc.git] / sysdeps / unix / sysv / linux / adjtime.c
1 /* Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, write to the Free
16    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17    02111-1307 USA.  */
18
19 #include <errno.h>
20 #include <limits.h>
21 #include <sys/time.h>
22 #include <sys/timex.h>
23
24 #define MAX_SEC (INT_MAX / 1000000L - 2)
25 #define MIN_SEC (INT_MIN / 1000000L + 2)
26
27 #ifndef MOD_OFFSET
28 #define modes mode
29 #endif
30
31 #ifndef TIMEVAL
32 #define TIMEVAL timeval
33 #endif
34
35 #ifndef TIMEX
36 #define TIMEX timex
37 #endif
38
39 #ifndef ADJTIME
40 #define ADJTIME __adjtime
41 #endif
42
43 #ifndef ADJTIMEX
44 #define NO_LOCAL_ADJTIME
45 #define ADJTIMEX(x) __adjtimex (x)
46 #endif
47
48 #ifndef LINKAGE
49 #define LINKAGE
50 #endif
51
52 LINKAGE int
53 ADJTIME (itv, otv)
54      const struct TIMEVAL *itv;
55      struct TIMEVAL *otv;
56 {
57   struct TIMEX tntx;
58
59   if (itv)
60     {
61       struct TIMEVAL tmp;
62
63       /* We will do some check here. */
64       tmp.tv_sec = itv->tv_sec + itv->tv_usec / 1000000L;
65       tmp.tv_usec = itv->tv_usec % 1000000L;
66       if (tmp.tv_sec > MAX_SEC || tmp.tv_sec < MIN_SEC)
67         {
68           __set_errno (EINVAL);
69           return -1;
70         }
71       tntx.offset = tmp.tv_usec + tmp.tv_sec * 1000000L;
72       tntx.modes = ADJ_OFFSET_SINGLESHOT;
73     }
74   else
75     tntx.modes = 0;
76
77   if (ADJTIMEX (&tntx) < 0)
78     return -1;
79
80   if (otv)
81     {
82       if (tntx.offset < 0)
83         {
84           otv->tv_usec = -(-tntx.offset % 1000000);
85           otv->tv_sec  = -(-tntx.offset / 1000000);
86         }
87       else
88         {
89           otv->tv_usec = tntx.offset % 1000000;
90           otv->tv_sec  = tntx.offset / 1000000;
91         }
92     }
93   return 0;
94 }
95
96 #ifdef NO_LOCAL_ADJTIME
97 weak_alias (__adjtime, adjtime)
98 #endif