Linux system programming-signal advanced version sigaction function

sigaction function prototype

#include <signal.h>
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

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

Parameter Description:

void(*sa_handler)(int);
/*信号处理函数,不接受额外数据,SIG_IGN 为忽略,SIG_DFL 为默认动作,如果 sa_flags 中存在SA_SIGINFO 标志,
那么 sa_sigaction 将作为 signum 信号的处理函数,否则用 sa_handler */
	
void(*sa_sigaction)(int, siginfo_t *, void *);
//信号处理函数,能够接受额外数据和 sigqueue 配合使用

sigset_t sa_mask;
//阻塞关键字的信号集,可以在调用捕捉函数之前把信号添加到信号阻塞字,信号捕捉函数返回之前恢复为原先的值

int sa_flags;
//影响信号的行为,SA_SIGINFO 表示能够接受数据
  • sigaction functionIs a system call, according to the function prototype, we can see that in the function prototype, the first parameter signumnumber is registered should signal; the second argument act, if not null illustrate the need for a new configuration of the signal; the third parameter oldactto perform a recovery if you do not, you can back up the configuration before the signal is empty, to facilitate.

  • struct sigaction structureThe sa_maskmembers, set its focus on the signal of the signal will be set to block before capturing function calls, and restore the original default settings when capturing function returns. The purpose of this is to block the silent writing signal when the signal processing function is called. When the signal processing function is called, the operating system will create a new signal blocking word, including the signal being delivered. Therefore, it can be guaranteed that when processing a given signal, if this kind of signal occurs again, it will be blocked until the processing of the previous signal ends.

  • sigaction functionTimeliness: When the specified action is set for a certain signal, then until it is explicitly called againsigaction functionAnd it will remain valid until the action is changed.

  • void(*sa_sigaction)(int, siginfo_t *, void *); processing function, The first parameter intis a signal; third parameter void *is the extra data carried by the received signal, is not empty, it is additional data; and the second parameter struct siginfo_tof this structure is mainly applied to recording some information in the received signal

siginfo_t {
    
    
               int      si_signo;    /* Signal number */
               int      si_errno;    /* An errno value */
               int      si_code;     /* Signal code */
               int      si_trapno;   /* Trap number that caused
                                        hardware-generated signal
                                        (unused on most architectures) */
               pid_t    si_pid;      /* Sending process ID */
               uid_t    si_uid;      /* Real user ID of sending process */
               int      si_status;   /* Exit value or signal */
               clock_t  si_utime;    /* User time consumed */
               clock_t  si_stime;    /* System time consumed */
               sigval_t si_value;    /* Signal value */
               int      si_int;      /* POSIX.1b signal */
               void    *si_ptr;      /* POSIX.1b signal */
               int      si_overrun;  /* Timer overrun count; POSIX.1b timers */
               int      si_timerid;  /* Timer ID; POSIX.1b timers */
               void    *si_addr;     /* Memory location which caused fault */
               long     si_band;     /* Band event (was int in
                                        glibc 2.3.2 and earlier) */
               int      si_fd;       /* File descriptor */
               short    si_addr_lsb; /* Least significant bit of address
                                        (since kernel 2.6.32) */
           }
  • The signal can be acquired through this structure relevant information, si_signoand si_codethat two members must be implemented

  • About two local data sent from the presence of: si_valuesaving the information sent over the same time, in si_intor si_ptrmembers also save the corresponding data

Signaling function

#include <signal.h>
int sigqueue(pid_t pid, int sig, const union sigval value);
union sigval {
    
    
   int   sival_int;
   void *sival_ptr;
 };

1. Usesigqueue functionbefore,sigaction functionNeed to develop SA_SIGINFOsigns
2,sigaction structureThe sa_sigactionmembers provide a signal capture functions. If the implementation is sa_handlera member, then you will not be able to obtain additional data carried
3,sigqueue functionOnly a single transmission signal to a process that can be valuetransferred to an integer value or a pointer value of the signal processing function parameters
4,sigqueue functionNot only can you send additional data, you can also queue the signal (the operating system must implementPOSIX.1The real-time extension), provided for the blocking signal, the use of sigqueuetransmission signals a plurality of the same, when unblocked, the recipient will receive the signal transmitted in the queue, rather than directly receive time; however, the signal can not be unlimited line, the maximum value of the signal line is subjected to SIGQUEUE_MAXrestrictions, the maximum limit is reached, sigqueuewill fail, errnoit will be setEAGAIN

Example:

Receiving end:

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

//void (*sa_sigaction)(int, siginfo_t *, void *);
void handler(int signum, siginfo_t *info, void *context)
{
    
    
        printf("Get the signum:No(%d),SIGUSR1\n",signum);

        if(context){
    
    
                printf("content:%d\n",info->si_int);
                printf("content:%d\n",info->si_value.sival_int);
        }
}

void main()
{
    
    
        struct sigaction act;

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

        act.sa_sigaction = handler;
        act.sa_flags = SA_SIGINFO;

        printf("pid:%d\n",getpid());

//      int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
        sigaction(SIGUSR1,&act,NULL);
        while(1);
}

Sending end:

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

void main(int argc, char **argv)
{
    
    
        if(argc != 3){
    
    
                printf("Parameter error!\n");
                exit(1);
        }

        int signum = atoi(argv[1]);
        int pid = atoi(argv[2]);

        /*
        union sigval {
               int   sival_int;
               void *sival_ptr;
        };
        */

        union sigval value;
        value.sival_int = 888;

        //int sigqueue(pid_t pid, int sig, const union sigval value);
        sigqueue(pid,signum,value);
}

operation result:

Receiving end:

:~$ ./sigreceive 
pid:18883
Get the signum:No(10),SIGUSR1
context:888
context:888

Sending end:

:~$ ./sigsend 10 18883

Guess you like

Origin blog.csdn.net/lcx1837/article/details/108018158