Signal carrying information (signal registration function - advanced version)

Posted by sillysillysilly on Wed, 22 Dec 2021 15:59:36 +0100

1. Signal registration function - advanced version

Function prototype of sigaction:

#include <signal.h>

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

struct sigaction {

   void       (*sa_handler)(int); //Signal processor, no additional data, SIG_IGN is ignored, SIG_DFL is the default action

   void       (*sa_sigaction)(int, siginfo_t *, void *); //The signal processing program can accept additional data and use it with sigqueue

   sigset_t   sa_mask;//For the signal set of blocking keyword, the signal can be added to the signal blocking word before calling the capture function, and the signal capture function returns to the original value before returning.

   int        sa_flags;//Behavior affecting signals_ Siginfo indicates that data can be accepted

 };
//Callback function handle sa_handler,sa_ Only one sigaction can be selected

sigaction is a system call. According to this function prototype, in the function prototype,

The first parameter signum should be the number of the registered signal;

If the second parameter act is not empty, it indicates that a new configuration of the signal is required;

If the third parameter oldact is not empty, the previous signal configuration can be backed up for later recovery.

SA in struct sigaction structure_ Mask member, the signal set in its signal set will be set as blocking before the capture function is called, and the default original setting will be restored when the capture function returns. The purpose is to block the dictation signal when calling the signal processing function. 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 signal occurs again, it will be blocked until the processing of the previous signal is completed.

Timeliness of sigaction: when a specified action is set for a signal, it will remain valid until sigaction is explicitly called again and the action is changed.

The detailed configuration of the flag attribute in the struct sigaction structure, if set to sa_ The siginfo attribute indicates that the signal handler has additional information, that is, SA will be called_ Sigaction this function pointer points to the signal processing function. Otherwise, SA will be used by default_ The signal processing function pointed to by the handler. sa_sigaction and sa_handler uses the same memory space, which is equivalent to union, so only one of them can be set, not both at the same time.

About void (* sa_sigaction) (int, siginfo_t *, void *) in struct sigaction structure; Void * is the additional data carried by the received signal; The struct siginfo structure is mainly used to record some relevant information of 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 */
               int      si_band;     /* Band event */
               int      si_fd;       /* File descriptor */
}

struct siginfo structure has many members, si_signo and si_code is the two members that must be implemented. The relevant information of the signal can be obtained through this structure.
There are two places for the sent data, sigval_ t si_ The value member holds the sent information; At the same time, in si_int or Si_ The corresponding data is also saved in the PTR member

2. Signaling function - advanced version

#include <signal.h>

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

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

 

Before using this function, several operations must be completed:

(1) SA_SIGINFO flag is formulated when installing signal handler with sigaction function.

(2) the sa_sigaction member in the sigaction structure provides a signal capture function. If it is implemented as a sa_handler member, it will not be possible to obtain additional data.

The sigqueue function can only send signals to a single process. You can use the value parameter to pass an integer value or pointer value to the signal handler.

Sigqueue function can not only send additional data, but also queue signals (the operating system must realize the real-time expansion of POSIX.1). For signals with blocking settings, use sigqueue to send multiple identical signals. When unblocking, the receiver will receive the signals in the sent signal queue instead of directly receiving them once.

However, signals cannot be queued indefinitely, and the maximum value of signal queuing is subject to SIGQUEUE_MAX limit. When the maximum limit is reached, sigqueue will fail and errno will be set to EAGAIN.

3. Send signal code with additional data

Sender Code:

send.c

//Sender
#include <signal.h>
#include<stdio.h>

int main(int argc,char** argv)
{
       int signum;
       int pid;

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

       union sigval value;//Consortium
       value.sival_int = 100;

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

       sigqueue(pid,signum,value);

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

       printf("done !\n");

       return 0;
}

Compile: GCC send c -o sen 

Receiver code:

nicssignal.c

//receiving end
#include <signal.h>
#include<stdio.h>


void handler(int signum, siginfo_t *info, void *context)
{
       printf("get signum: %d\n",signum);

       if(context !=NULL)//Have data
       {
            printf("get data=%d\n",info->si_int);

            printf("get data=%d\n",info->si_value.sival_int);

            printf("form pid = %d\n",info->si_pid);//Sender pid
       }
}

int main()
{
        printf("pid = %d\n",getpid());

        struct sigaction act;
        act.sa_sigaction = handler;
        act.sa_flags = SA_SIGINFO ;//With additional information
/*
int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);
*/
         sigaction(SIGUSR1,&act,NULL);

         while(1);

         return 0;
}
   

Compilation: GCC nicssignal c -o pro

Operation process:

Run first:/ pro

Post run:/ sen 10 12819

Operation results:

 

 

Topics: Linux