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 "includes.h" 22#include "system/wait.h" 23 24/** 25 * @file 26 * @brief Signal handling 27 */ 28 29/**************************************************************************** 30 Catch child exits and reap the child zombie status. 31****************************************************************************/ 32 33static void sig_cld(int signum) 34{ 35 while (waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0) 36 ; 37 38 /* 39 * Turns out it's *really* important not to 40 * restore the signal handler here if we have real POSIX 41 * signal handling. If we do, then we get the signal re-delivered 42 * immediately - hey presto - instant loop ! JRA. 43 */ 44 45#if !defined(HAVE_SIGACTION) 46 CatchSignal(SIGCLD, sig_cld); 47#endif 48} 49 50/**************************************************************************** 51catch child exits - leave status; 52****************************************************************************/ 53 54static void sig_cld_leave_status(int signum) 55{ 56 /* 57 * Turns out it's *really* important not to 58 * restore the signal handler here if we have real POSIX 59 * signal handling. If we do, then we get the signal re-delivered 60 * immediately - hey presto - instant loop ! JRA. 61 */ 62 63#if !defined(HAVE_SIGACTION) 64 CatchSignal(SIGCLD, sig_cld_leave_status); 65#endif 66} 67 68/** 69 Block sigs. 70**/ 71 72void BlockSignals(bool block, int signum) 73{ 74#ifdef HAVE_SIGPROCMASK 75 sigset_t set; 76 sigemptyset(&set); 77 sigaddset(&set,signum); 78 sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL); 79#elif defined(HAVE_SIGBLOCK) 80 if (block) { 81 sigblock(sigmask(signum)); 82 } else { 83 sigsetmask(siggetmask() & ~sigmask(signum)); 84 } 85#else 86 /* yikes! This platform can't block signals? */ 87 static int done; 88 if (!done) { 89 DEBUG(0,("WARNING: No signal blocking available\n")); 90 done=1; 91 } 92#endif 93} 94 95/** 96 Catch a signal. This should implement the following semantics: 97 98 1) The handler remains installed after being called. 99 2) The signal should be blocked during handler execution. 100**/ 101 102void (*CatchSignal(int signum,void (*handler)(int )))(int) 103{ 104#ifdef HAVE_SIGACTION 105 struct sigaction act; 106 struct sigaction oldact; 107 108 ZERO_STRUCT(act); 109 110 act.sa_handler = handler; 111#ifdef SA_RESTART 112 /* 113 * We *want* SIGALRM to interrupt a system call. 114 */ 115 if(signum != SIGALRM) 116 act.sa_flags = SA_RESTART; 117#endif 118 sigemptyset(&act.sa_mask); 119 sigaddset(&act.sa_mask,signum); 120 sigaction(signum,&act,&oldact); 121 return oldact.sa_handler; 122#else /* !HAVE_SIGACTION */ 123 /* FIXME: need to handle sigvec and systems with broken signal() */ 124 return signal(signum, handler); 125#endif 126} 127 128/** 129 Ignore SIGCLD via whatever means is necessary for this OS. 130**/ 131 132void CatchChild(void) 133{ 134 CatchSignal(SIGCLD, sig_cld); 135} 136 137/** 138 Catch SIGCLD but leave the child around so it's status can be reaped. 139**/ 140 141void CatchChildLeaveStatus(void) 142{ 143 CatchSignal(SIGCLD, sig_cld_leave_status); 144} 145