On Wed, May 31, 2017 at 02:07:19PM +0200, Mike Belopuhov wrote: > On Wed, May 31, 2017 at 08:37 +0200, Jan Schreiber wrote: > > 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! > > > > That was me (mikeb@).
Then you should commit it. OK bluhm@ > > > 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. > > > > We've tweaked the description for EV_RECEIPT a bit because FreeBSD > version didn't make a whole lot sense.