Module Name: src
Committed By: thorpej
Date: Thu Feb 17 16:28:29 UTC 2022
Modified Files:
src/sys/kern: sys_eventfd.c sys_timerfd.c
Log Message:
Implement eventfd_ioctl() and handle FIONBIO so that fcntl(O_NONBLOCK)
works. While here, also implement FIONREAD and FIONWRITE, and document
why we don't implement FIONSPACE.
Also implement FIONBIO and FIONREAD for in timerfd_ioctl() (for the same
reason).
PR kern/56718
To generate a diff of this commit:
cvs rdiff -u -r1.8 -r1.9 src/sys/kern/sys_eventfd.c
cvs rdiff -u -r1.7 -r1.8 src/sys/kern/sys_timerfd.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/kern/sys_eventfd.c
diff -u src/sys/kern/sys_eventfd.c:1.8 src/sys/kern/sys_eventfd.c:1.9
--- src/sys/kern/sys_eventfd.c:1.8 Wed Nov 24 16:35:33 2021
+++ src/sys/kern/sys_eventfd.c Thu Feb 17 16:28:29 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: sys_eventfd.c,v 1.8 2021/11/24 16:35:33 thorpej Exp $ */
+/* $NetBSD: sys_eventfd.c,v 1.9 2022/02/17 16:28:29 thorpej Exp $ */
/*-
* Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_eventfd.c,v 1.8 2021/11/24 16:35:33 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_eventfd.c,v 1.9 2022/02/17 16:28:29 thorpej Exp $");
/*
* eventfd
@@ -310,6 +310,39 @@ eventfd_fop_write(file_t * const fp, off
}
static int
+eventfd_ioctl(file_t * const fp, u_long const cmd, void * const data)
+{
+ struct eventfd * const efd = fp->f_eventfd;
+
+ switch (cmd) {
+ case FIONBIO:
+ return 0;
+
+ case FIONREAD:
+ mutex_enter(&efd->efd_lock);
+ *(int *)data = efd->efd_val != 0 ? sizeof(eventfd_t) : 0;
+ mutex_exit(&efd->efd_lock);
+ return 0;
+
+ case FIONWRITE:
+ *(int *)data = 0;
+ return 0;
+
+ case FIONSPACE:
+ /*
+ * FIONSPACE doesn't really work for eventfd, because the
+ * writability depends on the contents (value) being written.
+ */
+ break;
+
+ default:
+ break;
+ }
+
+ return EPASSTHROUGH;
+}
+
+static int
eventfd_fop_poll(file_t * const fp, int const events)
{
struct eventfd * const efd = fp->f_eventfd;
@@ -521,7 +554,7 @@ static const struct fileops eventfd_file
.fo_name = "eventfd",
.fo_read = eventfd_fop_read,
.fo_write = eventfd_fop_write,
- .fo_ioctl = fbadop_ioctl,
+ .fo_ioctl = eventfd_ioctl,
.fo_fcntl = fnullop_fcntl,
.fo_poll = eventfd_fop_poll,
.fo_stat = eventfd_fop_stat,
Index: src/sys/kern/sys_timerfd.c
diff -u src/sys/kern/sys_timerfd.c:1.7 src/sys/kern/sys_timerfd.c:1.8
--- src/sys/kern/sys_timerfd.c:1.7 Wed Nov 24 16:35:33 2021
+++ src/sys/kern/sys_timerfd.c Thu Feb 17 16:28:29 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: sys_timerfd.c,v 1.7 2021/11/24 16:35:33 thorpej Exp $ */
+/* $NetBSD: sys_timerfd.c,v 1.8 2022/02/17 16:28:29 thorpej Exp $ */
/*-
* Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_timerfd.c,v 1.7 2021/11/24 16:35:33 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_timerfd.c,v 1.8 2022/02/17 16:28:29 thorpej Exp $");
/*
* timerfd
@@ -306,6 +306,15 @@ timerfd_fop_ioctl(file_t * const fp, uns
int error = 0;
switch (cmd) {
+ case FIONBIO:
+ break;
+
+ case FIONREAD:
+ itimer_lock();
+ *(int *)data = timerfd_is_readable(tfd) ? sizeof(uint64_t) : 0;
+ itimer_unlock();
+ break;
+
case TFD_IOC_SET_TICKS: {
const uint64_t * const new_ticksp = data;
if (*new_ticksp > INT_MAX) {