1  /* Synchronous I/O multiplexing.  Linux/microblaze version.
       2     Copyright (C) 2019-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
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the 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 <errno.h>
      20  #include <signal.h>
      21  #include <time.h>
      22  #include <sys/poll.h>
      23  #include <sysdep-cancel.h>
      24  
      25  #ifndef __ASSUME_TIME64_SYSCALL
      26  #include <sysdeps/unix/sysv/linux/pselect32.c>
      27  #elif !defined __ASSUME_PSELECT
      28  int
      29  __pselect32 (int nfds, fd_set *readfds, fd_set *writefds,
      30  	     fd_set *exceptfds, const struct __timespec64 *timeout,
      31  	     const sigset_t *sigmask)
      32  {
      33    /* The fallback uses 'select' which shows the race condition regarding
      34       signal mask set/restore, requires two additional syscalls, and has
      35       a worse timeout precision (microseconds instead of nanoseconds).  */
      36  
      37    struct timeval tv32, *ptv32 = NULL;
      38    if (timeout != NULL)
      39      {
      40        if (! valid_nanoseconds (timeout->tv_nsec))
      41  	{
      42  	  __set_errno (EINVAL);
      43  	  return -1;
      44  	}
      45  
      46        tv32 = valid_timespec64_to_timeval (*timeout);
      47        ptv32 = &tv32;
      48      }
      49  
      50    sigset_t savemask;
      51    if (sigmask != NULL)
      52      __sigprocmask (SIG_SETMASK, sigmask, &savemask);
      53  
      54    /* select itself is a cancellation entrypoint.  */
      55    int ret = __select (nfds, readfds, writefds, exceptfds, ptv32);
      56  
      57    if (sigmask != NULL)
      58      __sigprocmask (SIG_SETMASK, &savemask, NULL);
      59  
      60    return ret;
      61  }
      62  #endif /* __ASSUME_PSELECT  */