The branch main has been updated by gahr:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=b89104dfd5cf001b34963b9e02083027f9d215d5

commit b89104dfd5cf001b34963b9e02083027f9d215d5
Author:     Pietro Cerutti <g...@freebsd.org>
AuthorDate: 2025-08-07 20:24:06 +0000
Commit:     Pietro Cerutti <g...@freebsd.org>
CommitDate: 2025-08-11 20:31:01 +0000

    null: support EVFILT_READ/EVFILT_WRITE kevent filters
    
    This enhances the full, null, and zero devices to support read and write 
kevent filters.
    
    A read event is immediately triggered for full and null, and never for zero.
    A write event is immediately triggered for zero and null, and never for 
full.
    
    Reviewed by:            cognet
    MFC after:              1 week
    Differential Revision:  https://reviews.freebsd.org/D51807
---
 sys/dev/null/null.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/sys/dev/null/null.c b/sys/dev/null/null.c
index 7ffc618e63ee..8525eb9543c3 100644
--- a/sys/dev/null/null.c
+++ b/sys/dev/null/null.c
@@ -4,6 +4,7 @@
  * Copyright (c) 2000 Mark R. V. Murray & Jeroen C. van Gelderen
  * Copyright (c) 2001-2004 Mark R. V. Murray
  * Copyright (c) 2014 Eitan Adler
+ * Copyright (c) 2025 Pietro Cerutti
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -39,6 +40,7 @@
 #include <sys/disk.h>
 #include <sys/bus.h>
 #include <sys/filio.h>
+#include <sys/event.h>
 
 #include <machine/bus.h>
 #include <machine/vmparam.h>
@@ -53,12 +55,26 @@ static d_write_t null_write;
 static d_ioctl_t null_ioctl;
 static d_ioctl_t zero_ioctl;
 static d_read_t zero_read;
+static d_kqfilter_t kqfilter;
+static int one_ev(struct knote *kn, long hint);
+static int zero_ev(struct knote *kn, long hint);
+
+static const struct filterops one_fop = {
+       .f_isfd =       1,
+       .f_event =      one_ev
+};
+
+static const struct filterops zero_fop = {
+       .f_isfd =       1,
+       .f_event =      zero_ev
+};
 
 static struct cdevsw full_cdevsw = {
        .d_version =    D_VERSION,
        .d_read =       zero_read,
        .d_write =      full_write,
        .d_ioctl =      zero_ioctl,
+       .d_kqfilter =   kqfilter,
        .d_name =       "full",
 };
 
@@ -67,6 +83,7 @@ static struct cdevsw null_cdevsw = {
        .d_read =       (d_read_t *)nullop,
        .d_write =      null_write,
        .d_ioctl =      null_ioctl,
+       .d_kqfilter =   kqfilter,
        .d_name =       "null",
 };
 
@@ -75,6 +92,7 @@ static struct cdevsw zero_cdevsw = {
        .d_read =       zero_read,
        .d_write =      null_write,
        .d_ioctl =      zero_ioctl,
+       .d_kqfilter =   kqfilter,
        .d_name =       "zero",
        .d_flags =      D_MMAP_ANON,
 };
@@ -197,5 +215,35 @@ null_modevent(module_t mod __unused, int type, void *data 
__unused)
        return (0);
 }
 
+static int
+one_ev(struct knote *kn, long hint)
+{
+
+       return (1);
+}
+
+static int
+zero_ev(struct knote *kn, long hint)
+{
+
+       return (0);
+}
+
+static int
+kqfilter(struct cdev *dev, struct knote *kn)
+{
+
+       switch (kn->kn_filter) {
+       case EVFILT_READ:
+           kn->kn_fop = dev->si_devsw == &null_cdevsw ? &zero_fop : &one_fop;
+           return (0);
+       case EVFILT_WRITE:
+           kn->kn_fop = dev->si_devsw == &full_cdevsw ? &zero_fop : &one_fop;
+           return (0);
+       default:
+           return (EOPNOTSUPP);
+       }
+}
+
 DEV_MODULE(null, null_modevent, NULL);
 MODULE_VERSION(null, 1);

Reply via email to