From 14a7800cd14c6617fbd529e3b110dd6565808280 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Mon, 15 Jun 2026 20:06:14 +0800 Subject: [PATCH] man: document that send/recv honor the socket's O_NONBLOCK io_uring normally arms internal poll and reissues a send/recv once the socket is ready, so the request returns -EAGAIN only when the operation is non-blocking: MSG_DONTWAIT set in the request flags, or an O_NONBLOCK socket. send(2) and recv(2) treat the two equivalently, and io_uring completes the request with -EAGAIN just as the syscall would. Document this in the ERRORS section of the send, sendmsg, recv and recvmsg prep pages. Signed-off-by: Kefu Chai --- man/io_uring_prep_recv.3 | 23 ++++++++++++++++++++++- man/io_uring_prep_recvmsg.3 | 25 ++++++++++++++++++++++++- man/io_uring_prep_send.3 | 23 ++++++++++++++++++++++- man/io_uring_prep_sendmsg.3 | 22 ++++++++++++++++++++++ 4 files changed, 90 insertions(+), 3 deletions(-) diff --git a/man/io_uring_prep_recv.3 b/man/io_uring_prep_recv.3 index 509b35523..81218e593 100644 --- a/man/io_uring_prep_recv.3 +++ b/man/io_uring_prep_recv.3 @@ -135,7 +135,28 @@ Instead it returns the negated .I errno directly in the CQE .I res -field. +field. Some common error cases are: +.TP +.B -EAGAIN +The operation would have blocked. io_uring normally arms internal poll and +reissues the request once the socket is ready, so this does not occur for a +socket in blocking mode. It is returned when the operation is non-blocking and +cannot complete immediately, that is when +.B MSG_DONTWAIT +was set in the +.I flags +argument or the socket is marked +.BR O_NONBLOCK ; +.BR recv (2) +treats the two equivalently. To have io_uring poll and retry instead, do not +mark the socket +.B O_NONBLOCK +and do not set +.BR MSG_DONTWAIT . +Otherwise treat +.B -EAGAIN +as transient and reissue the request. +.P .SH NOTES Despite accepting a size_t number of bytes, these functions can transfer at most INT_MAX bytes per call (the maximum for the underlying syscall interface). diff --git a/man/io_uring_prep_recvmsg.3 b/man/io_uring_prep_recvmsg.3 index 74a0c9ef3..b06cdeebc 100644 --- a/man/io_uring_prep_recvmsg.3 +++ b/man/io_uring_prep_recvmsg.3 @@ -107,7 +107,30 @@ Instead it returns the negated .I errno directly in the CQE .I res -field. +field. Some common error cases are: +.TP +.B -EAGAIN +The operation would have blocked. io_uring normally arms internal poll and +reissues the request once the socket is ready, so this does not occur for a +socket in blocking mode. It is returned when the operation is non-blocking and +cannot complete immediately, that is when +.B MSG_DONTWAIT +was set in the +.I msg_flags +of the +.I msghdr +argument or the socket is marked +.BR O_NONBLOCK ; +.BR recv (2) +treats the two equivalently. To have io_uring poll and retry instead, do not +mark the socket +.B O_NONBLOCK +and do not set +.BR MSG_DONTWAIT . +Otherwise treat +.B -EAGAIN +as transient and reissue the request. +.P .SH NOTES As with any request that passes in data in a struct, that data must remain valid until the request has been successfully submitted. It need not remain diff --git a/man/io_uring_prep_send.3 b/man/io_uring_prep_send.3 index f4470528e..0ea43ff70 100644 --- a/man/io_uring_prep_send.3 +++ b/man/io_uring_prep_send.3 @@ -184,7 +184,28 @@ Instead it returns the negated .I errno directly in the CQE .I res -field. +field. Some common error cases are: +.TP +.B -EAGAIN +The operation would have blocked. io_uring normally arms internal poll and +reissues the request once the socket is ready, so this does not occur for a +socket in blocking mode. It is returned when the operation is non-blocking and +cannot complete immediately, that is when +.B MSG_DONTWAIT +was set in the +.I flags +argument or the socket is marked +.BR O_NONBLOCK ; +.BR send (2) +treats the two equivalently. To have io_uring poll and retry instead, do not +mark the socket +.B O_NONBLOCK +and do not set +.BR MSG_DONTWAIT . +Otherwise treat +.B -EAGAIN +as transient and reissue the request. +.P .SH NOTES Despite accepting a size_t number of bytes, these functions can transfer at most INT_MAX bytes per call (the maximum for the underlying syscall interface). diff --git a/man/io_uring_prep_sendmsg.3 b/man/io_uring_prep_sendmsg.3 index 7bb7a5341..39b1ea4ef 100644 --- a/man/io_uring_prep_sendmsg.3 +++ b/man/io_uring_prep_sendmsg.3 @@ -105,6 +105,28 @@ directly in the CQE .I res field. Some common error cases are: .TP +.B -EAGAIN +The operation would have blocked. io_uring normally arms internal poll and +reissues the request once the socket is ready, so this does not occur for a +socket in blocking mode. It is returned when the operation is non-blocking and +cannot complete immediately, that is when +.B MSG_DONTWAIT +was set in the +.I msg_flags +of the +.I msghdr +argument or the socket is marked +.BR O_NONBLOCK ; +.BR send (2) +treats the two equivalently. To have io_uring poll and retry instead, do not +mark the socket +.B O_NONBLOCK +and do not set +.BR MSG_DONTWAIT . +Otherwise treat +.B -EAGAIN +as transient and reissue the request. +.TP .B -ENOMEM The .BR ulimit (1)