Linux signal instance

Source: Internet
Author: User
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"
 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.