Advanced Programming in the UNIX® Environment

(lily) #1
ptg10805159

328 Signals Chapter 10


To support this feature, the system calls aredivided into two categories: the ‘‘slow’’
system calls and all the others. The slow system calls arethose that can block forever.
Included in this category are
•Reads that can block the caller forever if data isn’t present with certain file types
(pipes, terminal devices, and network devices)
•Writes that can block the caller forever if the data can’t be accepted immediately
by these same file types
•Opens on certain file types that block the caller until some condition occurs
(such as a terminal device open waiting until an attached modem answers the
phone)
•Thepausefunction (which by definition puts the calling process to sleep until a
signal is caught) and thewaitfunction
•Certainioctloperations
•Some of the interprocess communication functions (Chapter 15)
The notable exception to these slow system calls is anything related to disk I/O.
Although a read or a write of a disk file can block the caller temporarily (while the disk
driver queues the request and then the request is executed), unless a hardwareerror
occurs, the I/O operation always returns and unblocks the caller quickly.
One condition that is handled by interrupted system calls, for example, is when a
process initiates a read from a terminal device and the user at the terminal walks away
from the terminal for an extended period. In this example, the process could be blocked
for hours or days and would remain so unless the system was taken down.

POSIX.1 semantics for interruptedreadsandwriteschanged with the 2001 version of the
standard. Earlier versions gave implementations a choice of how to deal withreadsand
writesthat have processed partial amounts of data. Ifreadhas received and transferred
data to an application’s buffer,but has not yet received all that the application requested and is
then interrupted, the operating system could either fail the system call, witherrnoset to
EINTR, or allow the system call to succeed, returning the partial amount of data received.
Similarly,ifwriteis interrupted after transferring some of the data in an application’s buffer,
the operation system could either fail the system call, witherrnoset toEINTR, or allow the
system call to succeed, returning the partial amount of data written. Historically,
implementations derived from System V fail the system call, whereas BSD-derived
implementations return partial success.With the 2001 version of the POSIX.1 standard, the
BSD-style semantics arerequired.

The problem with interrupted system calls is that we now have to handle the error
return explicitly.The typical code sequence (assuming a read operation and assuming
that we want to restart the read even if it’s interrupted) would be
again:
if ((n = read(fd, buf, BUFFSIZE)) < 0) {
if (errno == EINTR)
goto again; /* just an interrupted system call */
/* handle other errors */
}
Free download pdf