00001 /* 00002 Unix SMB/CIFS implementation. 00003 signal handling functions 00004 00005 Copyright (C) Andrew Tridgell 1998 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 2 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program; if not, write to the Free Software 00019 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00020 */ 00021 00022 #include "includes.h" 00023 00024 /**************************************************************************** 00025 Catch child exits and reap the child zombie status. 00026 ****************************************************************************/ 00027 00028 static void sig_cld(int signum) 00029 { 00030 while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0) 00031 ; 00032 00033 /* 00034 * Turns out it's *really* important not to 00035 * restore the signal handler here if we have real POSIX 00036 * signal handling. If we do, then we get the signal re-delivered 00037 * immediately - hey presto - instant loop ! JRA. 00038 */ 00039 00040 #if !defined(HAVE_SIGACTION) 00041 CatchSignal(SIGCLD, sig_cld); 00042 #endif 00043 } 00044 00045 /**************************************************************************** 00046 catch child exits - leave status; 00047 ****************************************************************************/ 00048 00049 static void sig_cld_leave_status(int signum) 00050 { 00051 /* 00052 * Turns out it's *really* important not to 00053 * restore the signal handler here if we have real POSIX 00054 * signal handling. If we do, then we get the signal re-delivered 00055 * immediately - hey presto - instant loop ! JRA. 00056 */ 00057 00058 #if !defined(HAVE_SIGACTION) 00059 CatchSignal(SIGCLD, sig_cld_leave_status); 00060 #endif 00061 } 00062 00063 /******************************************************************* 00064 Block sigs. 00065 ********************************************************************/ 00066 00067 void BlockSignals(BOOL block,int signum) 00068 { 00069 #ifdef HAVE_SIGPROCMASK 00070 sigset_t set; 00071 sigemptyset(&set); 00072 sigaddset(&set,signum); 00073 sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL); 00074 #elif defined(HAVE_SIGBLOCK) 00075 if (block) { 00076 sigblock(sigmask(signum)); 00077 } else { 00078 sigsetmask(siggetmask() & ~sigmask(signum)); 00079 } 00080 #else 00081 /* yikes! This platform can't block signals? */ 00082 static int done; 00083 if (!done) { 00084 DEBUG(0,("WARNING: No signal blocking available\n")); 00085 done=1; 00086 } 00087 #endif 00088 } 00089 00090 /******************************************************************* 00091 Catch a signal. This should implement the following semantics: 00092 00093 1) The handler remains installed after being called. 00094 2) The signal should be blocked during handler execution. 00095 ********************************************************************/ 00096 00097 void (*CatchSignal(int signum,void (*handler)(int )))(int) 00098 { 00099 #ifdef HAVE_SIGACTION 00100 struct sigaction act; 00101 struct sigaction oldact; 00102 00103 ZERO_STRUCT(act); 00104 00105 act.sa_handler = handler; 00106 #ifdef SA_RESTART 00107 /* 00108 * We *want* SIGALRM to interrupt a system call. 00109 */ 00110 if(signum != SIGALRM) 00111 act.sa_flags = SA_RESTART; 00112 #endif 00113 sigemptyset(&act.sa_mask); 00114 sigaddset(&act.sa_mask,signum); 00115 sigaction(signum,&act,&oldact); 00116 return oldact.sa_handler; 00117 #else /* !HAVE_SIGACTION */ 00118 /* FIXME: need to handle sigvec and systems with broken signal() */ 00119 return signal(signum, handler); 00120 #endif 00121 } 00122 00123 /******************************************************************* 00124 Ignore SIGCLD via whatever means is necessary for this OS. 00125 ********************************************************************/ 00126 00127 void CatchChild(void) 00128 { 00129 CatchSignal(SIGCLD, sig_cld); 00130 } 00131 00132 /******************************************************************* 00133 Catch SIGCLD but leave the child around so it's status can be reaped. 00134 ********************************************************************/ 00135 00136 void CatchChildLeaveStatus(void) 00137 { 00138 CatchSignal(SIGCLD, sig_cld_leave_status); 00139 }
1.4.7