The Unreliable signal(3) API

The signal(3) function forms the basis for the unreliable signals interface. Its function synopsis is as follows:

#include <signal.h>

void (*signal(int sig, void (*func)(int)))(int)
/* Alternatively */

typedef void (*sig_t)(int);

sig_t signal(int sig, sig_t func);

The first synopsis is rather difficult to decipher. The FreeBSD man(1) page offers a second interpretation of the first. The signal(3) function's first argument sig identifies the signal for which the caller wants to register an action. The second argument func identifies the action or the function pointer.

The return value from signal(3) is the previous action that was established at the time of the call. Alternatively, the value SIG_ERR indicates that an error has occurred and the variable errno should be examined for the cause.

The argument sig identifies the signal to be prepared. Table 15.1 shows some of the more commonly used signals available under UNIX.

Table 15.1. Commonly Used Signals
Signal Description
SIGHUP The terminal line has hung up. This refers to when a modem line experiences a hangup due to a loss of carrier. However, it also applies to any terminal device when it is closed for logout(1).
SIGINT The terminal line has received the interrupt character.
SIGQUIT The terminal line has received the quit character. The default action produces a core file.
SIGUSR1 User-defined signal 1.
SIGUSR2 User-defined signal 2.
SIGTERM The process is being terminated (often the result of the kill(1) command).
SIGCHLD A child process has terminated.
SIGPIPE A write to a half-closed pipe has occurred.
SIGALRM The timer for function alarm(3) has expired.

The argument func allows the caller to register the action that is required for the given signal. There are three possible values for the argument func. They are

SIG_DFL Default signal action
SIG_IGN Ignore the signal
function pointer The signal handler

The SIG_DFL macro causes the system default action for the named signal to be registered. The default action is not the same for all signals. For SIGINT, the default action causes the program to terminate. Alternatively, the default action for SIGCHLD is to ignore the signal.

The SIG_IGN macro allows the programmer to indicate that the signal is to be ignored. Once this action is registered, it remains in effect for the indicated signal sig until it is changed.

Note

Calling signal(3) with SIG_DFL or SIG_IGN is considered reliable. These actions can be registered reliably by signal(3) because they do not change after a signal is raised.


The programmer may also choose to register a signal handler to be called when a signal is received. This is accomplished by providing the function's pointer in the func argument. This practice is now discouraged, because this part of the signal(3) API is unreliable on non-BSD platforms.

The program shown in Listing 15.1 shows a simple demonstration program using the unreliable signal API.

Code Listing 15.1. ursig1.cā€”A Simple signal(3) Example Program
1:   /* ursig1.c */
2:
3:   #include <stdio.h>
4:   #include <signal.h>
5:   #include <unistd.h>
6:
7:   static int count = 0;
8:
9:   void
10:  handler(int signo) {
11:
12:      signal(SIGINT,handler);     /* Re-instate handler */
13:      ++count;                    /* Increment count */
14:      write(1,"Got SIGINT
",11); /* Write message */
15:  }
16:
17:  int
18:  main(int argc,char **argv) {
19:
20:      signal(SIGINT,handler);     /* Register function */
21:
22:      while ( count < 2 ) {
23:          puts("Waiting for SIGINT..");
24:          sleep(4);               /* Snooze */
25:      }
26:      puts("End.");
27:      return 0;
28:  }

Line 12 of Listing 15.1 is necessary for non-BSD systems. Otherwise, only the first SIGINT signal will be caught by the function handler(), because the signal reverts to its default action.

Compiling and running this program under FreeBSD yields the following result:

$ make ursig1
cc -c -D_POSIX_C_SOURCE=199309L -D_POSIX_SOURCE -Wall ursig1.c
cc -o ursig1 ursig1.o
$ ./ursig1
Waiting for SIGINT..
^CGot SIGINT
Waiting for SIGINT..
^CGot SIGINT
End.
$

In the example session shown, the loop in lines 22ā€“24 causes the message Waiting for SIGINT.. to appear. Then the user presses Ctrl+C, which is shown as ^C in the session output. Immediately after Ctrl+C is pressed, the message Got SIGINT is displayed. Later, another Ctrl+C is pressed to demonstrate that the signal can be caught more than once. The program terminates normally after it notices that SIGINT has been received twice (see line 22). The message Got SIGINT comes from line 14 of Listing 15.1, demonstrating that the signal handler was executed.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.227.26.217