1. Signal Set and signal set processing functions
A signal set is a single vector, each of which corresponds to a signal of the Linux system. You can use the following functions to process the signal set:
# Include <signal. h>
Int sigemptyset (sigset_t * Set );
Int sigfillset (sigset_t * Set );
Int sigaddset (sigset_t * Set );
Int sigdelset (sigset_t * Set );
Sigemptyset clears a signal set. sigfillset clears all the positions in the signal set. The sigaddset function sets the bit corresponding to the signal specified by the signo parameter to 1; sigdelset sets the corresponding signo bits to 0.
Use the following function to check whether the corresponding bit of the signal set is set:
# Include <signal. h>
Int sigismember (sigset_t * Set, int aigno );
If the returned value is 1, it indicates that the bit is set. If the returned value is 0, it indicates that the bit is not set. If the bit fails, it returns-1.
// Sigset. c use the signal set processing function to test and set the corresponding signal bit
# Include <stdio. h>
# Include <signal. h>
Int main ()
{
Sigset_t sig_set;
Sigemptyset (& sig_set); // clear the Signal Set
Sigaddset (& sig_set, SIGKILL-1); // sets the corresponding bit of sigkill
If (sigismember (& sig_set, sigkill) = 1 ){
Printf ("sigkill has been set/N ");
Else
Printf ("can't set Signal Set/N ");
Return 0;
}
2. Shielding Signals
Blocks some signals so that the process does not process them even if it receives the signal.
Use the following functions:
# Include <signal. h>
Int sigprocmask (INT how, const sigset_t * Set, sigset_t * oldset );
Function Description: sigprocmask () can be used to change the current signal shielding. The operation depends on the parameter how.
The new signal shielding function of sig_block is composed of the current signal shielding function and the signal shielding function specified by the set parameter.
Sig_unblock deletes the current signal shielding function from the signal shielding function specified by the set parameter.
Sig_setmask sets the current signal shielding to the signal shielding specified by the set parameter.
If the oldset parameter is not a null pointer, the current signal shielding will return this pointer.
If the return value is successfully executed, 0 is returned. If an error exists,-1 is returned.
The Set parameter of the error code efault cannot be accessed by the oldset pointer address.
Eintr this call is interrupted
If the set value is null, no signal shielding word is changed regardless of how. This method is used to obtain the signal shielding characters of the current process.
Sigprocmask (0, null, & oset );
# Include <stdio. h>
# Include <stdlib. h>
# Include <signal. h>
Void sigusr1_handler (INT signo)
{
Printf ("catch SIGUSR1/N ");
}
Int main (void)
{
Sigset_t set;
If (signal (SIGUSR1, sigusr+handler) = sig_err ){
Perror ("can handle t set handler for SIGUSR1 ");
Exit (1 );
}
Sigemptyset (& set); // clear the Signal Set
Sigaddset (& set, SIGUSR1-1); // set SIGUSR1
If (sigprocmask (sig_block, & set, null) =-1) {// shield this signal
Perror ("fail to set signal-Mask ");
Exit (1 );
}
Printf ("SIGUSR1 is not available/N ");
Sleep (10); // sleep, waiting for the user to send the SIGUSR1 signal
If (sigprocmask (sig_unblock, & set, null) =-1) {// restores the blocked Signal
Perror ("fail to set signal-Mask ");
Exit (1 );
}
Printf ("SIGUSR1 is available now/N ");
Sleep (10); // sleep, waiting for the user to send the SIGUSR1 signal
Return 0;
}
3. process pending Signals
If a signal is blocked, but the process still receives the signal from somewhere, this signal is called pending. This signal is pending.
If there are any pending but no blocking signals after sigprocmask is called, at least one of these released pending signals will be sent to the process before the function returns. In Linux, The sigpending function is used to check pending signals. The prototype of the function is as follows;
# Include <signal. h>
Int sigpending (sigset_t * Set );
Set indicates all pending signals in the current process. If a pending signal set is obtained successfully, 0 is returned; otherwise,-1 is returned.
In the following example, the SIGUSR1 signal is blocked first, and then the SIGUSR1 signal is sent to the process. The signal is pending. Use the sigpending function to test whether there is a pending SIGUSR1 signal, finally, cancel the blocking on the signal and process the signal.
# Include <stdio. h>
# Include <stdlib. h>
# Include <signal. h>
Void sigusr1_handler (INT signo)
{
Printf ("catch SIGUSR1/N ");
}
Int main (void)
{
Sigset_t set;
Sigset_t sig_pend;
Sigemptyset (& set );
Sigemptyset (& sig_pend );
If (signal (SIGUSR1, sigusr+handler) = sig_err ){
Perror ("can handle t set handler for SIGUSR1 ");
Exit (1 );
}
Sigaddset (& set, SIGUSR1-1); // Add the SIGUSR1 signal
If (sigprocmask (sig_block, & set, null) =-1) {// block SIGUSR1
Perror ("fail to set signal-Mask ");
Exit (1 );
}
Sleep (10); // sleep 10. receives signals during sleep. Note that the process will not be awakened by pending signals after sleep.
If (sigpending (& sig_pend) =-1) {// obtain all pending signal Sets
Perror ("fail to get pending signal ");
Exit (1 );
}
If (sigismember (& sig_pend, SIGUSR1-1) = 1) // test whether the SIGUSR1 signal is pending
Printf ("there is a signal, SIGUSR1, is pending/N ");
Else {
Perror ("fail to test signal-set ");
Exit (1 );
}
If (sigprocmask (sig_unblock, & set, null) =-1) {// cancel blocking of SIGUSR1
Perror ("fail to set signal-Mask ");
Exit (1 );
}
Printf ("SIGUSR1 is available again/N ");
Return 0;
}
4. Advanced Signal Processing functions
Prototype:
# Include <signal. h>
Define the int sigaction (int signum, const struct sigaction * Act, struct sigaction * oldact) function );
Function Description: sigaction () sets the signal processing function based on the signal number specified by SIGNUM. The SIGNUM parameter can specify all signals other than sigkill and sigstop.
For example, the parameter structure sigaction is defined as follows:
Struct sigaction
{
Void (* sa_handler) (INT );
Sigset_t sa_mask;
Int sa_flags;
Void (* sa_restorer) (void );
}
Sa_handler this parameter is the same as the signal () parameter handler, representing a new signal processing function. For other meanings, see signal ().
Sa_mask is used to set the signal specified by sa_mask to be temporarily shelved when processing this signal.
Sa_restorer is not used.
Sa_flags is used to set other operations related to signal processing. The following values are available.
Or operation (|) combination a_nocldstop: If the SIGNUM parameter is sigchld, the parent process sa_oneshot/sa_resethand will not be notified when the child process is paused: Before calling the new signal processing function, change the Signal Processing Method to the preset one.
Sa_restart: system calls that are interrupted by signals will be restarted on their own.
Sa_nomask/sa_nodefer: Ignore the re-arrival of the signal before processing the signal. If the oldact parameter is not a null pointer, the original signal processing method will be returned from the sigaction structure.
If the return value is successfully executed, 0 is returned. If an error exists,-1 is returned.
The error code einval parameter SIGNUM is invalid, or an attempt to intercept the sigkill/sigstopsigkill Signal
The efault parameter Act and the oldact pointer address cannot be accessed.
Eintr this call is interrupted
5. sa_nocldwait Option
After the sa_nocldwait option is set, when the signal is sigchild, the sub-process of the called process is terminated and system resources are released immediately. If a process is called to call the wait function, the process is blocked. After all its sub-processes are released, the wait function returns-1 and sets the errno error code to echild, this option can be used to avoid zombie processes.
// Nowait. c
# Include <stdio. h>
# Include <stdlib. h>
# Include <signal. h>
# Include <unistd. h>
# Include <errno. h>
Int main (void)
{
Struct sigaction Act;
Pid_t PID;
Act. sa_handler = sig_dfl;
Act. sa_flags = sa_nocldwait;
Act. sa_sigaction = NULL;
Sigemptyset (& act. sa_mask );
If (sigaction (sigchld, & act, null) =-1 ){
Perror ("fail to set handler for sigchild ");
Exit (1 );
}
PID = fork ();
If (PID <0 ){
Perror ("fail to fork ");
Exit (1 );
} Else if (pid = 0 ){
Printf ("the 1st child/N ");
Exit (0); // the first process exits immediately
} Else {
PID = fork ();
If (PID <0 ){
Perror ("fail to fork ");
Exit (1 );
} Else if (pid = 0 ){
Printf ("the 2nd child/N ");
Sleep (5); // sleep for 5 seconds to exit
Exit (0 );
} Else {
If (wait (null) =-1) // call the wait function, this function must return an error
If (errno = echild)
Printf ("all child quit, no child is zome/N ");
Printf ("the parent/N ");
}
}
Return 0;
}
Run:
./Nowait
The 1st child
The 2nd child
All child quit, no child is zome
The parent
6. sa_nodefer Option
If the sa_nodefer option is set, the signal is not blocked when the processing function is executed when the signal is captured, unless the sa_mask specifies to block the signal.
// Nodefer. c
# Include <stdio. h>
# Include <stdlib. h>
# Include <signal. h>
Void sigusr1_handler (INT signo)
{
Printf ("catch SIGUSR1/N ");
Sleep (5); // wait for the next SIGUSR1 signal
Printf ("back to main/N ");
}
Int main (void)
{
Struct sigaction Act;
Act. sa_handler = sigusrw.handler;
Act. sa_flags = sa_nodefer;
Act. sa_sigaction = NULL;
Sigemptyset (& act. sa_mask );
If (sigaction (SIGUSR1, & act, null) =-1 ){
Perror ("fail to set handler for sigchild ");
Exit (1 );
}
Printf ("process begin/N ");
Sleep (10); // wait for the SIGUSR1 signal
Printf ("done/N ");
Return 0;
}
7. sa_resethand options
If the sa_resethand option is set, after signal processing is returned, the signal processing function is almost restored to the default signal processing function.
# Include <stdio. h>
# Include <stdlib. h>
# Include <signal. h>
Void sigusr1_handler (INT signo)
{
Printf ("catch SIGUSR1/N ");
}
Int main (void)
{
Struct sigaction Act;
Act. sa_handler = sigusrw.handler;
Act. sa_flags = sa_resethand;
Act. sa_sigaction = NULL;
Sigemptyset (& act. sa_mask );
If (sigaction (SIGUSR1, & act, null) =-1 ){
Perror ("fail to set handler for sigchild ");
Exit (1 );
}
Printf ("process begin/N ");
Sleep (5); // wait for the first SIGUSR1
Sleep (5); // wait for the second SIGUSR1
Printf ("done/N ");
Return 0;
}