FCNTL(2) | System Calls | FCNTL(2) |
fcntl - file control
#include <sys/types.h> #include <unistd.h> #include <fcntl.h> int fcntl(int fildes, int cmd, /* arg */ ...);
The fcntl() function provides for control over open files. The fildes argument is an open file descriptor.
The fcntl() function can take a third argument, arg, whose data type, value, and use depend upon the value of cmd. The cmd argument specifies the operation to be performed by fcntl().
The values for cmd are defined in <fcntl.h> and include:
F_DUPFD
F_DUP2FD
F_DUP3FD
F_DUPFD_CLOEXEC
F_DUPFD_CLOFORK
F_DUP2FD_CLOEXEC
F_DUP2FD_CLOFORK
F_FREESP
F_FREESP64
F_ALLOCSP
F_ALLOCSP64
F_GETFD
F_GETFL
F_GETOWN
F_GETXFL
F_SETFD
F_SETFL
F_SETOWN
The following commands are available for POSIX advisory or mandatory record locking. POSIX record locking is supported for regular files, and may be supported for other files. See the FILE LOCKING section of this manual page for information about the types of file locks available and their interaction.
F_GETLK
F_GETLK64
F_SETLK
F_SETLK64
F_SETLKW
F_SETLKW64
The following commands are available for OFD (open file description) advisory record locking. OFD record locking is supported for regular files, and may be supported for other files. See the FILE LOCKING section of this manual page for information about the types of file locks available and their interaction. OFD-style record locks are currently limited to spanning the entire file and these locks are currently not supported over remote file systems (e.g. nfs(5)) which use the Network Lock Manager.
F_OFD_GETLK
F_OFD_GETLK64
F_OFD_SETLK
F_OFD_SETLK64
F_OFD_SETLKW
F_OFD_SETLKW64
The following values for cmd are used for file share reservations. A share reservation is placed on an entire file to allow cooperating processes to control access to the file. See the SHARE RESERVATIONS section of this manual page below for additional information.
F_SHARE
F_UNSHARE
Two types of file locks are supported: POSIX-style and OFD-style. OFD-style locks are associated with the open file description (not descriptor) instead of with a process. Either type is advisory by default, but POSIX-style locks can be mandatory if, and only if, mandatory locking has been enabled on the file being locked. Each type of lock may be created through two different interfaces. POSIX-style locks are created via the F_SETLK, F_SETLK64, F_SETLKW, or F_SETLKW64 commands to this system call or by use of the lockf(3C) routine. There is no difference between locks created via one mechanism or the other. Likewise, OFD-style locks are created via the F_OFD_SETLK, F_OFD_SETLK64, F_OFD_SETLKW, or F_OFD_SETLKW64 commands to this system call or by use of the Linux/BSD-compatible flock(3C) routine. Note that this system call supports the creation of range-specified OFD-style file locks, while flock(3C) does not. However, the current implementation of OFD-style locking is limited to locking the entire file. This limitation might be removed in the future.
The essential distinction between POSIX-style locks and OFD-style locks lie in how ownership of a lock is scoped. POSIX locks are scoped to a process. All POSIX locks associated with a file for a given process are removed when any file descriptor for that file is closed by that process or the process holding that file descriptor terminates. POSIX-style locks are not inherited by a child process created using fork(2). An OFD-style lock is scoped to the file description for a file, not the process or open file descriptor. Thus all file descriptors referring to the same description (i.e. those created via the F_DUPFD, F_DUP2FD, F_DUP3FD, F_DUPFD_CLOEXEC, F_DUP2FD_CLOEXEC, F_DUPFD_CLOFORK, or F_DUP2FD_CLOFORK commands to the fcntl(2) system call, or those created via the dup(2) system call, or those inherited by a child process created via fork(2)) reference the same lock, but a file descriptor obtained via a separate open(2) call on the same file will reference a different lock. A lock is removed only on the last close(2) of the description, or when the lock is explicitly unlocked.
Locks of both styles are compatible. A file that has been locked with one style of lock will be regarded as locked when creation of a lock of either style is attempted, and information about the lock will be provided via any of the F_GETLK, F_GETLK64, F_OFD_GETLK, or F_OFD_GETLK64 commands to this system call if that lock would conflict with an attempt to create the specified lock regardless of whether the specified lock is of the same style as the conflicting extant lock. Because ownership of OFD-style locks is scoped to the open description rather than the calling process, the l_pid field of a lock descriptor for any such lock will always be set to −1.
When a shared lock is set on a segment of a file, other callers (regardless of whether in the same or different process and of whether referenced via the same open file) will be able to set shared locks on that segment or a portion of it. A POSIX-style shared lock prevents any other process from setting an exclusive lock on any portion of the protected area. A OFD-style shared lock prevents any caller (even callers in the same process) from setting an exclusive lock on any portion of the protected area, unless the caller makes the request against a file descriptor referencing the same open file against which the shared lock was created, in which case the lock will be downgraded to a shared lock with respect to the specified region. A request for a shared lock of either style will fail if the file descriptor was not opened with read access.
A POSIX-style exclusive lock will prevent any other process from setting a shared lock or an exclusive lock (of either style) on any portion of the protected area. A request for an exclusive lock will fail if the file descriptor was not opened with write access.
The flock structure contains at least the following elements:
short l_type; /* lock operation type */ short l_whence; /* lock base indicator */ off_t l_start; /* starting offset from base */ off_t l_len; /* lock length; l_len == 0 means
until end of file */ int l_sysid; /* system ID running process holding lock */ pid_t l_pid; /* process ID of process holding lock */
The value of l_whence is SEEK_SET, SEEK_CUR, or SEEK_END, to indicate that the relative offset l_start bytes will be measured from the start of the file, current position or end of the file, respectively. The value of l_len is the number of consecutive bytes to be locked. The value of l_len may be negative (where the definition of off_t permits negative values of l_len). After a successful F_GETLK, F_GETLK64, F_OFD_GETLK, or F_OFD_GETLK64 request, that is, one in which a lock was found, the value of l_whence will be SEEK_SET.
The l_pid and l_sysid fields are used only with F_GETLK or F_GETLK64 to return the process ID of the process holding a POSIX-style blocking lock and to indicate which system is running that process, or −1 if it is an OFD-style lock. These fields must both be initialized to 0 prior to issuing a OFD-style locking command (F_OFD_GETLK or F_OFD_GETLK64).
If l_len is positive, the area affected starts at l_start and ends at l_start + l_len − 1. If l_len is negative, the area affected starts at l_start + l_len and ends at l_start − 1. Locks may start and extend beyond the current end of a file, but must not be negative relative to the beginning of the file. A lock will be set to extend to the largest possible value of the file offset for that file by setting l_len to 0. If such a lock also has l_start set to 0 and l_whence is set to SEEK_SET, the whole file will be locked.
If a lock exists for which l_len is 0 and which includes the last byte of the requested segment, and an unlock (F_UNLCK) request is made in which l_len is non-zero and the offset of the last byte of the requested segment is the maximum value for an object of type off_t, then the F_UNLCK request will be treated as a request to unlock from the start of the requested segment with an l_len equal to 0. Otherwise, the request will attempt to unlock only the requested segment.
There will be at most one type of lock set for each byte in the file. Before a successful return from an F_SETLK, F_SETLK64, F_SETLKW, or F_SETLKW64 request when the calling process has previously existing POSIX-style locks on bytes in the region specified by the request, the previous POSIX-style lock type for each byte in the specified region will be replaced by the new lock type. As specified above under the descriptions of shared locks and exclusive locks, an F_SETLK, F_SETLK64, F_SETLKW, or F_SETLKW64 request will (respectively) fail or block when locks exist on bytes in the specified region and the type of any of those locks conflicts with the type specified in the request.
Similarly, before a successful return from an F_OFD_SETLK, F_OFD_SETLK64, F_OFD_SETLKW, or F_OFD_SETLKW64 request when previously-created OFD-style locks associated with the open file apply to bytes in the region specified by the request, the previous OFD-style lock type for each byte in the specified region will be replaced by the new lock type. As specified above under the descriptions of shared locks and exclusive locks, an F_OFD_SETLK, F_OFD_SETLK64, F_OFD_SETLKW, or F_OFD_SETLKW64 request will (respectively) fail or block when locks exist on bytes in the specified region and the type of any of those locks conflicts with the type specified in the request.
A potential for deadlock occurs if a process controlling a locked region is put to sleep by attempting to lock another process' locked region. If the system detects that sleeping until a locked region is unlocked would cause a deadlock, fcntl() will fail with an EDEADLK error. This deadlock detection and error value apply only to POSIX-style locks. No deadlock detection is performed when attempting to set an OFD-style lock.
File share reservations are an advisory form of access control among cooperating processes, on both local and remote machines. They are most often used by DOS or Windows emulators and DOS based NFS clients. However, native UNIX versions of DOS or Windows applications may also choose to use this form of access control.
A share reservation is described by an fshare structure defined in <sys/fcntl.h>, which is included in <fcntl.h> as follows:
typedef struct fshare {
short f_access;
short f_deny;
int f_id; } fshare_t;
A share reservation specifies the type of access, f_access, to be requested on the open file descriptor. If access is granted, it further specifies what type of access to deny other processes, f_deny. A single process on the same file may hold multiple non-conflicting reservations by specifying an identifier, f_id, unique to the process, with each request.
An F_UNSHARE request releases the reservation with the specified f_id. The f_access and f_deny fields are ignored.
Valid f_access values are:
F_RDACC
F_WRACC
F_RWACC
Valid f_deny values are:
F_COMPAT
F_RDDNY
F_WRDNY
F_RWDNY
F_NODNY
Upon successful completion, the value returned depends on cmd as follows:
F_DUPFD, F_DUP2FD, F_DUP3FD
F_DUPFD_CLOEXEC, F_DUPFD_CLOFORK
F_DUP2FD_CLOEXEC, F_DUP2FD_CLOFORK
F_FREESP
F_GETFD
F_GETFL
F_GETLK
F_GETLK64
F_GETOWN
F_GETXFL
F_OFD_GETLK
F_OFD_GETLK64
F_OFD_SETLK
F_OFD_SETLK64
F_OFD_SETLKW
F_OFD_SETLKW64
F_SETFD
F_SETFL
F_SETLK
F_SETLK64
F_SETLKW
F_SETLKW64
F_SETOWN
F_SHARE
F_UNSHARE
Otherwise, −1 is returned and errno is set to indicate the error.
The fcntl() function will fail if:
EAGAIN
The cmd argument is F_FREESP, the file exists, mandatory file/record locking is set, and there are outstanding record locks on the file; or the cmd argument is F_SETLK, F_SETLK64, F_SETLKW, or F_SETLKW64, mandatory file/record locking is set, and the file is currently being mapped to virtual memory using mmap(2).
The cmd argument is F_SHARE and f_access conflicts with an existing f_deny share reservation.
EBADF
The cmd argument is F_FREESP and fildes is not a valid file descriptor open for writing.
The cmd argument is F_DUP2FD, F_DUP2FD_CLOEXEC, F_DUP2FD_CLOFORK, or F_DUP3FD and arg is negative or is not less than the current resource limit for RLIMIT_NOFILE.
The cmd argument is F_SHARE, the f_access share reservation is for write access, and fildes is not a valid file descriptor open for writing.
The cmd argument is F_SHARE, the f_access share reservation is for read access, and fildes is not a valid file descriptor open for reading.
EFAULT
EINTR
EINVAL
The cmd argument is F_UNSHARE and a reservation with this f_id for this process does not exist.
The cmd argument is F_DUP2FD_CLOEXEC or F_DUP2FD_CLOFORK and fildes is equal to arg.
The cmd argument is F_DUP3FD and the fourth flags argument contains unknown values.
EIO
EMFILE
ENOLCK
ENOLINK
EOVERFLOW
The cmd argument is F_GETLK, F_SETLK, F_SETLKW, F_OFD_GETLK, F_OFD_SETLK, or F_OFD_SETLKW, and the smallest or, if l_len is non-zero, the largest, offset of any byte in the requested segment cannot be represented correctly in an object of type off_t.
The cmd argument is F_GETLK64, F_SETLK64, F_SETLKW64, F_OFD_GETLK64, F_OFD_SETLK64, or F_OFD_SETLKW64, and the smallest or, if l_len is non-zero, the largest, offset of any byte in the requested segment cannot be represented correctly in an object of type off64_t.
The fcntl() function may fail if:
EAGAIN
EDEADLK
The cmd argument is F_FREESP, mandatory record locking is enabled, O_NDELAY and O_NONBLOCK are clear and a deadlock condition was detected.
EOPNOTSUPP
See attributes(7) for descriptions of the following attributes:
ATTRIBUTE TYPE | ATTRIBUTE VALUE |
Interface Stability | Standard |
MT-Level | Async-Signal Safe |
chmod(2), close(2), creat(2), dup(2), exec(2), fork(2), mmap(2), open(2), pipe(2), read(2), sigaction(2), write(2), dup2(3C), flock(3C), lockf(3C), fcntl.h(3HEAD), attributes(7), lf64(7), standards(7), lockd(8)
Programming Interfaces Guide
In the past, the variable errno was set to EACCES rather than EAGAIN when a section of a file is already locked by another process. Therefore, portable application programs should expect and test for either value.
Advisory locks allow cooperating processes to perform consistent operations on files, but do not guarantee exclusive access. Files can be accessed without advisory locks, but inconsistencies may result. The network share locking protocol does not support the f_deny value of F_COMPAT. For network file systems, if f_access is F_RDACC, f_deny is mapped to F_RDDNY. Otherwise, it is mapped to F_RWDNY.
To prevent possible file corruption, the system may reject mmap() requests for advisory locked files, or it may reject advisory locking requests for mapped files. Applications that require a file be both locked and mapped should lock the entire file (l_start and l_len both set to 0). If a file is mapped, the system may reject an unlock request, resulting in a lock that does not cover the entire file.
The process ID returned for locked files on network file systems might not be meaningful.
If the file server crashes and has to be rebooted, the lock manager (see lockd(8)) 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.
June 21, 2024 | OmniOS |