ioctl(), vioctl()

Updated: April 19, 2023

Control a device

Synopsis:

#include <sys/ioctl.h> 

int ioctl( int fd, 
           int request, 
           ... );

int vioctl( int fd, 
            int request, 
            va_list arg );

Arguments:

fd
An open file descriptor for the file or device that you want to manipulate.
request
What you want to do to the file or device; see below for a summary. The macros and definitions that you use in specifying a request are located in the file <sys/ioctl.h>.
arg
A variable-argument list of the additional arguments, which you must have initialized with the va_start() macro. Used with vioctl() only.
Additional arguments
As required by the request.

Library:

libc

Use the -l c option to qcc to link against this library. This library is usually included automatically.

Description:

The ioctl() function manipulates the underlying parameters of files. In particular, it can be used to control many of the operating attributes of files (such as the attributes of terminals).

The vioctl() function is a "varargs" version of ioctl().

The request argument determines whether the subsequent arguments are an “in” or “out” parameter; it also specifies the size of the arguments in bytes.

I/O control commands

Use these macros to set up the I/O control commands:

_IO(class, cmd)
A command with no associated data.
_IOR(class, cmd, data)
Get information from the device.
_IOW(class, cmd, data)
Pass information to the device.
_IOWR(class, cmd, data)
Pass some information to the device, and get some from it.

The arguments to these macros are:

class
A single character that denotes the major category for the command.
cmd
An integer that identifies the command in the class.
data
The type of data to pass to and/or from the device. The additional argument to ioctl() must be a pointer to this type of data.
Note: The size of the structure that's passed as the last field to the __IO* macros must be less than 2^14 == 16 KB. Anything larger than this interferes with the upper two directional bits.

How ioctl() commands map to other commands

Some ioctl() commands map to calls to fcntl(), tcgetattr(), tcsetattr(), and tcsetsid(). Other commands are transformed into devctl() commands, and the rest are simply passed to devctl(). Here's a summary (for details, see the Devctl and Ioctl Commands reference):

ioctl() command Description Maps to:
CIO*, CRIOGET Handle cryptography operations These commands are used by the legacy devcrypto system driver interface. The preferred cryptography mechanism is the newer qcrypto library; for more information, see Cryptography for developers in the System Security Guide.
FIOASYNC Set or clear asynchronous I/O fcntl(): F_GETFL (which becomes a devctl() DCMD_ALL_GETFLAGS), followed by fcntl(): F_SETFL (which becomes a devctl() DCMD_ALL_SETFLAGS), setting or clearing O_ASYNC
FIOCLEX Set “close on exec” on a file descriptor fcntl(): F_SETFD with FD_CLOEXEC
FIOGETOWN Get the owner fcntl(): F_GETOWN
FIONBIO Set or clear non-blocking I/O fcntl(): F_GETFL (which becomes a devctl() DCMD_ALL_GETFLAGS), followed by fcntl(): F_SETFL (which becomes a devctl() DCMD_ALL_SETFLAGS), setting or clearing O_NONBLOCK
FIONCLEX Remove “close on exec” fcntl(): F_SETFD with ~FD_CLOEXEC
FIONREAD Get the number of bytes to read devctl(): DCMD_CHR_ISCHARS
FIOSETOWN Set the owner fcntl(): F_SETOWN
NOSIOCGIFCONF Get ifnet list Passed to devctl()
SIOCADDMULTI Add multicast address Passed to devctl()
SIOCADDRT Add route Passed to devctl()
SIOCAIFADDR Add or change an interface alias Passed to devctl()
SIOCALIFADDR Add interface address Passed to devctl()
SIOCATMARK At out-of-band mark? Passed to devctl()
SIOCDELMULTI Delete multicast address Passed to devctl()
SIOCDELRT Delete route Passed to devctl()
SIOCDIFADDR Delete interface address Passed to devctl()
SIOCDIFPHYADDR Delete gif addresses Passed to devctl()
SIOCDLIFADDR Delete interface address Passed to devctl()
SIOCGDRVSPEC Get driver-specific parameters Passed to devctl()
SIOCGETSGCNT Get the source group packet count Passed to devctl()
SIOCGETVIFCNT Get the packet count for a virtual interface Passed to devctl()
SIOCGHIWAT Get high watermark Passed to devctl()
SIOCGIFADDR Get the interface address Passed to devctl()
SIOCGIFALIAS Get interface alias Passed to devctl()
SIOCGIFASYNCMAP Get ppp asyncmap Passed to devctl()
SIOCGIFBRDADDR Get broadcast address Passed to devctl()
SIOCGIFCAP Get capabilities Passed to devctl()
SIOCGIFCONF Return a list of interface (transport layer) addresses Passed to devctl()
SIOCGIFDLT Get data link type Passed to devctl()
SIOCGIFDSTADDR Get point-to-point address Passed to devctl()
SIOCGIFFLAGS Get ifnet flags Passed to devctl()
SIOCGIFGENERIC Generic interface get op Passed to devctl()
SIOCGIFMEDIA Get net media Passed to devctl()
SIOCGIFMETRIC Get interface metric Passed to devctl()
SIOCGIFMTU Get ifnet MTU Passed to devctl()
SIOCGIFNETMASK Get net address mask Passed to devctl()
SIOCGIFPDSTADDR Get gif pdst address Passed to devctl()
SIOCGIFPSRCADDR Get gif psrc address Passed to devctl()
SIOCGLIFADDR Get interface address Passed to devctl()
SIOCGLIFPHYADDR Get gif addresses Passed to devctl()
SIOCGLOWAT Get low watermark Passed to devctl()
SIOCGPGRP Get process group fcntl(): F_GETOWN
SIOCIFCREATE Create clone interface Passed to devctl()
SIOCIFDESTROY Destroy clone interface Passed to devctl()
SIOCIFGCLONERS Get cloners Passed to devctl()
SIOCSDRVSPEC Set driver-specific parameters Passed to devctl()
SIOCSHIWAT Set high watermark Passed to devctl()
SIOCSIFADDR Set ifnet address Passed to devctl()
SIOCSIFASYNCMAP Set ppp asyncmap Passed to devctl()
SIOCSIFBRDADDR Set broadcast address Passed to devctl()
SIOCSIFCAP Set capabilities Passed to devctl()
SIOCSIFDSTADDR Set point-to-point address Passed to devctl()
SIOCSIFFLAGS Set ifnet flags Passed to devctl()
SIOCSIFGENERIC Generic interface set op Passed to devctl()
SIOCSIFMEDIA Set net media Passed to devctl()
SIOCSIFMETRIC Set interface metric Passed to devctl()
SIOCSIFMTU Set ifnet MTU Passed to devctl()
SIOCSIFNETMASK Set net address mask Passed to devctl()
SIOCSIFPHYADDR Set gif address Passed to devctl()
SIOCSLIFPHYADDR Set gif addresses Passed to devctl()
SIOCSLOWAT Set low watermark Passed to devctl()
SIOCSPGRP Set process group fcntl(): F_SETOWN
TCFLSH Flush buffers Passed to devctl()
TCGETA Get the terminal's properties in a termio structure tcgetattr()
TCGETS Get the terminal's properties in a termios structure tcgetattr()
TCSBRK Send a break for a period of time devctl() : DCMD_CHR_SERCTL
TCSETA Set the terminal's properties tcsetattr()
TCSETAF Set the terminal's properties, waiting until all currently written data has been transmitted, and discarding any received but unread data tcsetattr()
TCSETAW Set the terminal's properties, waiting until all currently written data has been transmitted tcsetattr()
TCSETS Set the terminal's properties from a termios structure devctl() : DCMD_CHR_TCSETATTR
TCSETSF Drain the output, flush the input, and set Passed to devctl()
TCSETSW Drain output, set Passed to devctl()
TCXONC Perform a flow-control operation on a data stream devctl(): DCMD_CHR_TCFLOW
TIOCCBRK Clear the break bit tcsetattr()
TIOCCDTR Clear the Data Terminal Ready line devctl() : DCMD_CHR_LINESTATUS, followed by DCMD_CHR_SERCTL
TIOCDRAIN Wait until output has drained devctl(): DCMD_CHR_TCDRAIN
TIOCEXCL Set exclusive use of tty fcntl(): F_SETLK
TIOCFLUSH Flush buffers devctl(): DCMD_CHR_TCFLUSH
TIOCGETA Get the terminal's properties in a termios structure devctl() : DCMD_CHR_TCGETATTR
TIOCGETC Get special characters tcgetattr()
TIOCGETP Get the terminal's parameters in a sgttyb structure tcgetattr()
TIOCGETPGRP Get the process group of the tty (POSIX) Passed to devctl()
TIOCGLTC Get local special characters tcgetattr()
TIOCGPGRP Get the process group of the tty devctl(): DCMD_CHR_TCGETPGRP
TIOCGSIZE Get window size devctl(): DCMD_CHR_GETSIZE
TIOCGWINSZ Get window size devctl(): DCMD_CHR_GETSIZE
TIOCHPCL Hang up on last close tcsetattr()
TIOCLGET Get local modes tcgetattr()
TIOCLSET Set entire local mode word tcsetattr()
TIOCMBIC Clear modem port B interrupt devctl() : DCMD_CHR_LINESTATUS, followed by DCMD_CHR_SERCTL
TIOCMBIS Set modem port B interrupt devctl() : DCMD_CHR_LINESTATUS, followed by DCMD_CHR_SERCTL
TIOCMGET Get the state of the modem lines devctl() : DCMD_CHR_SERCTL
TIOCMSET Set all modem bits Passed to devctl()
TIOCNOTTY Make this terminal not be the controlling terminal for the process tcsetsid()
TIOCNXCL Reset exclusive use of tty fcntl(): F_SETLK
TIOCOUTQ Output queue size devctl(): DCMD_CHR_OSCHARS
TIOCPKT Pty: set/clear packet mode Passed to devctl()
TIOCSBRK Set break bit Passed to devctl()
TIOCSCTTY Make the terminal become the controlling tty tcsetsid()
TIOCSDTR Set the Data Terminal Ready line devctl() : DCMD_CHR_LINESTATUS, followed by DCMD_CHR_SERCTL
TIOCSETA Set the terminal's properties from a termios structure devctl() : DCMD_CHR_TCSETATTR
TIOCSETAF Drain the output, flush the input, and set devctl(): DCMD_CHR_TCSETATTRF
TIOCSETAW Drain output, set devctl(): DCMD_CHR_TCSETATTRD
TIOCSETC Set special characters tcsetattr()
TIOCSETN Similar to TIOCSETP, but the changes are made immediately without discarding any data. tcsetattr()
TIOCSETP Set the terminal's parameters in a sgttyb structure. No change is made until all currently written data has been transmitted, at which point any received but unread data is discarded. tcsetattr()
TIOCSETPGRP Set the process group of the tty (POSIX) Passed to devctl()
TIOCSINUSE Set exclusive use of tty fcntl(): F_SETLK
TIOCSLTC Set local special characters tcsetattr()
TIOCSPGRP Set the process group of the tty devctl(): DCMD_CHR_TCSETPGRP
TIOCSSIZE Set the window size devctl(): DCMD_CHR_SETSIZE
TIOCSTART Start output, like CtrlQ Passed to devctl()
TIOCSTI Simulate terminal input devctl(): DCMD_CHR_TCINJECTC
TIOCSTOP Stop output, like CtrlS Passed to devctl()
TIOCSWINSZ Set window size devctl(): DCMD_CHR_SETSIZE
UIOCCMD() User control operator n Passed to devctl()
Note: If you're writing a resource manager, note that the iofunc_devctl_default() function handles the DCMD_ALL_GETFLAGS and DCMD_ALL_SETFLAGS commands; your resource manager will need to handle all other devctl commands that apply to it.

Registering an I/O control handler

An ioctl() command with data to pass is often passed to devctl(). However, this mechanism is not supported for commands that pass data using pointers to data buffers. For these types of ioctl() commands, you can register an I/O control handler that serializes the data. For more information, see _register_ioctl_handler() and _unregister_ioctl_handler().

Returns:

A value based on the request, or -1 if an error occurs (errno is set).

Errors:

EBADF
Invalid descriptor fd.
EINVAL
The request or optional variables aren't valid.
ENOBUFS
There wasn't enough memory available to allocate for data referred to by embedded pointers.
ENOTTY
The fd argument isn't associated with a character-special device; the specified request doesn't apply to the kind of object that the descriptor fd references.

Classification:

ioctl() is POSIX 1003.1 OB XSR; vioctl() is QNX Neutrino. The ioctl() function is marked as obsolescent, and may be removed from a future version of the standard.

Safety:  
Cancellation point Yes
Interrupt handler No
Signal handler No
Thread No

Caveats:

The ioctl() function is a Unix function that varies greatly from platform to platform.