summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Fiddaman <omnios@citrus-it.co.uk>2021-08-06 11:44:02 +0000
committerAndy Fiddaman <omnios@citrus-it.co.uk>2021-09-15 15:13:18 +0000
commitd7159b37699523966f5e7af69b1bd84e2a084fa4 (patch)
treebe8dd25136fb31328c6dfeff6d25adf65ce58343
parent74e3b2c76b52940c79c5399e1c9c91a35b2b0c16 (diff)
downloadillumos-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.c11
-rw-r--r--usr/src/pkg/manifests/system-test-ostest.mf4
-rw-r--r--usr/src/test/os-tests/runfiles/default.run5
-rw-r--r--usr/src/test/os-tests/tests/Makefile2
-rw-r--r--usr/src/test/os-tests/tests/eventfd.c140
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);
+}