(root)/
glibc-2.38/
sysdeps/
unix/
sysv/
linux/
gettimeofday.c
       1  /* gettimeofday - set time.  Linux version.
       2     Copyright (C) 2020-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public License as
       7     published by the Free Software Foundation; either version 2.1 of the
       8     License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <time.h>
      20  #include <string.h>
      21  
      22  /* Optimize the function call by setting the PLT directly to vDSO symbol.  */
      23  #ifdef USE_IFUNC_GETTIMEOFDAY
      24  # include <sysdep.h>
      25  # include <sysdep-vdso.h>
      26  
      27  # ifdef SHARED
      28  # include <dl-vdso.h>
      29  # include <libc-vdso.h>
      30  
      31  static int
      32  __gettimeofday_syscall (struct timeval *restrict tv, void *restrict tz)
      33  {
      34    if (__glibc_unlikely (tz != 0))
      35      memset (tz, 0, sizeof *tz);
      36    return INLINE_SYSCALL_CALL (gettimeofday, tv, tz);
      37  }
      38  
      39  # undef INIT_ARCH
      40  # define INIT_ARCH() \
      41    void *vdso_gettimeofday = dl_vdso_vsym (HAVE_GETTIMEOFDAY_VSYSCALL)
      42  libc_ifunc (__gettimeofday,
      43  	    vdso_gettimeofday ? VDSO_IFUNC_RET (vdso_gettimeofday)
      44  			      : (void *) __gettimeofday_syscall)
      45  
      46  # else
      47  int
      48  __gettimeofday (struct timeval *restrict tv, void *restrict tz)
      49  {
      50    if (__glibc_unlikely (tz != 0))
      51      memset (tz, 0, sizeof *tz);
      52  
      53    return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
      54  }
      55  # endif
      56  weak_alias (__gettimeofday, gettimeofday)
      57  #else /* USE_IFUNC_GETTIMEOFDAY  */
      58  /* Conversion of gettimeofday function to support 64 bit time on archs
      59     with __WORDSIZE == 32 and __TIMESIZE == 32/64  */
      60  #include <errno.h>
      61  
      62  int
      63  __gettimeofday64 (struct __timeval64 *restrict tv, void *restrict tz)
      64  {
      65    if (__glibc_unlikely (tz != 0))
      66      memset (tz, 0, sizeof (struct timezone));
      67  
      68    struct __timespec64 ts64;
      69    if (__clock_gettime64 (CLOCK_REALTIME, &ts64))
      70  	  return -1;
      71  
      72    *tv = timespec64_to_timeval64 (ts64);
      73    return 0;
      74  }
      75  
      76  # if __TIMESIZE != 64
      77  libc_hidden_def (__gettimeofday64)
      78  
      79  int
      80  __gettimeofday (struct timeval *restrict tv, void *restrict tz)
      81  {
      82    struct __timeval64 tv64;
      83    if (__gettimeofday64 (&tv64, tz))
      84  	  return -1;
      85  
      86    if (! in_time_t_range (tv64.tv_sec))
      87      {
      88        __set_errno (EOVERFLOW);
      89        return -1;
      90      }
      91  
      92    *tv = valid_timeval64_to_timeval (tv64);
      93    return 0;
      94  }
      95  # endif
      96  weak_alias (__gettimeofday, gettimeofday)
      97  #endif