2005-10-06 17:30:50 +10:00
/** \file signal.c
The library for various signal related issues
*/
# include "config.h"
2006-02-28 23:17:16 +10:00
2005-10-06 17:30:50 +10:00
# include <stdlib.h>
# include <stdio.h>
# include <sys/types.h>
# include <signal.h>
# include <dirent.h>
# include <unistd.h>
2005-10-06 21:54:16 +10:00
# include <errno.h>
2005-10-06 17:30:50 +10:00
2006-07-31 06:26:59 +10:00
# ifdef HAVE_SIGINFO_H
# include <siginfo.h>
# endif
2005-10-06 17:30:50 +10:00
# include "common.h"
2006-02-28 23:17:16 +10:00
# include "fallback.h"
2005-10-06 21:54:16 +10:00
# include "util.h"
2006-02-28 23:17:16 +10:00
2005-10-06 21:54:16 +10:00
# include "wutil.h"
2005-10-06 17:30:50 +10:00
# include "signal.h"
# include "event.h"
# include "reader.h"
# include "proc.h"
2006-07-20 08:55:49 +10:00
2005-10-06 17:30:50 +10:00
/**
Struct describing an entry for the lookup table used to convert
between signal names and signal ids , etc .
*/
struct lookup_entry
{
/**
Signal id
*/
int signal ;
/**
Signal name
*/
const wchar_t * name ;
/**
Signal description
*/
2011-12-26 19:18:46 -08:00
const wchar_t * desc ;
2005-10-06 17:30:50 +10:00
} ;
2006-06-20 10:50:10 +10:00
/**
The number of signal blocks in place . Increased by signal_block , decreased by signal_unblock .
*/
2006-02-10 01:50:20 +10:00
static int block_count = 0 ;
2005-10-06 17:30:50 +10:00
/**
Lookup table used to convert between signal names and signal ids ,
etc .
*/
2010-10-08 08:43:57 +08:00
static const struct lookup_entry lookup [ ] =
2005-10-06 17:30:50 +10:00
{
2006-05-15 02:39:36 +10:00
# ifdef SIGHUP
2005-10-06 17:30:50 +10:00
{
2011-12-26 19:18:46 -08:00
SIGHUP ,
2005-10-06 17:30:50 +10:00
L " SIGHUP " ,
2006-01-04 22:51:02 +10:00
N_ ( L " Terminal hung up " )
2005-10-06 17:30:50 +10:00
}
,
2006-05-15 02:39:36 +10:00
# endif
# ifdef SIGINT
2005-10-06 17:30:50 +10:00
{
SIGINT ,
L " SIGINT " ,
2006-01-04 22:51:02 +10:00
N_ ( L " Quit request from job control (^C) " )
2005-10-06 17:30:50 +10:00
}
,
2006-05-15 02:39:36 +10:00
# endif
# ifdef SIGQUIT
2005-10-06 17:30:50 +10:00
{
SIGQUIT ,
L " SIGQUIT " ,
2006-01-04 22:51:02 +10:00
N_ ( L " Quit request from job control with core dump (^ \\ ) " )
2005-10-06 17:30:50 +10:00
}
,
2006-05-15 02:39:36 +10:00
# endif
# ifdef SIGILL
2005-10-06 17:30:50 +10:00
{
SIGILL ,
L " SIGILL " ,
2006-01-04 22:51:02 +10:00
N_ ( L " Illegal instruction " )
2005-10-06 17:30:50 +10:00
}
,
2006-05-15 02:39:36 +10:00
# endif
# ifdef SIGTRAP
2005-10-06 17:30:50 +10:00
{
2011-12-26 19:18:46 -08:00
SIGTRAP ,
2005-10-06 17:30:50 +10:00
L " SIGTRAP " ,
2006-01-04 22:51:02 +10:00
N_ ( L " Trace or breakpoint trap " )
2005-10-06 17:30:50 +10:00
}
,
2006-05-15 02:39:36 +10:00
# endif
# ifdef SIGABRT
2005-10-06 17:30:50 +10:00
{
SIGABRT ,
L " SIGABRT " ,
2006-01-04 22:51:02 +10:00
N_ ( L " Abort " )
2005-10-06 17:30:50 +10:00
}
,
2006-05-15 02:39:36 +10:00
# endif
# ifdef SIGBUS
2005-10-06 17:30:50 +10:00
{
2011-12-26 19:18:46 -08:00
SIGBUS ,
2005-10-06 17:30:50 +10:00
L " SIGBUS " ,
2006-01-04 22:51:02 +10:00
N_ ( L " Misaligned address error " )
2005-10-06 17:30:50 +10:00
}
,
2006-05-15 02:39:36 +10:00
# endif
# ifdef SIGFPE
2005-10-06 17:30:50 +10:00
{
2011-12-26 19:18:46 -08:00
SIGFPE ,
2005-10-06 17:30:50 +10:00
L " SIGFPE " ,
2006-01-04 22:51:02 +10:00
N_ ( L " Floating point exception " )
2005-10-06 17:30:50 +10:00
}
,
2006-05-15 02:39:36 +10:00
# endif
# ifdef SIGKILL
2005-10-06 17:30:50 +10:00
{
2011-12-26 19:18:46 -08:00
SIGKILL ,
2005-10-06 17:30:50 +10:00
L " SIGKILL " ,
2006-01-04 22:51:02 +10:00
N_ ( L " Forced quit " )
2005-10-06 17:30:50 +10:00
}
,
2006-05-15 02:39:36 +10:00
# endif
# ifdef SIGUSR1
2005-10-06 17:30:50 +10:00
{
SIGUSR1 ,
L " SIGUSR1 " ,
2006-01-04 22:51:02 +10:00
N_ ( L " User defined signal 1 " )
2005-10-06 17:30:50 +10:00
}
,
2006-05-15 02:39:36 +10:00
# endif
# ifdef SIGUSR2
2005-10-06 17:30:50 +10:00
{
SIGUSR2 , L " SIGUSR2 " ,
2006-01-04 22:51:02 +10:00
N_ ( L " User defined signal 2 " )
2005-10-06 17:30:50 +10:00
}
,
2006-05-15 02:39:36 +10:00
# endif
# ifdef SIGSEGV
2005-10-06 17:30:50 +10:00
{
2011-12-26 19:18:46 -08:00
SIGSEGV ,
2005-10-06 17:30:50 +10:00
L " SIGSEGV " ,
2006-01-04 22:51:02 +10:00
N_ ( L " Address boundary error " )
2005-10-06 17:30:50 +10:00
}
,
2006-05-15 02:39:36 +10:00
# endif
# ifdef SIGPIPE
2005-10-06 17:30:50 +10:00
{
SIGPIPE ,
L " SIGPIPE " ,
2006-01-04 22:51:02 +10:00
N_ ( L " Broken pipe " )
2005-10-06 17:30:50 +10:00
}
,
2006-05-15 02:39:36 +10:00
# endif
# ifdef SIGALRM
2005-10-06 17:30:50 +10:00
{
2011-12-26 19:18:46 -08:00
SIGALRM ,
2005-10-06 17:30:50 +10:00
L " SIGALRM " ,
2006-01-04 22:51:02 +10:00
N_ ( L " Timer expired " )
2005-10-06 17:30:50 +10:00
}
,
2006-05-15 02:39:36 +10:00
# endif
# ifdef SIGTERM
2005-10-06 17:30:50 +10:00
{
SIGTERM ,
L " SIGTERM " ,
2006-01-04 22:51:02 +10:00
N_ ( L " Polite quit request " )
2005-10-06 17:30:50 +10:00
}
,
2006-05-15 02:39:36 +10:00
# endif
# ifdef SIGCHLD
2005-10-06 17:30:50 +10:00
{
SIGCHLD ,
L " SIGCHLD " ,
2006-01-04 22:51:02 +10:00
N_ ( L " Child process status changed " )
2005-10-06 17:30:50 +10:00
}
,
2006-05-15 02:39:36 +10:00
# endif
# ifdef SIGCONT
2005-10-06 17:30:50 +10:00
{
SIGCONT ,
L " SIGCONT " ,
2006-01-04 22:51:02 +10:00
N_ ( L " Continue previously stopped process " )
2005-10-06 17:30:50 +10:00
}
,
2006-05-15 02:39:36 +10:00
# endif
# ifdef SIGSTOP
2005-10-06 17:30:50 +10:00
{
SIGSTOP ,
L " SIGSTOP " ,
2006-01-04 22:51:02 +10:00
N_ ( L " Forced stop " )
2005-10-06 17:30:50 +10:00
}
,
2006-05-15 02:39:36 +10:00
# endif
# ifdef SIGTSTP
2005-10-06 17:30:50 +10:00
{
SIGTSTP ,
L " SIGTSTP " ,
2006-01-04 22:51:02 +10:00
N_ ( L " Stop request from job control (^Z) " )
2005-10-06 17:30:50 +10:00
}
,
2006-05-15 02:39:36 +10:00
# endif
# ifdef SIGTTIN
2005-10-06 17:30:50 +10:00
{
2011-12-26 19:18:46 -08:00
SIGTTIN ,
2005-10-06 17:30:50 +10:00
L " SIGTTIN " ,
2006-01-04 22:51:02 +10:00
N_ ( L " Stop from terminal input " )
2005-10-06 17:30:50 +10:00
}
,
2006-05-15 02:39:36 +10:00
# endif
# ifdef SIGTTOU
2005-10-06 17:30:50 +10:00
{
SIGTTOU ,
L " SIGTTOU " ,
2006-01-04 22:51:02 +10:00
N_ ( L " Stop from terminal output " )
2005-10-06 17:30:50 +10:00
}
,
2006-05-15 02:39:36 +10:00
# endif
# ifdef SIGURG
2005-10-06 17:30:50 +10:00
{
2011-12-26 19:18:46 -08:00
SIGURG ,
2005-10-06 17:30:50 +10:00
L " SIGURG " ,
2006-01-04 22:51:02 +10:00
N_ ( L " Urgent socket condition " )
2005-10-06 17:30:50 +10:00
}
,
2006-05-15 02:39:36 +10:00
# endif
# ifdef SIGXCPY
2005-10-06 17:30:50 +10:00
{
SIGXCPU ,
L " SIGXCPU " ,
2006-01-04 22:51:02 +10:00
N_ ( L " CPU time limit exceeded " )
2005-10-06 17:30:50 +10:00
}
,
2006-05-15 02:39:36 +10:00
# endif
2006-01-19 04:40:46 +10:00
# ifdef SIGXFSZ
2005-10-06 17:30:50 +10:00
{
2011-12-26 19:18:46 -08:00
SIGXFSZ ,
2005-10-06 17:30:50 +10:00
L " SIGXFSZ " ,
2006-01-04 22:51:02 +10:00
N_ ( L " File size limit exceeded " )
2005-10-06 17:30:50 +10:00
}
,
2006-01-19 04:40:46 +10:00
# endif
2006-05-15 02:39:36 +10:00
# ifdef SIGVTALRM
2005-10-06 17:30:50 +10:00
{
SIGVTALRM ,
L " SIGVTALRM " ,
2006-01-04 22:51:02 +10:00
N_ ( L " Virtual timer expired " )
2005-10-06 17:30:50 +10:00
}
,
2006-05-15 02:39:36 +10:00
# endif
2006-01-19 04:40:46 +10:00
# ifdef SIGPROF
2005-10-06 17:30:50 +10:00
{
SIGPROF ,
L " SIGPROF " ,
2006-01-04 22:51:02 +10:00
N_ ( L " Profiling timer expired " )
2005-10-06 17:30:50 +10:00
}
,
2006-01-19 04:40:46 +10:00
# endif
# ifdef SIGWINCH
2005-10-06 17:30:50 +10:00
{
SIGWINCH ,
L " SIGWINCH " ,
2006-01-04 22:51:02 +10:00
N_ ( L " Window size change " )
2005-10-06 17:30:50 +10:00
}
,
2006-01-19 04:40:46 +10:00
# endif
# ifdef SIGWIND
{
SIGWIND ,
L " SIGWIND " ,
N_ ( L " Window size change " )
}
,
# endif
2006-08-01 10:25:50 +10:00
# ifdef SIGIO
2005-10-06 17:30:50 +10:00
{
SIGIO ,
L " SIGIO " ,
2006-01-12 00:17:35 +10:00
N_ ( L " I/O on asynchronous file descriptor is possible " )
2005-10-06 17:30:50 +10:00
}
,
2006-05-15 02:39:36 +10:00
# endif
2005-10-06 17:30:50 +10:00
# ifdef SIGPWR
{
2011-12-26 19:18:46 -08:00
SIGPWR ,
2005-10-06 17:30:50 +10:00
L " SIGPWR " ,
2006-01-04 22:51:02 +10:00
N_ ( L " Power failure " )
2005-10-06 17:30:50 +10:00
}
,
# endif
2006-01-19 04:40:46 +10:00
# ifdef SIGSYS
2005-10-06 17:30:50 +10:00
{
2011-12-26 19:18:46 -08:00
SIGSYS ,
2005-10-06 17:30:50 +10:00
L " SIGSYS " ,
2006-01-04 22:51:02 +10:00
N_ ( L " Bad system call " )
2005-10-06 17:30:50 +10:00
}
,
2006-01-19 04:40:46 +10:00
# endif
# ifdef SIGINFO
{
SIGINFO ,
L " SIGINFO " ,
N_ ( L " Information request " )
}
,
# endif
# ifdef SIGSTKFLT
{
SIGSTKFLT ,
L " SISTKFLT " ,
N_ ( L " Stack fault " )
}
,
# endif
# ifdef SIGEMT
{
SIGEMT ,
L " SIGEMT " ,
N_ ( L " Emulator trap " )
}
,
# endif
# ifdef SIGIOT
{
SIGIOT ,
L " SIGIOT " ,
N_ ( L " Abort (Alias for SIGABRT) " )
}
,
# endif
# ifdef SIGUNUSED
{
SIGUNUSED ,
L " SIGUNUSED " ,
N_ ( L " Unused signal " )
}
,
# endif
2005-10-06 17:30:50 +10:00
{
0 ,
0 ,
0
}
}
;
/**
2011-12-26 19:18:46 -08:00
Test if \ c name is a string describing the signal named \ c canonical .
2005-10-06 17:30:50 +10:00
*/
2011-12-26 19:18:46 -08:00
static int match_signal_name ( const wchar_t * canonical ,
2005-10-06 17:30:50 +10:00
const wchar_t * name )
{
if ( wcsncasecmp ( name , L " sig " , 3 ) = = 0 )
name + = 3 ;
2011-12-26 19:18:46 -08:00
return wcscasecmp ( canonical + 3 , name ) = = 0 ;
2005-10-06 17:30:50 +10:00
}
int wcs2sig ( const wchar_t * str )
{
2005-10-06 21:54:16 +10:00
int i , res ;
wchar_t * end = 0 ;
2011-12-26 19:18:46 -08:00
2005-10-06 17:30:50 +10:00
for ( i = 0 ; lookup [ i ] . desc ; i + + )
{
if ( match_signal_name ( lookup [ i ] . name , str ) )
{
return lookup [ i ] . signal ;
}
}
2005-10-06 21:54:16 +10:00
errno = 0 ;
res = wcstol ( str , & end , 10 ) ;
2007-01-09 13:20:05 +10:00
if ( ! errno & & res > = 0 & & ! * end )
2005-10-06 21:54:16 +10:00
return res ;
2011-12-26 19:18:46 -08:00
return - 1 ;
2005-10-06 17:30:50 +10:00
}
const wchar_t * sig2wcs ( int sig )
{
int i ;
2006-05-15 02:39:36 +10:00
2005-10-06 17:30:50 +10:00
for ( i = 0 ; lookup [ i ] . desc ; i + + )
{
if ( lookup [ i ] . signal = = sig )
{
return lookup [ i ] . name ;
}
}
2006-05-15 02:39:36 +10:00
return _ ( L " Unknown " ) ;
2005-10-06 17:30:50 +10:00
}
2006-02-02 01:49:11 +10:00
const wchar_t * signal_get_desc ( int sig )
2005-10-06 17:30:50 +10:00
{
int i ;
2006-05-15 02:39:36 +10:00
2005-10-06 17:30:50 +10:00
for ( i = 0 ; lookup [ i ] . desc ; i + + )
{
if ( lookup [ i ] . signal = = sig )
{
2006-01-04 22:51:02 +10:00
return _ ( lookup [ i ] . desc ) ;
2005-10-06 17:30:50 +10:00
}
}
2006-05-15 02:39:36 +10:00
return _ ( L " Unknown " ) ;
2005-10-06 17:30:50 +10:00
}
2006-01-24 06:40:14 +10:00
/**
Standard signal handler
*/
2005-10-06 17:30:50 +10:00
static void default_handler ( int signal , siginfo_t * info , void * context )
{
2012-02-08 19:02:25 -08:00
event_t e = event_t : : signal_event ( signal ) ;
2006-05-15 08:27:58 +10:00
if ( event_get ( & e , 0 ) )
{
event_fire ( & e ) ;
}
2005-10-06 17:30:50 +10:00
}
/**
Respond to a winch signal by checking the terminal size
*/
static void handle_winch ( int sig , siginfo_t * info , void * context )
{
2011-12-26 19:18:46 -08:00
common_handle_winch ( sig ) ;
default_handler ( sig , 0 , 0 ) ;
2005-10-06 17:30:50 +10:00
}
2006-05-14 20:16:23 +10:00
/**
2007-10-02 20:09:37 +10:00
Respond to a hup signal by exiting , unless it is caught by a
2007-04-17 06:10:53 +10:00
shellscript function , in which case we do nothing .
2006-05-14 20:16:23 +10:00
*/
static void handle_hup ( int sig , siginfo_t * info , void * context )
{
2012-02-08 19:02:25 -08:00
event_t e = event_t : : signal_event ( SIGHUP ) ;
2006-05-15 08:27:58 +10:00
if ( event_get ( & e , 0 ) )
2006-05-14 20:16:23 +10:00
{
2011-12-26 19:18:46 -08:00
default_handler ( sig , 0 , 0 ) ;
2006-05-14 20:16:23 +10:00
}
else
{
reader_exit ( 1 , 1 ) ;
}
2011-12-26 19:18:46 -08:00
2006-05-14 20:16:23 +10:00
}
2005-10-06 17:30:50 +10:00
/**
Interactive mode ^ C handler . Respond to int signal by setting
interrupted - flag and stopping all loops and conditionals .
*/
static void handle_int ( int sig , siginfo_t * info , void * context )
{
reader_handle_int ( sig ) ;
2011-12-26 19:18:46 -08:00
default_handler ( sig , info , context ) ;
2005-10-06 17:30:50 +10:00
}
2005-10-06 21:54:16 +10:00
/**
sigchld handler . Does notification and calls the handler in proc . c
*/
static void handle_chld ( int sig , siginfo_t * info , void * context )
{
job_handle_signal ( sig , info , context ) ;
2011-12-26 19:18:46 -08:00
default_handler ( sig , info , context ) ;
2005-10-06 21:54:16 +10:00
}
void signal_reset_handlers ( )
{
int i ;
2011-12-26 19:18:46 -08:00
2005-10-06 21:54:16 +10:00
struct sigaction act ;
sigemptyset ( & act . sa_mask ) ;
act . sa_flags = 0 ;
act . sa_handler = SIG_DFL ;
2011-12-26 19:18:46 -08:00
2005-10-06 21:54:16 +10:00
for ( i = 0 ; lookup [ i ] . desc ; i + + )
{
sigaction ( lookup [ i ] . signal , & act , 0 ) ;
2011-12-26 19:18:46 -08:00
}
2005-10-06 21:54:16 +10:00
}
2005-10-06 17:30:50 +10:00
/**
Sets appropriate signal handlers .
*/
void signal_set_handlers ( )
{
struct sigaction act ;
2006-02-16 23:36:32 +10:00
2012-02-25 18:54:49 -08:00
if ( get_is_interactive ( ) = = - 1 )
2006-02-16 23:36:32 +10:00
return ;
2011-12-26 19:18:46 -08:00
2005-10-06 17:30:50 +10:00
sigemptyset ( & act . sa_mask ) ;
act . sa_flags = SA_SIGINFO ;
act . sa_sigaction = & default_handler ;
2011-12-26 19:18:46 -08:00
2005-10-06 17:30:50 +10:00
/*
First reset everything to a use default_handler , a function
whose sole action is to fire of an event
*/
sigaction ( SIGINT , & act , 0 ) ;
sigaction ( SIGQUIT , & act , 0 ) ;
sigaction ( SIGTSTP , & act , 0 ) ;
sigaction ( SIGTTIN , & act , 0 ) ;
sigaction ( SIGTTOU , & act , 0 ) ;
sigaction ( SIGCHLD , & act , 0 ) ;
2011-12-26 19:18:46 -08:00
2005-10-06 17:30:50 +10:00
/*
Ignore sigpipe , it is generated if fishd dies , but we can
recover .
*/
sigaction ( SIGPIPE , & act , 0 ) ;
2006-02-16 23:36:32 +10:00
2012-02-25 18:54:49 -08:00
if ( get_is_interactive ( ) )
2005-10-06 17:30:50 +10:00
{
/*
Interactive mode . Ignore interactive signals . We are a
shell , we know whats best for the user . ; - )
*/
2011-12-26 19:18:46 -08:00
2005-10-06 17:30:50 +10:00
act . sa_handler = SIG_IGN ;
2011-12-26 19:18:46 -08:00
2005-10-06 17:30:50 +10:00
sigaction ( SIGINT , & act , 0 ) ;
sigaction ( SIGQUIT , & act , 0 ) ;
sigaction ( SIGTSTP , & act , 0 ) ;
sigaction ( SIGTTIN , & act , 0 ) ;
sigaction ( SIGTTOU , & act , 0 ) ;
2005-10-14 21:40:33 +10:00
act . sa_sigaction = & handle_int ;
2005-10-06 17:30:50 +10:00
act . sa_flags = SA_SIGINFO ;
if ( sigaction ( SIGINT , & act , 0 ) )
{
wperror ( L " sigaction " ) ;
2007-01-22 01:03:41 +10:00
FATAL_EXIT ( ) ;
2005-10-06 17:30:50 +10:00
}
2005-10-06 21:54:16 +10:00
act . sa_sigaction = & handle_chld ;
2005-10-06 17:30:50 +10:00
act . sa_flags = SA_SIGINFO ;
if ( sigaction ( SIGCHLD , & act , 0 ) )
{
wperror ( L " sigaction " ) ;
2007-01-22 01:03:41 +10:00
FATAL_EXIT ( ) ;
2005-10-06 17:30:50 +10:00
}
2011-12-26 19:18:46 -08:00
2007-01-22 01:01:14 +10:00
# ifdef SIGWINCH
2005-10-06 17:30:50 +10:00
act . sa_flags = SA_SIGINFO ;
2005-10-14 21:40:33 +10:00
act . sa_sigaction = & handle_winch ;
2005-10-06 17:30:50 +10:00
if ( sigaction ( SIGWINCH , & act , 0 ) )
{
wperror ( L " sigaction " ) ;
2007-01-22 01:03:41 +10:00
FATAL_EXIT ( ) ;
2005-10-06 17:30:50 +10:00
}
2007-01-22 01:01:14 +10:00
# endif
2005-10-06 17:30:50 +10:00
2006-05-14 20:16:23 +10:00
act . sa_flags = SA_SIGINFO ;
act . sa_sigaction = & handle_hup ;
if ( sigaction ( SIGHUP , & act , 0 ) )
{
wperror ( L " sigaction " ) ;
2007-01-22 01:03:41 +10:00
FATAL_EXIT ( ) ;
2006-05-14 20:16:23 +10:00
}
2005-10-06 17:30:50 +10:00
}
else
{
/*
Non - interactive . Ignore interrupt , check exit status of
processes to determine result instead .
*/
act . sa_handler = SIG_IGN ;
sigaction ( SIGINT , & act , 0 ) ;
sigaction ( SIGQUIT , & act , 0 ) ;
act . sa_handler = SIG_DFL ;
2005-10-06 21:54:16 +10:00
act . sa_sigaction = & handle_chld ;
2005-10-06 17:30:50 +10:00
act . sa_flags = SA_SIGINFO ;
if ( sigaction ( SIGCHLD , & act , 0 ) )
{
wperror ( L " sigaction " ) ;
2012-02-28 15:11:46 -08:00
exit_without_destructors ( 1 ) ;
2005-10-06 17:30:50 +10:00
}
}
2011-12-26 19:18:46 -08:00
2005-10-06 17:30:50 +10:00
}
2005-10-06 21:54:16 +10:00
void signal_handle ( int sig , int do_handle )
{
struct sigaction act ;
2011-12-26 19:18:46 -08:00
2005-10-06 21:54:16 +10:00
/*
These should always be handled
*/
if ( ( sig = = SIGINT ) | |
( sig = = SIGQUIT ) | |
( sig = = SIGTSTP ) | |
( sig = = SIGTTIN ) | |
( sig = = SIGTTOU ) | |
( sig = = SIGCHLD ) )
return ;
2011-12-26 19:18:46 -08:00
2006-05-15 02:39:36 +10:00
sigemptyset ( & act . sa_mask ) ;
2005-10-14 21:40:33 +10:00
if ( do_handle )
{
2006-05-15 02:39:36 +10:00
act . sa_flags = SA_SIGINFO ;
2005-10-14 21:40:33 +10:00
act . sa_sigaction = & default_handler ;
}
else
{
2006-05-15 02:39:36 +10:00
act . sa_flags = 0 ;
2005-10-14 21:40:33 +10:00
act . sa_handler = SIG_DFL ;
}
2011-12-26 19:18:46 -08:00
2005-10-06 21:54:16 +10:00
sigaction ( sig , & act , 0 ) ;
}
2005-10-14 21:40:33 +10:00
void signal_block ( )
{
2012-02-18 23:26:39 -08:00
ASSERT_IS_MAIN_THREAD ( ) ;
2011-12-26 19:18:46 -08:00
sigset_t chldset ;
2006-02-10 01:50:20 +10:00
if ( ! block_count )
{
sigfillset ( & chldset ) ;
2011-12-26 19:18:46 -08:00
sigprocmask ( SIG_BLOCK , & chldset , 0 ) ;
2006-02-10 01:50:20 +10:00
}
2011-12-26 19:18:46 -08:00
2006-02-10 01:50:20 +10:00
block_count + + ;
2006-10-30 07:09:11 +10:00
// debug( 0, L"signal block level increased to %d", block_count );
2005-10-14 21:40:33 +10:00
}
void signal_unblock ( )
{
2012-02-18 23:26:39 -08:00
ASSERT_IS_MAIN_THREAD ( ) ;
2011-12-26 19:18:46 -08:00
sigset_t chldset ;
2006-05-15 02:39:36 +10:00
2006-02-10 01:50:20 +10:00
block_count - - ;
2006-05-15 02:39:36 +10:00
2007-01-22 01:03:41 +10:00
if ( block_count < 0 )
{
debug ( 0 , _ ( L " Signal block mismatch " ) ) ;
bugreport ( ) ;
FATAL_EXIT ( ) ;
}
2011-12-26 19:18:46 -08:00
2006-02-10 01:50:20 +10:00
if ( ! block_count )
{
sigfillset ( & chldset ) ;
2011-12-26 19:18:46 -08:00
sigprocmask ( SIG_UNBLOCK , & chldset , 0 ) ;
2006-02-10 01:50:20 +10:00
}
2006-10-30 07:09:11 +10:00
// debug( 0, L"signal block level decreased to %d", block_count );
}
2006-05-15 02:39:36 +10:00
2006-10-30 07:09:11 +10:00
int signal_is_blocked ( )
{
return ! ! block_count ;
2005-10-14 21:40:33 +10:00
}
2006-10-30 07:09:11 +10:00