1 /* Copyright (C) 1995-2022 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, see
16    <https://www.gnu.org/licenses/>.  */
17 
18 #include <errno.h>
19 #include <limits.h>
20 #include <sys/time.h>
21 #include <sys/timex.h>
22 #include <sysdep.h>
23 
24 #define MAX_SEC	(INT_MAX / 1000000L - 2)
25 #define MIN_SEC	(INT_MIN / 1000000L + 2)
26 
27 int
__adjtime64(const struct __timeval64 * itv,struct __timeval64 * otv)28 __adjtime64 (const struct __timeval64 *itv, struct __timeval64 *otv)
29 {
30   struct __timex64 tntx;
31 
32   if (itv)
33     {
34       struct __timeval64 tmp;
35 
36       /* We will do some check here. */
37       tmp.tv_sec = itv->tv_sec + itv->tv_usec / 1000000L;
38       tmp.tv_usec = itv->tv_usec % 1000000L;
39       if (tmp.tv_sec > MAX_SEC || tmp.tv_sec < MIN_SEC)
40 	return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
41       tntx.offset = tmp.tv_usec + tmp.tv_sec * 1000000L;
42       tntx.modes = ADJ_OFFSET_SINGLESHOT;
43     }
44   else
45     tntx.modes = ADJ_OFFSET_SS_READ;
46 
47   if (__glibc_unlikely (__clock_adjtime64 (CLOCK_REALTIME, &tntx) < 0))
48     return -1;
49 
50   if (otv)
51     {
52       if (tntx.offset < 0)
53 	{
54 	  otv->tv_usec = -(-tntx.offset % 1000000);
55 	  otv->tv_sec  = -(-tntx.offset / 1000000);
56 	}
57       else
58 	{
59 	  otv->tv_usec = tntx.offset % 1000000;
60 	  otv->tv_sec  = tntx.offset / 1000000;
61 	}
62     }
63   return 0;
64 }
65 
66 #if __TIMESIZE != 64
libc_hidden_def(__adjtime64)67 libc_hidden_def (__adjtime64)
68 
69 int
70 __adjtime (const struct timeval *itv, struct timeval *otv)
71 {
72   struct __timeval64 itv64, *pitv64 = NULL;
73   struct __timeval64 otv64;
74   int retval;
75 
76   if (itv != NULL)
77     {
78       itv64 = valid_timeval_to_timeval64 (*itv);
79       pitv64 = &itv64;
80     }
81   retval = __adjtime64 (pitv64, otv != NULL ? &otv64 : NULL);
82   if (otv != NULL)
83     *otv = valid_timeval64_to_timeval (otv64);
84 
85   return retval;
86 }
87 #endif
88 
89 #ifdef VERSION_adjtime
90 weak_alias (__adjtime, __wadjtime);
91 default_symbol_version (__wadjtime, adjtime, VERSION_adjtime);
92 #else
93 weak_alias (__adjtime, adjtime)
94 #endif
95