summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/kern_event.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index eca90df..e1c2ca7 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -283,6 +283,7 @@ filt_proc(struct knote *kn, long hint)
kev.flags = kn->kn_flags | EV_ADD | EV_ENABLE | EV_FLAG1;
kev.fflags = kn->kn_sfflags;
kev.data = kn->kn_id; /* parent */
+ kev.udata = kn->kn_kevent.udata; /* preserve udata */
error = kqueue_register(kn->kn_kq, &kev, NULL);
if (error)
kn->kn_fflags |= NOTE_TRACKERR;
@@ -447,7 +448,6 @@ kqueue_register(struct kqueue *kq, struct kevent *kev, struct proc *p)
* kn now contains the matching knote, or NULL if no match
*/
if (kev->flags & EV_ADD) {
- int attach = 0;
if (kn == NULL) {
kn = knote_alloc();
@@ -458,25 +458,34 @@ kqueue_register(struct kqueue *kq, struct kevent *kev, struct proc *p)
kn->kn_fp = fp;
kn->kn_kq = kq;
kn->kn_fop = fops;
- attach = 1;
- }
- kn->kn_sfflags = kev->fflags;
- kn->kn_sdata = kev->data;
- kev->fflags = 0;
- kev->data = 0;
- kn->kn_kevent = *kev;
- if (attach) {
+ kn->kn_sfflags = kev->fflags;
+ kn->kn_sdata = kev->data;
+ kev->fflags = 0;
+ kev->data = 0;
+ kn->kn_kevent = *kev;
+
knote_attach(kn, fdp);
if ((error = fops->f_attach(kn)) != 0) {
knote_drop(kn, p);
goto done;
}
+ } else {
+ /*
+ * The user may change some filter values after the
+ * initial EV_ADD, but doing so will not reset any
+ * filter which have already been triggered.
+ */
+ kn->kn_sfflags = kev->fflags;
+ kn->kn_sdata = kev->data;
+ kn->kn_kevent.udata = kev->udata;
}
+
s = splhigh();
if (kn->kn_fop->f_event(kn, 0))
KNOTE_ACTIVATE(kn);
splx(s);
+
} else if (kev->flags & EV_DELETE) {
kn->kn_fop->f_detach(kn);
knote_drop(kn, p);
OpenPOWER on IntegriCloud