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.