diff options
author | jhb <jhb@FreeBSD.org> | 2016-07-25 15:56:37 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2016-07-25 15:56:37 +0000 |
commit | 8260830da87c9b81593b28fb3822aced3233660b (patch) | |
tree | 18079c6d79a125256237f9bfe47f96ea1663c58b /lib | |
parent | 8925d1cf89b69ae37c22a7e4dceb2848732b3d62 (diff) | |
download | FreeBSD-src-8260830da87c9b81593b28fb3822aced3233660b.zip FreeBSD-src-8260830da87c9b81593b28fb3822aced3233660b.tar.gz |
MFC 302860: Fix aio system call wrappers in librt.
- Update aio_return/waitcomplete wrappers for the ssize_t return type.
- Fix the aio_return() wrapper to fail with EINVAL on a pending job.
This matches the semantics of the in-kernel system call. Also,
aio_return() returns errors via errno, not via the return value.
Approved by: re (gjb)
Sponsored by: Chelsio Communications
Diffstat (limited to 'lib')
-rw-r--r-- | lib/librt/aio.c | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/lib/librt/aio.c b/lib/librt/aio.c index 25d7662..fe4a118 100644 --- a/lib/librt/aio.c +++ b/lib/librt/aio.c @@ -54,8 +54,8 @@ typedef void (*aio_func)(union sigval val, struct aiocb *iocb); extern int __sys_aio_read(struct aiocb *iocb); extern int __sys_aio_write(struct aiocb *iocb); -extern int __sys_aio_waitcomplete(struct aiocb **iocbp, struct timespec *timeout); -extern int __sys_aio_return(struct aiocb *iocb); +extern ssize_t __sys_aio_waitcomplete(struct aiocb **iocbp, struct timespec *timeout); +extern ssize_t __sys_aio_return(struct aiocb *iocb); extern int __sys_aio_error(struct aiocb *iocb); extern int __sys_aio_fsync(int op, struct aiocb *iocb); @@ -136,12 +136,13 @@ __aio_write(struct aiocb *iocb) return aio_io(iocb, &__sys_aio_write); } -int +ssize_t __aio_waitcomplete(struct aiocb **iocbp, struct timespec *timeout) { + ssize_t ret; int err; - int ret = __sys_aio_waitcomplete(iocbp, timeout); + ret = __sys_aio_waitcomplete(iocbp, timeout); if (*iocbp) { if ((*iocbp)->aio_sigevent.sigev_notify == SIGEV_THREAD) { err = errno; @@ -155,13 +156,20 @@ __aio_waitcomplete(struct aiocb **iocbp, struct timespec *timeout) return (ret); } -int +ssize_t __aio_return(struct aiocb *iocb) { if (iocb->aio_sigevent.sigev_notify == SIGEV_THREAD) { - if (__sys_aio_error(iocb) == EINPROGRESS) - return (EINPROGRESS); + if (__sys_aio_error(iocb) == EINPROGRESS) { + /* + * Fail with EINVAL to match the semantics of + * __sys_aio_return() for an in-progress + * request. + */ + errno = EINVAL; + return (-1); + } __sigev_list_lock(); __sigev_delete(SI_ASYNCIO, (sigev_id_t)iocb); __sigev_list_unlock(); |