File Control Operations

The fcntl.h header exposes the underlying system calls required to open and close files, and offers more fine-grained control over file access permissions (called a file mode), creation, truncation, and other functionalities that are not exposed by the C library interfaces.

Opening a File

Files are opened via the int open(char const *path, int flags, ...); system call, which returns an integer file descriptor number that is passed to other system calls to perform operations on the open file.

The flags argument is the bitwise-OR of various flag bits; flags must specify exactly one of the following access modes,

O_RDONLY

Open file for reading only.

O_WRONLY

Open file for writing only.

O_RDWR

Open file for reading and writing; unspecified result if applied to a FIFO (special file type).

Note

Two additional access mode flags, O_EXEC and O_SEARCH are specified in POSIX, but they are not implemented on many operating systems such as Linux and MacOS.

Additionally, the following optional values may be specified,

O_APPEND

Prior to each write, set the file offset to the end of the file.

O_CREAT

If the file does not exist, it is created, with the following properties:

  • User ID: Set to the effective user ID of the process

  • Group ID Set to the group ID of the parent directory, or the effective group ID of the process (implementation defined).

  • Access Permissions Bits: Set to the value of a variadic mode_t mode argument, bitwise-ANDed with the complement of the umask value for the process.

Warning

When the O_CREAT flag is specified, a third mode_t mode argument must be supplied–it is a very common mistake to forget to supply a mode argument. Additionally, because is is passed as a variadic argument, the value must be of type mode_t or the behavior is undefined. A very common misuse that invokes undefined behavior is to call open with an integer constant value, such as: int fd = open("file.txt", O_RDONLY | O_CREAT, 0777);. In this example, the value 0777 is an integer literal with type int, not mode_t. It must be explicitly cast for correctness, int fd = open("file.txt", O_RDONLY | O_CREAT, (mode_t) 0777);

The sys/stat.h header defines several macros which can be used to construct the mode parameter; these are defined with specific numeric values of type mode_t, so they do not need to be explicitly cast,

Name

Numeric Value

Description

S_IRWXU

0700

Read, write, execute/search by owner.

S_IRUSR

0400

Read permission, owner.

S_IWUSR

0200

Write permission, owner.

S_IXUSR

0100

Execute/search permission, owner.

S_IRWXG

070

Read, write, execute/search by group.

S_IRGRP

040

Read permission, group.

S_IWGRP

020

Write permission, group.

S_IXGRP

010

Execute/search permission, group.

S_IRWXO

07

Read, write, execute/search by others.

S_IROTH

04

Read permission, others.

S_IWOTH

02

Write permission, others.

S_IXOTH

01

Execute/search permission, others.

S_ISUID

04000

Set-user-ID on execution.

S_ISGID

02000

Set-group-ID on execution.

S_ISVTX

01000

On directories, restricted deletion flag.

O_TRUNC

May only be used with O_RDWR and O_WRONLY–if the file exists, truncate it, setting its size to 0.

Several additional optional flags are available, as described in OPEN(2).

The returned file descriptor integer is the lowest number available; if an error occurs, -1 is returned, and errno is set. The errors which can occur are described in detail in OPEN(2).

Closing Files

An open file can be closed with the int close(int fd) system call, returning 0 on success, -1 on failure, with errno set to indicate the error. See CLOSE(2) for more information.