Liburing 2026.10.29
static
YoSTEALTH/Liburing

Types, enums and errors

Structures, enums and exceptions the functions take and return.

exception UnsupportedError(OSError)#

The running kernel does not support this io_uring feature (an OSError subclass).

Example

# on Linux 6.12, which has no `IORING_REGISTER_QUERY`
>>> try:
...     io_uring_register_query(Query())
... except UnsupportedError as e:
...     e.errno, str(e)
(22, 'Kernel `6.12` does not support `IORING_REGISTER_QUERY`')

Note

  • errno is the kernel's (EINVAL, EOPNOTSUPP, or EBADF for a call without a ring on kernels before 6.13).
  • Raised by the io_uring_register_* functions, by io_uring_queue_init* (setup flags, on kernels that have IORING_REGISTER_QUERY) and by calls that need an IORING_FEAT_* the ring lacks (io_uring_set_iowait, the *_min_timeout waits). An unsupported IORING_OP_* fails in its CQE: probe() tells.

class io_uring_op#

Subclass of IntEnum.

value IORING_OP_NOP = <io_uring_op.IORING_OP_NOP: 0>#

value IORING_OP_READV = <io_uring_op.IORING_OP_READV: 1>#

value IORING_OP_WRITEV = <io_uring_op.IORING_OP_WRITEV: 2>#

value IORING_OP_FSYNC = <io_uring_op.IORING_OP_FSYNC: 3>#

value IORING_OP_READ_FIXED = <io_uring_op.IORING_OP_READ_FIXED: 4>#

value IORING_OP_WRITE_FIXED = <io_uring_op.IORING_OP_WRITE_FIXED: 5>#

value IORING_OP_POLL_ADD = <io_uring_op.IORING_OP_POLL_ADD: 6>#

value IORING_OP_POLL_REMOVE = <io_uring_op.IORING_OP_POLL_REMOVE: 7>#

value IORING_OP_SYNC_FILE_RANGE = <io_uring_op.IORING_OP_SYNC_FILE_RANGE: 8>#

value IORING_OP_SENDMSG = <io_uring_op.IORING_OP_SENDMSG: 9>#

value IORING_OP_RECVMSG = <io_uring_op.IORING_OP_RECVMSG: 10>#

value IORING_OP_TIMEOUT = <io_uring_op.IORING_OP_TIMEOUT: 11>#

value IORING_OP_TIMEOUT_REMOVE = <io_uring_op.IORING_OP_TIMEOUT_REMOVE: 12>#

value IORING_OP_ACCEPT = <io_uring_op.IORING_OP_ACCEPT: 13>#

value IORING_OP_ASYNC_CANCEL = <io_uring_op.IORING_OP_ASYNC_CANCEL: 14>#

value IORING_OP_CONNECT = <io_uring_op.IORING_OP_CONNECT: 16>#

value IORING_OP_FALLOCATE = <io_uring_op.IORING_OP_FALLOCATE: 17>#

value IORING_OP_OPENAT = <io_uring_op.IORING_OP_OPENAT: 18>#

value IORING_OP_CLOSE = <io_uring_op.IORING_OP_CLOSE: 19>#

value IORING_OP_FILES_UPDATE = <io_uring_op.IORING_OP_FILES_UPDATE: 20>#

value IORING_OP_STATX = <io_uring_op.IORING_OP_STATX: 21>#

value IORING_OP_READ = <io_uring_op.IORING_OP_READ: 22>#

value IORING_OP_WRITE = <io_uring_op.IORING_OP_WRITE: 23>#

value IORING_OP_FADVISE = <io_uring_op.IORING_OP_FADVISE: 24>#

value IORING_OP_MADVISE = <io_uring_op.IORING_OP_MADVISE: 25>#

value IORING_OP_SEND = <io_uring_op.IORING_OP_SEND: 26>#

value IORING_OP_RECV = <io_uring_op.IORING_OP_RECV: 27>#

value IORING_OP_OPENAT2 = <io_uring_op.IORING_OP_OPENAT2: 28>#

value IORING_OP_EPOLL_CTL = <io_uring_op.IORING_OP_EPOLL_CTL: 29>#

value IORING_OP_SPLICE = <io_uring_op.IORING_OP_SPLICE: 30>#

value IORING_OP_PROVIDE_BUFFERS = <io_uring_op.IORING_OP_PROVIDE_BUFFERS: 31>#

value IORING_OP_REMOVE_BUFFERS = <io_uring_op.IORING_OP_REMOVE_BUFFERS: 32>#

value IORING_OP_TEE = <io_uring_op.IORING_OP_TEE: 33>#

value IORING_OP_SHUTDOWN = <io_uring_op.IORING_OP_SHUTDOWN: 34>#

value IORING_OP_RENAMEAT = <io_uring_op.IORING_OP_RENAMEAT: 35>#

value IORING_OP_UNLINKAT = <io_uring_op.IORING_OP_UNLINKAT: 36>#

value IORING_OP_MKDIRAT = <io_uring_op.IORING_OP_MKDIRAT: 37>#

value IORING_OP_SYMLINKAT = <io_uring_op.IORING_OP_SYMLINKAT: 38>#

value IORING_OP_LINKAT = <io_uring_op.IORING_OP_LINKAT: 39>#

value IORING_OP_MSG_RING = <io_uring_op.IORING_OP_MSG_RING: 40>#

value IORING_OP_FSETXATTR = <io_uring_op.IORING_OP_FSETXATTR: 41>#

value IORING_OP_SETXATTR = <io_uring_op.IORING_OP_SETXATTR: 42>#

value IORING_OP_FGETXATTR = <io_uring_op.IORING_OP_FGETXATTR: 43>#

value IORING_OP_GETXATTR = <io_uring_op.IORING_OP_GETXATTR: 44>#

value IORING_OP_SOCKET = <io_uring_op.IORING_OP_SOCKET: 45>#

value IORING_OP_URING_CMD = <io_uring_op.IORING_OP_URING_CMD: 46>#

value IORING_OP_SEND_ZC = <io_uring_op.IORING_OP_SEND_ZC: 47>#

value IORING_OP_SENDMSG_ZC = <io_uring_op.IORING_OP_SENDMSG_ZC: 48>#

value IORING_OP_READ_MULTISHOT = <io_uring_op.IORING_OP_READ_MULTISHOT: 49>#

value IORING_OP_WAITID = <io_uring_op.IORING_OP_WAITID: 50>#

value IORING_OP_FUTEX_WAIT = <io_uring_op.IORING_OP_FUTEX_WAIT: 51>#

value IORING_OP_FUTEX_WAKE = <io_uring_op.IORING_OP_FUTEX_WAKE: 52>#

value IORING_OP_FUTEX_WAITV = <io_uring_op.IORING_OP_FUTEX_WAITV: 53>#

value IORING_OP_FIXED_FD_INSTALL = <io_uring_op.IORING_OP_FIXED_FD_INSTALL: 54>#

value IORING_OP_FTRUNCATE = <io_uring_op.IORING_OP_FTRUNCATE: 55>#

value IORING_OP_BIND = <io_uring_op.IORING_OP_BIND: 56>#

value IORING_OP_LISTEN = <io_uring_op.IORING_OP_LISTEN: 57>#

value IORING_OP_RECV_ZC = <io_uring_op.IORING_OP_RECV_ZC: 58>#

value IORING_OP_EPOLL_WAIT = <io_uring_op.IORING_OP_EPOLL_WAIT: 59>#

value IORING_OP_READV_FIXED = <io_uring_op.IORING_OP_READV_FIXED: 60>#

value IORING_OP_WRITEV_FIXED = <io_uring_op.IORING_OP_WRITEV_FIXED: 61>#

value IORING_OP_PIPE = <io_uring_op.IORING_OP_PIPE: 62>#

value IORING_OP_NOP128 = <io_uring_op.IORING_OP_NOP128: 63>#

value IORING_OP_URING_CMD128 = <io_uring_op.IORING_OP_URING_CMD128: 64>#

value IORING_OP_LAST = <io_uring_op.IORING_OP_LAST: 65>#

class io_uring_socket_op#

Subclass of IntEnum.

value SOCKET_URING_OP_SIOCINQ = <io_uring_socket_op.SOCKET_URING_OP_SIOCINQ: 0>#

value SOCKET_URING_OP_SIOCOUTQ = <io_uring_socket_op.SOCKET_URING_OP_SIOCOUTQ: 1>#

value SOCKET_URING_OP_GETSOCKOPT = <io_uring_socket_op.SOCKET_URING_OP_GETSOCKOPT: 2>#

value SOCKET_URING_OP_SETSOCKOPT = <io_uring_socket_op.SOCKET_URING_OP_SETSOCKOPT: 3>#

value SOCKET_URING_OP_TX_TIMESTAMP = <io_uring_socket_op.SOCKET_URING_OP_TX_TIMESTAMP: 4>#

value SOCKET_URING_OP_GETSOCKNAME = <io_uring_socket_op.SOCKET_URING_OP_GETSOCKNAME: 5>#

class Timespec()#

Example

>>> ts = timespec(2)
>>> ts.sec
2
>>> ts.nsec
0
>>> ts.sec = 1           # second
>>> ts.nsec = 500000000  # nanosecond

Note

  • Takes no arguments (TypeError for any): use timespec(second) to make one from seconds.

property sec: int#

Whole seconds.

property nsec: int#

Nanoseconds, after the whole seconds.

class SigsetT(signals=None)#

Signal set (sigset_t), e.g. for sigmask of wait functions.

Example

>>> mask = SigsetT([signal.SIGINT, signal.SIGTERM])
>>> mask = SigsetT()  # empty set

Note

  • ValueError for an invalid signal number.

class SiginfoT()#

Signal information (siginfo_t), filled by the kernel, e.g. infop of io_uring_prep_waitid.

Example

>>> pid = os.posix_spawn('/bin/sh', ['sh', '-c', 'exit 7'], os.environ)
>>> info = SiginfoT()
>>> sqe = io_uring_get_sqe(ring)
>>> io_uring_prep_waitid(sqe, os.P_PID, pid, info, os.WEXITED)
True
>>> io_uring_submit_and_wait(ring, 1)
1
>>> info.si_pid == pid, info.si_code == os.CLD_EXITED, info.si_status
(True, True, 7)
Setup used to run this example
    'io_uring_get_probe_ring', 'io_uring_ring_dontfork', 'io_uring_queue_exit', 'io_uring_register',
    'io_uring_set_iowait', 'io_uring_sq_ready', 'io_uring_sq_space_left', 'io_uring_sqring_wait', 'io_uring_get_sqe',
    'io_uring_get_events', 'io_uring_close_ring_fd', 'io_uring_register_ring_fd', 'io_uring_unregister_ring_fd',
    'io_uring_register_personality', 'io_uring_unregister_personality', 'io_uring_unregister_files',
    'io_uring_register_eventfd', 'io_uring_unregister_eventfd', 'io_uring_register_buffers', 'io_uring_buf_ring_head',
    'io_uring_register_iowq_aff', 'io_uring_register_iowq_max_workers', 'io_uring_cq_has_overflow',
    'io_uring_cq_eventfd_enabled', 'io_uring_cq_eventfd_toggle', 'BufReg', 'Napi', 'ClockRegister', 'Bpf', 'SQE',
    'SiginfoT', 'io_uring_prep_waitid', 'io_uring_prep_cancel', 'io_uring_prep_cancel64', 'ZcrxIfqReg',
)  # fmt: skip
def ring(ns):
    make_ring(ns)

Note

  • The kernel writes it at the completion: the request holds it until then.

property si_signo: int#

Signal number.

property si_errno: int#

Errno value, if any.

property si_code: int#

Signal code (e.g. os.CLD_EXITED).

property si_pid: int#

Process id of the child (SIGCHLD / waitid info).

property si_uid: int#

Real user id of the child (SIGCHLD / waitid info).

property si_status: int#

Exit status (si_code == CLD_EXITED) or signal number (killed, stopped, ...).

class OpenHow(flags=None, mode=None, resolve=None)#

How to Open a Path (struct open_how of openat2, for io_uring_prep_openat2): flags are the O_* of open, mode the permission bits of a file O_CREAT / O_TMPFILE makes, resolve restricts how the path is looked up (RESOLVE_*).

Example #1

>>> how = OpenHow(O_CREAT | O_RDWR, 0o777, RESOLVE_CACHED)
>>> io_uring_prep_openat2(sqe, 'file.txt', how)
True
Setup used to run this example
    'io_uring_prep_readv', 'io_uring_prep_read_fixed', 'io_uring_prep_readv_fixed', 'io_uring_prep_writev',
    'io_uring_prep_write_fixed', 'io_uring_prep_writev_fixed', 'io_uring_prep_close', 'io_uring_prep_close_direct',
    'io_uring_prep_madvise', 'io_uring_prep_madvise64', 'io_uring_prep_pipe', 'OpenHow',
)  # fmt: skip
def file_io(ns):
    '''`file_ring`, with an `sqe` of the ring.'''
    file_ring(ns)
    ns['sqe'] = io_uring_get_sqe(ns['ring'])

Example #2

# or: the fields one by one
>>> how = OpenHow()
>>> how.flags   = O_CREAT | O_RDWR
>>> how.mode    = 0
>>> how.resolve = RESOLVE_CACHED
>>> io_uring_prep_openat2(sqe, 'file.txt', how)
True

Flags

Resolve

RESOLVE_BENEATH        # The path may not escape the directory of dfd (no .. past it, no absolute path).
RESOLVE_IN_ROOT        # The directory of dfd acts as / for the lookup (as a chroot would).
RESOLVE_NO_MAGICLINKS  # No magic links (/proc/*/fd/*): OSError: ELOOP.
RESOLVE_NO_SYMLINKS    # No symbolic links at all: OSError: ELOOP.
RESOLVE_NO_XDEV        # Stay on the mount dfd is on: OSError: EXDEV.
RESOLVE_CACHED         # Only what is cached: OSError: EAGAIN when the kernel would have to block (5.12+).

Note

  • mode is only to set when creating new or temp file (O_CREAT / O_TMPFILE): openat2 is strict, any other mode (and any unknown bit in flags or resolve) fails the request with OSError: EINVAL.
  • You can use same OpenHow() reference if opening multiple files with same settings.
  • The result of the request is the new file descriptor in cqe.res.

property flags: int#

The O_* open flags (O_RDONLY, O_CREAT | O_RDWR, O_TMPFILE, ...).

property mode: int#

Permission bits (0o644) of a file O_CREAT / O_TMPFILE makes; 0 otherwise.

property resolve: int#

RESOLVE_* flags restricting the path lookup (0: none).

class EpollEvent(no=None, events=None, data=None)#

Event for io_uring_prep_epoll_ctl (one, the events and the user data to get back) and io_uring_prep_epoll_wait (EpollEvent(no=n): room for n events, read with events[i]).

Example

>>> EPOLL_CTL_ADD = 1  # <sys/epoll.h>
>>> ev = EpollEvent(events=select.EPOLLIN, data=123)
>>> sqe = io_uring_get_sqe(ring)
>>> io_uring_prep_epoll_ctl(sqe, epfd, fd, EPOLL_CTL_ADD, ev)
True
>>> io_uring_submit_and_wait(ring, 1)
1

>>> ready = EpollEvent(no=8)
>>> sqe = io_uring_get_sqe(ring)
>>> io_uring_prep_epoll_wait(sqe, epfd, ready, 8)
True
>>> io_uring_submit_and_wait(ring, 2)
1
>>> ready[0].events, ready[0].data  # after the completion: `fd` is readable
(1, 123)
Setup used to run this example
def epoll(ns):
    '''A ring, `epfd` (an epoll instance) and `fd` (the read end of a pipe with data in it).'''
    make_ring(ns)
    ns['epfd'] = keep(ns, select.epoll()).fileno()
    r, w = os.pipe()
    os.write(w, b'x')
    ns['fd'] = r

property events: int#

The event mask (EPOLLIN, ...) of the event.

property data: int#

The user data of the event.

class Statx()#

Statx - Structures for the extended file attribute retrieval system call statx().

Example

>>> stat = Statx()
>>> if sqe := io_uring_get_sqe(ring):
...     io_uring_prep_statx(sqe, stat, 'file.txt')
...
True
>>> io_uring_submit_and_wait(ring, 1)  # submit and wait for the completion
1
>>> stat.isfile
True
>>> stat.size
10
Setup used to run this example
    'Sqe', 'put_sqe', 'io_uring_prep_open', 'io_uring_prep_open_direct', 'io_uring_prep_read', 'io_uring_prep_write',
    'io_uring_prep_statx', 'Statx', 'io_uring_register_files', 'io_uring_register_files_tags',
)  # fmt: skip
def file_ring(ns):
    '''A ring (2 entries for `put_sqe`, to show a full one), an empty `cqe` and `fd` of `./file.txt`
    (`hi... bye!`).'''
    make_ring(ns, entries=2 if ns['_name'] == 'put_sqe' else 1024)
    ns['cqe'] = Cqe()
    make_file(ns)

Note

property mask: int#

STATX_* bits of the fields the kernel filled in (what was asked for, less what the file system does not have, plus what came for free).

property blksize: int#

Preferred I/O block size, in bytes.

property attributes: int#

STATX_ATTR_* attributes of the file (STATX_ATTR_IMMUTABLE, STATX_ATTR_ENCRYPTED, ...): only the bits set in attributes_mask mean anything.

property uid: int#

Owner's user id (STATX_UID).

property gid: int#

Owner's group id (STATX_GID).

property mode: int#

File type (mode & S_IFMT, STATX_TYPE) and permission bits (mode & ~S_IFMT: S_IRUSR, S_ISUID, ..., STATX_MODE).

property ino: int#

Inode number (STATX_INO).

property size: int#

Size in bytes (STATX_SIZE); for a symbolic link the length of its target.

property blocks: int#

Number of 512-byte blocks allocated (STATX_BLOCKS).

property attributes_mask: int#

Which STATX_ATTR_* bits of attributes the file system supports.

property rdev_major: int#

Major number of the device a character or block device file (ischr / isblk) stands for.

property rdev_minor: int#

Minor number of the device a character or block device file stands for.

property dev_major: int#

Major number of the device the file lives on.

property dev_minor: int#

Minor number of the device the file lives on.

property mnt_id: int#

Id of the mount the file is on (STATX_MNT_ID, Linux 5.8+), as in /proc/self/mountinfo.

property dio_mem_align: int#

Memory alignment O_DIRECT I/O on the file needs, in bytes (STATX_DIOALIGN, Linux 6.1+); 0 when the file does not support direct I/O.

property atime: float#

Last access, seconds since the epoch as float (STATX_ATIME).

property btime: float#

Creation (birth) time as float (STATX_BTIME; 0.0 where the file system does not keep it).

property ctime: float#

Last status (inode) change as float (STATX_CTIME).

property mtime: float#

Last modification of the contents as float (STATX_MTIME).

property isfile: bool#

Same as isreg: a regular file.

property isreg: bool#

A regular file.

property isdir: bool#

A directory.

property ischr: bool#

A character device (rdev_major / rdev_minor name it).

property isblk: bool#

A block device (rdev_major / rdev_minor name it).

property isfifo: bool#

A FIFO (named pipe).

property issock: bool#

A socket.

class FUTEX#

One futex of a Futex: futex[i], or the Futex itself (its first one).

Example

>>> futex = Futex(2)
>>> futex[1].state = 5
>>> futex[1].state
5

Note

  • val and flags are the futex_waitv entry's, only for a Futex made with vector=True (MemoryError otherwise).

property state: int#

The futex's value (a u32).

property val: int#

The value the futex_waitv entry expects: the wait sleeps only while the futex still holds it (a different value when the request starts completes it with OSError: EAGAIN at once).

property flags: int#

The futex_waitv entry's FUTEX2_* flags (FUTEX2_SIZE_U32, | FUTEX2_PRIVATE for a futex shared by threads of one process only).

class Futex(no=None, flags=None, vector=None)#

Subclass of FUTEX.

Futex State - User Address Memory

Type

no int
flags int
vector bool
return None

Example #1

>>> futex = Futex()
>>> futex.state
0
>>> futex.private
False
>>> io_uring_prep_futex_wait(sqe, futex, 0, FUTEX_BITSET_MATCH_ANY, FUTEX2_SIZE_U32)
True
>>> futex.state = 1
>>> io_uring_prep_futex_wake(sqe, futex, 1, FUTEX_BITSET_MATCH_ANY, FUTEX2_SIZE_U32)
True
Setup used to run this example
    'io_uring_sqe_set_data64', 'io_uring_sqe_set_flags', 'io_uring_sqe_set_buf_group',
    'io_uring_prep_nop', 'io_uring_prep_provide_buffers', 'Futex', 'timespec',
)  # fmt: skip
def sqe(ns):
    ns['sqe'] = io_uring_get_sqe(make_ring(ns))

Example #2

# a vector of futexes, for `io_uring_prep_futex_waitv`
>>> fwv = Futex(1, None, True)  # `vector=True`
>>> io_uring_prep_futex_waitv(sqe, fwv)
True

Example #3

# a process-private futex
>>> futex = Futex(2, FUTEX2_PRIVATE | FUTEX2_SIZE_U32)
>>> futex.private
True

Flags

Note

property private: bool#

Whether it was made with FUTEX2_PRIVATE (read only).

trap_error(errno: int) -> int#

Trap Error: errno as is when it is >= 0, else raises the OSError for -errno.

Type

Example

>>> trap_error(1)
1

>>> trap_error(-11)
BlockingIOError: [Errno 11] Resource temporarily unavailable

>>> trap_error(-1)
PermissionError: [Errno 1] Operation not permitted

Note

  • any errno >= 0 is considered safe and is returned.
  • the C errno variable is not looked at: -1 raises PermissionError (EPERM), as -N raises errno N.

timespec(second: float) -> Timespec#

Type

second float
return Timespec

Example

>>> ts = timespec(1)        # int
>>> ts = timespec(1.5)      # float
>>> io_uring_prep_timeout(sqe, ts, 0)
True
Setup used to run this example
    'io_uring_sqe_set_data64', 'io_uring_sqe_set_flags', 'io_uring_sqe_set_buf_group',
    'io_uring_prep_nop', 'io_uring_prep_provide_buffers', 'Futex', 'timespec',
)  # fmt: skip
def sqe(ns):
    ns['sqe'] = io_uring_get_sqe(make_ring(ns))

Note

  • ValueError if second is negative, nan or inf; OverflowError if too large.
Generated by tools/setu_docs.py from the docstrings of Liburing 2026.10.29 (CPython 3.14+).