int sigaction(int sig, const struct sigaction *restrictact, struct sigaction *restrict oact);
struct sigaction
void(*) (int) | sa_handler | 指向信号处理函数或是宏 SIG_IGN (忽略)或 SIG_DFL(默认) |
sigset_t | sa_mask | 指定在执行处理函数时要被阻塞的信号 |
int | sa_flags | 针对信号的标志位 |
void(*) (int, siginfo_t *, void *) | sa_sigaction | 指向信号处理函数 |
SIGKILL 和 SIGSTOP不能加入sa_mask中。
如果act不为空,则对应信号的处理函数被act指向的结构设置。如果为空,信号不发生变化。
如果oact不为空,返回旧的处理函数。如果此时act为空,则可得到信号的当前的处理函数。
sa_flags中SA_SIGINFO被清除,使用sa_handler。SA_SIGINFO被设置,使用sa_sigaction,说明实现支持Realtime Signals Extension option 或 XSI Extension option。
sa_flags有以下选项:
- SA_NOCLDSTOP
子进程停止(如:收到SIGSTOP
信号)时不产生SIGCHLD信号。只有子进程运行终止时才产生。
此选项只有当sig 为 SIGCHLD 时才起作用,对其它信号没影响。 - SA_ONSTACK
如果设置,并且调用了sigaltstack
,将信号提交到指定的堆栈上去,否则,提交到当前堆栈 - SA_RESETHAND
SIGILL 和 SIGTRAP不受影响
若设置,在信号函数的入口,信号的处理函数将被设为SIG_DFL(默认),同时SA_SIGINFO被清除。
若设置,类似设置了 SA_NODEFER
-
-
SA_RESTART
可中断函数的定义:当函数出错时, errno设置为EINTR的函数
若设置,可中断函数重新启动,并且不设置EINTR,除非有特殊情况发生(如:系统不支持)
没设置,被此信号中断的函数出错返回,并设置 errno为EINTR
-
-
SA_SIGINFO
没设置,使用 sa_handler。此时程序不能修改 sa_sigaction
若设置,使用 sa_sigaction ,函数原型为:void func(int signo, siginfo_t *info, void *context);
info : 信号产生的原因
context : 可指向一个 ucontext_t 结构变量,指向被中断线程的上下文
Thesi_errno member may contain implementation-defined additional error information; if non-zero, it contains an errornumber identifying the condition that caused the signal to be generated.
Thesi_code member contains a code identifying the cause of the signal.
If the value ofsi_code is less than or equal to 0, then the signal was generated by a process andsi_pid and si_uid, respectively, indicate the process ID and the real user ID of the sender. The<signal.h> header description contains information about the signal-specific contents of the elements of thesiginfo_t type.
-
-
SA_NOCLDWAIT
-
-
SA_NODEFER
When a signal is caught by a signal-catching function installed by sigaction(), a new signal mask is calculated and installed for the duration of the signal-catching function (or until a call to eithersigprocmask() or sigsuspend() is made). This mask is formed by taking the union of the current signal mask and the value of thesa_mask for the signal being delivered unless SA_NODEFER or SA_RESETHAND is set, and then including the signal being delivered. If and when the user's signal handler returns normally, the original signal mask is restored.
Once an action is installed for a specific signal, it shall remain installed until another action is explicitly requested (by another call tosigaction()), until the SA_RESETHAND flag causes resetting of the handler, or until one of theexec functions is called.
If the previous action for sig had been established by signal(), the values of the fields returned in the structure pointed to byoact are unspecified, and in particular oact->sa_handler is not necessarily the same value passed tosignal(). However, if a pointer to the same structure or a copy there of is passed to a subsequent call tosigaction() via the act argument,handling of the signal shall be as if the original call tosignal() were repeated.
If sigaction() fails, no new signal handler is installed.
It is unspecified whether an attempt to set the action for a signal that cannot be caught or ignored to SIG_DFL is ignored or causes an error to be returned witherrno set to [EINVAL].
If SA_SIGINFO is not set in sa_flags, then the disposition of subsequent occurrences ofsig when it is already pending is implementation-defined; the signal-catching function shall be invoked with a single argument. If the implementation supports the Realtime Signals Extension option, and if SA_SIGINFO is set insa_flags, then subsequent occurrences of sig generated by sigqueue() or as a result of any signal-generating function that supports the specification of an application-defined value (whensig is already pending)shall be queued in FIFO order until delivered or accepted; the signal-catching function shall be invoked with three arguments. The application specified value is passed to the signal-catching function as thesi_value member of the siginfo_t structure.
The result of the use of sigaction() and a sigwait() function concurrently within a process on the same signal is unspecified.
RETURN VALUE
Upon successful completion, sigaction() shall return 0; otherwise, -1 shall be returned,errno shall be set to indicate the error, and no new signal-catching function shall be installed.
ERRORS
The sigaction() function shall fail if:
[EINVAL]
- The sig argument is not a valid signal number or an attempt is made to catch a signal that cannot be caught or ignore asignal that cannot be ignored.
[ENOTSUP]- The SA_SIGINFO bit flag is set in the sa_flags field of the sigaction structure, and the implementation does not support either the Realtime Signals Extension option, or the XSI Extension option.
The sigaction() function may fail if:
[EINVAL]
- An attempt was made to set the action to SIG_DFL for a signal that cannot be caught or ignored (or both).
EXAMPLES
#include <signal.h> static void handler(int signum) { /* Take appropriate actions for signal delivery */ } int main() { struct sigaction sa; sa.sa_handler = handler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; /* Restart functions if interrupted by handler */ if (sigaction(SIGINT, &sa, NULL) == -1) /* Handle error */; /* Further code */ }
APPLICATION USAGE
The sigaction() function supersedes the signal() function, and should be used in preference. In particular,sigaction() and signal() should not be used in the same process to control the same signal. The behavior of reentrant functions, as defined in the DESCRIPTION, is as specified by this volume of IEEE Std 1003.1-2001, regardless of invocation from a signal-catching function. This is the only intended meaning of the statement that reentrant functions may be used in signal-catching functions without restrictions.Applications must still consider all effects of such functions on such things as data structures, files, and process state. In particular, application writers need to consider the restrictions on interactions when interruptingsleep() and interactions among multiple handles for a file description. The fact that any specific function is listed as reentrant does not necessarily mean that invocation of that function from a signal-catching function is recommended.
In order to prevent errors arising from interrupting non-reentrant function calls, applications should protect calls to these functions either by blocking the appropriate signals or through the use of some programmatic semaphore (seesemget() , sem_init() , sem_open() ,and so on). Note in particular that even the "safe" functions may modifyerrno; the signal-catching function, if notexecuting as an independent thread, may want to save and restore its value. Naturally, the same principles apply to the reentrancyof application routines and asynchronous data access. Note thatlongjmp() and siglongjmp() are not in the list of reentrant functions. This is because the codeexecuting afterlongjmp() and siglongjmp() can call any unsafe functions with the same danger as calling those unsafefunctions directly from the signal handler. Applications that uselongjmp() and siglongjmp() from within signal handlers require rigorous protection in order to beportable. Many of the other functions that are excluded from the list are traditionally implemented using eithermalloc() or free() functions or the standard I/Olibrary, both of which traditionally use data structures in a non-reentrant manner. Since any combination of different functionsusing a common data structure can cause reentrancy problems, this volume of IEEE Std 1003.1-2001 does not define thebehavior when any unsafe function is called in a signal handler that interrupts an unsafe function.
If the signal occurs other than as the result of calling abort(),kill(), or raise(), the behavior is undefined ifthe signal handler calls any function in the standard library other than one of the functions listed in the table above or refersto any object with static storage duration other than by assigning a value to a static storage duration variable of type volatile sig_atomic_t. Furthermore, if such a call fails, the value of errno is unspecified.
Usually, the signal is executed on the stack that was in effect before the signal was delivered. An alternate stack may bespecified to receive a subset of the signals being caught.
When the signal handler returns, the receiving thread resumes execution at the point it was interrupted unless the signalhandler makes other arrangements. Iflongjmp() or _longjmp() is used to leave the signal handler, then the signal mask must be explicitlyrestored.
This volume of IEEE Std 1003.1-2001 defines the third argument of a signal handling function when SA_SIGINFO is set asavoid * instead of a ucontext_t *, but without requiring type checking. New applications should explicitly cast thethird argument of the signal handling function toucontext_t *.
The BSD optional four argument signal handling function is not supported by this volume of IEEE Std 1003.1-2001. TheBSD declaration would be:
void handler(int sig, int code, struct sigcontext *scp, char *addr);where sig is the signal number, code is additional information on certain signals,scp is a pointer to thesigcontext structure, and addr is additional address information. Much the same information is available in theobjects pointed to by the second argument of the signal handler specified when SA_SIGINFO is set.
RATIONALE
Although this volume of IEEE Std 1003.1-2001 requires that signals that cannot be ignored shall not be added to thesignal mask when a signal-catching function is entered, there is no explicit requirement that subsequent calls tosigaction() reflect this in the information returned in the oact argument. In other words, if SIGKILL is included inthesa_mask field of act, it is unspecified whether or not a subsequent call tosigaction() returns withSIGKILL included in the sa_mask field ofoact.
The SA_NOCLDSTOP flag, when supplied in the act-> sa_flags parameter, allows overloading SIGCHLD with theSystem V semantics that each SIGCLD signal indicates a single terminated child. Most conforming applications that catch SIGCHLD areexpected to install signal-catching functions that repeatedly call the waitpid()function with the WNOHANG flag set, acting on each child for which status is returned, untilwaitpid() returns zero. If stopped children are not of interest, the use of the SA_NOCLDSTOPflag can prevent the overhead from invoking the signal-catching routine when they stop.
Some historical implementations also define other mechanisms for stopping processes, such as theptrace() function. Theseimplementations usually do not generate a SIGCHLD signal when processes stop due to this mechanism; however, that is beyond thescope of this volume of IEEE Std 1003.1-2001.
This volume of IEEE Std 1003.1-2001 requires that calls to sigaction() that supply a NULLact argumentsucceed, even in the case of signals that cannot be caught or ignored (that is, SIGKILL or SIGSTOP). The System Vsignal() and BSD sigvec() functions return [EINVAL] in these cases and, in thisrespect, their behavior varies fromsigaction().
This volume of IEEE Std 1003.1-2001 requires that sigaction() properly save and restore a signal action set upby the ISO C standardsignal() function. However, there is no guarantee that thereverse is true, nor could there be given the greater amount of information conveyed by thesigaction structure. Because ofthis, applications should avoid using both functions for the same signal in the same process. Since this cannot always be avoidedin case of general-purpose library routines, they should always be implemented withsigaction().
It was intended that the signal() function should be implementable as a libraryroutine usingsigaction().
The POSIX Realtime Extension extends the sigaction() function as specified by the POSIX.1-1990 standard to allow the application to request on a per-signal basis via an additional signal action flag that the extra parameters, including the application-defined signal value, if any, be passed to the signal-catching function.