Sometimes, it is useful for a process to send a signal to itself. (We see an example of this in Handling Job-Control Signals.) The raise() function performs this task.
#include <signal.h>
int raise
(int sig);
Returns 0 on success, or nonzero on error
In a single-threaded program, a call to raise() is equivalent to the following call to kill():
kill(getpid(), sig);
On a system that supports threads, raise(sig) is implemented as:
pthread_kill(pthread_self(), sig)
We describe the pthread_kill() function in Sending a Signal to a Thread, but for now it is sufficient to say that this implementation means that the signal will be delivered to the specific thread that called raise(). By contrast, the call kill(getpid(), sig) sends a signal to the calling process, and that signal may be delivered to any thread in the process.
The raise() function originates from C89. The C standards don’t cover operating system details such as process IDs, but raise() can be specified within the C standard because it doesn’t require reference to process IDs.
When a process sends itself a signal using raise() (or kill()), the signal is delivered immediately (i.e., before raise() returns to the caller).
Note that raise() returns a nonzero value (not necessarily -1) on error. The only error that can occur with raise() is EINVAL
, because sig was invalid. Therefore, where we specify one of the SIGxxxx
constants, we don’t check the return status of this function.
Example 20-3. Using the kill() system call
signals/t_kill.c
#include <signal.h> #include "tlpi_hdr.h" int main(int argc, char *argv[]) { int s, sig; if (argc != 3 || strcmp(argv[1], "--help") == 0) usageErr("%s sig-num pid\n", argv[0]); sig = getInt(argv[2], 0, "sig-num"); s = kill(getLong(argv[1], 0, "pid"), sig); if (sig != 0) { if (s == -1) errExit("kill"); } else { /* Null signal: process existence check */ if (s == 0) { printf("Process exists and we can send it a signal\n"); } else { if (errno == EPERM) printf("Process exists, but we don't have " "permission to send it a signal\n"); else if (errno == ESRCH) printf("Process does not exist\n"); else errExit("kill"); } } exit(EXIT_SUCCESS); }signals/t_kill.c
The killpg() function sends a signal to all of the members of a process group.
#include <signal.h>
int killpg
(pid_t pgrp, int sig);
Returns 0 on success, or -1 on error
A call to killpg() is equivalent to the following call to kill():
kill(-pgrp, sig);
If pgrp is specified as 0, then the signal is sent to all processes in the same process group as the caller. SUSv3 leaves this point unspecified, but most UNIX implementations interpret this case in the same way as Linux.