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