(root)/
glibc-2.38/
signal/
tst-sigwait-eintr.c
       1  /* Check that sigwait does not fail with EINTR (bug 22478).
       2     Copyright (C) 2017-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 <stdio.h>
      22  #include <support/check.h>
      23  #include <support/xunistd.h>
      24  #include <time.h>
      25  #include <unistd.h>
      26  
      27  /* Handler for SIGUSR1.  */
      28  static void
      29  sigusr1_handler (int signo)
      30  {
      31    TEST_VERIFY (signo == SIGUSR1);
      32  }
      33  
      34  /* Spawn a subprocess to send two signals: First SIGUSR1, then
      35     SIGUSR2.  Return the PID of the process.  */
      36  static pid_t
      37  signal_sender (void)
      38  {
      39    pid_t pid = xfork ();
      40    if (pid == 0)
      41      {
      42        static const struct timespec delay = { 1, };
      43        if (nanosleep (&delay, NULL) != 0)
      44          FAIL_EXIT1 ("nanosleep: %m");
      45        if (kill (getppid (), SIGUSR1) != 0)
      46          FAIL_EXIT1 ("kill (SIGUSR1): %m");
      47        if (nanosleep (&delay, NULL) != 0)
      48          FAIL_EXIT1 ("nanosleep: %m");
      49        if (kill (getppid (), SIGUSR2) != 0)
      50          FAIL_EXIT1 ("kill (SIGUSR2): %m");
      51        _exit (0);
      52      }
      53    return pid;
      54  }
      55  
      56  static int
      57  do_test (void)
      58  {
      59    if (signal (SIGUSR1, sigusr1_handler) == SIG_ERR)
      60      FAIL_EXIT1 ("signal (SIGUSR1): %m\n");
      61  
      62    sigset_t sigs;
      63    sigemptyset (&sigs);
      64    sigaddset (&sigs, SIGUSR2);
      65    if (sigprocmask (SIG_BLOCK, &sigs, NULL) != 0)
      66      FAIL_EXIT1 ("sigprocmask (SIGBLOCK, SIGUSR2): %m");
      67    pid_t pid = signal_sender ();
      68    int signo = 0;
      69    int ret = sigwait (&sigs, &signo);
      70    if (ret != 0)
      71      {
      72        support_record_failure ();
      73        errno = ret;
      74        printf ("error: sigwait failed: %m (%d)\n", ret);
      75      }
      76    TEST_VERIFY (signo == SIGUSR2);
      77  
      78    int status;
      79    xwaitpid (pid, &status, 0);
      80    TEST_VERIFY (status == 0);
      81  
      82    return 0;
      83  }
      84  
      85  #include <support/test-driver.c>