Add Book to My BookshelfPurchase This Book Online

Chapter 10 - Signals

UNIX Systems Programming for SVR4
David A. Curry
 Copyright © 1996 O'Reilly & Associates, Inc.

Porting Berkeley Signals to SVR4
Berkeley signals are both a blessing and a curse. They are a blessing because they introduced several important concepts such as reliable signals and restartable system calls. They are a curse because they are different from every other version of UNIX.
4.2BSD was the first version of UNIX to overhaul the signal mechanism; it is here that the concepts of reliable signals and restartable system calls were both introduced. In this section, we examine the 4.2BSD and 4.3BSD signal mechanisms in detail, as they pertain to porting programs that use them to SVR4.
It is important to understand that the way in which Berkeley implemented the new signal mechanism not only provided a number of new functions that will be described shortly, but it also changed the behavior of the standard signal function. Thus, any program being ported from 4.2BSD or 4.3BSD to SVR4 will need to have its signal handling code examined, not just those programs that use the new functions.
Fortunately, however, most programmers avoided the new Berkeley signal functions, and continued to simply use signal. Because they did not take advantage of any of the special features, the porting effort will usually be simple. The thing to remember in this case is that in Berkeley UNIX, the signal function provides reliable signals, while in SVR4 it does not. However, in SVR4, the sigset function provides reliable signals. So, most programs that use signal can be ported from Berkeley UNIX simply by placing the line
    #define signal sigset
at the top of the program. The only exception to this rule occurs when the program handles SIGCHLD; recall that the sigset function implements the System V semantics for this signal. In this case, the program must be modified to use sigaction.
For those programs that do make use of the Berkeley signal functions, the rest of this chapter provides a basic description of these functions and how they work.
The sigvec Function
The primary function for handling signals in Berkeley UNIX is called sigvec:
    #include <signal.h>
    int sigvec(int sig, struct sigvec *vec, struct sigvec *ovec);
The function sets the disposition for the signal identified in sig to the information provided in vec if it is non-null; if ovec is non-null, the previous disposition information is returned.
The struct sigvec structure is defined this way in 4.2BSD:
    struct sigvec {
        int    (*sv_handler)(int, int, struct sigcontext *);
        int    sv_mask;
        int    sv_onstack;
    };
The sv_handler element of the structure is a pointer to the handler function; it may also take on the values SIG_DFL and SIG_IGN. The sv_mask element specifies a signal mask (see below) of signals that should be blocked for the duration of the signal handler. The sv_onstack element, if non-zero, indicates that the signal should be handled on an alternate signal stack instead of the process' main stack.
In 4.3BSD, the structure was changed to:
    struct sigvec {
        int    (*sv_handler)(int, int, struct sigcontext *);
        int    sv_mask;
        int    sv_flags;
    };
The sv_flags element could take on the values SV_ONSTACK to indicate the alternate signal stack, and SV_INTERRUPT to specify that the signal should interrupt system calls rather than restart them.
Generally speaking, if sv_mask and sv_flags (sv_onstack) are not used, calls to sigvec can be replaced with analogous calls to sigset. If the sv_mask element of the structure is used, sigaction should be used, with the sa_mask element of the sigaction structure. If the alternate signal stack is used (which it rarely, if ever, was), the sigaction function must be used, in conjunction with sigaltstack (not described in this book).
Handler Calling Conventions
Signal handlers in Berkeley UNIX use three arguments:
    int (*handler)(int sig, int code, struct sigcontext *context);
The sig parameter is the signal number, just as in all other versions of UNIX. The code parameter related the signal to a hardware trap; this information is provided by SVR4 in the si_info element of the siginfo_t structure. The context parameter describes the program context to be restored on return from the signal handler; this information can be obtained by using the sa_sigaction handler with sigaction.
Signal Masks
Berkeley UNIX provides the concept of signal masks just as SVR4 does. A signal mask defines the set of signals currently blocked from delivery. If the i th bit in the mask is 1, then signal number i is blocked. The i th bit is set by or ing in a 1 shifted left i-1 places:
    1 << (i-1)
4.3BSD defines a macro, sigmask, that performs this computation:
    #include <signal.h>
    int sigmask(int sig);
Calls to sigmask should be replaced with calls to sigemptyset, sigfillset, sigaddset, and sigdelset.
To install a new signal mask, use the sigsetmask function:
    #include <signal.h>
    int sigsetmask(int mask);
This returns the previous signal mask. You can, instead, call sigprocmask with SIG_SETMASK as the first argument.
To add a set of signals to the current signal mask, use the sigblock function:
    #include <signal.h>
    int sigblock(int mask);
The previous mask is returned. You can, instead, call sigprocmask with SIG_BLOCK as the first argument, or sighold.
Waiting for Signals
Berkeley UNIX also provides a sigpause function:
    #include <signal.h>
    int sigpause(int mask);
The new mask is installed and the program blocked until a signal occurs. When sigpause returns, the old signal mask is restored. Note that this behavior is identical to the POSIX sigsuspend function, but that it is not the same as the SVR3 sigpause function.
The setjmp and longjmp Functions
In Berkeley UNIX, the setjmp and longjmp functions do save and restore the signal mask, unlike in the SVR4 version. Replace calls to setjmp and longjmp with calls to sigsetjmp and siglongjmp, respectively.

Previous SectionNext Section
Books24x7.com, Inc © 2000 –  Feedback