Add Book to My BookshelfPurchase This Book Online

Chapter 6 - Special-Purpose File Operations

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

File Descriptor Attributes
Each open file descriptor has associated with it several attributes that you can examine and change. This book has already discussed one of these attributes, the read/write offset, which is examined and changed with the lseek function (or the fseek function, in the case of the Standard I/O Library). To examine and change the other file descriptor attributes, you can use two other functions, fcntl and ioctl.
The ioctl function was originally intended primarily for performing device control operations (that is, telling a tape drive to rewind the tape). However, as the need for other similar control functions arose, more and more duties were added to ioctl until it became used not only for performing device control operations, but also for regular file operations, operations on file descriptors, and operations on network communications modules. Unfortunately, because it was only designed for device control, ioctl was not very well suited for some of the tasks it was asked to perform.
Fortunately, the designers of System V UNIX recognized this and began working to reverse the trend of piling everything onto ioctl. They created the fcntl function, and moved all of the operations on regular files and file descriptors out of ioctl's area of responsibility. However, even the best laid plans don't go as well as they ought to. Because many vendors' operating systems were based on Berkeley UNIX, even though most of the vendors adopted fcntl (especially once it became a part of the POSIX standard), they still left some functionality under ioctl. Thus, most versions of UNIX, and SVR4 is no exception, use both ioctl and fcntl to perform operations on files and file descriptors, with some overlap for reasons of backward compatibility.
    #include <unistd.h>
    #include <sys/ioctl.h>
    int ioctl(int fd, int cmd, /* arg */ ...);
    #include <sys/types.h>
    #include <fcntl.h>
    int fcntl(int fd, int cmd, /* arg */ ...);
The ioctl function performs the request identified by cmd on the open file descriptor referenced by fd. The arg parameter is of varying type depending on the value of cmd, but it is usually either an integer or a pointer. The ioctl function returns a value greater than or equal to zero, depending on the value of cmd, on success. On failure, it returns -1 and stores the reason for failure in the external variable errno. In SVR4, the legal values for cmd are:
FIOCLEX
Set the close-on-exec flag for the file descriptor. This means that if the calling program executes another program with one of the exec system calls (see Chapter 11, Processes), the file descriptor is automatically closed before the new program is executed. The arg parameter is ignored by this command.
FIONCLEX
Clear the close-on-exec flag (see FIOCLEX) for the file descriptor. The arg parameter is ignored by this command.
FIONBIO
Set or clear non-blocking I/O on the file. The arg parameter is given as a pointer to an integer; if the integer's value is 1 then non-blocking I/O is enabled, if the integer's value is 0 then it is disabled. Non-blocking I/O means that reads and writes to the file return immediately if no data is available to be read, or no space (in the operating system buffers or on the disk) is available to store the data. If non-blocking I/O is not set, then reads and writes block, waiting for more data or space to become available. You can also set this attribute when the file is opened by using the O_NDELAY or O_NONBLOCK options.
FIOASYNC
Set or clear asynchronous I/O on the file. The arg parameter is given as a pointer to an integer; if the integer's value is 1 then asynchronous I/O is enabled, if the integer's value is 0, then it is disabled. Asynchronous I/O in this context means that when data becomes available for reading on the file descriptor, or when data can be written, the process is sent a SIGIO signal (see Chapter 10, Signals) notifying it of the change in the descriptor's status.
FIONREAD
Determine the number of characters available to be read. The arg parameter is given as a pointer to an integer in which the value is returned. While this is a valid way of determining whether there is input to be read, the select and poll functions described later in this chapter are more efficient.
FIOSETOWN
Set the process-group identifier (see Chapter 11, Processes) that subsequently receives SIGIO or SIGURG signals for the file descriptor. The arg parameter is a pointer to an integer containing the process-group identifier.
This command is not available in HP-UX 10.x.
FIOGETOWN
Get the process-group identifier that is receiving SIGIO or SIGURG signals for the file descriptor. The arg parameter is a pointer to an integer; after this call the integer contains the process-group identifier.
This command is not available in HP-UX 10.x.
There are numerous other commands as well, but their use is less common and beyond the scope of this chapter.
The fcntl function performs the request identified by cmd on the open file descriptor referenced by fd. The arg parameter is of varying type depending on the value of cmd, but it is usually either an integer or a pointer. In SVR4, the legal values for cmd are:
F_DUPFD
Return a new file descriptor with the following characteristics:
 Lowest numbered available file descriptor greater than or equal to the integer value given in arg
 Same open file (or pipe) as the original file
 Same read/write offset as the original file (that is, both file descriptors share the same read/write offset)
 Same access mode (read, write, read/write) as the original file
 Shares any locks associated with the original file descriptor
 Same file status flags (see below) as the original file (that is, both file descriptors share the same file status flags)
 Clears the close-on-exec flag associated with the new descriptor
F_GETFD
Get the close-on-exec flag associated with the file descriptor fd. If the low-order bit of the return value is 0, the file remains open across an exec. If the low-order bit is 1, the file closes on exec.
F_SETFD
Set the close-on-exec flag associated with the file descriptor fd to the low-order bit of the integer value given in arg, as described previously.
F_GETFL
Get the current status flags (see F_SETFL) for the file descriptor fd.
F_SETFL
Set the current status flags for the file descriptor fd to those contained in arg. Most of these flags can also be set when the file is opened with the open function described in Chapter 3, Low-Level I/O Routines; see the description there for more information on the meaning of each of these flags. The valid status flags are:
FD_CLOEXEC
Set the file descriptor's close-on-exec flag; this can also be set with F_SETFD, described previously
O_RDONLY
Open for reading only (this can only be set by the open function, but can be returned by the F_GETFL command)
O_WRONLY
Open for writing only (this can only be set by the open function, but can be returned by the F_GETFL command)
O_RDWR
Open for reading and writing (this can only be set by the open function, but it can be returned by the F_GETFL command)
O_APPEND
Append mode
O_NDELAY
Non-blocking mode
O_NONBLOCK
Non-blocking mode
O_DSYNC
Synchronous write operations (data only)
O_RSYNC
Synchronous read operations
O_SYNC
Synchronous write operations (data and file attributes)
Both ioctl and fcntl have other uses besides those described in this section. You will encounter these functions in several chapters throughout the rest of the book.

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