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.

Signals and System Calls
System calls (functions that call the operating system to perform some task on behalf of the program, such as transferring data to or from a disk) can be divided into two categories: those that are “slow” and those that aren't. A slow system call is one that can block forever. This category includes:
 opens of files that block until some condition occurs (e.g., an open of a terminal device that waits until a modem answers the phone)
 reads from certain types of files, such as pipes, terminal devices, and network connections, that can block forever if no data is present
 writes to these same types of files, that can block if the data cannot be immediately accepted
 the pause system call, which, by definition, blocks until a signal arrives
 the wait system call, which blocks until a child process completes
 certain ioctl operations (see Chapter 12, Terminals)
 selected interprocess communications functions
Notice that operations pertaining to disk input and output are not considered slow system calls. Although these operations do block the caller temporarily while the data is moved to or from disk, unless a hardware failure occurs, the operation always returns and unblocks the caller quickly.
In earlier versions of UNIX, if a process caught a signal while it was blocked in one of these slow system calls, the system call was interrupted. It would return an error, and errno would contain EINTR. The thinking behind this is that if a signal arrives and the process is catching it, this is probably significant enough to justify breaking out of the system call.
The problem with interruptible system calls is that programs have to handle this case explicitly. If a system call can get interrupted every time a signal arrives, then anywhere the application doesn't want to be interrupted, it needs code like this:
    again:
        if ((n = read(fd, buf, sizeof(buf))) < 0) {
            if (errno == EINTR)
                goto again;
            ...
        }
To ease the burden on programmers, 4.2BSD introduced the automatic restarting of certain system calls. The system calls that are automatically restarted are: ioctl, read, readv, write, writev, wait, and waitpid. If any of these calls is interrupted by a signal, it is automatically restarted when the signal handler function returns. Unfortunately, while this alleviated the need for writing code like that shown above, it broke just about every program that relied on the system call being interrupted! To solve this new problem, 4.3BSD allowed the programmer to disable this feature on a per-signal basis.
System V has, historically, never restarted system calls. However, in SVR4, a programmer can enable the automatic restart of system calls on a per-signal basis. This preserves backward compatibility with previous versions, yet allows the programmer access to the sometimes more desirable automatic restart behavior.

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