2.1 File description (FD) interface

At the lowest level, right on top of the operating system, is the FD interface. At this level, all C subroutines translate to the underlying operating system software interrupt. In the Linux man page, all of these subroutines are in chapter 2. You can specify the chapter from which a topic is found. For example, to look up the topic ``open'' in chapter 2, you execute the command man 2 open.

At this level, the interface to a file is represented by an integer. In fact, 0 is hardwired to stdin, 1 is hardwired to stdout and 2 is hardwired to stderr. You can also open new files using the function open.

At this level, a programmer has much control of the access mode of a file. Just to list a few interesting ``status flags'':

The read and write operations using this interface are primitive. The read operation requires the FD, number of bytes to attempt to read, and where in memory to read it to. The write operation requires the FD, number of bytes ready to be written, and where in memory to write from.

The family of subroutines that use FDs is quite rich. For example, the subroutine fcntl is very handy because it can control many aspects of a FD. For example, it can set or release a lease on a file. A ``lease'' is essentially a listener that calls a callback function when a file is opened for read or write operations. fcntl can also monitor a directory so that any changes to the directory triggers some code execution.

Another interesting function is select. This subroutine permits a program to ``wait'' for I/O activities on a number of files. In other words, it blocks a process until at least one of the monitored FDs have input (data ready to be read) or output (written data is transferred) activities. This way, a single-threaded program can handle the simultaneous operations of multiple files. select returns a value that indicates which FDs (being monitored) had activities. A famous single-threaded program that uses select is the open source proxy cache squid.

If you are interested in networking, you will also find listen, socket, accept, connect and bind useful.

socket creates a socket, which can be connection-based, datagram-based or some other options. bind associates a socket with a ``name''. A ``name'' can be a TCP/IP port at a particular IP address.

listen blocks a thread until there is an attempt to connect to a socket. When listen unblocks, the process should either reject the connection, or use accept to accept the connection. Once a connection is accepted, it creates a new FD for that connection. Note that a socket may generate multiple simultaneous connections. A process may use connect to initiate a connection.

For child-parent process communication, sockets are usually an overkill. This is why ``pipes'' are usually used instead. A pipe is a pair of FDs (one for writing, one for reading). The function pipe is used to create pipes. pipe is usually used in conjunction with fork so that a child process may communicate with a parent process using a FD.

In summary, the FD interface is low level, but it provides a lot of options for special file handling.

Copyright © 2006-10-16 by Tak Auyeung