(root)/
coreutils-9.4/
gnulib-tests/
test-pthread_sigmask1.c
       1  /* Test of pthread_sigmask in a single-threaded program.
       2     Copyright (C) 2011-2023 Free Software Foundation, Inc.
       3  
       4     This program is free software: you can redistribute it and/or modify
       5     it under the terms of the GNU General Public License as published by
       6     the Free Software Foundation, either version 3 of the License, or
       7     (at your option) any later version.
       8  
       9     This program 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
      12     GNU General Public License for more details.
      13  
      14     You should have received a copy of the GNU General Public License
      15     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      16  
      17  /* Written by Bruno Haible <bruno@clisp.org>, 2011.  */
      18  
      19  #include <config.h>
      20  
      21  #include <signal.h>
      22  
      23  #include "signature.h"
      24  SIGNATURE_CHECK (pthread_sigmask, int, (int, const sigset_t *, sigset_t *));
      25  
      26  #include <errno.h>
      27  #include <limits.h>
      28  #include <stdio.h>
      29  #include <stdlib.h>
      30  #include <unistd.h>
      31  
      32  #include "macros.h"
      33  
      34  #if !(defined _WIN32 && !defined __CYGWIN__)
      35  
      36  static volatile int sigint_occurred;
      37  
      38  static void
      39  sigint_handler (int sig)
      40  {
      41    sigint_occurred++;
      42  }
      43  
      44  int
      45  main (int argc, char *argv[])
      46  {
      47    sigset_t set;
      48    pid_t pid = getpid ();
      49    char command[80];
      50  
      51    if (LONG_MAX < pid)
      52      {
      53        fputs ("Skipping test: pid too large\n", stderr);
      54        return 77;
      55      }
      56  
      57    signal (SIGINT, sigint_handler);
      58  
      59    sigemptyset (&set);
      60    sigaddset (&set, SIGINT);
      61  
      62    /* Check error handling.  */
      63    ASSERT (pthread_sigmask (1729, &set, NULL) == EINVAL);
      64  
      65    /* Block SIGINT.  */
      66    ASSERT (pthread_sigmask (SIG_BLOCK, &set, NULL) == 0);
      67  
      68    /* Request a SIGINT signal from outside.  */
      69    sprintf (command, "sh -c 'sleep 1; kill -INT %ld' &", (long) pid);
      70    ASSERT (system (command) == 0);
      71  
      72    /* Wait.  */
      73    sleep (2);
      74  
      75    /* The signal should not have arrived yet, because it is blocked.  */
      76    ASSERT (sigint_occurred == 0);
      77  
      78    /* Unblock SIGINT.  */
      79    ASSERT (pthread_sigmask (SIG_UNBLOCK, &set, NULL) == 0);
      80  
      81    /* The signal should have arrived now, because POSIX says
      82         "If there are any pending unblocked signals after the call to
      83          pthread_sigmask(), at least one of those signals shall be delivered
      84          before the call to pthread_sigmask() returns."  */
      85    ASSERT (sigint_occurred == 1);
      86  
      87    return 0;
      88  }
      89  
      90  #else
      91  
      92  /* On native Windows, getpid() values and the arguments that are passed to
      93     the (Cygwin?) 'kill' program are not necessarily related.  */
      94  
      95  int
      96  main ()
      97  {
      98    fputs ("Skipping test: native Windows platform\n", stderr);
      99    return 77;
     100  }
     101  
     102  #endif