进程,信号

#include <signal.h>

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

 指向信号处理函数

其中 sa_handlersa_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有以下选项:

  1. SA_NOCLDSTOP 
    子进程停止(如:收到SIGSTOP信号)时不产生SIGCHLD信号。只有子进程运行终止时才产生。
    此选项只有当sig 为 SIGCHLD 时才起作用,对其它信号没影响。
  2. SA_ONSTACK
    如果设置,并且调用了sigaltstack,将信号提交到指定的堆栈上去,否则,提交到当前堆栈
  3. SA_RESETHAND
    SIGILL 和 SIGTRAP不受影响
    若设置,在信号函数的入口,信号的处理函数将被设为SIG_DFL(默认),同时SA_SIGINFO被清除。
    若设置,类似设置了 SA_NODEFER
  4. SA_RESTART
    可中断函数的定义:当函数出错时, errno设置为EINTR的函数
    若设置,可中断函数重新启动,并且不设置EINTR,除非有特殊情况发生(如:系统不支持)
    没设置,被此信号中断的函数出错返回,并设置 errno为EINTR
  5. SA_SIGINFO
    没设置,使用 sa_handler。此时程序不能修改 sa_sigaction 
    若设置,使用 sa_sigaction ,函数原型为:
    void func(int signo, siginfo_t *info, void *context);
    
    

    info : 信号产生的原因
    context : 可指向一个 ucontext_t 结构变量,指向被中断线程的上下文

    [Option Start]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.[Option End]

    [Option Start] Thesi_code member contains a code identifying the cause of the signal. [Option End]

    [Option Start]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.[Option End] The<signal.h> header description contains information about the signal-specific contents of the elements of thesiginfo_t type.

  6. SA_NOCLDWAIT
    [Option Start]If set, andsig equals SIGCHLD, child processes of the calling processes shall not be transformed into zombie processes when they terminate. If the calling process subsequently waits for its children, and the process has no unwaited-for children that were transformed into zombie processes, it shall block until all of its children terminate, and wait(), waitid(), and waitpid() shall fail and seterrno to [ECHILD]. Otherwise, terminating child processes shall be transformed into zombie processes, unless SIGCHLD is set to SIG_IGN.[Option End]
  7. SA_NODEFER
    [Option Start]If set andsig is caught, sig shall not be added to the thread's signal mask on entry to the signal handler unless itis included insa_mask. Otherwise, sig shall always be added to the thread's signal mask on entry to the signal handler.[Option End]

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  [Option Start]  unless SA_NODEFER or SA_RESETHAND is set,[Option End] 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()),  [Option Start]  until the SA_RESETHAND flag causes resetting of the handler,[Option End]  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. [Option Start]  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. [Option End]

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.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值