Hi,

I recently stumbled upon software that relies on EV_RECEIPT and
EV_DISPATCH to be available as flags. It also showed up as dependency
for a Rust crate.
FreeBSD has it since 8.1 and OSX since 10.5.
Patch is below.

mike@ looked throug, thanks a lot!

Jan

Index: sys/kern/kern_event.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_event.c,v
retrieving revision 1.78
diff -u -p -u -r1.78 kern_event.c
--- sys/kern/kern_event.c       11 Feb 2017 19:51:06 -0000      1.78
+++ sys/kern/kern_event.c       30 May 2017 22:38:49 -0000
@@ -512,7 +512,7 @@ sys_kevent(struct proc *p, void *v, regi
                        kevp = &kq->kq_kev[i];
                        kevp->flags &= ~EV_SYSFLAGS;
                        error = kqueue_register(kq, kevp, p);
-                       if (error) {
+                       if (error || (kevp->flags & EV_RECEIPT)) {
                                if (SCARG(uap, nevents) != 0) {
                                        kevp->flags = EV_ERROR;
                                        kevp->data = error;
@@ -788,9 +788,13 @@ start:
                        kn->kn_fop->f_detach(kn);
                        knote_drop(kn, p, p->p_fd);
                        s = splhigh();
-               } else if (kn->kn_flags & EV_CLEAR) {
-                       kn->kn_data = 0;
-                       kn->kn_fflags = 0;
+               } else if (kn->kn_flags & (EV_CLEAR | EV_DISPATCH)) {
+                       if (kn->kn_flags & EV_CLEAR) {
+                               kn->kn_data = 0;
+                               kn->kn_fflags = 0;
+                       }
+                       if (kn->kn_flags & EV_DISPATCH)
+                               kn->kn_status |= KN_DISABLED;
                        kn->kn_status &= ~(KN_QUEUED | KN_ACTIVE);
                        kq->kq_count--;
                } else {
Index: sys/sys/event.h
===================================================================
RCS file: /cvs/src/sys/sys/event.h,v
retrieving revision 1.23
diff -u -p -u -r1.23 event.h
--- sys/sys/event.h     24 Sep 2016 18:39:17 -0000      1.23
+++ sys/sys/event.h     30 May 2017 22:31:04 -0000
@@ -68,6 +68,8 @@ struct kevent {
 /* flags */
 #define EV_ONESHOT     0x0010          /* only report one occurrence */
 #define EV_CLEAR       0x0020          /* clear event state after reporting */
+#define EV_RECEIPT     0x0040          /* force EV_ERROR on success, data=0 */
+#define EV_DISPATCH    0x0080          /* disable event after reporting */
 
 #define EV_SYSFLAGS    0xF000          /* reserved by system */
 #define EV_FLAG1       0x2000          /* filter-specific flag */
Index: lib/libc/sys/kqueue.2
===================================================================
RCS file: /cvs/src/lib/libc/sys/kqueue.2,v
retrieving revision 1.33
diff -u -p -u -r1.33 kqueue.2
--- lib/libc/sys/kqueue.2       13 Aug 2016 17:05:02 -0000      1.33
+++ lib/libc/sys/kqueue.2       30 May 2017 22:30:29 -0000
@@ -184,10 +184,25 @@ Disable the event so
 .Fn kevent
 will not return it.
 The filter itself is not disabled.
+.It Dv EV_DISPATCH
+Disable the event source immediately after delivery of an event.
+See
+.Dv EV_DISABLE
+above.
 .It Dv EV_DELETE
 Removes the event from the kqueue.
 Events which are attached to file descriptors are automatically deleted
 on the last close of the descriptor.
+.It Dv EV_RECEIPT
+Causes
+.Fn kevent
+to return with
+.Dv EV_ERROR
+set without draining any pending events after updating events in the kqueue.
+When a filter is successfully added the
+.Va data
+field will be zero.
+This flag is useful for making bulk changes to a kqueue.
 .It Dv EV_ONESHOT
 Causes the event to return only the first occurrence of the filter
 being triggered.

Reply via email to