(root)/
glibc-2.38/
sysdeps/
unix/
sysv/
linux/
sigtimedwait.c
       1  /* Copyright (C) 1997-2023 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 <signal.h>
      19  #include <sysdep.h>
      20  
      21  int
      22  __sigtimedwait64 (const sigset_t *set, siginfo_t *info,
      23  		  const struct __timespec64 *timeout)
      24  {
      25  #ifndef __NR_rt_sigtimedwait_time64
      26  # define __NR_rt_sigtimedwait_time64 __NR_rt_sigtimedwait
      27  #endif
      28  
      29    int result;
      30  #ifdef __ASSUME_TIME64_SYSCALLS
      31    result = SYSCALL_CANCEL (rt_sigtimedwait_time64, set, info, timeout,
      32  			   __NSIG_BYTES);
      33  #else
      34    bool need_time64 = timeout != NULL && !in_int32_t_range (timeout->tv_sec);
      35    if (need_time64)
      36      {
      37        result = SYSCALL_CANCEL (rt_sigtimedwait_time64, set, info, timeout,
      38  			       __NSIG_BYTES);
      39        if (result == 0 || errno != ENOSYS)
      40  	return result;
      41        __set_errno (EOVERFLOW);
      42        return -1;
      43      }
      44    else
      45      {
      46        struct timespec ts32, *pts32 = NULL;
      47        if (timeout != NULL)
      48  	{
      49  	  ts32 = valid_timespec64_to_timespec (*timeout);
      50  	  pts32 = &ts32;
      51  	}
      52        result = SYSCALL_CANCEL (rt_sigtimedwait, set, info, pts32,
      53  			       __NSIG_BYTES);
      54      }
      55  #endif
      56  
      57    /* The kernel generates a SI_TKILL code in si_code in case tkill is
      58       used.  tkill is transparently used in raise().  Since having
      59       SI_TKILL as a code is useful in general we fold the results
      60       here.  */
      61    if (result != -1 && info != NULL && info->si_code == SI_TKILL)
      62      info->si_code = SI_USER;
      63  
      64    return result;
      65  }
      66  #if __TIMESIZE != 64
      67  libc_hidden_def (__sigtimedwait64)
      68  
      69  int
      70  __sigtimedwait (const sigset_t *set, siginfo_t *info,
      71  		const struct timespec *timeout)
      72  {
      73    struct __timespec64 ts64, *pts64 = NULL;
      74    if (timeout != NULL)
      75      {
      76        ts64 = valid_timespec_to_timespec64 (*timeout);
      77        pts64 = &ts64;
      78      }
      79    return __sigtimedwait64 (set, info, pts64);
      80  }
      81  #endif
      82  libc_hidden_def (__sigtimedwait)
      83  weak_alias (__sigtimedwait, sigtimedwait)