LCOV - code coverage report
Current view: top level - lib/util - signal.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 23 23 100.0 %
Date: 2021-09-23 10:06:22 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    signal handling functions
       4             : 
       5             :    Copyright (C) Andrew Tridgell 1998
       6             :    
       7             :    This program is free software; you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation; either version 3 of the License, or
      10             :    (at your option) any later version.
      11             :    
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             :    
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include "replace.h"
      22             : #include "system/wait.h"
      23             : #include "debug.h"
      24             : #include "lib/util/signal.h" /* Avoid /usr/include/signal.h */
      25             : 
      26             : /**
      27             :  * @file
      28             :  * @brief Signal handling
      29             :  */
      30             : 
      31             : /****************************************************************************
      32             :  Catch child exits and reap the child zombie status.
      33             : ****************************************************************************/
      34             : 
      35         807 : static void sig_cld(int signum)
      36             : {
      37         807 :         while (waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0)
      38             :                 ;
      39             : 
      40             :         /*
      41             :          * Turns out it's *really* important not to
      42             :          * restore the signal handler here if we have real POSIX
      43             :          * signal handling. If we do, then we get the signal re-delivered
      44             :          * immediately - hey presto - instant loop ! JRA.
      45             :          */
      46             : 
      47             : #if !defined(HAVE_SIGACTION)
      48             :         CatchSignal(SIGCLD, sig_cld);
      49             : #endif
      50         807 : }
      51             : 
      52             : /****************************************************************************
      53             : catch child exits - leave status;
      54             : ****************************************************************************/
      55             : 
      56        3784 : static void sig_cld_leave_status(int signum)
      57             : {
      58             :         /*
      59             :          * Turns out it's *really* important not to
      60             :          * restore the signal handler here if we have real POSIX
      61             :          * signal handling. If we do, then we get the signal re-delivered
      62             :          * immediately - hey presto - instant loop ! JRA.
      63             :          */
      64             : 
      65             : #if !defined(HAVE_SIGACTION)
      66             :         CatchSignal(SIGCLD, sig_cld_leave_status);
      67             : #endif
      68        3784 : }
      69             : 
      70             : /**
      71             :  Block sigs.
      72             : **/
      73             : 
      74       20411 : void BlockSignals(bool block, int signum)
      75             : {
      76             : #ifdef HAVE_SIGPROCMASK
      77             :         sigset_t set;
      78       20411 :         sigemptyset(&set);
      79       20411 :         sigaddset(&set,signum);
      80       20411 :         sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
      81             : #elif defined(HAVE_SIGBLOCK)
      82             :         if (block) {
      83             :                 sigblock(sigmask(signum));
      84             :         } else {
      85             :                 sigsetmask(siggetmask() & ~sigmask(signum));
      86             :         }
      87             : #else
      88             :         /* yikes! This platform can't block signals? */
      89             :         static int done;
      90             :         if (!done) {
      91             :                 DEBUG(0,("WARNING: No signal blocking available\n"));
      92             :                 done=1;
      93             :         }
      94             : #endif
      95       20411 : }
      96             : 
      97             : /**
      98             :  Catch a signal. This should implement the following semantics:
      99             : 
     100             :  1) The handler remains installed after being called.
     101             :  2) The signal should be blocked during handler execution.
     102             : **/
     103             : 
     104      142002 : void (*CatchSignal(int signum,void (*handler)(int )))(int)
     105             : {
     106             : #ifdef HAVE_SIGACTION
     107             :         struct sigaction act;
     108             :         struct sigaction oldact;
     109             : 
     110      142002 :         ZERO_STRUCT(act);
     111             : 
     112      142002 :         act.sa_handler = handler;
     113             : #ifdef SA_RESTART
     114             :         /*
     115             :          * We *want* SIGALRM to interrupt a system call.
     116             :          */
     117      142002 :         if(signum != SIGALRM)
     118      129758 :                 act.sa_flags = SA_RESTART;
     119             : #endif
     120      142002 :         sigemptyset(&act.sa_mask);
     121      142002 :         sigaddset(&act.sa_mask,signum);
     122      142002 :         sigaction(signum,&act,&oldact);
     123      142002 :         return oldact.sa_handler;
     124             : #else /* !HAVE_SIGACTION */
     125             :         /* FIXME: need to handle sigvec and systems with broken signal() */
     126             :         return signal(signum, handler);
     127             : #endif
     128             : }
     129             : 
     130             : /**
     131             :  Ignore SIGCLD via whatever means is necessary for this OS.
     132             : **/
     133             : 
     134       31205 : void (*CatchChild(void))(int)
     135             : {
     136       31205 :         return CatchSignal(SIGCLD, sig_cld);
     137             : }
     138             : 
     139             : /**
     140             :  Catch SIGCLD but leave the child around so it's status can be reaped.
     141             : **/
     142             : 
     143        3846 : void (*CatchChildLeaveStatus(void))(int)
     144             : {
     145        3846 :         return CatchSignal(SIGCLD, sig_cld_leave_status);
     146             : }

Generated by: LCOV version 1.13