(root)/
glibc-2.38/
sysdeps/
unix/
sysv/
linux/
ppoll.c
       1  /* Copyright (C) 2006-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 <errno.h>
      19  #include <signal.h>
      20  #include <time.h>
      21  #include <sys/poll.h>
      22  #include <sysdep-cancel.h>
      23  
      24  int
      25  __ppoll64 (struct pollfd *fds, nfds_t nfds, const struct __timespec64 *timeout,
      26             const sigset_t *sigmask)
      27  {
      28    /* The Linux kernel can in some situations update the timeout value.
      29       We do not want that so use a local variable.  */
      30    struct __timespec64 tval;
      31    if (timeout != NULL)
      32      {
      33        tval = *timeout;
      34        timeout = &tval;
      35      }
      36  
      37  #ifndef __NR_ppoll_time64
      38  # define __NR_ppoll_time64 __NR_ppoll
      39  #endif
      40  
      41  #ifdef __ASSUME_TIME64_SYSCALLS
      42    return SYSCALL_CANCEL (ppoll_time64, fds, nfds, timeout, sigmask,
      43  			 __NSIG_BYTES);
      44  #else
      45    int ret;
      46    bool need_time64 = timeout != NULL && !in_int32_t_range (timeout->tv_sec);
      47    if (need_time64)
      48      {
      49        ret = SYSCALL_CANCEL (ppoll_time64, fds, nfds, timeout, sigmask,
      50  			    __NSIG_BYTES);
      51        if (ret == 0 || errno != ENOSYS)
      52  	return ret;
      53        __set_errno (EOVERFLOW);
      54        return -1;
      55      }
      56  
      57    struct timespec ts32;
      58    if (timeout != NULL)
      59      ts32 = valid_timespec64_to_timespec (*timeout);
      60  
      61    return SYSCALL_CANCEL (ppoll, fds, nfds, timeout ? &ts32 : NULL, sigmask,
      62  			 __NSIG_BYTES);
      63  #endif
      64  }
      65  
      66  #if __TIMESIZE != 64
      67  libc_hidden_def (__ppoll64)
      68  
      69  int
      70  ppoll (struct pollfd *fds, nfds_t nfds, const struct timespec *timeout,
      71           const sigset_t *sigmask)
      72  {
      73    struct __timespec64 ts64;
      74    if (timeout)
      75      ts64 = valid_timespec_to_timespec64 (*timeout);
      76  
      77    return __ppoll64 (fds, nfds, timeout ? &ts64 : NULL, sigmask);
      78  }
      79  #endif
      80  libc_hidden_def (ppoll)