1350 Chapter 63
Establish the signal handler before enabling signal-driven I/O
Because the default action of SIGIO is to terminate the process, we should enable the
handler for SIGIO before enabling signal-driven I/O on a file descriptor. If we enable
signal-driven I/O before establishing the SIGIO handler, then there is a time window
during which, if I/O becomes possible, delivery of SIGIO will terminate the process.
On some UNIX implementations, SIGIO is ignored by default.
Setting the file descriptor owner
We set the file descriptor owner using an fcntl() operation of the following form:
fcntl(fd, F_SETOWN, pid);
We may specify that either a single process or all of the processes in a process
group are to be signaled when I/O is possible on the file descriptor. If pid is positive,
it is interpreted as a process ID. If pid is negative, its absolute value specifies a pro-
cess group ID.
On older UNIX implementations, an ioctl() operation—either FIOSETOWN or
SIOCSPGRP—was used to achieve the same effect as F_SETOWN. For compatibility,
these ioctl() operations are also provided on Linux.
Typically, pid is specified as the process ID of the calling process (so that the signal is
sent to the process that has the file descriptor open). However, it is possible to specify
another process or a process group (e.g., the caller’s process group), and signals will
be sent to that target, subject to the permission checks described in Section 20.5,
where the sending process is considered to be the process that does the F_SETOWN.
The fcntl() F_GETOWN operation returns the ID of the process or process group
that is to receive signals when I/O is possible on a specified file descriptor:
id = fcntl(fd, F_GETOWN);
if (id == -1)
errExit("fcntl");
A process group ID is returned as a negative number by this call.
The ioctl() operation that corresponds to F_GETOWN on older UNIX implementa-
tions was FIOGETOWN or SIOCGPGRP. Both of these ioctl() operations are also provided
on Linux.
A limitation in the system call convention employed on some Linux architectures
(notably, x86) means that if a file descriptor is owned by a process group ID less
than 4096, then, instead of returning that ID as a negative function result from the
fcntl() F_GETOWN operation, glibc misinterprets it as a system call error. Consequently,
the fcntl() wrapper function returns –1, and errno contains the (positive) process
group ID. This is a consequence of the fact that the kernel system call interface
indicates errors by returning a negative errno value as a function result, and there
are a few cases where it is necessary to distinguish such results from a successful call
that returns a valid negative value. To make this distinction, glibc interprets negative