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