The fcntl function performs controlling operations on the open
file specified by the file_desc argument.
The values for the request argument are defined in the header
file <fcntl.h>, and include the following:
F_DUPFD Returns a new file descriptor that is the lowest
numbered available (that is, not already open)
file descriptor greater than or equal to the third
argument (arg) taken as an integer of type int.
The new file descriptor refers to the same file as
the original file descriptor (file_desc). The FD_
CLOEXEC flag associated with the new file descriptor
is cleared to keep the file open across calls to one
of the exec functions.
The following two calls are equivalent:
fid = dup(file_desc);
fid = fcntl(file_desc, F_DUPFD, 0);
Consider the following call:
fid = dup2(file_desc, arg);
It is similar (but not equivalent) to:
close(arg);
fid = fcntl(file_desc, F_DUPFD, arg);
F_GETFD Gets the value of the close-on-exec flag associated
with the file descriptor file_desc. File descriptor
flags are associated with a single file descriptor
and do not affect other file descriptors that refer
to the same file. The arg argument should not be
specified.
F_SETFD Sets the close-on-exec flag associated with file_
desc to the value of the third argument, taken as
type int.
If the third argument is 0, the file remains open
across the exec functions, which means that a child
process spawned by the exec function inherits this
file descriptor from the parent.
If the third argument is FD_CLOEXEC, the file is
closed on successful execution of the next exec
function, which means that the child process spawned
by the exec function will not inherit this file
descriptor from the parent.
F_GETFL Gets the file status flags and file access modes,
defined in <fcntl.h>, for the file description
associated with file_desc. The file access modes
can be extracted from the return value using the
mask O_ACCMODE, which is defined in <fcntl.h>. File
status flags and file access modes are associated
with the file description and do not affect other
file descriptors that refer to the same file with
different open file descriptions.
F_SETFL Sets the file status flags, defined in <fcntl.h>,
for the file description associated with file_desc
from the corresponding bits in the third argument,
arg, taken as type int. Bits corresponding to the
file access mode and the file creation flags,
as defined in <fcntl.h>, that are set in arg
are ignored. If any bits in arg other than those
mentioned here are changed by the application, the
result is unspecified.
Note: The only status bit recognized is O_APPEND.
Support for O_APPEND is not standard-compliant.
The X/Open standard states that "File status flags
and file access modes are associated with the file
description and do not affect other file descriptors
that refer to the same file with different open
file descriptions." However, because the append bit
is stored in the FCB, all file descriptors using
the same FCB are using the same append flag, so
that setting this flag with fcntl(F_SETFL) will
affect all files sharing the FCB; that is, all files
duplicated from the same file descriptor.
Record Locking Requests
F_GETLK Gets the first lock that blocks the lock description
pointed to by the arg parameter, taken as a pointer
to type struct flock. The information retrieved
overwrites the information passed to the fcntl
function in the flock structure. If no lock is found
that would prevent this lock from being created,
then the structure is left unchanged except for the
lock type, which is set to F_UNLCK.
F_SETLK Sets or clears a file segment lock according to
the lock description pointed to by arg, taken as
a pointer to type struct flock. F_SETLK is used to
establish shared locks (F_RDLCK), or exclusive locks
(F_WRLCK), as well as remove either type of lock (F_
UNLCK). If a shared (read) or exclusive (write)
lock cannot be set, the fcntl function returns
immediately with a value of -1.
An unlock (F_UNLCK) request in which the l_len of
the flock structure is nonzero and the offset of the
last byte of the requested segment is the maximum
value for an object of type off_t, when the process
has an existing lock in which l_len is 0 and which
includes the last byte of the requested segment,
is treated as a request to unlock from the start
of the requested segment with an l_len equal to 0.
Otherwise, an unlock (F_UNLCK) request attempts to
unlock only the requested file.
F_SETLKW Same as F_SETLK except that if a shared or exclusive
lock is blocked by other locks, the process will
wait until it is unblocked. If a signal is received
while fcntl is waiting for a region, the function
is interrupted, -1 is returned, and errno is set to
EINTR.
File Locking
The C RTL supports byte-range file locking using the F_GETLK,
F_SETLK, and F_SETLKW commands of the fcntl function, as defined
in the X/Open specification. Byte-range file locking is supported
across OpenVMS clusters. You can only use offsets that fit into
32-bit unsigned integers.
When a shared lock is set on a segment of a file, other processes
on the cluster are able to set shared locks on that segment or
a portion of it. A shared lock prevents any other process from
setting an exclusive lock on any portion of the protected area.
A request for a shared lock fails if the file descriptor was not
opened with read access.
An exclusive lock prevents any other process on the cluster from
setting a shared lock or an exclusive lock on any portion of the
protected area. A request for an exclusive lock fails if the file
descriptor was not opened with write access.
The flock structure describes the type (l_type), starting offset
(l_whence), relative offset (l_start), size (l_len) and process
ID (l_pid) of the segment of the file to be affected.
The value of l_whence is set to SEEK_SET, SEEK_CUR or SEEK_END,
to indicate that the relative offset l_start bytes is measured
from the start of the file, from the current position, or from
the end of the file, respectively. The value of l_len is the
number of consecutive bytes to be locked. The l_len value may be
negative (where the definition of off_t permits negative values
of l_len). The l_pid field is only used with F_GETLK to return
the process ID of the process holding a blocking lock. After a
successful F_GETLK request, the value of l_whence becomes SEEK_
SET.
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 may
not be negative relative to the beginning of the file. If l_len
is set to 0 (zero), a lock may be set to always extend to the
largest possible value of the file offset for that file. If such
a lock also has l_start set to 0 (zero) and l_whence is set to
SEEK_SET, the whole file is locked.
Changing or unlocking a portion from the middle of a larger
locked segment leaves a smaller segment 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
effect.
All locks associated with a file for a given process are removed
when a file descriptor for that file is closed by that process
or the process holding that file descriptor terminates. Locks are
not inherited by a child process.
If the request argument is F_SETLKW, the lock is blocked by
some lock from another process, and putting the calling process
to sleep to wait for that lock to become free would cause a
deadlock, then the application will hang.