A Unix file is a sequence of m bytes:
B0, B1, . . . , Bk, . . . , Bm−1.
All I/O devices, such as networks, disks, and terminals, are modeled as files, and all input and output is performed by reading and writing the appropriate files.
Each process created by a Unix shell begins life with three open files: standard input (descriptor 0), standard output (descriptor 1), and standard error (descriptor 2).
In some situations, read and write transfer fewer bytes than the application requests. Such short counts do not indicate an error. The Rio package provides convenient, robust, and efficient I/O in applications such as network programs that are subject to short counts.
-Rio Unbuffered Input and Output Functions -Rio Buffered Input Functions
An application can retrieve information about a file (sometimes called the file’s metadata) by calling the stat and fstat functions.
A regular file contains some sort of binary or text data. To the kernel there is no difference between text files and binary files. A directory file contains information about other files. A socket is a file that is used to communicate with another process across a network
The kernel represents open files using three related data structures:
. Descriptor table.Each process has its own separate descriptor table whose entries are indexed by the process’s open file descriptors. Each open descriptor entry points to an entry in the file table.
. File table.The set of open files is represented by a file table that is shared by all processes. Each file table entry consists of (for our purposes) the current file position, a reference count of the number of descriptor entries that currently point to it, and a pointer to an entry in the v-node table. Closing a descriptor decrements the reference count in the associated file table entry. The kernel will not delete the file table entry until its reference count is zero.
. v-node table. Like the file table, the v-node table is shared by all processes. Each entry contains most of the information in the stat structure, including the st_mode and st_size members.An important consequence is that the parent and child must both close their descriptors before the kernel will delete the corresponding file table entry.
Each process has its own distinct descriptor table, while all processes share the same open file and v-node tables.
int dup2(int oldfd, int newfd);
copies descriptor table entry oldfd to descriptor table entry newfd, overwriting the previous contents of descriptor table entry newfd. If newfd was already open, then dup2 closes newfd before it copies oldfd.
The standard I/O library models an open file as a stream.To the programmer, a stream is a pointer to a structure of type FILE. Every ANSI C program begins with three open streams, stdin, stdout, and stderr, which correspond to standard input, standard output, and standard error, respectively. A stream of type FILE is an abstraction for a file descriptor and a stream buffer.
For most applications, standard I/O is the simpler, preferred alternative to Unix I/O. However, because of some mutually incompatible restrictions on standard I/O and network files, Unix I/O, rather than standard I/O, should be used for network applications.