From 67543ab1e3074e0f2f31f73b5feb5cec5cdbe70c Mon Sep 17 00:00:00 2001 From: Alfred Perlstein Date: Wed, 14 Jul 2004 07:02:03 +0000 Subject: [PATCH] Make FIOASYNC, FIOSETOWN and FIOGETOWN work on kqueues. --- sys/kern/kern_event.c | 31 +++++++++++++++++++++++++++++-- sys/sys/eventvar.h | 4 +++- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index bd0e6d9221c6..4b9a7513f855 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -33,10 +33,11 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #include #include #include +#include #include #include #include @@ -44,6 +45,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include #include #include @@ -811,9 +814,29 @@ kqueue_write(struct file *fp, struct uio *uio, struct ucred *active_cred, /*ARGSUSED*/ static int -kqueue_ioctl(struct file *fp, u_long com, void *data, +kqueue_ioctl(struct file *fp, u_long cmd, void *data, struct ucred *active_cred, struct thread *td) { + struct kqueue *kq; + + kq = fp->f_data; + switch (cmd) { + case FIOASYNC: + if (*(int *)data) { + kq->kq_state |= KQ_ASYNC; + } else { + kq->kq_state &= ~KQ_ASYNC; + } + return (0); + + case FIOSETOWN: + return (fsetown(*(int *)data, &kq->kq_sigio)); + + case FIOGETOWN: + *(int *)data = fgetown(&kq->kq_sigio); + return (0); + } + return (ENOTTY); } @@ -910,6 +933,7 @@ kqueue_close(struct file *fp, struct thread *td) kq->kq_state &= ~KQ_SEL; selwakeuppri(&kq->kq_sel, PSOCK); } + funsetown(&kq->kq_sigio); free(kq, M_KQUEUE); fp->f_data = NULL; @@ -928,6 +952,9 @@ kqueue_wakeup(struct kqueue *kq) kq->kq_state &= ~KQ_SEL; selwakeuppri(&kq->kq_sel, PSOCK); } + if (kq->kq_state & KQ_ASYNC) { + pgsigio(&kq->kq_sigio, SIGIO, 0); + } KNOTE(&kq->kq_sel.si_note, 0); } diff --git a/sys/sys/eventvar.h b/sys/sys/eventvar.h index 3701d4411b70..ef9087b61614 100644 --- a/sys/sys/eventvar.h +++ b/sys/sys/eventvar.h @@ -35,11 +35,13 @@ struct kqueue { TAILQ_HEAD(kqlist, knote) kq_head; /* list of pending event */ int kq_count; /* number of pending events */ - struct selinfo kq_sel; + struct selinfo kq_sel; + struct sigio *kq_sigio; struct filedesc *kq_fdp; int kq_state; #define KQ_SEL 0x01 #define KQ_SLEEP 0x02 +#define KQ_ASYNC 0x04 struct kevent kq_kev[KQ_NEVENTS]; };