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) {

Reply via email to