diff options
author | Andy Fiddaman <omnios@citrus-it.co.uk> | 2021-08-06 11:44:02 +0000 |
---|---|---|
committer | Andy Fiddaman <omnios@citrus-it.co.uk> | 2021-09-15 15:13:18 +0000 |
commit | d7159b37699523966f5e7af69b1bd84e2a084fa4 (patch) | |
tree | be8dd25136fb31328c6dfeff6d25adf65ce58343 | |
parent | 74e3b2c76b52940c79c5399e1c9c91a35b2b0c16 (diff) | |
download | illumos-joyent-d7159b37699523966f5e7af69b1bd84e2a084fa4.tar.gz |
14005 eventfd_read/write() don't return failure
Reviewed by: Robert Mustacchi <rm@fingolfin.org>
Reviewed by: Dan McDonald <danmcd@joyent.com>
Approved by: Robert Mustacchi <rm@fingolfin.org>
-rw-r--r-- | usr/src/lib/libc/port/sys/eventfd.c | 11 | ||||
-rw-r--r-- | usr/src/pkg/manifests/system-test-ostest.mf | 4 | ||||
-rw-r--r-- | usr/src/test/os-tests/runfiles/default.run | 5 | ||||
-rw-r--r-- | usr/src/test/os-tests/tests/Makefile | 2 | ||||
-rw-r--r-- | usr/src/test/os-tests/tests/eventfd.c | 140 |
5 files changed, 158 insertions, 4 deletions
diff --git a/usr/src/lib/libc/port/sys/eventfd.c b/usr/src/lib/libc/port/sys/eventfd.c index f165491cc1..d0d42e8f74 100644 --- a/usr/src/lib/libc/port/sys/eventfd.c +++ b/usr/src/lib/libc/port/sys/eventfd.c @@ -11,6 +11,7 @@ /* * Copyright (c) 2015, Joyent, Inc. All rights reserved. + * Copyright 2021 OmniOS Community Edition (OmniOSce) Association. */ #include <sys/eventfd.h> @@ -57,11 +58,17 @@ eventfd(unsigned int initval, int flags) int eventfd_read(int fd, eventfd_t *valp) { - return (read(fd, valp, sizeof (*valp)) < sizeof (*valp) ? -1 : 0); + ssize_t ret = read(fd, valp, sizeof (*valp)); + if (ret == -1 || (size_t)ret < sizeof (*valp)) + return (-1); + return (0); } int eventfd_write(int fd, eventfd_t val) { - return (write(fd, &val, sizeof (val)) < sizeof (val) ? -1 : 0); + ssize_t ret = write(fd, &val, sizeof (val)); + if (ret == -1 || (size_t)ret < sizeof (val)) + return (-1); + return (0); } diff --git a/usr/src/pkg/manifests/system-test-ostest.mf b/usr/src/pkg/manifests/system-test-ostest.mf index 596c19fb5d..e929737c68 100644 --- a/usr/src/pkg/manifests/system-test-ostest.mf +++ b/usr/src/pkg/manifests/system-test-ostest.mf @@ -13,7 +13,7 @@ # Copyright (c) 2012, 2016 by Delphix. All rights reserved. # Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved. # Copyright 2020 Joyent, Inc. -# Copyright 2020 OmniOS Community Edition (OmniOSce) Association. +# Copyright 2021 OmniOS Community Edition (OmniOSce) Association. # Copyright 2021 Tintri by DDN, Inc. All rights reserved. # @@ -53,6 +53,8 @@ file path=opt/os-tests/tests/ddi_ufm/ufm-test mode=0555 file path=opt/os-tests/tests/ddi_ufm/ufm-test-cleanup mode=0555 file path=opt/os-tests/tests/ddi_ufm/ufm-test-setup mode=0555 file path=opt/os-tests/tests/epoll_test mode=0555 +file path=opt/os-tests/tests/eventfd.32 mode=0555 +file path=opt/os-tests/tests/eventfd.64 mode=0555 file path=opt/os-tests/tests/file-locking/acquire-lock.32 mode=0555 file path=opt/os-tests/tests/file-locking/acquire-lock.64 mode=0555 file path=opt/os-tests/tests/file-locking/runtests.32 mode=0555 diff --git a/usr/src/test/os-tests/runfiles/default.run b/usr/src/test/os-tests/runfiles/default.run index e7b44684db..ecc3134fe5 100644 --- a/usr/src/test/os-tests/runfiles/default.run +++ b/usr/src/test/os-tests/runfiles/default.run @@ -12,7 +12,7 @@ # # Copyright (c) 2012 by Delphix. All rights reserved. # Copyright 2020 Joyent, Inc. -# Copyright 2020 OmniOS Community Edition (OmniOSce) Association. +# Copyright 2021 OmniOS Community Edition (OmniOSce) Association. # Copyright 2021 Tintri by DDN, Inc. All rights reserved. # @@ -28,6 +28,9 @@ outputdir = /var/tmp/test_results user = root tests = ['poll_test', 'epoll_test'] +[/opt/os-tests/tests/eventfd.32] +[/opt/os-tests/tests/eventfd.64] + [/opt/os-tests/tests/odirectory.32] [/opt/os-tests/tests/odirectory.64] diff --git a/usr/src/test/os-tests/tests/Makefile b/usr/src/test/os-tests/tests/Makefile index 2783408243..c2c8b9046d 100644 --- a/usr/src/test/os-tests/tests/Makefile +++ b/usr/src/test/os-tests/tests/Makefile @@ -13,6 +13,7 @@ # Copyright (c) 2012, 2016 by Delphix. All rights reserved. # Copyright 2020 Joyent, Inc. # Copyright 2021 Tintri by DDN, Inc. All rights reserved. +# Copyright 2021 OmniOS Community Edition (OmniOSce) Association. # SUBDIRS_i386 = i386 imc @@ -37,6 +38,7 @@ SUBDIRS = \ $(SUBDIRS_$(MACH)) PROGS = \ + eventfd \ odirectory \ writev diff --git a/usr/src/test/os-tests/tests/eventfd.c b/usr/src/test/os-tests/tests/eventfd.c new file mode 100644 index 0000000000..bb6ab7dc7d --- /dev/null +++ b/usr/src/test/os-tests/tests/eventfd.c @@ -0,0 +1,140 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2021 OmniOS Community Edition (OmniOSce) Association. + */ + +#include <err.h> +#include <errno.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/debug.h> +#include <sys/eventfd.h> +#include <unistd.h> + +static int +readn(int fd, uint_t n) +{ + uint_t i; + int failures = 0; + + for (i = 0; i < n; i++) { + eventfd_t v = 0xdeadbeef; + int ret; + + ret = eventfd_read(fd, &v); + if (ret != 0) { + warn("Reading %u/%u got ret %d (expected 0)", + i + 1, n, ret); + failures++; + } else if (v != 1) { + warnx("Reading %u/%u got value %"PRIu64" (expected 1)", + i + 1, n, v); + failures++; + } + } + + return (failures); +} + +static int +check_nosem(int fd) +{ + eventfd_t v = 0xdeadbeef; + int failures = 0; + int ret; + + ret = eventfd_read(fd, &v); + + if (ret != -1) { + warnx("no semaphores read got ret %d (expected -1)", ret); + failures++; + } + + if (errno != EAGAIN) { + warn("no semaphores read expected EAGAIN but got"); + failures++; + } + + if (v != 0xdeadbeef) { + warnx("no semaphores read modified value to %"PRIx64, v); + failures++; + } + + return (failures); +} + +static int +check_badwrite(int fd) +{ + int failures = 0; + int ret; + + ret = eventfd_write(fd, ULLONG_MAX); + + if (ret != -1) { + warnx("bad write got ret %d (expected -1)", ret); + failures++; + } + + if (errno != EINVAL) { + warn("bad write expected EINVAL but got"); + failures++; + } + + return (failures); +} + +int +main(void) +{ + int fd, failures = 0; + + /* Test eventfd semaphore semantics */ + fd = eventfd(2, EFD_NONBLOCK | EFD_CLOEXEC | EFD_SEMAPHORE); + if (fd == -1) + err(EXIT_FAILURE, "Could not create eventfd semaphore"); + + /* Consume the available semaphores */ + failures += readn(fd, 2); + + /* The next read should return -1/EAGAIN */ + failures += check_nosem(fd); + + /* Return two + three semaphores */ + if (eventfd_write(fd, 2) != 0) { + warn("Error while returning two semaphores"); + failures++; + } + if (eventfd_write(fd, 3) != 0) { + warn("Error while returning three semaphores"); + failures++; + } + + /* Consume the available semaphores */ + failures += readn(fd, 5); + + /* The next read should return -1/EAGAIN */ + failures += check_nosem(fd); + + /* + * Check that a writing too large a value results in an error from + * eventfd_write() - testing that an error from the underlying write() + * is passed back. + */ + failures += check_badwrite(fd); + + VERIFY0(close(fd)); + + return (failures == 0 ? EXIT_SUCCESS : EXIT_FAILURE); +} |