linux_ signal capture - signal function - sigaction function - sigaction structure

Continued from the previous article: linux_signal_sigemptyset function-sigfillset function-sigaddset function-sigdelset function-sigismember function-sigprocmask function-sigpending function

This time, I will share the signal capture of linux. Without further ado, let’s serve:

The catalog of articles published by this blogger on CSDN: [ My CSDN catalog, as a guide to the types of articles published by bloggers on CSDN ]

There are three signal processing methods, namely:
  1. Execute the default action
  2. Ignore (discard)
  3. Capture (call user processing function)
  This time, let's talk about signal capture.

1.signal function

Function:
  register a signal capture function.
Header file:
  #include <signal.h>
Function prototype:
  sighandler_t signal(int signum, sighandler_t handler);
Function parameters:
  signum: signal to be captured
  handler: callback function, operation to be performed. Definition: typedef void (*sighandler_t)(int);
Return Value:
  Success: Returns the previous value of the signal handler.
  Error: SIG_ERR is returned, errno is set to indicate the reason.

该函数由ANSI定义,由于历史原因在不同版本的Unix和不同版本的Linux中可能有不同的行为。因此应该尽量避免使用它,取而代之使用sigaction函数。

2. sigaction function

Function role:
  modify the signal processing action (usually used in Linux to register a signal capture function).
Header file:
  #include <signal.h>
Function prototype:
   int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
Function parameter:
  act: incoming parameter, new processing method.
  oldact: Outgoing parameter, the old processing method.
Return value:
  success: 0;
  failure: -1, set errno

2.1.struct sigaction structure

struct sigaction {
    void     (*sa_handler)(int);
    void     (*sa_sigaction)(int, siginfo_t *, void *);
    sigset_t   sa_mask; 
    int       sa_flags; 
    void     (*sa_restorer)(void);
};

   sa_restorer: This element is obsolete and should not be used. The POSIX.1 standard will not specify this element. (DEPRECATED)
   sa_sigaction: This signal handler is used when sa_flags is specified as the SA_SIGINFO flag. (Rarely used)
Key points:
   sa_handler: Specify the name of the processing function after signal capture (that is, the registration function). It can also be assigned as SIG_IGN table ignore or SIG_DFL table to execute the default action
   sa_mask: When calling the signal processing function, the set of signals to be masked (signal mask word). Note: The shielding takes effect only when the processing function is called, and it is a temporary setting.
   sa_flags: Usually set to 0, the table uses the default attributes.

2.2. Signal Capture Features

  1. When the process is running normally, there is a signal shield word in the default PCB, which is assumed to be set, which determines which signals the process automatically shields. When a signal capture function is registered, the function should be called after the signal is captured. However, this function may be executed for a long time, and the signal shielded during this period is not specified by set. Instead, use sa_mask to specify. After calling the signal processing function, restore to set.
  2. During the execution of the XXX signal capture function, the XXX signal is automatically blocked.
  3. Blocked regular signals do not support queuing, and only record once when they are generated multiple times.

3. Example - capture ctrl-c signal

#include <signal.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>

typedef void (*sighandler_t) (int);
//捕捉信号后执行的函数
void catchsigint(int signo)
{
    
    
    printf("-----------------catch\n");
}
int main(void)
{
    
    
    sighandler_t handler;
	//捕捉ctrl+c信号,在当前进程收到ctrl+c信号时执行do_sig函数
    handler = signal(SIGINT, catchsigint);//捕捉信号
    if (handler == SIG_ERR) 
	{
    
    
        perror("signal error");
        exit(1);
    }
    while (1);
    return 0;
}

4. Example sigaddset function - reflect the first item of the signal capture feature

//测试捕捉函数阻塞时再发送信号给该进程情况
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
/*自定义的信号捕捉函数*/
void sig_int(int signo)
{
    
    
	printf("catch signal SIGINT\n");//单次打印
    sleep(5);//阻塞期间,向该进程发送其它信号必须得等捕捉函数执行完才响应
    printf("----slept 5 s\n");
}
int main(void)
{
    
    
	struct sigaction act;		
	act.sa_handler = sig_int;
	act.sa_flags = 0;
	sigemptyset(&act.sa_mask);		//信号集合清零
    sigaddset(&act.sa_mask, SIGQUIT);//屏蔽ctrl+c信号
	sigaction(SIGINT, &act, NULL);//注册信号
	while(1);//让主进程阻塞
	return 0;
}
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
void docatch(int signo)
{
    
    
    printf("%d signal is catched\n", signo);
    sleep(5);
    printf("-------finish------\n");
}
int main(void)
{
    
    
    int ret;
    struct sigaction act;
    act.sa_handler = docatch;
    sigemptyset(&act.sa_mask);
    sigaddset(&act.sa_mask, SIGQUIT);
    act.sa_flags = 0;  //默认属性   信号捕捉函数执行期间,自动屏蔽本信号

    ret = sigaction(SIGINT, &act, NULL);
    if (ret < 0) {
    
    
        perror("sigaction error");
        exit(1);
    }
    while (1);
    return 0;
}

The above is the sharing of this time, I hope it will be helpful to everyone.

Guess you like

Origin blog.csdn.net/qq_44177918/article/details/130278570