kevent(2) notifies userland if an event happened based on given filter.

If an error is encountered during execution, the given descriptor will
have the EV_ERROR flag set and `data' will contain an errno(2) value.

This value might come from the kqueue subsystem itself or from the
f_attach() function responsible for attaching filters.  Every kind of
event watchable with kevent(2) has a specific f_attach() function.  When
it comes to file descriptors it translate into specific fo_kqfilter()
function.

The diff below fix some incoherences of errors returned by those
functions.  Note that these values aren't unified across BSDs.  So this
only makes all OpenBSD kqfilter coherent between themself.  It follows
the most-used approach, the following errno(2) values are returned:

- EOPNOTSUPP:   when there's no "filterops" for a given fd
- EINVAL:       when the requested filter isn't supported by the current
                "filterops"
- ENXIO:        when the underlying device is no longer valid/present

On top of those 3 values, which are returned by most of the kqfilters
the following exception exist and aren't touched by the diff below: 

- EPIPE:        returned only by pipe_kqfilter() when using EVFILT_WRITE
                if the other end of the pipe has been closed
- ENOMEM, and
  EAGAIN:       returned by nfs_kqfilter() when it fails to create a
                thread.

I'm questioning if it makes sense to return both EOPNOTSUPP and EINVAL,
I can see if there's any value for the user of such API.  But that might
be seen as a different discussion, at least this diff brings coherency.

Comments?  Oks?

Index: arch/arm64/arm64/acpiapm.c
===================================================================
RCS file: /cvs/src/sys/arch/arm64/arm64/acpiapm.c,v
retrieving revision 1.1
diff -u -p -r1.1 acpiapm.c
--- arch/arm64/arm64/acpiapm.c  23 Jan 2019 09:57:36 -0000      1.1
+++ arch/arm64/arm64/acpiapm.c  1 Apr 2020 08:39:14 -0000
@@ -53,6 +53,6 @@ int
 acpiapmkqfilter(dev_t dev, struct knote *kn)
 {
        if (!acpiapm_kqfilter)
-               return ENODEV;
+               return EOPNOTSUPP;
        return acpiapm_kqfilter(dev, kn);
 }
Index: arch/i386/i386/acpiapm.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/acpiapm.c,v
retrieving revision 1.1
diff -u -p -r1.1 acpiapm.c
--- arch/i386/i386/acpiapm.c    25 Nov 2007 15:45:17 -0000      1.1
+++ arch/i386/i386/acpiapm.c    1 Apr 2020 08:39:14 -0000
@@ -53,6 +53,6 @@ int
 acpiapmkqfilter(dev_t dev, struct knote *kn)
 {
        if (!acpiapm_kqfilter)
-               return ENODEV;
+               return EOPNOTSUPP;
        return acpiapm_kqfilter(dev, kn);
 } 
Index: dev/acpi/acpi.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpi.c,v
retrieving revision 1.378
diff -u -p -r1.378 acpi.c
--- dev/acpi/acpi.c     20 Feb 2020 16:56:52 -0000      1.378
+++ dev/acpi/acpi.c     1 Apr 2020 08:39:14 -0000
@@ -3539,7 +3539,7 @@ acpiioctl(dev_t dev, u_long cmd, caddr_t
 int
 acpikqfilter(dev_t dev, struct knote *kn)
 {
-       return (ENXIO);
+       return (EINVAL);
 }
 
 #endif /* SMALL_KERNEL */
Index: dev/cons.c
===================================================================
RCS file: /cvs/src/sys/dev/cons.c,v
retrieving revision 1.28
diff -u -p -r1.28 cons.c
--- dev/cons.c  19 Feb 2018 08:59:52 -0000      1.28
+++ dev/cons.c  1 Apr 2020 08:39:14 -0000
@@ -215,7 +215,7 @@ cnkqfilter(dev_t dev, struct knote *kn)
                dev = cn_tab->cn_dev;
        if (cdevsw[major(dev)].d_kqfilter)
                return ((*cdevsw[major(dev)].d_kqfilter)(dev, kn));
-       return (ENXIO);
+       return (EOPNOTSUPP);
 }
 
 int
Index: dev/usb/ugen.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/ugen.c,v
retrieving revision 1.103
diff -u -p -r1.103 ugen.c
--- dev/usb/ugen.c      22 Feb 2020 14:01:34 -0000      1.103
+++ dev/usb/ugen.c      1 Apr 2020 08:39:14 -0000
@@ -1365,7 +1365,7 @@ ugenkqfilter(dev_t dev, struct knote *kn
        /* XXX always IN */
        sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN];
        if (sce == NULL)
-               return (EINVAL);
+               return (ENXIO);
 
        switch (kn->kn_filter) {
        case EVFILT_READ:
Index: dev/usb/uhid.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/uhid.c,v
retrieving revision 1.77
diff -u -p -r1.77 uhid.c
--- dev/usb/uhid.c      20 Feb 2020 16:56:52 -0000      1.77
+++ dev/usb/uhid.c      1 Apr 2020 08:39:14 -0000
@@ -485,7 +485,7 @@ uhidkqfilter(dev_t dev, struct knote *kn
                return (ENXIO);
 
        if (usbd_is_dying(sc->sc_hdev.sc_udev))
-               return (EIO);
+               return (ENXIO);
 
        switch (kn->kn_filter) {
        case EVFILT_READ:

Reply via email to