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

ioctl(2)

FieldValue
Numbers (x64 / i386 / arm64-generic / arm32)16 / 54 / 29 / 54
Since (kernel)1.0
Man pageman2/ioctl.2
glibc wrapperioctl() declared in <sys/ioctl.h> as int ioctl(int fd, unsigned long request, …); POSIX specifies the request parameter as int, glibc’s prototype is the unsigned long form (man2/ioctl.2 comment); third argument is an untyped pointer, typed per request by user headers
Aliases coverednone
Ledger IDSC-ioctl

Purpose

ioctl() is the catch-all for device and object operations that do not fit the read/write stream model: the fd selects an object, the request code selects an operation, and argp is an untyped pointer to the operation’s in/out memory. There is no single standard: arguments, return values, and semantics vary by driver, and this page documents the dispatch model and the major request groups, not an exhaustive device list (per-request man pages listed under ioctl_* in man2 do that; man2/ioctl.2 SEE ALSO).

Kernel dispatch (verified against torvalds master fs/ioctl.c, fetched to source-cache/fetched/master-fs-ioctl.c; consistent with worklog 1-f / crossref XR-013 which documents the call as ioctl -> fs/ioctl dispatch -> driver unlocked_ioctl): SYSCALL_DEFINE3(ioctl) first runs the LSM security_file_ioctl() hook, then do_vfs_ioctl(), a VFS-wide switch that handles the generic commands below. If no generic command matches it returns -ENOIOCTLCMD and vfs_ioctl() hands the request to the file’s driver method filp->f_op->unlocked_ioctl(); a driver with no method yields ENOTTY. Regular files get a small extra pre-dispatch layer (file_ioctl()) for the positional requests handled in the fs layer.

Synopsis

#include <sys/ioctl.h>
int ioctl(int fd, unsigned long request, ...);

Arguments and behavior

ArgumentBehavior
fdOpen file descriptor; the valid request set depends on what fd refers to.
request32-bit device-dependent command code (see encoding below).
argpUntyped pointer (traditionally char *) to the request’s argument memory; requests without an argument ignore it.

Request encoding (man2/ioctl.2, macros in <asm/ioctl.h>): 2 direction bits (00 none, 01 write, 10 read, 11 read/write), 14 size bits (sizeof of the argument type), 8-bit type grouping a driver or purpose, 8-bit serial number. The size bits are explicitly unreliable – buggy macros and legacy values are common – and the encoding varies across architectures, so it must not be used to validate buffers. Old-style 16-bit constants (driver type byte + serial byte, e.g. TCGETS 0x00005401 with 0x54 = ‘T’ for the terminal driver) still exist alongside.

Major request groups (not exhaustive):

GroupExamplesHandled where
VFS generic close/exec flagsFIOCLEX, FIONCLEXdo_vfs_ioctl(), kernel-wide
Nonblocking / asyncFIONBIO, FIOASYNCdo_vfs_ioctl() (equivalents of fcntl F_SETFL bits)
Size and byte countsFIOQSIZE, FIGETBSZ, FIONREADdo_vfs_ioctl() (FIONREAD on regular files returns size - f_pos; otherwise falls through to the driver)
Filesystem freeze and mappingFIFREEZE, FITHAW, FS_IOC_FIEMAPdo_vfs_ioctl()
Reflink and dedupeFICLONE, FICLONERANGE, FIDEDUPERANGEdo_vfs_ioctl(); detailed on ioctl_ficlonerange(2)/ioctl_fideduperange(2)
Inode flags and xattrsFS_IOC_GETFLAGS, FS_IOC_SETFLAGS, FS_IOC_FSGETXATTR, FS_IOC_FSSETXATTRdo_vfs_ioctl() (chattr-style flags)
Misc fs identity (master)FS_IOC_GETFSUUID, FS_IOC_GETFSSYSFSPATHdo_vfs_ioctl() in the master tree, newer than the cached man page
TerminalsTCGETS/TCSETS, TIOCGWINSZ, …tty driver via ->unlocked_ioctl; documented on ioctl_tty(2)
Driver-specificeverything elsethe fd’s own ->unlocked_ioctl()

Return value and errors

Usually 0 on success; a few requests use the return value as an output parameter and return a nonnegative value. On error, -1 and errno: EBADF (bad fd), EFAULT (argp points outside the address space), EINVAL (request or argp invalid for the object), ENOTTY (fd is not associated with a character special device, or the request does not apply to the kind of object fd references). Driver methods return their own additional errno values.

Flags and constants

No flag argument; request codes are constants. The _IO(type,nr) / _IOR / _IOW / _IOWR macros build request values from a type letter, serial number, and argument type (man2/ioctl.2). Generic command constants live in <asm-generic/ioctls.h>, <linux/fs.h>, and friends; their numeric values are architecture-dependent through the encoding, so pages here quote names, not numbers.

Security and notes

  • ENOTTY is the traditional wrong-error for “not a tty” checks and also the generic “request not supported by this object” answer; do not treat it as a terminal-only error.
  • open() of a device can have side effects (carrier waits, resets); opening with O_NONBLOCK avoids blocking (man2/ioctl.2 NOTES).
  • LSM note in the kernel source: new generic commands require compat-mode-compatible argument sizes and a heads-up to the LSM mailing list (master fs/ioctl.c comment).
  • The historical BKL-holding .ioctl file operation and compat_sys_ioctl plumbing are outside the scope of the documented dispatch chain above; the cached man page and the master source only establish the ->unlocked_ioctl() path used here (source-limited, per crossref XR-013).

References

  • man2/ioctl.2 in the cached man-pages tree (dated 2021-03-22).
  • Kernel dispatch: torvalds master fs/ioctl.c (fetched copy source-cache/fetched/master-fs-ioctl.c; SYSCALL_DEFINE3 -> do_vfs_ioctl -> vfs_ioctl -> f_op->unlocked_ioctl), cross-checked with crossref XR-013 in src/linux/crossref/ledger.md and worklog 1-f.
  • Syscalls ledger row SC-ioctl; siblings fcntl, open; domain hub.