In contrast to process-associated record locks (see File Locks), open file description record locks are associated with an open file description rather than a process.
Using fcntl
to apply an open file description lock on a region that
already has an existing open file description lock that was created via the
same file descriptor will never cause a lock conflict.
Open file description locks are also inherited by child processes across
fork
, or clone
with CLONE_FILES
set
(see Creating a Process), along with the file descriptor.
It is important to distinguish between the open file description (an
instance of an open file, usually created by a call to open
) and
an open file descriptor, which is a numeric value that refers to the
open file description. The locks described here are associated with the
open file description and not the open file descriptor.
Using dup
(see Duplicating Descriptors) to copy a file
descriptor does not give you a new open file description, but rather copies a
reference to an existing open file description and assigns it to a new
file descriptor. Thus, open file description locks set on a file
descriptor cloned by dup
will never conflict with open file
description locks set on the original descriptor since they refer to the
same open file description. Depending on the range and type of lock
involved, the original lock may be modified by a F_OFD_SETLK
or
F_OFD_SETLKW
command in this situation however.
Open file description locks always conflict with process-associated locks, even if acquired by the same process or on the same open file descriptor.
Open file description locks use the same struct flock
as
process-associated locks as an argument (see File Locks) and the
macros for the command
values are also declared in the header file
fcntl.h. To use them, the macro _GNU_SOURCE
must be
defined prior to including any header file.
In contrast to process-associated locks, any struct flock
used as
an argument to open file description lock commands must have the l_pid
value set to 0. Also, when returning information about an
open file description lock in a F_GETLK
or F_OFD_GETLK
request,
the l_pid
field in struct flock
will be set to -1
to indicate that the lock is not associated with a process.
When the same struct flock
is reused as an argument to a
F_OFD_SETLK
or F_OFD_SETLKW
request after being used for an
F_OFD_GETLK
request, it is necessary to inspect and reset the
l_pid
field to 0.
int
F_OFD_GETLK ¶This macro is used as the command argument to fcntl
, to
specify that it should get information about a lock. This command
requires a third argument of type struct flock *
to be passed
to fcntl
, so that the form of the call is:
fcntl (filedes, F_OFD_GETLK, lockp)
If there is a lock already in place that would block the lock described
by the lockp argument, information about that lock is written to
*lockp
. Existing locks are not reported if they are
compatible with making a new lock as specified. Thus, you should
specify a lock type of F_WRLCK
if you want to find out about both
read and write locks, or F_RDLCK
if you want to find out about
write locks only.
There might be more than one lock affecting the region specified by the
lockp argument, but fcntl
only returns information about
one of them. Which lock is returned in this situation is undefined.
The l_whence
member of the lockp structure are set to
SEEK_SET
and the l_start
and l_len
fields are set
to identify the locked region.
If no conflicting lock exists, the only change to the lockp structure
is to update the l_type
field to the value F_UNLCK
.
The normal return value from fcntl
with this command is either 0
on success or -1, which indicates an error. The following errno
error conditions are defined for this command:
EBADF
The filedes argument is invalid.
EINVAL
Either the lockp argument doesn’t specify valid lock information, the operating system kernel doesn’t support open file description locks, or the file associated with filedes doesn’t support locks.
int
F_OFD_SETLK ¶This macro is used as the command argument to fcntl
, to
specify that it should set or clear a lock. This command requires a
third argument of type struct flock *
to be passed to
fcntl
, so that the form of the call is:
fcntl (filedes, F_OFD_SETLK, lockp)
If the open file already has a lock on any part of the
region, the old lock on that part is replaced with the new lock. You
can remove a lock by specifying a lock type of F_UNLCK
.
If the lock cannot be set, fcntl
returns immediately with a value
of -1. This command does not wait for other tasks
to release locks. If fcntl
succeeds, it returns 0.
The following errno
error conditions are defined for this
command:
EAGAIN
The lock cannot be set because it is blocked by an existing lock on the file.
EBADF
Either: the filedes argument is invalid; you requested a read lock but the filedes is not open for read access; or, you requested a write lock but the filedes is not open for write access.
EINVAL
Either the lockp argument doesn’t specify valid lock information, the operating system kernel doesn’t support open file description locks, or the file associated with filedes doesn’t support locks.
ENOLCK
The system has run out of file lock resources; there are already too many file locks in place.
Well-designed file systems never report this error, because they have no limitation on the number of locks. However, you must still take account of the possibility of this error, as it could result from network access to a file system on another machine.
int
F_OFD_SETLKW ¶This macro is used as the command argument to fcntl
, to
specify that it should set or clear a lock. It is just like the
F_OFD_SETLK
command, but causes the process to wait until the request
can be completed.
This command requires a third argument of type struct flock *
, as
for the F_OFD_SETLK
command.
The fcntl
return values and errors are the same as for the
F_OFD_SETLK
command, but these additional errno
error conditions
are defined for this command:
EINTR
The function was interrupted by a signal while it was waiting. See Primitives Interrupted by Signals.
Open file description locks are useful in the same sorts of situations as
process-associated locks. They can also be used to synchronize file
access between threads within the same process by having each thread perform
its own open
of the file, to obtain its own open file description.
Because open file description locks are automatically freed only upon closing the last file descriptor that refers to the open file description, this locking mechanism avoids the possibility that locks are inadvertently released due to a library routine opening and closing a file without the application being aware.
As with process-associated locks, open file description locks are advisory.