#include <sys/types.h> #include <unistd.h> #include <fcntl.h>
int fcntl(fd, cmd, arg) int fd, cmd, arg;
fcntl() performs a variety of functions on open descriptors. The argument fd is an open descriptor used by cmd as follows:
Note: this is a per-process and per-descriptor flag. Setting or clearing it for a particular descriptor does not affect the flag on descriptors copied from it by dup.2v or F_DUPFD, nor does it affect the flag on other processes of that descriptor.
O_NDELAY and FNDELAY are identical.
Descriptor status flag values set by F_SETFL affects descriptors copied using dup.2v F_DUPFD or other processes.
Setting or clearing the FNDELAY flag on a descriptor causes an FIONBIO ioctl.2 request 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 causes an FIOASYNC ioctl.2 request to be performed on the object referred to by that descriptor, setting or clearing asynchronous mode. Thus, all descriptors referring to the object are affected.
Record locking is done with either shared (F_RDLCK), or exclusive (F_WRLCK) locks. More than one process may hold a shared lock on a particular file segment, but if one process holds an exclusive lock on the segment, no other process may hold any lock on the segment until the exclusive lock is removed.
In order to claim a shared lock, a descriptor must be opened with read access. Descriptors for exclusive locks must be opened with write access.
A shared lock may be changed to an exclusive lock, and vice versa, simply by specifying the appropriate lock type with a F_SETLK or F_SETLKW cmd. Before the previous lock is released and the new lock applied, any other processes already in line must gain and release their locks.
If cmd is F_SETLKW and the requested lock cannot be claimed immediately (for instance, when another process holds an exclusive lock that overlaps the current request) the calling process is blocked until the lock may be acquired. These blocks may be interrupted by signals. Care should be taken to avoid deadlocks caused by multiple processes all blocking the same records.
A shared or exclusive lock is either advisory or mandatory depending on the mode bits of the file containing the locked segment. The lock is mandatory if the set-GID bit (S_ISGID) is set and the group execute bit (S_IXGRP) is clear (see stat.2v for information about mode bits). Otherwise, the lock is advisory.
If a process holds a mandatory shared lock on a segment of a file, other processes may read from the segment, but write operations block until all locks are removed. If a process holds a mandatory exclusive lock on a segment of a file, both read and write operations block until the lock is removed (see WARNINGS).
An advisory lock does not affect read and write access to the locked segment. Advisory locks may be used by cooperating processes checking for locks using F_GETLCK and voluntarily observing the indicated read and write restrictions.
The record to be locked or unlocked is described by the flock structure defined in <fcntl.h> as follows:
struct flock {
short l_type; /* F_RDLCK, F_WRLCK, or F_UNLCK */ short l_whence; /* flag to choose starting offset */ long l_start; /* relative offset, in bytes */ long l_len; /* length, in bytes; 0 means lock to EOF */ pid_t l_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 file segment to be affected. l_whence is set to SEEK_SET, SEEK_CUR, or SEEK_END (see lseek.2v to indicate that the relative offset is to be measured from the start of the file, current position, or EOF, 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. Note: do not confuse struct flock with the function flock.2 They are unrelated.
Locks may start or extend beyond the current EOF, but may not be negative relative to the beginning of the file. Setting l_len to zero (0) extends the lock to EOF. If l_whence is set to SEEK_SET and l_start and l_len are set to zero (0), the entire file is locked. Changing or unlocking the subset of a locked segment leaves the smaller segments at either end locked. Locking a segment 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.2v system call.
fcntl() record locks are implemented in the kernel for local locks, and throughout the network by the network lock daemon (lockd(8C)) for remote locks on NFS files. If the file server crashes and has to be rebooted, the lock daemon attempts to recover all locks that were associated with that server. If a lock cannot be reclaimed, the process that held the lock is issued a SIGLOST signal.
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 remains 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.
On success, the value returned by fcntl() depends on cmd as follows:
On failure, fcntl() returns -1 and sets errno to indicate the error.
Note: In future, fcntl() may generate EAGAIN under these conditions, so applications testing for EACCES should also test for EAGAIN.
cmd is F_SETLK or F_SETLKW and the process does not have the appropriate read or write permissions on the file.
cmd
is
F_GETLK,
F_SETLK,
or
F_SETLKW
and
arg
points to invalid data.
Advisory locks allow cooperating processes to perform consistent operations on files, but do not guarantee exclusive access. Files can be accessed without advisory files, but inconsistencies may result.
read.2v and write.2v system calls on files are affected by mandatory file and record locks (see chmod.2v
File locks obtained by fcntl() do not interact with flock() locks. 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.
Created by unroff & hp-tools. © somebody (See intro for details). All Rights Reserved. Last modified 11/5/97