Each buffer starts with an io_uring_recvmsg_out header, then the name (namelen bytes), the control data (controllen bytes) and the payload: cqe.res counts all of it.
Check cqe.flags of every completion, whatever cqe.res: one without IORING_CQE_F_MORE (an OSError, OSError: ENOBUFS when the group runs out, a cancel) ends the request; submit a new one to keep receiving.
Accepts a connection on the listening socket fd (accept4); cqe.res is the new fd. addr (optional) gets the peer address at the completion and is held until then.
Like io_uring_prep_accept, but the connection goes into a direct (registered) descriptor.
Note
Function argument file_index position has changed for C origin for better usability.
If file_index is None (or IORING_FILE_INDEX_ALLOC) a free direct descriptor will be auto assigned. The allocated descriptor is returned in the cqe.res; OSError: ENFILE when the table has no free slot.
With an explicit file_indexcqe.res is 0: remember the slot. A slot already holding a file has it closed and replaced.
Accepts connections repeatedly, one completion per connection (cqe.res is the new fd); addr (optional) gets the peer address.
Note
Linux 5.19+.
Same as io_uring_prep_accept, but keeps going while IORING_CQE_F_MORE is set; a completion without it (an error, a cancel) ends the request, submit a new one to keep accepting.
Every connection overwrites addr, possibly before the last one was read: usually leave it None.
Like io_uring_prep_multishot_accept, but each connection goes into a free direct (registered) descriptor, returned in cqe.res.
Note
Linux 5.19+.
Needs a registered file table first (io_uring_register_files_sparse); OSError: ENFILE ends the request when it has no free slot. SOCK_CLOEXEC in flags gives OSError: EINVAL.
Needs IOSQE_BUFFER_SELECT and the group of a buffer ring (io_uring_sqe_set_buf_group): sends from it until it runs out of buffers, which also serializes sends in flight on one socket.
One completion: cqe.res is the total number of bytes sent, cqe.flags >> IORING_CQE_BUFFER_SHIFT the first buffer id; the rest follow it in ring order until cqe.res bytes are covered.
Sends buf to the address addr (sendto, UDP); cqe.res is the number of bytes sent. addr and buf are held until the completion.
Note
Function arguments position has changed for C origin for better usability.
addr must suit the socket's family.
io_uring_prep_send_zc(sqe: SQE, sockfd: int, buf: Buffer, flags: int | None = None, zc_flags: int | None = None) -> bool#
Zero-copy send of buf; zc_flags are IORING_RECVSEND_* flags. Completes twice: the result, then a notification (IORING_CQE_F_NOTIF) once buf can be reused.
Note
Linux 6.0+.
The first completion is the usual one: cqe.res is the number of bytes sent (OSError on failure), and IORING_CQE_F_MORE in cqe.flags says the notification follows (also after a failure: check the flag first). The notification has the same user_data, cqe.res0 and IORING_CQE_F_NOTIF.
Do not change buf before the notification; the ring holds it (locked: no resize) until then. A notification says nothing about the data having been sent or received.
Zero copy is not guaranteed; OSError: EOPNOTSUPP means the protocol has none, use io_uring_prep_send.
Zero-copy io_uring_prep_sendmsg: completes twice, the result then a notification (IORING_CQE_F_NOTIF) once the buffers can be reused. msg is held until the completion.
Note
Linux 6.1+.
The completions are those of io_uring_prep_send_zc: IORING_CQE_F_MORE on the first means the notification follows; do not change the iov buffers of msg before it.
OSError: ENOMEM can mean a too low locked memory limit (ulimit -l).
Receives into buf from the socket sockfd (recv); cqe.res is the number of bytes received.
Note
Linux 5.6+.
buf may be None when the buffer comes from a provided buffer group (IOSQE_BUFFER_SELECT): then cqe.flags has IORING_CQE_F_BUFFER and the buffer id in cqe.flags >> IORING_CQE_BUFFER_SHIFT.
buf is held (locked: no resize) until the completion.
cqe.flags has IORING_CQE_F_SOCK_NONEMPTY (Linux 5.19+) when the socket still had data after the receive.
buf is normally None: the buffers come from a provided buffer group (IOSQE_BUFFER_SELECT and io_uring_sqe_set_buf_group, required), one per completion (IORING_CQE_F_BUFFER, the id in cqe.flags >> IORING_CQE_BUFFER_SHIFT). A buf only caps each receive at len(buf) bytes (fairness between many sockets). MSG_WAITALL is not allowed.
Check cqe.flags of every completion, whatever cqe.res: one without IORING_CQE_F_MORE (an OSError, the peer closing, OSError: ENOBUFS when the group runs out, a cancel) ends the request; submit a new one to keep receiving. Return used buffers to the ring promptly.
Shuts down part of a full-duplex connection (shutdown); how is SHUT_RD, SHUT_WR or SHUT_RDWR. cqe.res is 0.
Note
Linux 5.11+.
io_uring_prep_socket(sqe: SQE, domain: int, type: int, protocol: int | None = None, flags: int | None = None) -> bool#
Creates a socket (socket); cqe.res is the new fd. protocol and flags default to 0.
Note
Linux 5.19+.
flags is unused by the kernel so far (the SOCK_* type flags go into type).
io_uring_prep_socket_direct(sqe: SQE, domain: int, type: int, protocol: int | None = None, file_index: int | None = None, flags: int | None = None) -> bool#
Creates a socket into a direct (registered) descriptor. protocol and flags default to 0.
Note
Linux 5.19+.
io_uring_prep_socket_direct includes io_uring_prep_socket_direct_alloc feature: file_index=None (or IORING_FILE_INDEX_ALLOC) assigns a free direct descriptor, returned in cqe.res; OSError: ENFILE when the table has no free slot.
With an explicit file_indexcqe.res is 0. A slot already holding a file has it closed and replaced.
Linux 6.7+ (SOCKET_URING_OP_SIOCINQ, SOCKET_URING_OP_SIOCOUTQ, SOCKET_URING_OP_GETSOCKOPT, SOCKET_URING_OP_SETSOCKOPT); SOCKET_URING_OP_TX_TIMESTAMP 6.17+; SOCKET_URING_OP_GETSOCKNAME 6.19+.
optval is held (locked: no resize) until the completion.
SOCKET_URING_OP_SIOCINQ / SOCKET_URING_OP_SIOCOUTQ: cqe.res is the number of unread / unsent bytes queued (OSError: EINVAL on a listening socket); level, optname and optval are ignored.
SOCKET_URING_OP_GETSOCKOPT: SOL_SOCKET options only; the option is written into optval and cqe.res is its size. SOCKET_URING_OP_SETSOCKOPT: cqe.res is 0.
SOCKET_URING_OP_GETSOCKNAME: the bound address is written into optval (truncated if too short) and cqe.res is its full size; see io_uring_prep_cmd_getsockname.
SOCKET_URING_OP_TX_TIMESTAMP: multishot (IORING_CQE_F_MORE), one completion per transmit timestamp of a socket set up with SO_TIMESTAMPING; the ring needs IORING_SETUP_CQE32 or IORING_SETUP_CQE_MIXED (the timestamp is in cqe.big_cqe), cqe.res is the timestamp key (TCP: byte offset, UDP: packet count) and the upper bits of cqe.flags the type; the last completion (no IORING_CQE_F_MORE) has cqe.res0 or raises the OSError.
The kernel checks len(optval) for the option (an int option needs 4 bytes, else OSError: EINVAL).
optval is raw bytes in the host's byte order: int.to_bytes(4, sys.byteorder) for an int option.
Gets the local address of fd (peer=0, the default) or of its peer (peer=1) into sockaddr, written at the completion (getsockname / getpeername); sockaddr is held until then.