SA_RESTART --------------------------------------- set the SA_RESTART attribute of the signal S. if the system call is interrupted by the signal S, when the signal processing function returns, the system call is automatically restored. # include & lt; signal. h & gt; # include & lt; stdio. h & gt; # include &
SA_RESTART
-----------------------------------------
Set the SA_RESTART attribute of the signal S. if the system call is interrupted by the signal S, after the signal processing function returns,
The system call will be automatically restored.
# Include
# Include
# Include
# Include
# Include
Void sig_handler (int signum)
{
Printf ("at handler \ n ");
Sleep (10 );
Printf ("leave handler \ n ");
}
Int main (int argc, char ** argv)
{
Char buf [100];
Int ret;
Struct sigaction action, old_action;
Action. sa_handler = sig_handler;
Sigemptyset (& action. sa_mask );
Action. sa_flags = 0;
Action. sa_flags | = SA_RESTART;/* set or not set this attribute */
Sigaction (SIGINT, NULL, & old_action );
If (old_action.sa_handler! = SIG_IGN ){
Sigaction (SIGINT, & action, NULL );
}
Bzero (buf, 100 );
Ret = read (0, buckets, 100 );
If (ret =-1 ){
Perror ("read ");
}
Printf ("read % d bytes: \ n", ret );
Printf ("% s \ n", buf );
Return 0;
}
If not set, when reading data from standard input, if ctrl + c is pressed, the read system call is interrupted and-1 is returned.
If this parameter is set, after the signal processing function returns, the read system call is resumed, but before the signal processing function returns, the read cannot read data.
Int sigemptyset (sigset_t * set );
Int sigfillset (sigset_t * set );
Int sigaddset (sigset_t * set, int signum );
Int sigdelset (sigset_t * set, int signum );
Int sigismember (const sigset_t * set, int signum );
Int sigsuspend (const sigset_t * mask );
Int sigpending (sigset_t * set );
Shield some signals of a process
-------------------------------------
Blocking does not prohibit delivery of signals, but temporarily blocks delivery of signals,
After unblocking, the signal will be delivered and will not be lost
# Include
# Include
# Include
# Include
# Include
Void sig_handler (int signum)
{
Printf ("catch sigint \ n ");
}
Int main (int argc, char ** argv)
{
Sigset_t block;
Struct sigaction action, old_action;
Action. sa_handler = sig_handler;
Sigemptyset (& action. sa_mask );
Action. sa_flags = 0;
Sigaction (SIGINT, NULL, & old_action );
If (old_action.sa_handler! = SIG_IGN ){
Sigaction (SIGINT, & action, NULL );
}
Sigemptyset (& block );
Sigaddset (& block, SIGINT );
Printf ("block sigint \ n ");
Sigprocmask (SIG_BLOCK, & block, NULL );
Sleep (5 );
/* After the unblock signal, the previously triggered signal will be delivered.
* Trigger multiple times and deliver only once */
Sigprocmask (SIG_UNBLOCK, & block, NULL );
Printf ("unblock sigint \ n ");
Sleep (5 );
Return 0;
}
Shielding certain signals within the signal processing function
----------------------------------------
# Include
# Include
# Include
# Include
# Include
Void sig_handler (int signum)
{
Printf ("in handle... sigterm is blocked \ n ");
Sleep (5 );
Printf ("handle done \ n ");
}
Void handle_term (int signum)
{
Printf ("catch sigterm and exit .. \ n ");
Exit (0 );
}
Int main (int argc, char ** argv)
{
Struct sigaction action, old_action;
/* Set SIGINT */
Action. sa_handler = sig_handler;
Sigemptyset (& action. sa_mask );
Sigaddset (& action. sa_mask, SIGTERM );
Action. sa_flags = 0;
Sigaction (SIGINT, NULL, & old_action );
If (old_action.sa_handler! = SIG_IGN ){
Sigaction (SIGINT, & action, NULL );
}
/* Set SIGTERM */
Action. sa_handler = handle_term;
Sigemptyset (& action. sa_mask );
Action. sa_flags = 0;
Sigaction (SIGTERM, NULL, & old_action );
If (old_action.sa_handler! = SIG_IGN ){
Sigaction (SIGTERM, & action, NULL );
}
Printf ("pid = % d \ n", getpid ());
While (1 ){
Sleep (1 );
}
Return 0;
}
Press ctrl + c. after receiving the SIGINT, enter sig_handler and block SIGTERM.
Kill the process and the program will not receive the SIGTERM signal. it will not receive the signal until sig_handler returns.
SIGTERM signal, and then exit the program
Int setjmp (jmp_buf env );
Int sigsetjmp (sigjmp_buf env, int savesigs );
Void longjmp (jmp_buf env, int val );
Void siglongjmp (sigjmp_buf env, int val );
--------------------------------------------------------
Setjmp () saves the current stack environment and marks the current address, which is called elsewhere in the program.
Longjmp directly jumps to the Mark position, restores the stack, and continues the program execution.
Setjmp call is a bit of fork taste, setjmp () return 0 if returning directly,
And non-zero when returning from longjmp using the saved context.
If (setjmp (jmpbuf )){
Printf ("return from jmp \ n ");
} Else {
Printf ("return directly \ n ");
}
The only difference between setjmp and sigsetjmp is that setjmp does not necessarily restore the signal set, while sigsetjmp can
Recovery signal set
# Include
# Include
# Include
# Include
# Include
# Include
Void sig_alrm (int signum );
Void sig_usr1 (int signum );
Void print_mask (const char * str );
Static sigjmp_buf jmpbuf;
Static volatile sig_atomic_t canjmp;
Static int sigalrm_appear;
Int main (int argc, char ** argv)
{
Struct sigaction action, old_action;
/* Set SIGUSR1 */
Action. sa_handler = sig_usr1;
Sigemptyset (& action. sa_mask );
Action. sa_flags = 0;
Sigaction (SIGUSR1, NULL, & old_action );
If (old_action.sa_handler! = SIG_IGN ){
Sigaction (SIGUSR1, & action, NULL );
}
/* Set SIGALRM */
Action. sa_handler = sig_alrm;
Sigemptyset (& action. sa_mask );
Action. sa_flags = 0;
Sigaction (SIGALRM, NULL, & old_action );
If (old_action.sa_handler! = SIG_IGN ){
Sigaction (SIGALRM, & action, NULL );
}
Printf ("pid = % d \ n", getpid ());
Print_mask ("starting main :");
Sleep (10 );
If (sigsetjmp (jmpbuf, 1 )! = 0 ){
Print_mask ("ending main :");
} Else {
Printf ("setjmp return \ n ");
Canjmp = 1;
While (1 ){
Sleep (1 );
}
}
Return 0;
}
Void sig_usr1 (int signum)
{
Time_t starttime;
If (canjmp = 0 ){
Printf ("please set jmp first \ n ");
Return;
}
Print_mask ("starting sig_usr1 :");
Alarm (3 );
While (! Sigalrm_appear );
Print_mask ("finishing sig_usr1 :");
Canjmp = 0;
Siglongjmp (jmpbuf, 1 );
}
Void sig_alrm (int signum)
{
Print_mask ("in sig_alrm :");
Sigalrm_appear = 1;
Return;
}
Void print_mask (const char * str)
{
Sigset_t sigset;
Int I, errno_save, flag = 0;
Errno_save = errno;
If (sigprocmask (0, NULL, & sigset) <0 ){
Printf ("sigprocmask error \ n ");
Exit (0 );
}
Printf ("% s \ n", str );
Fflush (stdout );
For (I = 1; I <NSIG; I ++ ){
If (sigismember (& sigset, I )){
Flag = 1;
Psignal (I, "blocked ");
}
}
If (! Flag ){
Printf ("no blocked signal \ n ");
}
Printf ("\ n ");
Errno = errno_save;
}
Run kill-USR1 Send Signal
The program receives SIGUSR1, enters sig_usr1, automatically shields the SIGUSR1 signal, and then enables
The timer generates the SIGALRM signal and enters the sig_alrm. at this time, the SIGUSR1 and SIGALRM are automatically blocked,
After the main function is returned, the signal shielding is restored to the original state.
Author "kenby"