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 1102 : static void sig_cld(int signum) 36 : { 37 2201 : 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 1102 : } 51 : 52 : /**************************************************************************** 53 : catch child exits - leave status; 54 : ****************************************************************************/ 55 : 56 3142 : 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 3142 : } 69 : 70 : /** 71 : Block sigs. 72 : **/ 73 : 74 25615 : void BlockSignals(bool block, int signum) 75 : { 76 : #ifdef HAVE_SIGPROCMASK 77 400 : sigset_t set; 78 25615 : sigemptyset(&set); 79 25615 : sigaddset(&set,signum); 80 25615 : 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 25615 : } 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 198648 : void (*CatchSignal(int signum,void (*handler)(int )))(int) 105 : { 106 : #ifdef HAVE_SIGACTION 107 2658 : struct sigaction act; 108 2658 : struct sigaction oldact; 109 : 110 198648 : ZERO_STRUCT(act); 111 : 112 198648 : act.sa_handler = handler; 113 : #ifdef SA_RESTART 114 : /* 115 : * We *want* SIGALRM to interrupt a system call. 116 : */ 117 198648 : if(signum != SIGALRM) 118 146358 : act.sa_flags = SA_RESTART; 119 : #endif 120 198648 : sigemptyset(&act.sa_mask); 121 198648 : sigaddset(&act.sa_mask,signum); 122 198648 : sigaction(signum,&act,&oldact); 123 198648 : 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 36311 : void (*CatchChild(void))(int) 135 : { 136 36311 : 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 3138 : void (*CatchChildLeaveStatus(void))(int) 144 : { 145 3138 : return CatchSignal(SIGCLD, sig_cld_leave_status); 146 : }