(root)/
glibc-2.38/
misc/
tst-pselect.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 <intprops.h>
      20  #include <support/check.h>
      21  #include <support/support.h>
      22  #include <support/xsignal.h>
      23  #include <support/xunistd.h>
      24  #include <support/xtime.h>
      25  #include <stdlib.h>
      26  
      27  static volatile int handler_called;
      28  
      29  static void
      30  handler (int sig)
      31  {
      32    handler_called = 1;
      33  }
      34  
      35  
      36  static void
      37  test_pselect_basic (void)
      38  {
      39    struct sigaction sa;
      40    sa.sa_handler = handler;
      41    sa.sa_flags = 0;
      42    sigemptyset (&sa.sa_mask);
      43  
      44    xsigaction (SIGUSR1, &sa, NULL);
      45  
      46    sa.sa_handler = SIG_IGN;
      47    xsigaction (SIGCHLD, &sa, NULL);
      48  
      49    sigset_t ss_usr1;
      50    sigemptyset (&ss_usr1);
      51    sigaddset (&ss_usr1, SIGUSR1);
      52    TEST_COMPARE (sigprocmask (SIG_BLOCK, &ss_usr1, NULL), 0);
      53  
      54    int fds[2][2];
      55    xpipe (fds[0]);
      56    xpipe (fds[1]);
      57  
      58    fd_set rfds;
      59    FD_ZERO (&rfds);
      60  
      61    sigset_t ss;
      62    TEST_COMPARE (sigprocmask (SIG_SETMASK, NULL, &ss), 0);
      63    sigdelset (&ss, SIGUSR1);
      64  
      65    struct timespec to = { .tv_sec = 0, .tv_nsec = 500000000 };
      66  
      67    pid_t parent = getpid ();
      68    pid_t p = xfork ();
      69    if (p == 0)
      70      {
      71        xclose (fds[0][1]);
      72        xclose (fds[1][0]);
      73  
      74        FD_SET (fds[0][0], &rfds);
      75  
      76        int e;
      77        do
      78  	{
      79  	  if (getppid () != parent)
      80  	    FAIL_EXIT1 ("getppid()=%d != parent=%d", getppid(), parent);
      81  
      82  	  errno = 0;
      83  	  e = pselect (fds[0][0] + 1, &rfds, NULL, NULL, &to, &ss);
      84  	}
      85        while (e == 0);
      86  
      87        TEST_COMPARE (e, -1);
      88        TEST_COMPARE (errno, EINTR);
      89  
      90        TEMP_FAILURE_RETRY (write (fds[1][1], "foo", 3));
      91  
      92        exit (0);
      93      }
      94  
      95    xclose (fds[0][0]);
      96    xclose (fds[1][1]);
      97  
      98    FD_SET (fds[1][0], &rfds);
      99  
     100    TEST_COMPARE (kill (p, SIGUSR1), 0);
     101  
     102    int e = pselect (fds[1][0] + 1, &rfds, NULL, NULL, NULL, &ss);
     103    TEST_COMPARE (e, 1);
     104    TEST_VERIFY (FD_ISSET (fds[1][0], &rfds));
     105  }
     106  
     107  static void
     108  test_pselect_large_timeout (void)
     109  {
     110    support_create_timer (0, 100000000, false, NULL);
     111  
     112    int fds[2];
     113    xpipe (fds);
     114  
     115    fd_set rfds;
     116    FD_ZERO (&rfds);
     117    FD_SET (fds[0], &rfds);
     118  
     119    sigset_t ss;
     120    TEST_COMPARE (sigprocmask (SIG_SETMASK, NULL, &ss), 0);
     121    sigdelset (&ss, SIGALRM);
     122  
     123    struct timespec ts = { TYPE_MAXIMUM (time_t), 0 };
     124  
     125    TEST_COMPARE (pselect (fds[0] + 1, &rfds, NULL, NULL, &ts, &ss), -1);
     126    TEST_VERIFY (errno == EINTR || errno == EOVERFLOW);
     127  }
     128  
     129  static int
     130  do_test (void)
     131  {
     132    test_pselect_basic ();
     133  
     134    test_pselect_large_timeout ();
     135  
     136    return 0;
     137  }
     138  
     139  #include <support/test-driver.c>