SignalAction(), SignalAction_r()

Examine and/or specify actions for signals

Synopsis:

#include <sys/neutrino.h>

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

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

Arguments:

pid
A process ID, or 0 for the current process.
sigstub
The address of a signal stub handler. This is a small piece of code in the user's space that interfaces the user's signal handler to the kernel. The library provides a standard one, __signalstub(). This argument can be NULL if act is also NULL.
signo
The signal whose action you want to set or get; see "POSIX and QNX Neutrino signals," below.

If the signal terminates a process, the cleanup of the terminated process occurs by default at the priority of the thread that sent the signal. If you OR the SIG_TERMER_NOINHERIT flag (defined in <signal.h>) into signo, the cleanup occurs at the priority of the thread that received the signal.

act
NULL, or a pointer to a sigaction structure that specifies the new action for the signal.
oact
NULL, or a pointer to a sigaction structure where the function can store the old action.

Library:

libc

Use the -l c option to qcc to link against this library. This library is usually included automatically.

Description:

The SignalAction() and SignalAction_r() kernel calls let the calling process 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.

Note:
  • You should call the POSIX sigaction() function or the ANSI signal() function instead of using these kernel calls directly.
  • In order to attach signal handlers to a process with a different real or effective user ID, your process must have the PROCMGR_AID_SIGNAL ability enabled. For more information, see procmgr_ability().

These functions are identical except in the way they indicate errors. See the Returns section for details.

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. You can use various combinations of act and oact to query or set (or both) the action for a signal.

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.

You can target a signal 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 (e.g. SIGSEGV) are always delivered to the thread that caused them.

In a multithreaded process, if a signal terminates a thread, by default all threads and thus the process are terminated. You can override this standard POSIX behavior when you create the thread; see the PTHREAD_MULTISIG_ALLOW and PTHREAD_MULTISIG_DISALLOW flags in the entry for ThreadCreate().

Note:
  • It isn't safe to use floating-point operations in signal handlers.
  • 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().

POSIX and QNX Neutrino signals

The signals are defined in <signal.h>. The entire range of signals goes from _SIGMIN (1) to _SIGMAX (64):

Signal range Description
1–57 57 POSIX signals (including traditional UNIX signals)
41–56 16 POSIX realtime signals (SIGRTMIN to SIGRTMAX)
57–64 Eight special-purpose QNX Neutrino signals, some of which are named (e.g., SIGSELECT). They're always masked, and attempts to unmask them are ignored.

The following global variables are also declared in <signal.h>:

const char * const sys_siglist[]
An array of descriptions of the signals. You can use strsignal() to get the description of a signal.
const int sys_nsig
The number of entries in the sys_siglist array.
Note: The sys_siglist array doesn't include the QNX Neutrino signals, and strsignal() returns a pointer to an empty string for them.

The POSIX and UNIX signals include:

Signal Description Default action
SIGABRT Abnormal termination, issued by functions such as abort() Kill the process and write a dump file
SIGALRM Alarm clock, issued by functions such as alarm() Kill the process
SIGBUS Bus error, or a memory parity error (a QNX Neutrino-specific interpretation). If a second fault occurs while your process is in a signal handler for this fault, the process is terminated. Kill the process and write a dump file
SIGCHLD or SIGCLD A child process terminated Ignore the signal, but still let the process's children become zombies
SIGCONT Continue the process. You can't block this signal. Make the process continue if it's STOPPED; otherwise ignore the signal
SIGDEADLK A mutex deadlock occurred. If a process dies while holding a mutex, and you haven't called SyncMutexEvent() to set up an event to be delivered to the mutex's owner when the mutex dies, the kernel delivers a SIGDEADLK to all threads that are waiting on the mutex without a timeout.

SIGDEADLK and SIGEMT refer to the same signal. Some utilities (e.g., gdb, ksh, slay, and kill) know about SIGEMT, but not SIGDEADLK.

Kill the process and write a dump file
SIGEMT EMT instruction (emulation trap)

SIGDEADLK and SIGEMT refer to the same signal. Some utilities (e.g., gdb, ksh, slay, and kill) know about SIGEMT, but not SIGDEADLK.

Kill the process and write a dump file
SIGFPE Floating point exception Kill the process and write a dump file
SIGHUP Hangup; the session leader died, or the controlling terminal closed Kill the process
SIGILLa Illegal hardware instruction. If a second fault occurs while your thread is in a signal handler for this fault, the process is terminated. Kill the process and write a dump file
SIGINT Interrupt; typically generated when you press CtrlC or CtrlBreak (you can change this with stty) Kill the process
SIGIO Asynchronous I/O Ignore the signal
SIGIOT I/O trap; a synonym for SIGABRT Kill the process
SIGKILL Kill. You can't block or catch this signal. Kill the process
SIGPIPE Write on pipe with no reader Kill the process
SIGPOLL System V name for SIGIO Ignore the signal
SIGPROF Profiling timer expired. POSIX has marked this signal as obsolescent; QNX Neutrino doesn't support profiling timers or send this signal. Kill the process
SIGPWR Power failure Ignore the signal
SIGQUIT Quit; typically generated when you press Ctrl\ (you can change this with stty) Kill the process and write a dump file
SIGSEGV Segmentation violation; an invalid memory reference was detected. If a second fault occurs while your process is in a signal handler for this fault, the process will be terminated. Kill the process and write a dump file
SIGSTOP Stop the process. You can't block or catch this signal. Stop the process
SIGSYS Bad argument to system call Kill the process and write a dump file
SIGTERM Termination signal Kill the process
SIGTRAP Trace trap Kill the process and write a dump file
SIGTSTP Stop signal from tty; typically generated when you press CtrlZ (you can change this with stty) Stop the process
SIGTTIN Background read attempted from control terminal Stop the process
SIGTTOU Background write attempted to control terminal Stop the process
SIGURG Urgent condition on I/O channel Ignore the signal
SIGUSR1 User-defined signal 1 Kill the process
SIGUSR2 User-defined signal 2 Kill the process
SIGVTALRM Virtual timer expired. POSIX has marked this signal as obsolescent; QNX Neutrino doesn't support virtual timers or send this signal. Kill the process
SIGWINCH The size of the terminal window changed Ignore the signal
SIGXCPU Soft CPU time limit exceeded see the RLIMIT_CPU resource for setrlimit()) Kill the process and write a dump file

a One possible cause for a SIGILL signal is trying to perform an operation that requires I/O privileges. A thread can request these privileges by making sure it has the PROCMGR_AID_IO ability enabled (see procmgr_ability()) and then calling ThreadCtl(), specifying the _NTO_TCTL_IO flag:

ThreadCtl( _NTO_TCTL_IO, 0 );

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 was 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, or you tried to set SIGKILL or SIGSTOP to something other than SIG_DFL.
EPERM
The calling process doesn't have the required permission; see procmgr_ability().
ESRCH
The process indicated by pid doesn't exist.

Classification:

QNX Neutrino

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