1. sigaction ()
# Include <signal. h>
Int sigaction (int signum, const struct sigaction * act, struct sigaction * oldact ));
The sigaction function is used to change the behavior of a process after receiving a specific signal. The first parameter of this function is the signal value, which can be any specific valid signal Except SIGKILL and SIGSTOP (define your own processing function for these two signals, will cause a signal installation error ). The second parameter is a pointer to an instance of the sigaction structure. In the instance of the sigaction structure, the processing of specific signals is specified, which can be blank, the process processes the signal by default. The third parameter oldact points to the object to save the original processing of the corresponding signal. You can specify oldact as NULL. If the second and third parameters are set to NULL, this function can be used to check the signal validity.
The second parameter is the most important, including the processing of the specified signal, the information transmitted by the signal, and the functions to be shielded during the execution of the signal processing function.
The sigaction structure is defined as follows:
(*_sa_sigaction)(, siginfo *, * (*sa_restorer)(
Sa_restorer is out of date and POSIX does not support it and should not be used again.
1. The two elements _ sa_handler and * _ sa_sigaction in the combined data structure specify the signal Association function, that is, the user-specified signal processing function. In addition to user-defined processing functions, it can also be SIG_DFL (using the default processing method) or SIG_IGN (ignoring signals ).
2. The processing function specified by _ sa_handler has only one parameter, namely, the signal value. Therefore, the signal cannot transmit any information except the signal value; the signal processing function specified by _ sa_sigaction has three parameters and is set for real-time signals (of course, non-real-time signals are also supported). It specifies a three-parameter signal processing function. The first parameter is the signal value, the third parameter is not used (posix has no standard to use this parameter), and the second parameter is a pointer to the siginfo_t structure, the structure contains the data value carried by the signal. The structure pointed to by the parameter is as follows:
typedef si_signo; si_errno; si_code;pid_t si_pid;pid_t si_uid; si_status;clock_t si_utime;clock_t si_stime; **
The Union data member in the siginfo_t structure ensures that the structure adapts to all signals. For real-time signals, the following structure is used:
typedef
The fourth domain of the structure is also a joint data structure:
*
The combined data structure indicates that the si_value in the siginfo_t structure either holds a 4-byte integer or a pointer, which constitutes the signal-related data. The signal processing function contains such signal-related data pointers, but does not specify how to operate the data. The procedure should be agreed by the program developers according to the specific task.
Sigqueue structure: when the system calls sigqueue to send signals, the third parameter of sigqueue is the sigval Union data structure. When sigqueue is called, the data in the data structure will be copied to the second parameter of the signal processing function. In this way, the signal can be sent with additional information. It is very meaningful for Program Development to transmit signals.
The third parameter association between siginfo_t.si_value and sigqueue (pid_t pid, int sig, const union sigval val) is:
Therefore, siginfo_t.si_value can be used to obtain the data transmitted by the third parameter sigqueue (pid_t pid, int sig, const union sigval val.
For example, siginfo_t.si_value.sival_int or siginfo_t.si_value.
The signal parameter transmission process is shown as follows:
3. sa_mask specifies which signals should be blocked during the execution of the signal processing program. By default, the current signal is blocked to prevent nested sending of the signal. Unless the SA_NODEFER or SA_NOMASK flag is specified, the blocked signal starts to be executed after the processing program is executed.
Note: The prerequisite for signal blocking specified by sa_mask is that the signal specified by sa_mask is blocked only when the processing function of the signal is executed by sigaction.
4. sa_flags contains many flag spaces, including the SA_NODEFER and SA_NOMASK. Another important flag is SA_SIGINFO. When this flag is set, the parameters attached to the signal can be passed to the signal processing function. Therefore, you should specify a processing function for sa_sigaction in the sigaction structure instead of a signal processing function for sa_handler. Otherwise, setting this flag becomes meaningless. Even if a signal processing function is specified for sa_sigaction, if SA_SIGINFO is not set, the signal processing function cannot obtain the data transmitted from the signal, access to this information in the signal processing function will lead to a segment error (Segmentation fault ).
Note: many documents have stated that if this flag is set, three-parameter signal processing functions must be defined. This is not the case. The verification method is simple: implement a single parameter signal processing function and set this flag in the program to view the running result of the program. In fact, you can regard this flag as a switch for whether to transmit a parameter. If this bit is set, a parameter is transmitted. Otherwise, no parameter is transmitted.
Ii. sigqueue ()
I have previously learned some simple signal sending functions such as kill, raise, alarm, and abort. Now we have learned a new powerful signal sending function sigqueue.
# Include <sys/types. h>
# Include <signal. h>
Int sigqueue (pid_t pid, int sig, const union sigval val)
0 is returned if the call is successful. Otherwise,-1 is returned.
Sigqueue () is a relatively new system call for sending signals, mainly for real-time signals (of course, the first 32 types are also supported). It supports signal parameters and functions sigaction () in combination.
The first parameter of sigqueue is the process ID of the received signal, the second parameter is used to determine the signal to be sent, and the third parameter is a combined data structure union sigval, which specifies the signal transmission parameter, 4-byte value.
Typedef union sigval {
Int sival_int;
Void * sival_ptr;
} Sigval_t;
Sigqueue () transmits more additional information than kill (), but sigqueue () can only send signals to one process, rather than to one process group. If signo is set to 0, an error check is executed, but no signal is actually sent. A 0 signal can be used to check the validity of the pid and whether the current process has the permission to send signals to the target process.
When sigqueue is called, the information specified by sigval_t will be copied to the siginfo_t structure of the three-parameter signal processing function registered by the corresponding sig, so that the signal processing function can process the information. Because sigqueue system calls support sending parameters, it is more flexible and powerful than kill () system calls.
3. sigqueue and sigaction Application Instances
Example 1: Use sigaction to install the SIGINT Signal
#include <unistd.h><sys/stat.h><sys/wait.h><sys/types.h><fcntl.h><stdlib.h><stdio.h><errno.h><.h><signal.h> ERR_EXIT(m) \ ( handler( main( argc, *=&= (sigaction(SIGINT, &act, NULL) < handler(
Result:
<Sys/stat. h> <sys/wait. h> <sys/types. h> <fcntl. h> <stdlib. h> <stdio. h> <errno. h> <. h> <signal. h> ERR_EXIT (m) \ (handler (main (argc, * = & = (sigaction (sig, & act, & oldact)
Result:
<Sys/stat. h> <sys/wait. h> <sys/types. h> <fcntl. h> <stdlib. h> <stdio. h> <errno. h> <. h> <signal. h> ERR_EXIT (m) \ (handler (main (argc, * = & = (sigaction (SIGINT, & act, NULL) <= & = (sigaction (SIGQUIT, & act2, NULL)
Result:
<Unistd. h> <signal. h> <stdlib. h> sighandler (signo, siginfo_t * info, * main (= & = SA_SIGINFO; (sigaction (SIGINT, & act, NULL) =-= (sigqueue (getpid (), SIGINT, mysigval) =-sighandler (signo, siginfo_t * info, * printf (, info->, info->
Result:
<Unistd. h> <signal. h> <stdlib. h> sighandler (signo, siginfo_t * info, * main (= & = SA_SIGINFO; (sigaction (SIGINT, & act, NULL) =-sighandler (signo, siginfo_t * info, * printf (, info->, info->
Sender:
#include <stdio.h><unistd.h><signal.h><stdlib.h> main( argc, **(argc != ,argv[= atoi(argv[= (sigqueue(pid,SIGINT,mysigval) == -
Result:
The figure shows that the message is received successfully.