aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/kern_event.c
diff options
context:
space:
mode:
authorJonathan Lemon <jlemon@FreeBSD.org>2000-06-22 18:39:31 +0000
committerJonathan Lemon <jlemon@FreeBSD.org>2000-06-22 18:39:31 +0000
commitd2693dbbc4a50cadea996cfa60f52b91c9d39e4c (patch)
treee15766ae2ec383846ad2a89b9014d92c64e9e86c /sys/kern/kern_event.c
parent55f087be8e5dcc1384615c0977d26d95c14f9f7e (diff)
downloadsrc-d2693dbbc4a50cadea996cfa60f52b91c9d39e4c.tar.gz
src-d2693dbbc4a50cadea996cfa60f52b91c9d39e4c.zip
Add code so that the udata field is preserved across a TRACK event.
When re-adding an event, do not reset the event state. If the event was pending, it will remain pending. This allows the user to change the udata field after the event was registered, while not losing any events which have already occurred. Reported by: jmg
Notes
Notes: svn path=/head/; revision=61962
Diffstat (limited to 'sys/kern/kern_event.c')
-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 eca90dfee9e0..e1c2ca71546d 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);