__sigactionset() — Examine or change signal actions

Standards

Standards / Extensions C or C++ Dependencies
z/OS® UNIX both

POSIX(ON)
OS/390 V2R6

Format

#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);

General description

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:

size_t newct
newct is the number of __sigactionset_t structures to be processed in the new array. The value of newct must be from 0 to 64. If this parameter is 0, the new parameter is ignored, and may be NULL. If the newct parameter is not 0, new must be an array containing at least newct __sigactionset_t structures.
const __sigactionset_t new[]
new is an optional array of __sigactionset_t structures. When newct is 0, new may be NULL, and no signal actions will be changed.

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.

size_t*oldct
oldct is both an input and output parameter. It points to a word containing the number of output entries allowed, used, or needed in the old array.

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.

__sigactionset_t old[]
old is an optional array of __sigactionset_t structures.

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.

int options
options is a collection of flag bits that affects the operation __sigactionset(). The following flag bit can be set in options:
__SSET_IGINVALID
Tells the system to ignore invalid bits in the __sa_signals field in all __sigactionset_t array entries in the new parameter. Also, the system will ignore attempts to set SIGKILL, SIGSTOP or SIGTRACE to an action other than SIG_DFL, or SIGIO to SIG_IGN.

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".

Special behavior for XPLINK-compiled C++: Restrictions concerning setjmp.h and ucontext.h:
  1. All XPLINK programs compiled with the V2R10 or later C compilers that are to run with Language Environment V2R10 or later libraries and use the jmp_buf, sigjmp_buf or ucontext_t types must not be compiled with C headers from Language Environment V2R9 or earlier.
  2. Non-XPLINK functions compiled with any level of Language Environment headers must not define jmp_buf, sigjmp_buf or ucontext_t data items and pass them to XPLINK functions that call getcontext(), longjmp(), _longjmp(), setjmp(), _setjmp(), setcontext(), sigsetjmp(), or swapcontext() with these passed-in data items.
  3. When __XPLINK__ is defined, the Language Environment V2R10 and later headers define a larger jmp_buf, sigjmp_buf or ucontext_t area that is required by setjmp(), getcontext(), and related functions when they are called from an XPLINK routine. If __XPLINK__ is not defined, the Language Environment V2R10 and later headers define a shorter jmp_buf, sigjmp_buf or ucontext_t area. The Language Environment headers before V2R10 also define the shorter version of these data areas. If an XPLINK function calls setjmp(), getcontext() or similar functions with a short jmp_buf, sigjmp_buf or ucontext_t area, a storage overlay or program check may occur when the C library tries to store past the end of the passed-in (too short) data area.

Usage note

The use of the SIGTHSTOP and SIGTHCONT signal is not supported with this function.

__sigactionset_t type

The __sigactionset_t type is defined as follows:
       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:

sigset_t __sa_signals
This is a signal set. It contains the signals whose actions are described by the other members in this structure. For more information on signal sets, see sigemptyset() — Initialize a signal mask to exclude all signals.

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.

int __sa_flags
A collection of flag bits that affect the behavior of the specified signal.

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.

void (* __sa_handler)(int)
A pointer to the function assigned to handle the signals in the __sa_signals signal set. This function will be invoked passing one parameter of type int that contains the signal type for which this function is being invoked. The value of this member can also be SIG_DFL (indicating the default action) or SIG_IGN (indicating that the signal is to be ignored).
Note: This member and __sa_sigaction are mutually exclusive. When the SA_SIGINFO flag is set in __sa_flags, __sa__sigaction is used. Otherwise, __sa_handler is used.
sigset_t __sa_mask
This signal set identifies a set of signals that are to be added to the signal mask of the calling thread before the signal-handling function __sa_handler or __sa_sigaction is invoked. For more information on signal sets, see sigemptyset() — Initialize a signal mask to exclude all signals. You cannot use this mechanism to block SIGKILL, SIGSTOP, or SIGTRACE. If __sa_mask includes these signals, they will simply be ignored; __sigactionset() will not return an error.

__sa_mask must be set by using one or more of the signal set manipulation functions: sigaddset(), sigdelset(), sigemptyset(), or sigfillset().

void (*_sa_sigaction)(int, siginfo_t *, void *)
A pointer to the function assigned to handle the signal, or SIG_DFL, or SIG_IGN. This function will be invoked passing three parameters. The first is of type int that contains the signal type for which this function is being invoked. The second is of type siginfo_t* where the siginfo_t contain additional information about the source of the signal. The third is of type void* but will actually point to a ucontext_t containing the context information at the of time the signal interrupt.
Notes:
  1. The user must cast SIG_DFL or SIG_IGN to match the __sa_sigaction definition.
  2. This member and sa_handler are mutually exclusive. When the SA_SIGINFO flag is set in __sa_flags, __sa_sigaction is used. Otherwise, __sa_handler is used.

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.

If the SA_SIGINFO flag is set, the signal catching function specified by __sa_sigaction is invoked as:
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.

Considerations for asynchronous signal-catching functions

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.

Returned value

If successful, __sigactionset() returns 0.

If unsuccessful, no signal actions are changed, __sigactionset() returns -1 and sets errno to one of the following values:

Error Code
Description
EINVAL
This error can occur if:
  • An unsupported signal bit was on in the __sa_signals signal set in the new parameter. This error will not be reported if the __SSET_IGINVALID flag is set in options. To obtain more information in this case, use __errno2().
  • An attempt was made to set the signal action for SIGSTOP, SIGKILL, or SIGTRACE to something other than SIG_DFL. This error will not be reported if the __SSET_IGINVALID flag is set in options. To obtain more information in this case, use __errno2().
  • The newct or oldct parameters are not in the range from 0 to 64.
  • newct was not 0 and new was NULL.
  • oldct was not 0 and old was NULL.
EMVSERR
An MVS™ environmental or internal error has occurred. Use __errno2() to obtain more information about this error.
ENOMEM
The input value in oldct was not 0, and was too small to let the system pass back all distinct current signal actions. When __sigactionset() returns, *oldct will be set to the number of array entries needed by the system.

Example

/*
 *  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);

Related information