Add Book to My BookshelfPurchase This Book Online

Chapter 3 - Low-Level I/O Routines

UNIX Systems Programming for SVR4
David A. Curry
 Copyright © 1996 O'Reilly & Associates, Inc.

Opening and Closing Files
Before any data can be read from or written to a file, that file must be opened for reading or writing (or both). Opening a file causes the operating system to locate (or create) the file on the disk, allocate an entry in the process' open file table, and set up assorted internal structures for moving data between the file and your program. The function used to open a file is called open:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *path, int oflag, /* mode_t mode */);
The path argument is a character string containing the pathname of the file to be opened, and oflag is a set of flags that control how the file is to be opened. oflag is constructed by or-ing together flags from the following list (the first three flags are mutually exclusive):
O_RDONLY
Open the file for reading only.
O_WRONLY
Open the file for writing only.
O_RDWR
Open the file for both reading and writing.
O_APPEND
If set, the read/write offset for the file (the point at which the next read or write is performed) is set to the end of the file prior to each write, causing all data written to be appended to the file.
O_CREAT
If the file exists, this option does nothing (except when O_EXCL is set; see the next option). If the file does not exist, this option tells the operating system to create it. The file is created with the permission bits provided in the third argument, mode, as modified by the process' umask value (see Chapter 6, Special-Purpose File Operations ).
O_EXCL
If O_CREAT is also set, this option checks to see if the file already exists. If the file does not exist, it is created. However, if the file does exist, the call to open fails. This allows cooperating processes to make use of the same file, because only one process can create the file at any given instant.
If O_EXCL and O_CREAT are both set, and the last path component of the filename to be opened is a symbolic link, open does not follow the link.
O_NDELAY or O_NONBLOCK
These constants affect the behavior of future reads and writes to a file. If the file is a regular disk file, a read or write returns -1 immediately if no data can be read or written, and errno is set to EAGAIN. This is regardless of which flag (O_NDELAY or O_NONBLOCK) is used.
If the file is a terminal device or a FIFO (see Chapter 13, Interprocess Communication), a read or write still returns immediately if no data can be read or written. If the O_NONBLOCK flag is used, the read or write returns -1 and sets errno to EAGAIN. If the O_NDELAY flag is used, however, the read or write returns 0 (which is not considered an error).
O_NOCTTY
If the file being opened is a terminal device, do not allocate that terminal as this process' controlling terminal. The controlling terminal is discussed in Chapter 11, Processes, and Chapter 12, Terminals.
O_DSYNC
Normally, write operations complete once the data to be transferred has been successfully copied to an operating system buffer; the transfer from the buffer to the physical storage media takes place without the process' knowledge. However, if this option is set, write operations on the descriptor do not complete until the data has been successfully transferred to the physical storage medium. This makes the process run much more slowly but allows it to be absolutely sure that the data is stored on the disk.
This flag is not available in IRIX 5.x.
O_RSYNC
Normally, a read request is satisifed with whatever data is stored on the disk at the time the request is processed. If another process is writing to the file at the same time, it is indeterminate whether the read will retrieve the old data or the new data (this is subject to the order in which the operating system processes the requests). However, if this option is set, the read request does not complete until any pending write operations affecting the data have been processed.
This flag is not available in IRIX 5.x.
O_SYNC
This option is similar to O_DSYNC, except that while O_DSYNC allows a write to complete once the data is successfully updated, O_SYNC forces the write to wait until both the data and the file's attributes (such as modification time) are updated.
This flag is not available in IRIX 5.x.
O_TRUNC
If the file exists and is being opened for writing, this option truncates its length to zero, deleting any existing data in the file.
If the file is opened successfully, open returns a file descriptor for the file. If the file cannot be opened, -1 is returned and an error code describing the reason for failure is placed into the external variable errno, where it can be examined or printed out with the perror function (see Chapter 2, Utility Routines).
On older UNIX systems such as Version 7 and pre-4.2 versions of BSD UNIX, open only accepted three values for oflag: 0 to open the file for reading, 1 to open it for writing, and 2 to open it for reading and writing. (For backward compatibility, the constants O_RDONLY, O_WRONLY, and O_RDWR are defined as 0, 1, and 2 respectively.) All of the other options described above were not available, and furthermore, open only opened existing files—to create a file, a separate system call, creat, was provided:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int creat(const char *path, mode_t mode);
If the file named in path does not exist, creat creates it, with the permission bits set to those in mode, as modified by the process' umask value (see Chapter 6, Special-Purpose File Operations). If the file named in path already exists, and is writable, it is truncated to zero length. If the file can be created successfully, creat returns a file descriptor (open for writing only) for the file. If the file cannot be created, creat returns -1 and places an error code describing the reason for failure into the external variable errno.
Once a program is finished using a file, it should close the file. This flushes any data written to the file but not yet placed on the disk by the operating system and frees up the resources (buffers, file table entry, etc.) used by that file. The function to close a file is called close:
#include <unistd.h>
int close(int fd);
If the file is closed successfully, close returns 0. If an error occurs during closing, close returns -1 and stores an error code in the external variable errno.
Porting Notes
As mentioned previously, older versions of UNIX do not support all the various flags to the open system call. The O_NOCTTY and O_NONBLOCK options are new to POSIX implementations; the O_DSYNC, O_RSYNC, and O_SYNC options are new to SVR4 implementations. These options are not supported by BSD or pre-SVR4 systems.
On BSD systems, the meaning of O_NDELAY applies only to the open call and does not affect future reads and writes.
The POSIX standard says that if O_EXCL is set when O_CREAT is not set, the result is implementation-defined. On some systems, it means that the file is opened for exclusive use (only one process may open the file at a time). However, on SVR4 systems, it simply has no effect.
Finally, on BSD systems, the O_ constants are defined in the include file sys/file.h instead of fcntl.h.

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