|                                                                                                        |
Lynx (etc) text mode tables arranged to 110 chars/line - where if properly adjusted the tables appear most "readable"... => lynx

 

[intro] [a:index] [s:index] [#:index] [sys_fcntl] [man fcntl]
[1..64] [65..128] [129..192] [193..256] [257..] [ref] [struc] [fcntl] [ioctl] [pguide] [man2]
[next] [back] [linux] [main] [bot] [top]
Syscalls pages archive (110K->1M), updated (2.3.0, ver. 1.66) man 2 pages (170K->1,2M)

Preliminary, from "glibc" <llio.html>, yet not thoroughly revised and, probably still providing much "GNU"/"C"-ish nonsense... i.e it is not clear what was meant w. "GNU extension" in the source documents because sometimes them refer to "Linux" which is occasionally stated a "GNU system" by those people, sometimes the (after 19 years of development:) still un-released "HURD" was more or less implicitely referred. I.e. any such references are entirely un-reliable and, thus not included in this text.
 
Linux source, fcntl flags and data array definitions re asm/fcntl.h (Linux) & fcntl.h (libc).

 

File Control

fcntl controls file properties by the rsp file descriptor which aren't covered by a specific system call e.g, inquiring or setting file status flags, manipulating record locks &c. Many of the flags to fcntl are arguments to open, as well.

fcntl commands:
  • F_DUPFD Duplicate fd,
    i.e. return another file descriptor pointing to the same open file.
  • F_GETFD Get fd flags.
  • F_SETFD Set fd flags.
  • F_GETFL Get status flags.
  • F_SETFL Set status flags.
  • F_GETLK Get a file lock.
  • F_SETLK Set or clear a file lock.
  • F_SETLKW F_SETLK, waiting for completion.
  • F_GETOWN Get PID or GID receiveing SIGIO signals.
  • F_SETOWN Set PID or GID receiveing SIGIO signals.
fcntl is a cancellation point in multi-threaded programs where a conflict might occur if the thread allocates some resources (memory, file descriptors, semaphores &c), coincidentally, which, after the rsp thread's termination remain allocated until the program ends unless the system call was protected by a respective cancellation handler.

[hp: Pse, NOTE that this might be libc specific! I'd yet not test any fcntl calls wrt that issue.]


Duplicating Descriptors

The command F_DUPFD duplicates a file descriptor, or allocates another file descriptor which refers to the same, open file as the original. Duplicate descriptors have a distinct set of file descriptor flags but, share file position and the file status flags.

The major use of duplicating a file descriptor is to redirecting input or output, i.e. changeing the file or pipe which a particular file descriptor corresponds to.

The F_DUPFD command can be substituted, executing atomically, with the dup and dup2 system calls, re fcntl.h for the flags to fcntl.

int F_DUPFD Macro
This macro is used as the command argument to fcntl, to copy the file descriptor given as the first argument.

The form of the call in this case is:

fcntl (old, F_DUPFD, next-filedes)

The next-filedes argument is of type int and specifies that the file descriptor returned should be the next available one greater than or equal to this value.

The return value from fcntl with this command is normally the value of the new file descriptor. A return value of -1 indicates an error. The following errno error conditions are defined for this command:

EBADF
The old argument is invalid.
EINVAL
The next-filedes argument is invalid.
EMFILE
There are no more file descriptors available - your program is already using the maximum. In BSD and GNU, the maximum is controlled by a resource limit that can be changed; re Limits on Resources, for more information about the RLIMIT_NOFILE limit.

ENFILE is not a possible error code for dup2 because dup2 does not create a new opening of a file; duplicate descriptors do not count toward the limit which ENFILE indicates. EMFILE is possible because it refers to the limit on distinct descriptor numbers in use in one process.

Here is an example showing how to use dup2 to do redirection. Typically, redirection of the standard streams (like stdin) is done by a shell or shell-like program before calling one of the exec functions (re Executing a File) to execute a new program in a child process. When the new program is executed, it creates and initializes the standard streams to point to the corresponding file descriptors, before its main function is invoked.

So, to redirect standard input to a file, the shell could do something like:

		pid = fork ();
		if (pid == 0)
		  {
		    char *filename;
		    char *program;
		    int file;
		    ...
		    file = TEMP_FAILURE_RETRY (open (filename, O_RDONLY));
		    dup2 (file, STDIN_FILENO);
		    TEMP_FAILURE_RETRY (close (file));
		    execv (program, NULL);
		  }

There is also a more detailed example showing how to implement redirection in the context of a pipeline of processes in Launching Jobs.


File Descriptor Flags

File descriptor flags are miscellaneous attributes of a file descriptor. These flags are associated with particular file descriptors, so that if you have created duplicate file descriptors from a single opening of a file, each descriptor has its own set of flags.

Currently there is just one file descriptor flag: FD_CLOEXEC, which causes the descriptor to be closed if you use any of the exec... functions (re Executing a File).

int F_GETFD
command, to returning the file descriptor flags associated with the fd.

The normal return value from fcntl with this command is a nonnegative number which can be interpreted as the bitwise OR of the individual flags (except that currently there is only one flag to use).

In case of an error, fcntl returns -1. The following errno error conditions are defined for this command:

EBADF
fd not valid.

int F_SETFD Macro
command argument to fcntl, specifying that it should set the file descriptor flags associated with the filedes argument. This requires a third int argument to specify the new flags:
		fcntl (filedes, F_SETFD, new-flags)

The normal return value from fcntl with this command is an unspecified value other than -1, which indicates an error. The flags and error conditions are the same as for the F_GETFD command.

The following macro is defined for use as a file descriptor flag with the fcntl function. The value is an integer constant usable as a bit mask value.

int FD_CLOEXEC Macro
This flag specifies that the file descriptor should be closed when an exec function is invoked; see Executing a File. When a file descriptor is allocated (as with open or dup), this bit is initially cleared on the new file descriptor, meaning that descriptor will survive into the new program after exec.

If you want to modify the file descriptor flags, you should get the current flags with F_GETFD and modify the value. Don't assume that the flags listed here are the only ones that are implemented; your program may be run years from now and more flags may exist then. For example, here is a function to set or clear the flag FD_CLOEXEC without altering any other flags:

		/* Set the FD_CLOEXEC flag of desc if value is nonzero,
		   or clear the flag if value is 0.
		   Return 0 on success, or -1 on error with errno set. */

		int
		set_cloexec_flag (int desc, int value)
		{
		  int oldflags = fcntl (desc, F_GETFD, 0);
		  /* If reading the flags failed, return error indication now.
		  if (oldflags < 0)
		    return oldflags;
		  /* Set just the flag we want to set. */
		  if (value != 0)
		    oldflags |= FD_CLOEXEC;
		  else
		    oldflags &= ~FD_CLOEXEC;
		  /* Store modified flag word in the descriptor. */
		  return fcntl (desc, F_SETFD, oldflags);
		}


[File Locks] : [Descriptor Flags] :

File Status Flags

File status flags are used to specify attributes of the opening of a file. Unlike the file descriptor flags discussed in Descriptor Flags, the file status flags are shared by duplicated file descriptors resulting from a single opening of the file. The file status flags are specified with the flags argument to open; re Opening and Closing Files.

File status flags fall into three categories, which are described in the following sections.


File Access Modes

The file access modes allow a file descriptor to be used for reading, writing, or both (GNU/Linux can also allow none of these, and allow execution of the file as a program). The access modes are chosen when the file is opened, and never change.

O_RDONLY Open the file for read access.
O_WRONLY Open the file for write access.
O_RDWR Open the file for reading and writing.

The portable way to extract the file access mode bits is with O_ACCMODE:

O_ACCMODE a mask that can be bitwise-ANDed with the file status flag value to produce a value
representing the file access mode. The mode will be O_RDONLY, O_WRONLY or, O_RDWR.

Opening Flags

The opening flags specify options affecting how open will behave. These options are not preserved once the file is open, with the exception of O_NONBLOCK, which is also an I/O operating mode. re Opening and Closing Files, for how to call open.

There are two sorts of options specified by opening flags.

File name translation flags:

O_CREAT If set, the file will be created if it doesn't already exist.
O_EXCL If both O_CREAT and O_EXCL are set, then open fails if the specified file already exists.
This is guaranteed to never clobber an existing file.
O_NONBLOCK prevents open from blocking for a "long time" to open the file, usually for devices
such as serial ports; harmless and ignored where not applicable.
Note that the O_NONBLOCK flag conicides with both. an I/O operating mode and a file name
translation flag. I.e. specifying O_NONBLOCK in open also sets nonblocking I/O mode;
re Operating Modes. To open the file without blocking but for normal I/O that blocks,
call open O_NONBLOCK and turn the rsp. bit off by fcntl, afterwards.
O_NOCTTY If the named file is a terminal device, don't make it the controlling terminal for the
process. re Job Control, for information about what "the controlling terminal" is.

The opening flags tell open to do additional operations which are not really related to opening the file. The reason to do them as part of open instead of in separate calls is that open can do them atomically:

O_TRUNC Truncate the file to zero length. - POSIX.1 requires write access.

BSD specific extensions:

O_SHLOCK Acquire a shared lock on the file, as with flock, re File Locks.
Atomically locking if O_CREAT specified, no other process will
get the lock on the new file first.
O_EXLOCK Atomically acquire an exclusive lock on the file. re File Locks.


[Getting File Status Flags] : [Opening Flags] :

I/O Operating Modes

The operating modes affect how input and output operations using a file descriptor work. These flags are set by open and can be fetched and changed with fcntl.

O_APPEND
Enables append mode. If set, all write operations write the data to the end of the file, extending it, regardless of the current file position. This is the only reliable way to append to a file. In append mode, written data are guaranteed to always being stored to the current end of the file, regardless of other processes writing to the file.

O_NONBLOCK
Enables nonblocking mode. If set, read requests on the file can return immediately with a failure status if there is no input immediately available, instead of blocking. Likewise, write requests can also return immediately with a failure status if the output can't be written immediately.

O_NDELAY
Another name for O_NONBLOCK, provided for compatibility with BSD, not defined by POSIX.1.

The remaining operating modes are BSD and "GNU" extensions which exist only on some systems.

O_ASYNC
enables asynchronous input mode; SIGIO signals will be generated when input is available. re Interrupt Input.

Asynchronous input mode is a BSD feature.

O_FSYNC
The bit that enables synchronous writing for the file. If set, each write call will make sure the data is reliably stored on disk before returning. Synchronous writing is a BSD feature.

O_SYNC
same as O_FSYNC.

O_NOATIME
If set, read will not update the access time of the file. re File Times. This is used by programs that do backups, so that backing up a file does not count as 'reading'. Only the owner of the file or the superuser may use this bit.

"GNU"-specific.


Getting and Setting File Status Flags

fcntl can fetch or change file status flags.

F_GETFL
This macro is used as the command argument to fcntl, to read the file status flags for the open file with descriptor filedes.

The normal return value from fcntl with this command is a nonnegative number which can be interpreted as the bitwise OR of the individual flags. Since the file access modes are not single-bit values, you can mask off other bits in the returned flags with O_ACCMODE to compare them.

In case of an error, fcntl returns -1. The following errno error conditions are defined for this command:

EBADF
The filedes argument is invalid.

F_SETFL
This macro is used as the command argument to fcntl, to set the file status flags for the open file corresponding to the filedes argument. This command requires a third int argument to specify the new flags, so the call looks like this:
		fcntl (filedes, F_SETFL, new-flags)

You can't change the access mode for the file in this way; that is, whether the file descriptor was opened for reading or writing.

The normal return value from fcntl with this command is an unspecified value other than -1, which indicates an error. The error conditions are the same as for the F_GETFL command.

If you want to modify the file status flags, you should get the current flags with F_GETFL and modify the value. Don't assume that the flags listed here are the only ones that are implemented; your program may be run years from now and more flags may exist then. For example, here is a function to set or clear the flag O_NONBLOCK without altering any other flags:

		/* Set the O_NONBLOCK flag of desc if value is nonzero,
		   or clear the flag if value is 0.
		   Return 0 on success, or -1 on error with errno set. */

		int
		set_nonblock_flag (int desc, int value)
		{
		  int oldflags = fcntl (desc, F_GETFL, 0);
		  /* If reading the flags failed, return error indication now. */
		  if (oldflags == -1)
		    return -1;
		  /* Set just the flag we want to set. */
		  if (value != 0)
		    oldflags |= O_NONBLOCK;
		  else
		    oldflags &= ~O_NONBLOCK;
		  /* Store modified flag word in the descriptor. */
		  return fcntl (desc, F_SETFL, oldflags);
		}

File Locks

The remaining fcntl commands are used to support record locking, which permits multiple cooperating programs to prevent each other from simultaneously accessing parts of a file in error-prone ways.

An exclusive or write lock gives a process exclusive access for writing to the specified part of the file. While a write lock is in place, no other process can lock that part of the file.

A shared or read lock prohibits any other process from requesting a write lock on the specified part of the file. However, other processes can request read locks.

The read and write functions do not actually check to see whether there are any locks in place. If you want to implement a locking protocol for a file shared by multiple processes, your application must do explicit fcntl calls to request and clear locks at the appropriate points.

Locks are associated with processes. A process can only have one kind of lock set for each byte of a given file. When any locked file descriptor is closed by the process, all locks on that file are released which that process holds, regardless of the rsp. file descriptors' state. Likewise, locks are released when a process exits, and not inherited by child processes created by the fork syscall.

When making a lock, use a struct flock to specify what kind of lock and where. re fcntl.h.

struct flock describes a file lock
short int l_type
either one of F_RDLCK, F_WRLCK, or F_UNLCK lock type.
short int l_whence
the whence argument to fseek or lseek, specifying the relation of "offset", either one of SEEK_SET, SEEK_CUR, SEEK_END.
off_t l_start
offset in bytes of the region to lock, wrt current file pointer as specified w. l_whence.
off_t l_len
length of the region to lock. 0 to extending the region till eof.
pid_t l_pid
process ID of the process holding the lock. Filled in w. F_GETLK, ignored while locking.

F_GETLK
command to requesting information about a lock; requires a third argument of type struct flock * to fcntl, so that the form of the call is:
		fcntl (filedes, F_GETLK, lockp)

If there is a lock already in place that would block the lock described by the lockp argument, information about that lock overwrites *lockp. Existing locks are not reported if they are compatible with making a new lock as specified. The lock type of F_WRLCK should be specified to finding 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. The l_whence member of the lockp structure is set to SEEK_SET and the l_start and l_len fields set to identify the locked region.

If no lock applies, the only change to the lockp structure is to update the l_type to a value of F_UNLCK.

The normal return value from fcntl with this command is an unspecified value other than -1, which is reserved to indicate 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, or the file associated with filedes doesn't support locks.

F_SETLK
command, specifying that the fcntl should set or clear a lock; requires a third argument of type struct flock *:
		fcntl (filedes, F_SETLK, lockp)

If the process 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 function does not block waiting for other processes to release locks. If fcntl succeeds, it return a value other than -1.

The following errno error conditions are defined for this function:

EAGAIN
EACCES
The lock cannot be set because it is blocked by an existing lock on the file. Some systems use EAGAIN in this case, and other systems use EACCES; your program should treat them alike, after F_SETLK ("GNU" always useing EAGAIN).
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, 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.

F_SETLKW
command to setting or clearing a lock. It is just like the F_SETLK command, but causes the process to block (or wait) until the request can be specified.

This command requires a third argument of type struct flock *, as for the F_SETLK command.

The fcntl return values and errors are the same as for the F_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. re Interrupted Primitives.
EDEADLK
The specified region is being locked by another process. But that process is waiting to lock a region which the current process has locked, so waiting for the lock would result in deadlock. The system does not guarantee that it will detect all such conditions, but it lets you know if it notices one.

The following macros are defined for use as values for the l_type member of the flock structure. The values are integer constants.

F_RDLCK
used to specify a read (or shared) lock.
F_WRLCK
used to specify a write (or exclusive) lock.
F_UNLCK
used to specify that the region is unlocked.

As an example of a situation where file locking is useful, consider a program that can be run simultaneously by several different users, that logs status information to a common file. One example of such a program might be a game that uses a file to keep track of high scores. Another example might be a program that records usage or accounting information for billing purposes.

Having multiple copies of the program simultaneously writing to the file could cause the contents of the file to become mixed up. But you can prevent this kind of problem by setting a write lock on the file before actually writing to the file.

If the program also needs to read the file and wants to make sure that the contents of the file are in a consistent state, then it can also use a read lock. While the read lock is set, no other process can lock that part of the file for writing.

Remember that file locks are only a voluntary protocol for controlling access to a file. There is still potential for access to the file by programs that don't use the lock protocol.


Interrupt-Driven Input

If you set the O_ASYNC status flag on a file descriptor (re File Status Flags), a SIGIO signal is sent whenever input or output becomes possible on that file descriptor. The process or process group to receive the signal can be selected by using the F_SETOWN command to the fcntl function. If the file descriptor is a socket, this also selects the recipient of SIGURG signals that are delivered when out-of-band data arrives on that socket; see Out-of-Band Data. - SIGURG is sent in any situation where select would report the socket as having an "exceptional condition". re Waiting for I/O.

If the file descriptor corresponds to a terminal device, then SIGIO signals are sent to the foreground process group of the terminal. re Job Control.

F_GETOWN
This macro is used as the command argument to fcntl, to specify that it should get information about the process or process group to which SIGIO signals are sent.

The return value is interpreted as a process ID; if negative, its absolute value is the process group ID.

The following errno error condition is defined for this command:

EBADF
The filedes argument is invalid.

F_SETOWN
This macro is used as the command argument to fcntl, to specify that it should set the process or process group to which SIGIO signals are sent. This command requires a third argument of type pid_t to be passed to fcntl, so that the form of the call is:
		fcntl (filedes, F_SETOWN, pid)

The pid argument should be a process ID. You can also pass a negative number whose absolute value is a process group ID.

The return value from fcntl with this command is -1 in case of error and some other value if successful. The following errno error conditions are defined for this command:

EBADF
The filedes argument is invalid.
ESRCH
There is no process or process group corresponding to pid.

 


[top] [back] [index]
[sys_fcntl] [a:index] [#:index] [1..64] [65...128] [129..190] [191..256] [257..] [ioctl]
H.-Peter Recktenwald, Berlin, 6.Mar.2001 = .hpr.l0 = : 690