(root)/
glibc-2.38/
sysdeps/
posix/
sigset.c
       1  /* Copyright (C) 1998-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  #define __need_NULL
      20  #include <stddef.h>
      21  #include <signal.h>
      22  #include <string.h>	/* For the real memset prototype.  */
      23  #include <sigsetops.h>
      24  
      25  /* Set the disposition for SIG.  */
      26  __sighandler_t
      27  sigset (int sig, __sighandler_t disp)
      28  {
      29    struct sigaction act;
      30    struct sigaction oact;
      31    sigset_t set;
      32    sigset_t oset;
      33  
      34    __sigemptyset (&set);
      35    if (sigaddset (&set, sig) < 0)
      36      return SIG_ERR;
      37  
      38    if (disp == SIG_HOLD)
      39      {
      40        /* Add the signal to the current signal mask.  */
      41        if (__sigprocmask (SIG_BLOCK, &set, &oset) < 0)
      42  	return SIG_ERR;
      43  
      44        /* If the signal was already blocked signal this to the caller.  */
      45        if (__sigismember (&oset, sig))
      46  	return SIG_HOLD;
      47  
      48        /* We need to determine whether a specific handler is installed.  */
      49        if (__sigaction (sig, NULL, &oact) < 0)
      50  	return SIG_ERR;
      51  
      52        return oact.sa_handler;
      53      }
      54    else
      55      {
      56        act.sa_handler = disp;
      57        __sigemptyset (&act.sa_mask);
      58        act.sa_flags = 0;
      59        if (__sigaction (sig, &act, &oact) < 0)
      60  	return SIG_ERR;
      61  
      62        /* Remove the signal from the current signal mask.  */
      63        if (__sigprocmask (SIG_UNBLOCK, &set, &oset) < 0)
      64  	return SIG_ERR;
      65  
      66        /* If the signal was already blocked return SIG_HOLD.  */
      67        return __sigismember (&oset, sig) ? SIG_HOLD : oact.sa_handler;
      68      }
      69  }