[Previous]
[Contents]
[Next]

fcntl()

provide control over an open file

Synopsis:

#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
int fcntl( int fildes, int cmd, ... );

Description:

The fcntl() function provides control over the open file referenced by file descriptor fildes. The type of control is specified by the argument cmd, which may require a third data argument (arg).

At least the following values for cmd() are defined in <fcntl.h>:

F_DUPFD
Allocate and return 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 int. The new file descriptor refers to the same file as fildes, and shares any locks.
F_GETFD
Get the file descriptor flags associated with the file descriptor fildes. File descriptor flags are associated with a single file descriptor, and don't affect other file descriptors referring to the same file.

The only defined file descriptor flag is:

F_SETFD
Set the file descriptor flags associated with fildes, to the third argument, arg, taken as type int. See the above discussion for more details.
F_GETFL
Get the file status flags and file access modes associated with fildes. The flags and modes are defined in the header <fcntl.h>. The file status flags are:

These flags are described in more detail in the open() documentation.

The file access modes are:

F_SETFL
Set the file status flags, as shown above, for the open file description associated with fildes() from the corresponding bits in the third argument, arg, taken as type int. The file access mode can't be changed by this function call. All bits set in arg, other than the file status bits, are ignored.
F_GETLK
Get the first lock that blocks the lock description pointed to by the third argument, arg, taken as a pointer to type struct flock, as defined in the header file <fcntl.h>, and documented below. The information returned overwrites the information passed to fcntl() in the structure pointed to by arg.

If no lock is found that would prevent this lock from being created, the structure is left unchanged, except for the lock type, which is set to F_UNLCK. If a lock is found, the l_pid member of the structure pointed to by arg is set to the process ID of the process holding the blocking lock and l_whence is set to SEEK_SET.

F_SETLK
Set or clear a file segment lock, according to the lock description pointed to by the third argument, arg, taken as a pointer to type struct flock, as defined in the header file <fcntl.h>, and documented below. This command is used to create shared (or read) locks (member l_type set to F_RDLCK) or exclusive (or write) locks (member l_type set to F_WRLCK), as well as to remove either type of lock (member l_type set to F_UNLCK). The lock types are defined in the header file <fcntl.h>. If a lock cannot be set, fcntl() returns immediately.
F_SETLKW
This command is the same as F_SETLK, except that if a lock is blocked by other locks, the process waits until the request can be satisfied. If a signal that is to be caught is received while fcntl() is waiting for a region, the call is interrupted without performing the lock operation, and fcntl() returns -1 with errno set to EINTR.

The flock() structure members are defined below:

short l_type
F_RDLCK, F_WRLCK or F_UNLCK.
short l_whence
Flag for starting offset, one of SEEK_SET, SEEK_CUR, or SEEK_END to indicate that the relative offset, l_start, is measured from the start of the file, the current seek position, or the end of the file, respectively.
off_t l_start
Relative offset in bytes.
off_t l_len
Consecutive bytes to lock; if 0, until EOF; if negative, the preceding bytes up to, but not including, the start byte.
pid_t l_pid
Process ID of the process holding the lock, returned when cmd is F_GETLK.

When a shared lock is set on a segment of a file, other processes can set shared locks on the same segment, or a portion of it. A shared lock prevents other processes from setting exclusive locks on any portion of the protected area. A request for a shared lock fails if the file was opened write-only.

An exclusive lock prevents any other process from setting a shared or an exclusive lock on an portion of the protected area. A request for an exclusive lock fails if the file was opened read-only.

Locks may start and extend beyond the current end of file, but may not start or extend before the beginning of the file; to attempt to do so is an error. A lock extends to "infinity" (the largest possible value for the file offset) if l_len is set to zero. If l_whence and l_start point to the beginning of the file, and l_len is zero, the entire file is locked.

The calling process may have only one type of lock set for each byte of a file. Before successfully returning from a F_SETLK or F_SETLKW request, the previous lock type (if any) for each byte in the specified lock region is replaced by the new lock type. All locks associated with a file for a given process are removed when a file descriptor for that file is closed by the process, or the process holding the file descriptor terminates. Locks aren't inherited by a child process using the fork() or spawn... functions. However, locks are inherited across exec... calls.


Note:
  • A potential for deadlock occurs if a process controlling a locked region is put to sleep by attempting to lock another process's locked region. If the system detects that sleeping until a locked region is unlocked would cause a deadlock, fcntl() fails with an EDEADLK error. However, the system can't always detect deadlocks in the network case, and care should be exercised in the design of your application for this possibility.
  • Locking is a protocol designed for updating a file shared among concurrently running applications. Locks are only advisory, that is, they don't prevent an errant or poorly-designed application from overwriting a locked region of a shared file. An application should use locks to indicate regions of a file that are to be updated by the application, and it should respect the locks of other applications.

    Locks are ignored by the following functions:

    • chsize()
    • ltrunc()
    • open()
    • read()
    • sopen()
    • write()

Returns:

On error, fcntl() returns -1, and errno is set to indicate the error. The successful return value(s) depend on the request type specified by arg:

F_DUPFD
A new file descriptor.
F_GETFD
Value of the file descriptor flags (never a negative value).
F_SETFD
Value other than -1.
F_GETFL
Value of the file status flags and access modes as shown above (never a negative value).
F_SETFL
Value other than -1.
F_GETLK
Value other than -1.
F_SETLK
Value other than -1.
F_SETLKW
Value other than -1.

Errors:

EAGAIN
The argument cmd is F_SETLK, the type of lock (l_type) is a shared lock (F_RDLCK), and the segment of a file to be locked is already exclusive-locked by another process, or the type is an exclusive lock and some portion of the segment of a file to be locked is already shared-locked or exclusive-locked by another process.
EBADF
The fildes argument isn't a valid file descriptor.

The argument cmd is F_SETLK or F_SETLKW, the type of lock (l_type) is a shared lock (F_RDLCK), and fildes isn't a valid file descriptor open for reading.

The argument cmd is F_SETLK or F_SETLKW, the type of lock (l_type) is an exclusive lock (F_WRLCK), and fildes isn't a valid file descriptor open for writing.

EDEADLK
The argument cmd is F_SETLKW, and a deadlock condition was detected.
EINTR
The argument cmd is F_SETLKW, and the function was interrupted by a signal.
EINVAL
The argument cmd is F_DUPFD, and the third argument is negative, or greater than the configured number of maximum open file descriptors per process.

The argument cmd is F_GETLK, F_SETLK or F_SETLKW, and the data arg isn't valid, or fildes refers to a file that doesn't support locking.

EMFILE
The argument cmd is F_DUPFD, and the process has no unused file descriptors, or no file descriptors greater than or equal to arg are available.
ENOLCK
The argument cmd is F_SETLK or F_SETLKW, and satisfying the lock or unlock request would cause the number of lock regions in the system to exceed the system-imposed limit.

Examples:

/*
 * This program makes "stdout" synchronous
 * to guarantee the data is recoverable
 * (if it is redirected to a file).
 */
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>

int main( void )
{
    int flags, retval;

    flags = fcntl( STDOUT_FILENO, F_GETFL );

    flags |= O_DSYNC;

    retval = fcntl( STDOUT_FILENO, F_SETFL, flags );
    if( retval == -1 ) {
        printf( "error setting stdout flags\n" );
        return;
    }

    printf( "hello QNX world\n" );
    return (EXIT_SUCCESS);
}

Classification:

POSIX 1003.1

Safety:
Interrupt handler No
Signal handler Yes, but modifies errno
Thread Yes

See also:

close(), dup(), dup2(), exec... functions, open()


[Previous]
[Contents]
[Next]