[Previous] [Contents] [Next]

SignalKill(), SignalKill_r()

Send a signal to a process group, process, or thread

Synopsis:

#include <sys/neutrino.h>

int SignalKill( uint32_t nd,
                pid_t pid,
                int tid,
                int signo,
                int code,
                int value );

int SignalKill_r( uint32_t nd,
                  pid_t pid,
                  int tid,
                  int signo,
                  int code,
                  int value );

Library:

libc

Description:

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

These kernel calls send the signal signo with a code specified by code and a value specified by value to a process group, process, or thread. If signo is zero, no signal is sent, but the validity of pid and tid are checked. This can be used as a test for existence.

The nd argument is the node descriptor of the node on which to look for pid and tid. To search the local node, set nd to ND_LOCAL_NODE or 0.

There are a total of 64 signals available. Of these, at least 8 are POSIX realtime signals that range from SIGRTMIN to SIGRTMAX. See SignalAction() for a complete list of signals. Valid user signals range from 1 to (NSIG - 1).

SignalKill() implements the capabilities of the POSIX functions kill(), sigqueue() and pthread_kill() in one call. The target of the signal is determined by pid and tid as follows:

pid tid target
= 0 --- Hit the process group of the caller
< 0 --- Hit a process group identified by -pid
> 0 = 0 Hit a single process identified by pid
> 0 > 0 Hit a single thread in process pid identified by tid

If the target is a thread, the signal is always delivered to exactly that thread. If the thread has the signal blocked (see SignalProcmask()), the signal remains pending on the thread.

If the target is a process, the signal is delivered to a thread that has the signal unblocked (see SignalProcmask(), SignalSuspend(), and SignalWaitinfo()). If multiple threads have the signal unblocked, only one thread is given the signal. Which thread receives the signal isn't deterministic. To make it deterministic, you have two choices:

If all threads have the signal blocked, it's made pending on the process. The first thread to unblock the signal receives the pending signal. If a signal is pending on a thread, it's never retargetted to the process or another thread, regardless of changes to the SIGNAL-blocked mask.

If the target is a process group, the signal is delivered as above to each process in the group.

A multithreaded application typically has one thread responsible for catching most or all signals. Threads that don't wish to be directly involved with signals block all signals in their mask.

The SIGNAL-blocked mask is maintained on a per-thread basis. The signal-ignore mask and signal handlers are maintained at the process level and are shared by all threads.

If multiple signals are delivered before the target can run and process the signals, the system queues them in priority order if the SA_SIGINFO bit was set for signo. Lower numbered signals have greater priority. If the SA_SIGINFO bit isn't set for signo, then at most one signal is queued at any time. Additional signals with the same signo replace existing ones. This is the default behavior for POSIX signal handlers installed using the old signal() function. The newer sigaction() function lets you control queuing or not on a per-signal basis. Signals with a code of SI_TIMER are never queued.

The code and value are always saved with the signal. This allows you to deliver data with the signal whether or not SA_SIGINFO has been set on the signo. If SA_SIGINFO is set, you can use signals to deliver small amounts of data without loss. If you wish to pass significant data, you may wish to consider the MsgSendPulse() and MsgSendv() functions, which deliver data with much greater efficiency. When a thread receives a signal by a signal handler or SignalWaitinfo() call, it can retrieve the signo, code and value from a siginfo_t structure, which contains at least the following members:

int si_signo
The signal number.
int si_code
The signal code.
union sigval si_value
The signal value.

The value of si_code is limited to an 8-bit signed value as follows:

Value Description
-128 <= si_code <= 0 User values
0 < signo <= 127 System values generated by the kernel

Some of the common user values defined by POSIX are:

Value 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) message queues

A successful return from this function means the signal has been delivered. What the process(es) or thread does with the signal isn't considered.

If a thread delivers signals that the receiving process has marked as queued faster than the receiver can consume them, the kernel may fail the call if it runs out of signal queue entries. If the signo, code, and value don't change, the kernel performs signal compression by saving an 8-bit count with each queued signal.

Blocking states

None. In the network case, lower priority threads may run.

Returns:

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

SignalKill()
If an error occurs, -1 is returned and errno is set. Any other value returned indicates success.
SignalKill_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:

EINVAL
The value of signo is less than 0 or greater than (_NSIG -1).
ESRCH
The process or process group indicated by pid or thread indicated by tid doesn't exist.
EPERM
The process doesn't have permission to send the signal to any receiving process.
EAGAIN
The kernel had insufficient resources to enqueue the signal.

Classification:

QNX 6

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

See also:

SignalAction(), SignalProcmask(), SignalSuspend(), SignalWaitinfo()


[Previous] [Contents] [Next]