[Previous] [Contents] [Next]

SignalAction(), SignalAction_r()

Examine and/or specify actions for signals

Synopsis:

#include <sys/neutrino.h>

int SignalAction( pid_t pid,
                  void ( * sigstub)(),
                  int signo,
                  const struct sigaction * act,
                  struct sigaction * oact );

int SignalAction_r( pid_t pid,
                    void * (sigstub)(),
                    int signo,
                    const struct sigaction * act,
                    struct sigaction * oact );

Library:

libc

Description:

The SignalAction() and SignalAction_r() functions are identical except in the way they indicate errors. See the Returns section for details.

These kernel calls allow the calling process to examine or specify (or both) the action to be associated with a specific signal in the process pid. If pid is zero, the calling process is used. The argument signo specifies the signal. There are 32 POSIX 1003.1a signals and 24 POSIX 1003.1b realtime signals as follows:

Regular signals Description Regular signals Description
SIGHUP Hangup SIGINT Interrupt
SIGQUIT Quit SIGILL Illegal instruction (not reset when caught)
SIGTRAP Trace trap (not reset when caught) SIGIOT IOT instruction
SIGABRT Used by abort() SIGEMT EMT instruction
SIGFPE Floating point exception SIGKILL Kill (can't be caught or ignored)
SIGBUS Bus error SIGSEGV Segmentation violation
SIGSYS Bad argument to system call SIGPIPE Write on pipe with no reader
SIGALRM Realtime alarm clock SIGTERM Software termination signal from kill
SIGUSR1 User-defined signal 1 SIGUSR2 User-defined signal 2
SIGCHLD Death of child SIGPWR Power-fail restart
SIGWINCH Window change SIGURG Urgent condition on I/O channel
SIGPOLL System V name for SIGIO SIGIO Asynchronous I/O
SIGSTOP Sendable stop signal not from tty SIGTSTP Stop signal from tty
SIGCONT Continue a stopped process SIGTTIN Attempted background tty read
SIGTTOU Attempted background tty write
Realtime signals Description
SIGRTMIN First realtime signal
SIGRTMAX Last realtime signal

The entire range of signals goes from _SIGMIN (1) to _SIGMAX (64).

If act isn't NULL then the specified signal is modified. If oact isn't NULL, the previous action is stored in the structure it points to. The combination of act and oact allows you to query or set (or both) the action for a signal.

The structure sigaction contains the following members:

void (*sa_handler)();
Address of a signal handler or action for nonqueued signals.
void (*sa_sigaction) (int signo, siginfo_t *info, void *other);
Address of a signal handler or action for queued signals.
sigset_t sa_mask
An additional set of signals to be masked (blocked) during execution of the signal-catching function.
int sa_flags
Special flags to affect behavior of the signal. There are two flags, SA_NOCLDSTOP and SA_SIGINFO, that are defined below.

The sa_handler and sa_sigaction members of act are implemented as a union and share common storage. They differ only in their prototype, with sa_handler being used for POSIX 1003.1a signals and sa_sigaction being used for POSIX 1003.1b queued realtime signals. The values stored using either name can be one of:

function
The address of a signal catching function. See below for details.
SIG_DFL
This sets the signal to the default action. The default action for SIGCHLD, SIGIO, SIGURG and SIGWINCH is to ignore the signal (SIG_IGN). The default action for SIG_HOLD is to stop the process. The default action for SIGCONT is to continue the program. The default for all other signals is to kill the process.
SIG_IGN
This ignores the signal. Setting SIG_IGN for a signal that's pending discards all pending signals, whether it's blocked or not. New signals are discarded. If you ignore SIGCHLD, your children won't enter the zombie state and you're unable to wait on their death using wait() or waitpid().

The function member of sa_handler or sa_sigaction is always invoked with the following arguments:

void handler(int signo, siginfo_t* info, void* other)

If you have an old style signal handler of the form:

void handler(int signo)

the extra arguments are still placed by the microkernel, the function simply ignores them.

While in the handler, signo is masked, preventing nested signals of the same type. In addition, any signals set in the sa_mask member of act are also ORed into the mask. When the handler returns through a normal return, the previous mask is restored and any pending and now unmasked signals are acted on. You return to the point in the program where it was interrupted. If the thread was blocked in the kernel when the interruption occurred, the kernel call returns with an EINTR (see ChannelCreate() and SyncMutexLock() for exceptions to this).

When you specify a handler you must provide the address of a signal stub handler for sigstub. This is a small piece of code in the user's space that interfaces the user's signal handler to the kernel. A standard one is provided in the library called __signalstub().

The siginfo_t structure of the function in sa_handler or sa_sigaction contains at least the following members:

Member Description
int si_signo The signal number, which should match the signo argument to the handler.
int si_code A signal code. The code is provided by the generator of the signal.
union sigval si_value A value associated with the signal. The value is provided by the generator of the signal.

Some of the common si_code values defined by POSIX are:

Signal Description
SI_USER Signal generated by kill() function
SI_QUEUE Signal generated by sigqueue() function
SI_TIMER Signal generated by a timer
SI_ASYNCIO Signal generated by asynchronous IO
SI_MESGQ Signal generated by POSIX (not QNX) messages queues

You can't ignore or catch SIGKILL or SIGSTOP.

The sa_flags member of act contains flags that modify the behavior of the signal. There are two defined flags:

Signal handlers and actions are defined for the process and affect all threads in the process. For example, if one thread ignores a signal then all threads ignore the signal.

A signal can be targeted at a thread, process or process group (see SignalKill()). When targeted at a process, at most one thread receives the signal. This thread must have the signal unblocked (see SignalProcmask()) to be a candidate for receiving it. All synchronously generated signals (i.e. SIGSEGV) are always delivered to the thread that caused them.

In a multi-threaded process, if a signal terminates a thread, by default all threads and thus the process are terminated. This standard POSIX behavior can be overridden at thread creation time (see ThreadCreate()).


Note: If you use longjmp() to return from a signal handler, the signal remains masked. You can use siglongjmp() to restore the mask to the state saved by a previous call to sigsetjmp().

Blocking states

These calls don't block.

Returns:

The only difference between these functions is the way they indicate errors:

SignalAction()
If an error occurs, -1 is returned and errno is set. Any other value returned indicates success.
SignalAction_r()
EOK is returned on success. This function does NOT set errno. If an error occurs, any value in the Errors section may be returned.

Errors:

EAGAIN
The system's unable to allocate a signal handler. This indicated critically low memory.
EFAULT
A fault occurred when the kernel tried to access the buffers provided.
EINVAL
The value of signo is less than 1 or greater than _SIGMAX. Attempt to set SIGKILL or SIGSTOP to something other than SIG_DFL.
EPERM
The process doesn't have permission to change the signal actions of the specified process.
ESRCH
The process indicated by pid doesn't exist.

Classification:

QNX 6

Safety:
Cancellation point No
Interrupt handler No
Signal handler Yes
Thread Yes

See also:

SignalKill()


[Previous] [Contents] [Next]