(root)/
glibc-2.38/
nptl/
tst-exec4.c
       1  /* Signal handler and mask set in thread which calls exec.
       2     Copyright (C) 2003-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 <pthread.h>
      20  #include <signal.h>
      21  #include <stdio.h>
      22  #include <stdlib.h>
      23  #include <unistd.h>
      24  #include <support/xsignal.h>
      25  
      26  static void *
      27  tf (void *arg)
      28  {
      29    /* Ignore SIGUSR1 and block SIGUSR2.  */
      30    xsignal (SIGUSR1, SIG_IGN);
      31  
      32    sigset_t ss;
      33    sigemptyset (&ss);
      34    sigaddset (&ss, SIGUSR2);
      35    if (pthread_sigmask (SIG_BLOCK, &ss, NULL) != 0)
      36      {
      37        puts ("1st run: sigmask failed");
      38        exit (1);
      39      }
      40  
      41    char **oldargv = (char **) arg;
      42    size_t n = 1;
      43    while (oldargv[n] != NULL)
      44      ++n;
      45  
      46    char **argv = (char **) alloca ((n + 1) * sizeof (char *));
      47    for (n = 0; oldargv[n + 1] != NULL; ++n)
      48      argv[n] = oldargv[n + 1];
      49    argv[n++] = (char *) "--direct";
      50    argv[n] = NULL;
      51  
      52    execv (argv[0], argv);
      53  
      54    puts ("execv failed");
      55  
      56    exit (1);
      57  }
      58  
      59  
      60  static int
      61  do_test (int argc, char *argv[])
      62  {
      63    if (argc == 1)
      64      {
      65        /* This is the second call.  Perform the test.  */
      66        struct sigaction sa;
      67  
      68        if (sigaction (SIGUSR1, NULL, &sa) != 0)
      69  	{
      70  	  puts ("2nd run: sigaction failed");
      71  	  return 1;
      72  	}
      73        if (sa.sa_handler != SIG_IGN)
      74  	{
      75  	  puts ("SIGUSR1 not ignored");
      76  	  return 1;
      77  	}
      78  
      79        sigset_t ss;
      80        if (pthread_sigmask (SIG_SETMASK, NULL, &ss) != 0)
      81  	{
      82  	  puts ("2nd run: sigmask failed");
      83  	  return 1;
      84  	}
      85        if (! sigismember (&ss, SIGUSR2))
      86  	{
      87  	  puts ("SIGUSR2 not blocked");
      88  	  return 1;
      89  	}
      90  
      91        return 0;
      92      }
      93  
      94    pthread_t th;
      95    if (pthread_create (&th, NULL, tf, argv) != 0)
      96      {
      97        puts ("create failed");
      98        exit (1);
      99      }
     100  
     101    /* This call should never return.  */
     102    pthread_join (th, NULL);
     103  
     104    puts ("join returned");
     105  
     106    return 1;
     107  }
     108  
     109  #define TEST_FUNCTION do_test (argc, argv)
     110  #include "../test-skeleton.c"