lib/signal.c

説明を見る。
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 }

Sambaに対してSat Aug 29 21:22:59 2009に生成されました。  doxygen 1.4.7