Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

open(2)

FieldValue
Numbers (x64 / i386 / arm64-generic / arm32)open 2 / 5 / - / 5; openat 257 / 295 / 56 / 322; creat 85 / 8 / - / 8 (per-call table below)
Since (kernel)open 1.0; creat 1.0; openat 2.6.16 (glibc 2.4)
Man pageman2/open.2 (creat.2 and openat.2 are .so aliases of it)
glibc wrapperopen/openat/creat declared in <fcntl.h>; openat needs _POSIX_C_SOURCE >= 200809L (glibc 2.10+; _ATFILE_SOURCE before); since glibc 2.26 the open() wrapper issues the openat() system call
Aliases coveredopenat, creat
Ledger IDSC-open, SC-openat, SC-creat

Numbers by call, from the ledger and cross-checked against the cached kernel tables (syscall_64.tbl, syscall_32.tbl, syscall_arm.tbl, syscall_generic.tbl):

Callx64i386g64arm32Since
open25-51.0
openat257295563222.6.16
creat858-81.0

Hub row note: the domain hub’s grouped row shows creat’s number set (85 / 8 / - / 8) because one row cannot hold three calls; the per-call values above are the ledger values. There is no open slot on arm64-generic: glibc’s open() there resolves to openat (56), consistent with the glibc 2.26+ wrapper behavior (man2/open.2 C library/kernel differences; worklog 1-c numbering notes).

Purpose

open() resolves pathname and returns a new file descriptor referring to a new open file description; the descriptor is the lowest-numbered free one and the file offset starts at 0. The open file description carries the file offset and the file status flags; duplicated descriptors and fork children share it, while separate open() calls create separate descriptions. openat() is the dirfd-relative form of the same operation; creat() is exactly open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode). The flags argument splits into one access mode plus file creation flags (which affect the open itself) and file status flags (which affect later I/O and are partly readable/changeable through fcntl(2)).

Synopsis

#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
int openat(int dirfd, const char *pathname, int flags, ...);
int creat(const char *pathname, mode_t mode);

Arguments and behavior

ArgumentBehavior
pathnamePath to open; may create the file if O_CREAT is set.
flagsOne access mode (O_RDONLY/O_WRONLY/O_RDWR) ORed with creation and status flags (table below).
modePermission bits for a created file; required when O_CREAT or O_TMPFILE is set, ignored otherwise. Effective mode is mode & umask in the absence of a default ACL.
dirfd (openat)Absolute pathname: dirfd ignored. Relative + AT_FDCWD: relative to cwd. Relative + fd: relative to that directory, which must be opened O_RDONLY or O_PATH. Passing an invalid fd as dirfd makes any relative pathname fail EBADF, a trick to require an absolute path.

O_* constants (values from /usr/include/asm-generic/fcntl.h and bits/fcntl-linux.h, x86-64 octal; “since” from man2/open.2):

ConstantValueSinceNote
O_RDONLY, O_WRONLY, O_RDWR0, 1, 2-Access mode is the low 2 bits; nonstandard access mode 3 is a check-only fd used by some drivers
O_CREAT00000100-Create as regular file; owner = euid; group by SysV/BSD semantics per parent set-GID bit
O_EXCL00000200-With O_CREAT: fail EEXIST if the file exists; symlinks not followed. Alone: only block-device EBUSY check (Linux 2.6+)
O_NOCTTY00000400-Do not make the terminal the controlling terminal
O_TRUNC00001000-Truncate existing regular file opened for writing
O_APPEND00002000-Position at EOF before each write, atomically in one step
O_NONBLOCK / O_NDELAY00004000-Nonblocking open and I/O; no effect on regular files and block devices
O_DSYNC00010000-Data-integrity completion (like fdatasync per write)
O_ASYNC020000-Signal-driven I/O (SIGIO); glibc header constant, kernel headers use the FASYNC synonym
O_LARGEFILE00100000-32-bit large-file support; _FILE_OFFSET_BITS=64 preferred
O_DIRECTORY002000002.1.126Fail ENOTDIR if pathname is not a directory
O_NOFOLLOW004000002.1.126Fail ELOOP if the basename is a symlink
O_NOATIME010000002.6.8Do not update st_atime; needs ownership or CAP_FOWNER
O_CLOEXEC020000002.6.23Set FD_CLOEXEC atomically at open time
O_SYNC040100002.6.33File-integrity completion; before 2.6.33 O_SYNC behaved like O_DSYNC and O_DSYNC kept the old bit
O_DIRECT000400002.4.10Minimize cache effects; alignment limits vary by filesystem and kernel version
O_PATH0100000002.6.39Location-only fd: read/write/ioctl/mmap fail EBADF; close, dup, F_GETFD/F_GETFL, fstat (3.6), fchdir (3.5) and *at dirfd use work
O_TMPFILE0202000003.11Unnamed temporary regular file in the given directory; needs O_WRONLY or O_RDWR; filesystem support required

AT_* constants for this family: openat() itself takes no flags argument; the only AT_* constant it uses is the dirfd special value AT_FDCWD = -100 (/usr/include/linux/fcntl.h). The other AT_* bits (AT_SYMLINK_NOFOLLOW, AT_EMPTY_PATH, and so on) belong to the other *at() calls and are documented on their pages (fstatat on stat.md, statx on statx.md).

Return value and errors

On success all three calls return the new nonnegative file descriptor. On error, -1 and errno: EACCES (search/permission denied, including the protected_fifos and protected_regular sysctl cases), EBADF (openat: relative path with invalid dirfd), EBUSY (O_EXCL on a mounted block device), EDQUOT, EEXIST (O_CREAT|O_EXCL), EFAULT, EINTR (blocked open of a slow device interrupted), EINVAL (O_DIRECT unsupported, invalid flag, O_TMPFILE misuse), EISDIR, ELOOP, EMFILE/ENFILE, ENAMETOOLONG, ENOENT, ENOMEM, ENOSPC, ENOTDIR, ENXIO, EOPNOTSUPP (O_TMPFILE unsupported), EOVERFLOW (32-bit open of a >2 GiB file; EFBIG before 2.6.24), EPERM (O_NOATIME without ownership; write blocked by a file seal, see fcntl.md), EROFS, ETXTBSY (writing a running executable, swap file, or module being loaded), EWOULDBLOCK (incompatible lease).

Security and notes

  • O_CLOEXEC is the fd-leak defense: setting FD_CLOEXEC via a separate fcntl(F_SETFD) after open() races with a concurrent fork+execve in multithreaded programs and can leak the fd into the child (man2/open.2, and the same warning on fcntl.md F_SETFD).
  • O_NOATIME requires the caller’s effective UID to match the file owner, or CAP_FOWNER in the caller’s user namespace; otherwise EPERM.
  • Writing can be refused with EPERM by F_SEAL_SHRINK/GROW/WRITE seals on a memfd (fcntl.md).
  • O_PATH descriptors are the /proc/self/fd/N idiom for exec/fexecve without read permission; O_PATH needs no permission on the object itself, only search permission on the path prefix.
  • openat2 (kernel 5.6; x64 437 / i386 437 / g64 437 / arm32 437) extends openat with struct open_how and RESOLVE_* restrictions; it has its own hub row and page (openat2.md), not covered here.

References

  • man2/open.2 in the cached man-pages tree (dated 2021-08-27); .so aliases creat.2, openat.2.
  • Constants: /usr/include/asm-generic/fcntl.h, /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h, /usr/include/linux/fcntl.h.
  • Syscalls ledger rows SC-open, SC-openat, SC-creat; kernel tables in source-cache/kernel.
  • Domain hub for status and sibling pages.