This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 4cec5015847f8f6edde9eb35fa585d3e5421af3e Author: Xiang Xiao <[email protected]> AuthorDate: Fri Sep 11 02:22:19 2026 +0800 fs/aio: fix aio_read/aio_write return values per POSIX Per POSIX, aio_read() and aio_write() must return -1 and set errno to EINVAL when the request cannot be queued (aio_reqprio < 0, aio_offset < 0), and the error must also be retrievable via aio_error(). Conversely, when queuing fails with a bad file descriptor, the error belongs to the asynchronous operation: the functions must return 0 and report EBADF through aio_error(). - Merge the offset/reqprio checks and return ERROR with errno set, after storing the result in aio_result for aio_error(). - Drop the aio_fildes < 0 early return: a closed descriptor is now caught by fcntl()/aio_queue() and reported through aio_result with the function returning OK. - aio_error(): report -EINVAL (failed validation) through errno instead of returning it as an error value. Signed-off-by: tengshuangshuang <[email protected]> --- fs/aio/aio_read.c | 27 ++++++--------------------- fs/aio/aio_write.c | 26 +++++--------------------- libs/libc/aio/aio_error.c | 11 +++++++++++ 3 files changed, 22 insertions(+), 42 deletions(-) diff --git a/fs/aio/aio_read.c b/fs/aio/aio_read.c index 88d541556c7..670784d4301 100644 --- a/fs/aio/aio_read.c +++ b/fs/aio/aio_read.c @@ -222,32 +222,17 @@ int aio_read(FAR struct aiocb *aiocbp) DEBUGASSERT(aiocbp); - if (aiocbp->aio_reqprio < 0) - { - set_errno(EINVAL); - return ERROR; - } - - if (aiocbp->aio_fildes < 0) - { - /* the EBADF should be collected by aio_error(), we need return OK at - * here - */ - - aiocbp->aio_result = -EBADF; - return OK; - } - /* for aio_read, the aio_offset should be large or equal than 0 */ - if (aiocbp->aio_offset < 0) + if (aiocbp->aio_offset < 0 || aiocbp->aio_reqprio < 0) { - /* the EINVAL should be collected by aio_error(), we need to return OK - * here + /* the EINVAL should be collected by aio_error(), we need to return + * ERROR here */ aiocbp->aio_result = -EINVAL; - return OK; + set_errno(EINVAL); + return ERROR; } /* The result -EINPROGRESS means that the transfer has not yet completed */ @@ -265,7 +250,7 @@ int aio_read(FAR struct aiocb *aiocbp) /* The errno has already been set (probably EBADF) */ aiocbp->aio_result = -get_errno(); - return ERROR; + return OK; } /* Defer the work to the worker thread */ diff --git a/fs/aio/aio_write.c b/fs/aio/aio_write.c index 6c5b3f37dcf..7c2b425a125 100644 --- a/fs/aio/aio_write.c +++ b/fs/aio/aio_write.c @@ -253,35 +253,19 @@ int aio_write(FAR struct aiocb *aiocbp) DEBUGASSERT(aiocbp); - if (aiocbp->aio_reqprio < 0) + if (aiocbp->aio_offset < 0 || aiocbp->aio_reqprio < 0) { + aiocbp->aio_result = -EINVAL; set_errno(EINVAL); return ERROR; } - if (aiocbp->aio_offset < 0) - { - aiocbp->aio_result = -EINVAL; - return OK; - } - - if (aiocbp->aio_fildes < 0) - { - /* for EBADF, the aio_write do not return error directly, but using - * aio_error to return this error code - */ - - aiocbp->aio_result = -EBADF; - return OK; - } - /* the aio_fildes that transferred in may be opened with O_RDONLY, for this - * case, we need to return OK directly, and using the aio_error to collect - * the EBADF error code + * case, we need to return OK directly, and set the EBADF error code */ flags = fcntl(aiocbp->aio_fildes, F_GETFL); - if ((flags & O_ACCMODE) == O_RDONLY) + if (flags == ERROR || (flags & O_ACCMODE) == O_RDONLY) { aiocbp->aio_result = -EBADF; return OK; @@ -302,7 +286,7 @@ int aio_write(FAR struct aiocb *aiocbp) /* The errno has already been set (probably EBADF) */ aiocbp->aio_result = -get_errno(); - return ERROR; + return OK; } /* Defer the work to the worker thread */ diff --git a/libs/libc/aio/aio_error.c b/libs/libc/aio/aio_error.c index 8f3a856b22e..dced059ba87 100644 --- a/libs/libc/aio/aio_error.c +++ b/libs/libc/aio/aio_error.c @@ -98,6 +98,17 @@ int aio_error(FAR const struct aiocb *aiocbp) return EINVAL; } + if (aiocbp->aio_offset < 0) + { + return -aiocbp->aio_result; + } + + if (aiocbp->aio_result == -EINVAL) + { + set_errno(EINVAL); + return ERROR; + } + if (aiocbp->aio_result < 0) { return -aiocbp->aio_result;
