(root)/
coreutils-9.4/
gnulib-tests/
test-sigaction.c
       1  /* Test of sigaction() function.
       2     Copyright (C) 2008-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 Eric Blake <ebb9@byu.net>, 2008.  */
      18  
      19  #include <config.h>
      20  
      21  #include <signal.h>
      22  
      23  #include "signature.h"
      24  SIGNATURE_CHECK (sigaction, int, (int, struct sigaction const *,
      25                                    struct sigaction *));
      26  
      27  #include <stddef.h>
      28  
      29  #include "macros.h"
      30  
      31  #ifndef SA_NOCLDSTOP
      32  # define SA_NOCLDSTOP 0
      33  #endif
      34  #ifndef SA_ONSTACK
      35  # define SA_ONSTACK 0
      36  #endif
      37  #ifndef SA_RESETHAND
      38  # define SA_RESETHAND 0
      39  #endif
      40  #ifndef SA_RESTART
      41  # define SA_RESTART 0
      42  #endif
      43  #ifndef SA_SIGINFO
      44  # define SA_SIGINFO 0
      45  #endif
      46  #ifndef SA_NOCLDWAIT
      47  # define SA_NOCLDWAIT 0
      48  #endif
      49  
      50  /* Define a mask of flags required by POSIX.  Some implementations
      51     provide other flags as extensions, such as SA_RESTORER, that we
      52     must ignore in this test.  */
      53  #define MASK_SA_FLAGS (SA_NOCLDSTOP | SA_ONSTACK | SA_RESETHAND | SA_RESTART \
      54                         | SA_SIGINFO | SA_NOCLDWAIT | SA_NODEFER)
      55  
      56  /* This test is unsafe in the presence of an asynchronous SIGABRT,
      57     because we install a signal-handler that is intentionally not
      58     async-safe.  Hopefully, this does not lead to too many reports of
      59     false failures, since people don't generally use 'kill -s SIGABRT'
      60     to end a runaway program.  */
      61  
      62  static void
      63  handler (int sig)
      64  {
      65    static int entry_count;
      66    struct sigaction sa;
      67    ASSERT (sig == SIGABRT);
      68    ASSERT (sigaction (SIGABRT, NULL, &sa) == 0);
      69    ASSERT ((sa.sa_flags & SA_SIGINFO) == 0);
      70    switch (entry_count++)
      71      {
      72      case 0:
      73        ASSERT ((sa.sa_flags & SA_RESETHAND) == 0);
      74        ASSERT (sa.sa_handler == handler);
      75        break;
      76      case 1:
      77        /* This assertion fails on glibc-2.3.6 systems with LinuxThreads,
      78           when this program is linked with -lpthread, due to the sigaction()
      79           override in libpthread.so.  */
      80  #if !(defined __GLIBC__ || defined __UCLIBC__)
      81        ASSERT (sa.sa_handler == SIG_DFL);
      82  #endif
      83        break;
      84      default:
      85        ASSERT (0);
      86      }
      87  }
      88  
      89  int
      90  main (void)
      91  {
      92    struct sigaction sa;
      93    struct sigaction old_sa;
      94    sa.sa_handler = handler;
      95  
      96    sa.sa_flags = 0;
      97    ASSERT (sigemptyset (&sa.sa_mask) == 0);
      98    ASSERT (sigaction (SIGABRT, &sa, NULL) == 0);
      99    ASSERT (raise (SIGABRT) == 0);
     100  
     101    sa.sa_flags = SA_RESETHAND | SA_NODEFER;
     102    ASSERT (sigaction (SIGABRT, &sa, &old_sa) == 0);
     103    ASSERT ((old_sa.sa_flags & MASK_SA_FLAGS) == 0);
     104    ASSERT (old_sa.sa_handler == handler);
     105    ASSERT (raise (SIGABRT) == 0);
     106  
     107    sa.sa_handler = SIG_DFL;
     108    ASSERT (sigaction (SIGABRT, &sa, &old_sa) == 0);
     109    ASSERT ((old_sa.sa_flags & SA_SIGINFO) == 0);
     110  #if !(defined __GLIBC__ || defined __UCLIBC__) /* see above */
     111    ASSERT (old_sa.sa_handler == SIG_DFL);
     112  #endif
     113  
     114    sa.sa_handler = SIG_IGN;
     115    ASSERT (sigaction (SIGABRT, &sa, NULL) == 0);
     116    ASSERT (raise (SIGABRT) == 0);
     117    ASSERT (sigaction (SIGABRT, NULL, &old_sa) == 0);
     118    ASSERT (old_sa.sa_handler == SIG_IGN);
     119    ASSERT (raise (SIGABRT) == 0);
     120  
     121    return 0;
     122  }