2003-08-13 05:53:07 +04:00
/*
Unix SMB / CIFS implementation .
signal handling functions
Copyright ( C ) Andrew Tridgell 1998
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2003-08-13 05:53:07 +04:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
2007-07-10 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2003-08-13 05:53:07 +04:00
*/
2014-09-22 13:57:52 +04:00
# include "replace.h"
2004-11-02 05:01:04 +03:00
# include "system/wait.h"
2014-09-22 13:57:52 +04:00
# include "debug.h"
# include "lib/util/signal.h" /* Avoid /usr/include/signal.h */
2003-08-13 05:53:07 +04:00
2006-02-28 16:12:39 +03:00
/**
* @ file
* @ brief Signal handling
*/
2003-08-13 05:53:07 +04:00
/****************************************************************************
Catch child exits and reap the child zombie status .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void sig_cld ( int signum )
{
2005-09-23 04:38:22 +04:00
while ( waitpid ( ( pid_t ) - 1 , ( int * ) NULL , WNOHANG ) > 0 )
2003-08-13 05:53:07 +04:00
;
/*
* Turns out it ' s * really * important not to
* restore the signal handler here if we have real POSIX
* signal handling . If we do , then we get the signal re - delivered
* immediately - hey presto - instant loop ! JRA .
*/
# if !defined(HAVE_SIGACTION)
CatchSignal ( SIGCLD , sig_cld ) ;
# endif
}
/****************************************************************************
catch child exits - leave status ;
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void sig_cld_leave_status ( int signum )
{
/*
* Turns out it ' s * really * important not to
* restore the signal handler here if we have real POSIX
* signal handling . If we do , then we get the signal re - delivered
* immediately - hey presto - instant loop ! JRA .
*/
# if !defined(HAVE_SIGACTION)
CatchSignal ( SIGCLD , sig_cld_leave_status ) ;
# endif
}
2006-02-28 16:12:39 +03:00
/**
2003-08-13 05:53:07 +04:00
Block sigs .
2006-02-28 16:12:39 +03:00
* */
2003-08-13 05:53:07 +04:00
2007-08-27 21:21:16 +04:00
void BlockSignals ( bool block , int signum )
2003-08-13 05:53:07 +04:00
{
# ifdef HAVE_SIGPROCMASK
sigset_t set ;
sigemptyset ( & set ) ;
sigaddset ( & set , signum ) ;
sigprocmask ( block ? SIG_BLOCK : SIG_UNBLOCK , & set , NULL ) ;
# elif defined(HAVE_SIGBLOCK)
if ( block ) {
sigblock ( sigmask ( signum ) ) ;
} else {
sigsetmask ( siggetmask ( ) & ~ sigmask ( signum ) ) ;
}
# else
/* yikes! This platform can't block signals? */
static int done ;
if ( ! done ) {
DEBUG ( 0 , ( " WARNING: No signal blocking available \n " ) ) ;
done = 1 ;
}
# endif
}
2006-02-28 16:12:39 +03:00
/**
2003-08-13 05:53:07 +04:00
Catch a signal . This should implement the following semantics :
1 ) The handler remains installed after being called .
2 ) The signal should be blocked during handler execution .
2006-02-28 16:12:39 +03:00
* */
2003-08-13 05:53:07 +04:00
void ( * CatchSignal ( int signum , void ( * handler ) ( int ) ) ) ( int )
{
# ifdef HAVE_SIGACTION
struct sigaction act ;
struct sigaction oldact ;
ZERO_STRUCT ( act ) ;
act . sa_handler = handler ;
# ifdef SA_RESTART
/*
* We * want * SIGALRM to interrupt a system call .
*/
if ( signum ! = SIGALRM )
act . sa_flags = SA_RESTART ;
# endif
sigemptyset ( & act . sa_mask ) ;
sigaddset ( & act . sa_mask , signum ) ;
sigaction ( signum , & act , & oldact ) ;
return oldact . sa_handler ;
# else /* !HAVE_SIGACTION */
/* FIXME: need to handle sigvec and systems with broken signal() */
return signal ( signum , handler ) ;
# endif
}
2006-02-28 16:12:39 +03:00
/**
2003-08-13 05:53:07 +04:00
Ignore SIGCLD via whatever means is necessary for this OS .
2006-02-28 16:12:39 +03:00
* */
2003-08-13 05:53:07 +04:00
2014-09-24 01:48:35 +04:00
void ( * CatchChild ( void ) ) ( int )
2003-08-13 05:53:07 +04:00
{
2014-09-24 01:48:35 +04:00
return CatchSignal ( SIGCLD , sig_cld ) ;
2003-08-13 05:53:07 +04:00
}
2006-02-28 16:12:39 +03:00
/**
2003-08-13 05:53:07 +04:00
Catch SIGCLD but leave the child around so it ' s status can be reaped .
2006-02-28 16:12:39 +03:00
* */
2003-08-13 05:53:07 +04:00
2014-09-24 01:48:35 +04:00
void ( * CatchChildLeaveStatus ( void ) ) ( int )
2003-08-13 05:53:07 +04:00
{
2014-09-24 01:48:35 +04:00
return CatchSignal ( SIGCLD , sig_cld_leave_status ) ;
2003-08-13 05:53:07 +04:00
}