1998-07-29 07:08:05 +04:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
1998-07-29 07:08:05 +04:00
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-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
1998-07-29 07:08:05 +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 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
1998-07-29 07:08:05 +04:00
*/
# include "includes.h"
/****************************************************************************
1999-12-13 16:27:58 +03:00
Catch child exits and reap the child zombie status .
1998-07-29 07:08:05 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-12-13 16:27:58 +03:00
1998-07-29 07:08:05 +04:00
static void sig_cld ( int signum )
{
1999-12-13 16:27:58 +03:00
while ( sys_waitpid ( ( pid_t ) - 1 , ( int * ) NULL , WNOHANG ) > 0 )
;
/*
* 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 .
*/
1998-07-29 07:08:05 +04:00
1999-12-13 16:27:58 +03:00
# if !defined(HAVE_SIGACTION)
1998-08-30 16:32:45 +04:00
CatchSignal ( SIGCLD , sig_cld ) ;
1999-12-13 16:27:58 +03:00
# endif
1998-07-29 07:08:05 +04:00
}
1999-12-13 16:27:58 +03:00
/****************************************************************************
catch child exits - leave status ;
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-07-29 07:08:05 +04:00
1999-12-13 16:27:58 +03:00
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
}
1998-07-29 07:08:05 +04:00
/*******************************************************************
1999-12-13 16:27:58 +03:00
Block sigs .
1998-07-29 07:08:05 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-12-13 16:27:58 +03:00
1998-07-29 07:08:05 +04:00
void BlockSignals ( BOOL block , int signum )
{
# 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 ) {
2000-06-12 10:09:39 +04:00
sigblock ( sigmask ( signum ) ) ;
1998-07-29 07:08:05 +04:00
} else {
2000-06-12 10:09:39 +04:00
sigsetmask ( siggetmask ( ) & ~ sigmask ( signum ) ) ;
1998-07-29 07:08:05 +04:00
}
# else
/* yikes! This platform can't block signals? */
static int done ;
if ( ! done ) {
DEBUG ( 0 , ( " WARNING: No signal blocking available \n " ) ) ;
done = 1 ;
}
# endif
}
/*******************************************************************
1999-12-13 16:27:58 +03:00
Catch a signal . This should implement the following semantics :
1998-07-29 07:08:05 +04:00
1999-12-13 16:27:58 +03:00
1 ) The handler remains installed after being called .
2 ) The signal should be blocked during handler execution .
1998-07-29 07:08:05 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-12-13 16:27:58 +03:00
2002-07-15 14:35:28 +04:00
void ( * CatchSignal ( int signum , void ( * handler ) ( int ) ) ) ( int )
1998-07-29 07:08:05 +04:00
{
# ifdef HAVE_SIGACTION
struct sigaction act ;
2002-07-15 14:35:28 +04:00
struct sigaction oldact ;
1998-07-29 07:08:05 +04:00
1998-09-05 17:24:20 +04:00
ZERO_STRUCT ( act ) ;
1998-07-29 07:08:05 +04:00
act . sa_handler = handler ;
# ifdef SA_RESTART
1999-12-13 16:27:58 +03:00
/*
* We * want * SIGALRM to interrupt a system call .
*/
if ( signum ! = SIGALRM )
act . sa_flags = SA_RESTART ;
1998-07-29 07:08:05 +04:00
# endif
sigemptyset ( & act . sa_mask ) ;
sigaddset ( & act . sa_mask , signum ) ;
2002-07-15 14:35:28 +04:00
sigaction ( signum , & act , & oldact ) ;
return oldact . sa_handler ;
1999-12-13 16:27:58 +03:00
# else /* !HAVE_SIGACTION */
1998-07-29 07:08:05 +04:00
/* FIXME: need to handle sigvec and systems with broken signal() */
2002-07-15 14:35:28 +04:00
return signal ( signum , handler ) ;
1998-07-29 07:08:05 +04:00
# endif
}
/*******************************************************************
1999-12-13 16:27:58 +03:00
Ignore SIGCLD via whatever means is necessary for this OS .
1998-07-29 07:08:05 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-12-13 16:27:58 +03:00
1998-07-29 07:08:05 +04:00
void CatchChild ( void )
{
CatchSignal ( SIGCLD , sig_cld ) ;
}
1999-12-13 16:27:58 +03:00
/*******************************************************************
Catch SIGCLD but leave the child around so it ' s status can be reaped .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void CatchChildLeaveStatus ( void )
{
CatchSignal ( SIGCLD , sig_cld_leave_status ) ;
}