Standards / Extensions | C or C++ | Dependencies |
---|---|---|
z/OS® UNIX | both | POSIX(ON) |
#define _XOPEN_SOURCE_EXTENDED 1
#include <signal.h>
int __sigactionset(size_t newct, const __sigactionset_t new[],
size_t *oldct, __sigactionset_t old[],
int options);
Examines and changes the actions associated with one or more signals. This function is equivalent to using sigaction() one or more times.
The parameters are:
When newct is not 0, the data in the new array of __sigactionset_t structures will cause the actions associated with one or more signals to be changed. The system will change the signal actions as if sigaction() were called multiple times. The first newct __sigactionset_t structures in the new array are processed in order, and may cause the actions for one or more signals to be set. For each array entry, the effect is the same as calling sigaction() once for each signal whose bit is on in the __sa_signals signal set. The fields __sa_handler, __sa_mask, __sa_flags, and __sa_sigaction correspond to the sa_handler, sa_mask, sa_flags, and sa_sigaction fields in the sigaction structure for sigaction().
If a signal appears in more than one __sa_signals signal set in the new array, the last action specified for that signal will be in effect when __sigactionset() returns. If all bits in all __sa_signals signal sets in the new parameter are off, no signal actions will be changed.
When __sigactionset() is called, *oldct is the maximum number of __sigactionset_t structures in the old array that the system can fill in. The value of *oldct must be from 0 to 64. If this parameter is 0, the old parameter is ignored, and may be NULL. If the *oldct parameter is not 0, old must be an array of __sigactionset_t structures that the system can fill in. The number of array entries in old must be at least *oldct. If not 0, *oldct must be large enough to allow the system to pass back all the unique actions currently associated with all signals. If *oldct is not large enough, __sigactionset() will fail and the errno will be set to ENOMEM.
If __sigactionset() returns with no error and *oldct was not 0, *oldct is set to the number of __sigactionset_t array entries in old that are filled in. If *oldct was too small, causing an ENOMEM error, *oldct is set to the number of __sigactionset_t structures the system would need in order to fill in all the distinct current signal actions. If *oldct was 0 when __sigactionset() was called, it is not updated.
When *oldct is not 0, the structures in the old array will be filled in with the signal actions currently in effect before any changes are made. The __sigactionset_t structure entries in old are filled in with all the distinct signal actions currently in effect, starting with the first array entry. Each __sigactionset_t structure in the array will contain information about one or more signals. Bits in the __sa_signals signal set in each array entry will indicate which signals that entry applies to. The system will try to use as few array entries as possible when passing back the different signal actions. The signal actions for SIGKILL, SIGSTOP, or SIGTRACE will not be returned.
The output information in each array entry is similar to that returned from sigaction(). In the __sigactionset_t structure, the fields __sa_handler, __sa_mask, __sa_flags, and __sa_sigaction correspond to the sa_handler, sa_mask, sa_flags, and sa_sigaction fields in the sigaction structure filled in by sigaction(). The signal action as described by these fields applies to all signals whose bits are on in the __sa_signals signal set in the array entry.
If old is not large enough to contain information about all distinct signal actions currently in effect, __sigactionset() fails, and ENOMEM is returned. There is no way to obtain the current signal actions for a specified subset of signals.
When old is NULL, the system does not return any information about the current signal actions.
If this option bit is off, the system will fail the __sigactionset() request if any invalid bits are found in any __sa_signals signal set in any new array entry. Also, __sigactionset() will fail if an attempt it made to set SIGKILL, SIGSTOP, or SIGTRACE to something other than SIG_DFL, or to set SIGIO to SIG_IGN.
This function is supported only in a POSIX(ON) program.
Special behavior for C++: The behavior when mixing signal-handling with C++ exception handling is undefined. Also, the use of signal-handling with constructors and destructors is undefined.
C++ and C language linkage conventions are incompatible, and therefore __sigactionset() cannot receive C++ function pointers. If you attempt to pass a C++ function pointer to __sigactionset(), the compiler will flag it as an error. Therefore to use the __sigactionset() function in the C++ language, you must ensure that signal handler routines have C linkage, by declaring them as extern "C".
The use of the SIGTHSTOP and SIGTHCONT signal is not supported with this function.
typedef struct __sigactionset_s
{
sigset_t __sa_signals;
int __sa_flags;
void (*__sa_handler)(int);
sigset_t __sa_mask;
void (*__sa_sigaction)(int, siginfo_t *, void *);
} __sigactionset_t;
The following are members of the structure:
In the new array of _sigactionset_t structures, the caller sets bits in this signal set. The signal action for each signal in the signal set will be set as described by the other members of the structure.
__sa_signals must be set using one or more of the signal set manipulation functions: sigaddset(), sigdelset(), sigemptyset(), or sigfillset().
In the old array of __sigactionset_t structures, the system sets the bits in the __sa_signals field. The current signal action for each member of the signal set is described by the other members of the structure. All signals in the set have the same signal action.
The flag bits in the __sa_flags field are the same as those in the sa_flags member of the sigaction structure. See sigaction() — Examine or change a signal action for a detailed description of these flag bits.
__sa_mask must be set by using one or more of the signal set manipulation functions: sigaddset(), sigdelset(), sigemptyset(), or sigfillset().
When a signal handler installed by __sigactionset(), with the _SA_OLD_STYLE flag set off, catches a signal, the system calculates a new signal mask by taking the union of the current signal mask at the time of the signal interrupt, the signals specified by __sa_mask, and the signal that was just caught (if the SA_NODEFER flag is not set). This new mask stays in effect until the signal handler returns, or sigprocmask(), sigsuspend(), siglongjmp(), sighold(), sigpause(), or sigrelse() is called. When the signal handler ends, the original signal mask is restored.
After an action has been specified for a particular signal, using __sigactionset() with the _SA_OLD_STYLE flag not set, it remains installed until it is explicitly changed with another call to __sigactionset(), sigaction(), signal(), bsd_signal(), sigset(), sigignore(), one of the exec functions, or until the SA_RESETHAND flag causes it to be reset to SIG_DFL.
After an action has been specified for a particular signal, using __sigactionset() with the _SA_OLD_STYLE flag set or using signal(), it remains installed until it is explicitly changed with another call to __sigactionset(), sigaction(), bsd_signal(), sigset(), signal(), sigignore(), one of the exec functions, or a signal catcher is driven, where it will be reset to SIG_DFL.
Successful setting of a signal action to SIG_IGN for a signal that is pending causes the pending signal to be discarded, whether or not it is blocked. This provides the ability to discard signals that are found to be blocked and pending by sigpending(). A signal is discarded across a call to __sigactionset() if any __sigactionset_t structure in the new array causes the action for that signal to be set to SIG_IGN. This happens even if a later __sigactionset_t structure in the new array sets the signal action to something other than SIG_IGN before __sigactionset() returns.
If a process sets the action of the SIGCHLD signal to SIG_IGN, child processes of the calling process will not be transformed into zombie processes when they terminate. If the calling process subsequently waits for its children, and the process has no unwaited from children that were transformed into zombie processes, it will block until all of its children terminate. The wait(), waitid(), or waitpid() function will fail and set errno to ECHILD.
void function(int signo, siginfo_t *info, void * context);
where function is
the specified signal-catching function, signo is
the signal number of the signal being delivered, info points
to an object of type siginfo_t associated with the
signal being delivered, and context points
to an object of type ucontext_t.For a signal catcher that has been loaded by fetch() or fetchep(), the address returned by __sigactionset() in the __sa_handler or __sa_sigaction fields may be different than the value originally passed in to sigaction() or __sigactionset() (when the signal action was first set). This signal catcher address can be passed in again to sigaction() or __sigactionset() to reestablish the same signal catcher. The effect will be similar to passing in the original catcher address obtained from fetch() or fetchep(). However, this address should not be used for any other purpose, such as directly calling the signal catcher. Always use the original address obtained from fetch() or fetchep() when calling the catcher directly.
Some of the functions have been restricted to be serially reusable with respect to asynchronous signals. For more information on these functions, see sigaction() — Examine or change a signal action.
If successful, __sigactionset() returns 0.
If unsuccessful, no signal actions are changed, __sigactionset() returns -1 and sets errno to one of the following values:
/*
* Note: This is just a code fragment
*/
void catch_sigchld(int, siginfo_t *, void *);
...
__sigactionset_t new[2], old[64];
int options;
int rc;
size_t oldct = 64;
/*
* Set SIGUSR1 and SIGUSR2 to SIG_IGN
* Set SIGCHLD to new-style catcher catch_sigchld()
* Save original signal setup in variable old
*/
bzero(new, sizeof new);
(void)sigemptyset(&(new[0].__sa_signals) );
(void)sigaddset (&(new[0].__sa_signals), SIGUSR1);
(void)sigaddset (&(new[0].__sa_signals), SIGUSR2);
(void)sigemptyset(&(new[1].__sa_signals) );
(void)sigaddset (&(new[1].__sa_signals), SIGCHLD);
new[0].__sa_handler = SIG_IGN;
new[1].__sa_sigaction = &catch_sigchld;
new[1].__sa_flags = SA_SIGINFO;
rc = __sigactionset((size_t)2, new, &oldct, old, __SSET_IGINVALID);