The function sigaction allows us to obtain or modify (or acquire and modify) a handler function associated with a particular signal, which replaces the function signal in the earlier version of the UNIX system, and in fact, at the end of this section, We will use sigaction to implement a signal function.
#include<signal.h>
int sigaction(int signo,conststruct sigaction *restrict act,struct sigaction *restrict oact);
Returns:0if OK,-1 on error.
The parameter signo specifies that we are acquiring or modifying the signal number, and if the Act pointer is a non-null pointer, then we are modifying the signal processing action, and if the oact pointer is a non-null pointer, the system will return the previous processing of the specified signal Signo. The structure used by the function is defined as follows:
struct sigaction
{
void(*sa_handler)(int);/*addr of signal handler,or SIG_IGN or SIG_DFL*/
sigset_t sa_mask;/*additional signals to block*/
int sa_flags;/*signal options,Figure 10.16*/
/*alternate handler*/
void(*sa_sigaction)(int,siginfo_t,void*);
};
When modifying the function's processing action, the parameter sa_handler is used to pass the signal processing function, and the parameter sa_mask is used to specify a signal set, which is added to the signal mask before the signal processing function is called, and when the signal processing function returns, the signal mask reverts to the previous value. In this way, we can block some signals when we call a signal processing function. If the operating system contains the signal that the current handler is processing in the signal mask by default, then whenever we are processing a given signal, the same signal must wait for the first signal to be processed before it can be sent. As mentioned in section 10.8, multiple occurrences of the same signal are generally not queued, and if the signal appears multiple times, the signal processing function of the signal is usually only called once when we are in contact with the signal blocking.
Once we set the processing action on a given signal, the action remains valid until the next time we explicitly call the function sigaction to change the signal. Unlike an unreliable signal in an earlier system, POSIX.1 requires that the signal processing function remain in the installation state until the function is explicitly called for modification.
The Sa_flags data field for the ACT structure specifies different options for signal processing, and figure 10.16 details the different options for signal processing, and the SUS column contains * If the identity is defined as part of the POSIX.1 standard, and if it is xsi, it is part of the XSI option.
The parameter sa_sigaction field is another signal processing function that is used only when the Sa_siginfo identity in Sigaction is specified, and the implementation may use the same storage for the sa_sigaction domain and the sa_handler domain. So the app just needs to use one of these two domains.
Option |
SUS |
FreeBSD 8.0 |
Linux 3.2.0 |
Mac OS X 10.6.8 |
Solaris Ten |
Description |
Sa_interrupt |
|
|
* |
|
|
System calls that are interrupted by this signal will not be restarted automatically and are the default selection for Sigaction (for XSI) |
Sa_nocldstop |
* |
* |
* |
* |
* |
If the signal is SIGCHLD, when the child process stops, do not generate a signal (job control), of course, when the child process terminates, the signal will still be generated (but do not need to look at the sa_nocldwait option described below), if the implementation of support XSI option , if the flag is set, SIGCHLD will not be sent if the child process that has been stopped continues to run. |
Sa_nocldwait |
* |
* |
* |
* |
* |
If the signal is SIGCHLD, this option is used to prevent the system from creating a zombie process (when the child process of the calling process terminates), and if the function wait is called later, the calling process will block until all its child processes are terminated, and then the wait function will return-1, and set the errno to Echild |
Sa_nodeffer |
* |
* |
* |
* |
* |
When the signal is present and the signal capture function is executing, the signal is not automatically blocked by the system (unless the signal is also included in the Sa_mask), note that this type of operation corresponds to an early unreliable signal |
Sa_onstack |
XSI |
* |
* |
* |
* |
If an alternative stack had been declared with Sigaltstack (2), this signal was delivered to the process on the alternative Stack. |
Sa_resethand |
* |
* |
* |
* |
* |
When the signal processing function is called, the action of the signal is reset to SIG_DFL, and the entry of the signal processing function is sa_siginfo cleared. Note that this type of operation corresponds to an early unreliable signal. For signal Sigill and sigtrap, it cannot be reset automatically. However, setting this flag will cause the Sigaction function to behave as if Sa_nodefer were set. |
Sa_restart |
* |
* |
* |
* |
* |
System calls that are interrupted by this signal will be automatically restarted |
Sa_siginfo |
* |
* |
* |
* |
* |
This option provides an additional information to the signal handler function: A pointer to the SIGINFO structure, a pointer to the identifier of the process context. |
Figure 10.16 Option Flags (sa_flags) for the handling of each signal
Normally, the signal processing function is called as follows:
void handler(int signo);
However, if the identity sa_siginfo is set, then the signal handler function will be called in the following form:
void handler(int signo, siginfo_t *info, void *context);
The SIGINFO structure contains information about why the signal was generated, and an example of that structure is shown below. All compatible POSIX.1 implementations contain at least Si_signo and Si_code members. In addition, implementations of the compatible XSI option need to include at least the following members:
struct siginfo
{
int si_signo;/* signal number */
int si_errno;/* if nonzero,errno value from errno.h */
int si_code;/* additional info(depends on signal) */
pid_t si_pid;/* sending process ID */
uid_t si_uid;/* sending process real user ID */
void*si_addr;/* address that caused the default */
int si_status;/* exit value or signal number */
union sigval si_value;/* application-specific value */
/*possibly other fields also */
}
The federated Sigval contains the following two data fields:
int sival_int;
void*sival_ptr;
An application can pass an integer in Si_value.sival_int or pass a pointer in si_value.sival_ptr when sending a signal.
Figure 10.17 shows the values for the different signal si_code, as defined in single UNIX specification, and it is possible to customize additional code values for the implementation.
If the signal is SIGCHLD, then Si_pid,si_status and Si_uid will be set, if the signal is SIGBUS,SIGILL,SIGFPE or SIGSEGV, then SI_ADDR contains the corresponding error address, although the address may not be accurate. The Si_errno contains the error number that corresponds to the condition that caused the signal, although its use is defined by the implementation.
The context parameter of a signal processing function is an untyped pointer that can be converted to a type ucontext_t structure that identifies the context at which the signal is sent, which contains at least the following data fields:
ucontext_t*uc_link;/* pointer to context resumed when this context returns*/
sigset_t uc_sigmask;/* signals blocked when this context is active */
stack_t uc_stack;/* stack used by this context */
mcontext_t uc_mcontext;/* machine-specific representation of saved context */
The domain Uc_stack describes the stack used by the current context and contains at least two members:
void*ss_sp;/* stack base or pointer */
size_t ss_size;/*stack size */
int ss_flags;/* flags */
When the implementation supports real-time signal expansion, signal processing functions established using Sa_siginfo will be reliably queued, and a segment of the signal number is reserved for real-time applications, and the application can use the function sigqueue (which will be explained in chapter 10.20) to pass the information through the signal.
Signal |
Code |
Reason |
Sigill |
Ill_illopc |
Illegal operation code |
Sigill |
Ill_illopn |
Number of illegal operations |
Sigill |
Ill_illadr |
Illegal addressing method |
Sigill |
Ill_illtrp |
Illegal traps |
Sigill |
Ill_prvopc |
Privileged Operation code |
Sigill |
Ill_prvreg |
Privileged Registers |
Sigill |
Ill_coproc |
Co-processor Error |
Sigill |
Ill_badstk |
Internal Stack Error |
|
|
|
SIGFPE |
Fpe_intdiv |
Integer except 0 |
SIGFPE |
fpe_intovf |
Integer overflow |
SIGFPE |
Fpe_fltdiv |
Floating point except 0 |
SIGFPE |
fpe_fltovf |
Floating-Point Overflow |
SIGFPE |
Fpe_fltund |
Floating point underflow |
SIGFPE |
Fpe_fltres |
Inaccurate floating-point results |
SIGFPE |
Fpe_fltinv |
Invalid floating-point operation |
SIGFPE |
Fpe_fltsub |
Subscript Overflow |
|
|
|
SIGSEGV |
Segv_maperr |
Invalid mapping address |
SIGSEGV |
Segv_accerr |
The mapping object is completely invalid |
|
|
|
Sigbus |
Bus_adraln |
Invalid address alignment |
Sigbus |
Bus_adrerr |
Physical address that does not exist |
Sigbus |
Bus_objerr |
Specific object hardware error |
|
|
|
SIGTRAP |
Trap_brkpt |
Process Breakpoint Traps |
SIGTRAP |
Trap_trace |
Process Trace Trap |
|
|
|
SIGCHLD |
cld_exited |
Child process Exit |
SIGCHLD |
Cld_killed |
Child process terminated abnormally (no core) |
SIGCHLD |
cld_dumped |
Child process terminated abnormally (with core) |
SIGCHLD |
cld_trapped |
Traced child have trap |
SIGCHLD |
cld_stopped |
Child process has stopped |
SIGCHLD |
cld_continued |
The stopped child process has continued to run |
|
|
|
Any |
Si_user |
Signal sent by Kill |
Any |
Si_queue |
Signal sent by Sigqueue |
Any |
Si_timer |
Time_settime Set Timer end |
Any |
Si_asyncio |
Asynchronous IO Request Completion |
Any |
Si_mesgq |
Message arrival in a message queue (real-time extension) |
Figure 10.17 siginfo_t code values
From for notes (Wiz)
10.14 sigaction function