Museum

Home

Lab Overview

Retrotechnology Articles

⇒ Online Manual

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

close(2)

execve(2)

flock(2)

fork(2)

getdtablesize(2)

ioctl(2)

open(2V)

sigvec(2)

lockf(3)

fcntl(5)

lockd(8C)

FCNTL(2V)  —  SYSTEM CALLS

NAME

fcntl − file control

SYNOPSIS

#include <fcntl.h>

int fcntl (des, cmd, arg)
int des, cmd, arg;

DESCRIPTION

fcntl() performs a variety of functions on open descriptors.  The argument des is an open descriptor to be operated on by cmd as follows:

F_DUPFD Return a new descriptor as follows:

Lowest numbered available descriptor greater than or equal to arg.

Refers to the same object as the original descriptor. 

New descriptor shares the same file pointer if the object was a file (that is, both descriptors share one file pointer). 

Same access mode (read, write or read/write). 

Same descriptor status flags (both descriptors share the same descriptor status flags). 

The close-on-exec flag associated with the new descriptor is set to remain open across execve(2) system calls. 

F_GETFD Get the close-on-exec flag associated with the descriptor des. If the low-order bit is 0, the file will remain open across execve, otherwise the file will be closed upon execution of execve. 

F_SETFD Set the close-on-exec flag associated with des to the low order bit of arg (0 or 1 as above).  Note: this flag is a per-process and per-descriptor flag; setting or clearing it for a particular descriptor will not affect the flag on descriptors copied from it by a dup(2) or F_DUPFD operation, nor will it affect the flag on other processes instances of that descriptor. 

F_GETFL Get descriptor status flags (see fcntl(5) for their definitions). 

F_SETFL Set descriptor status flags (see fcntl(5) for their definitions).  Only the following flags can have their values changed: O_APPEND, O_SYNC, and O_NDELAY, and the FASYNC, FNDELAY, and FNBIO flags defined in <sys/file.h>. 

In the 4.2BSD environment, the O_NDELAY and FNDELAY flags are the same flag; in the System V environment, the O_NDELAY and FNBIO flags are the same flag.  The FNDELAY and FNBIO flags may be used in either environment; the meaning of those flags is not dependent on the environment in which a program is built. 

As the descriptor status flags are shared with descriptors copied from a given descriptor by a dup(2) or F_DUPFD operation, and by other processes instances of that descriptor, a F_SETFL operation will affect those other descriptors and other instances of the given descriptor as well.  In addition, setting or clearing the FNDELAY flag on a descriptor will cause an FIONBIO ioctl(2) to be performed on the object referred to by that descriptor, setting or clearing non-blocking mode, and setting or clearing the FASYNC flag on a descriptor will cause an FIOASYNC ioctl(2) to be performed on the object referred to by that descriptor, setting or clearing asynchronous mode.  Thus, all descriptors referring to that object will be affected. 

F_GETLK Get a description of the first lock that would block the lock specified in the flock() structure pointed to by arg. The information retrieved overwrites the information in the flock() structure.  If no lock is found that would prevent this lock from being created, then the structure is passed back unchanged except for the lock type which will be set to F_UNLCK.

F_SETLK Set or clear an advisory record lock according to the flock() structure pointed to by arg. F_SETLK is used to establish shared ( F_RDLCK) and exclusive ( F_WRLCK) locks, or to remove either type of lock ( F_UNLCK).  If the specified lock cannot be applied, fcntl() will return with an error value of −1. 

F_SETLKW This cmd is the same as F_SETLK except that if a shared or exclusive lock is blocked by other locks, the requesting process will sleep until the lock may be applied. 

F_GETOWN Get the process ID or process group currently receiving SIGIO and SIGURG signals; process groups are returned as negative values. 

F_SETOWN Set the process or process group to receive SIGIO and SIGURG signals; process groups are specified by supplying arg as negative, otherwise arg is interpreted as a process ID. 

The SIGIO facilities are enabled by setting the FASYNC flag with F_SETFL.

NOTES

Advisory locks allow cooperating processes to perform consistent operations on files, but do not guarantee exclusive access (processes may still access files without using advisory locks, possibly resulting in inconsistencies). 

The record locking mechanism allows two types of locks: shared locks ( F_RDLCK) and exclusive locks ( F_WRLCK).  More than one process may hold a shared lock for a particular segment of a file at any given time, but multiple exclusive, or both shared and exclusive, locks may not exist simultaneously on any segment. 

In order to claim a shared lock, the descriptor must have been opened with read access.  The descriptor on which an exclusive lock is being placed must have been opened with write access. 

A shared lock may be upgraded to an exclusive lock, and vice versa, simply by specifying the appropriate lock type with a cmd of F_SETLK or F_SETLKW; the previous lock will be released and the new lock applied (possibly after other processes have gained and released the lock). 

If the cmd is F_SETLKW and the requested lock cannot be claimed immediately (for instance, another process holds an exclusive lock that partially or completely overlaps the current request) then the calling process will block until the lock may be acquired.  Processes blocked awaiting a lock may be awakened by signals. 

Care should be taken to avoid deadlock situations in applications in which multiple processes perform blocking locks on a set of common records. 

The record that is to be locked or unlocked is described by the flock() structure, which is defined in <fcntl.h> and includes the following members:

shortl_type;/∗ F_RDLCK, F_WRLCK, or F_UNLCK ∗/
shortl_whence; /∗ flag to choose starting offset ∗/
longl_start;/∗ relative offset, in bytes ∗/
longl_len;/∗ length, in bytes;  0 means lock to EOF ∗/
shortl_pid;/∗ returned with F_GETLK ∗/

The flock structure describes the type (l_type), starting offset (l_whence), relative offset (l_start), and size (l_len) of the segment of the file to be affected.  l_whence must be set to 0, 1, or 2 to indicate that the relative offset will be measured from the start of the file, current position, or end-of-file, respectively.  The process id field (l_pid) is only used with the F_GETLK cmd to return the description of a lock held by another process. 

Locks may start and extend beyond the current end-of-file, but may not be negative relative to the beginning of the file.  A lock may be set to always extend to the end-of-file by setting l_len to zero (0).  If such a lock also has l_whence and l_start set to zero (0), the entire file will be locked.  Changing or unlocking a segment from the middle of a larger locked segment leaves two smaller segments at either end.  Locking a segment that is already locked by the calling process causes the old lock type to be removed and the new lock type to take affect.  All locks associated with a file for a given process are removed when the file is closed or the process terminates.  Locks are not inherited by the child process in a fork(2) system call. 

In order to maintain consistency in the network case, data must not be cached on client machines.  For this reason, file buffering for an NFS file is turned off when the first lock is attempted on the file.  Buffering will remain off as long as the file is open.  Programs that do I/O buffering in the user address space, however, may have inconsistent results (the standard I/O package, for instance, is a common source of unexpected buffering). 

The advisory record locking capabilities of fcntl() are implemented throughout the network by the network lock daemon; see lockd (8C).  If the file server crashes and is rebooted, the lock daemon will attempt to recover all locks that were associated with that server.  If a lock cannot be reclaimed, the process that held the lock will be issued a SIGLOST signal. 

RETURN VALUE

Upon successful completion, the value returned depends on cmd as follows:

F_DUPFD
A new descriptor.

F_GETFD
Value of flag (only the low-order bit is defined).

F_GETFL
Value of flags.

F_GETOWN
Value of descriptor owner.

other Value other than −1.  Otherwise, a value of −1 is returned and errno is set to indicate the error. 

ERRORS

fcntl() will fail if one or more of the following are true:

EBADF des is not a valid open descriptor. 

EMFILE cmd is F_DUPFD and the maximum allowed number of descriptors are currently open. 

EINVAL cmd is F_DUPFD and arg is negative or greater than the maximum allowable number (see getdtablesize(2)). 

EFAULT cmd is F_GETLK, F_SETLK, or F_SETLKW and arg points to an invalid address. 

EINVAL cmd is F_GETLK, F_SETLK, or F_SETLKW and the data arg points to is not valid. 

EBADF cmd is F_SETLK or F_SETLKW and the process does not have the appropriate read or write permissions on the file. 

EAGAIN cmd is F_SETLK, the lock type (l_type) is F_RDLCK (shared lock), and the segment of the file to be locked already has an exclusive lock held by another process.  This error will also be returned if the lock type is F_WRLCK (exclusive lock) and another process already has the segment locked with either a shared or exclusive lock. 

EINTR cmd is F_SETLKW and a signal interrupted the process while it was waiting for the lock to be granted. 

ENOLCK cmd is F_SETLK or F_SETLKW and there are no more file lock entries available. 

SEE ALSO

close(2), execve(2), flock(2), fork(2), getdtablesize(2), ioctl(2), open(2V), sigvec(2), lockf(3), fcntl(5), lockd(8C)

BUGS

File locks obtained through the fcntl() mechanism do not interact in any way with those acquired via flock(2).  They do, however, work correctly with the exclusive locks claimed by lockf(3). 

F_GETLK returns F_UNLCK if the requesting process holds the specified lock.  Thus, there is no way for a process to determine if it is still holding a specific lock after catching a SIGLOST signal. 

In a network environment, the value of l_pid returned by F_GETLK is next to useless. 

Sun Release 4.0  —  Last change: 8 January 1988

Typewritten Software • bear@typewritten.org • Edmonds, WA 98026