summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_event.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/kern_event.c')
-rw-r--r--sys/kern/kern_event.c123
1 files changed, 71 insertions, 52 deletions
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index 85ea78c..f4b6c19 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -107,16 +107,7 @@ static void kqueue_wakeup(struct kqueue *kq);
static struct filterops *kqueue_fo_find(int filt);
static void kqueue_fo_release(int filt);
-static fo_rdwr_t kqueue_read;
-static fo_rdwr_t kqueue_write;
-static fo_truncate_t kqueue_truncate;
-static fo_ioctl_t kqueue_ioctl;
-static fo_poll_t kqueue_poll;
-static fo_kqfilter_t kqueue_kqfilter;
-static fo_stat_t kqueue_stat;
-static fo_close_t kqueue_close;
-
-static struct fileops kqueueops = {
+struct fileops kqueueops = {
.fo_read = kqueue_read,
.fo_write = kqueue_write,
.fo_truncate = kqueue_truncate,
@@ -303,7 +294,7 @@ filt_fileattach(struct knote *kn)
}
/*ARGSUSED*/
-static int
+int
kqueue_kqfilter(struct file *fp, struct knote *kn)
{
struct kqueue *kq = kn->kn_fp->f_data;
@@ -688,34 +679,7 @@ filt_usertouch(struct knote *kn, struct kevent *kev, u_long type)
int
sys_kqueue(struct thread *td, struct kqueue_args *uap)
{
- struct filedesc *fdp;
- struct kqueue *kq;
- struct file *fp;
- int fd, error;
-
- fdp = td->td_proc->p_fd;
- error = falloc(td, &fp, &fd, 0);
- if (error)
- goto done2;
-
- /* An extra reference on `fp' has been held for us by falloc(). */
- kq = malloc(sizeof *kq, M_KQUEUE, M_WAITOK | M_ZERO);
- mtx_init(&kq->kq_lock, "kqueue", NULL, MTX_DEF|MTX_DUPOK);
- TAILQ_INIT(&kq->kq_head);
- kq->kq_fdp = fdp;
- knlist_init_mtx(&kq->kq_sel.si_note, &kq->kq_lock);
- TASK_INIT(&kq->kq_task, 0, kqueue_task, kq);
-
- FILEDESC_XLOCK(fdp);
- TAILQ_INSERT_HEAD(&fdp->fd_kqlist, kq, kq_list);
- FILEDESC_XUNLOCK(fdp);
-
- finit(fp, FREAD | FWRITE, DTYPE_KQUEUE, kq, &kqueueops);
- fdrop(fp, td);
-
- td->td_retval[0] = fd;
-done2:
- return (error);
+ return (kern_kqueue(td));
}
#ifndef _SYS_SYSPROTO_H_
@@ -817,19 +781,75 @@ kevent_copyin(void *arg, struct kevent *kevp, int count)
}
int
+kern_kqueue(struct thread *td)
+{
+ struct file *fp;
+ int error;
+
+ error = kern_kqueue_locked(td, &fp);
+
+ fdrop(fp, td);
+ return (error);
+}
+
+int
+kern_kqueue_locked(struct thread *td, struct file **fpp)
+{
+ struct filedesc *fdp;
+ struct kqueue *kq;
+ struct file *fp;
+ int fd, error;
+
+ fdp = td->td_proc->p_fd;
+ error = falloc(td, &fp, &fd, 0);
+ if (error)
+ return (error);
+
+ /* An extra reference on `fp' has been held for us by falloc(). */
+ kq = malloc(sizeof *kq, M_KQUEUE, M_WAITOK | M_ZERO);
+ mtx_init(&kq->kq_lock, "kqueue", NULL, MTX_DEF|MTX_DUPOK);
+ TAILQ_INIT(&kq->kq_head);
+ kq->kq_fdp = fdp;
+ knlist_init_mtx(&kq->kq_sel.si_note, &kq->kq_lock);
+ TASK_INIT(&kq->kq_task, 0, kqueue_task, kq);
+
+ FILEDESC_XLOCK(fdp);
+ TAILQ_INSERT_HEAD(&fdp->fd_kqlist, kq, kq_list);
+ FILEDESC_XUNLOCK(fdp);
+
+ finit(fp, FREAD | FWRITE, DTYPE_KQUEUE, kq, &kqueueops);
+
+ td->td_retval[0] = fd;
+ *fpp = fp;
+ return (0);
+}
+
+int
kern_kevent(struct thread *td, int fd, int nchanges, int nevents,
struct kevent_copyops *k_ops, const struct timespec *timeout)
{
+ struct file *fp;
+ cap_rights_t rights;
+ int error;
+
+ if ((error = fget(td, fd, cap_rights_init(&rights, CAP_POST_EVENT), &fp)) != 0)
+ return (error);
+
+ error = kern_kevent_locked(td, fp, nchanges, nevents, k_ops, timeout);
+
+ fdrop(fp, td);
+ return (error);
+}
+
+int
+kern_kevent_locked(struct thread *td, struct file *fp, int nchanges, int nevents,
+ struct kevent_copyops *k_ops, const struct timespec *timeout)
+{
struct kevent keva[KQ_NEVENTS];
struct kevent *kevp, *changes;
struct kqueue *kq;
- struct file *fp;
- cap_rights_t rights;
int i, n, nerrors, error;
- error = fget(td, fd, cap_rights_init(&rights, CAP_POST_EVENT), &fp);
- if (error != 0)
- return (error);
if ((error = kqueue_acquire(fp, &kq)) != 0)
goto done_norel;
@@ -872,7 +892,6 @@ kern_kevent(struct thread *td, int fd, int nchanges, int nevents,
done:
kqueue_release(kq, 0);
done_norel:
- fdrop(fp, td);
return (error);
}
@@ -1526,7 +1545,7 @@ done_nl:
* This could be expanded to call kqueue_scan, if desired.
*/
/*ARGSUSED*/
-static int
+int
kqueue_read(struct file *fp, struct uio *uio, struct ucred *active_cred,
int flags, struct thread *td)
{
@@ -1534,7 +1553,7 @@ kqueue_read(struct file *fp, struct uio *uio, struct ucred *active_cred,
}
/*ARGSUSED*/
-static int
+int
kqueue_write(struct file *fp, struct uio *uio, struct ucred *active_cred,
int flags, struct thread *td)
{
@@ -1542,7 +1561,7 @@ kqueue_write(struct file *fp, struct uio *uio, struct ucred *active_cred,
}
/*ARGSUSED*/
-static int
+int
kqueue_truncate(struct file *fp, off_t length, struct ucred *active_cred,
struct thread *td)
{
@@ -1551,7 +1570,7 @@ kqueue_truncate(struct file *fp, off_t length, struct ucred *active_cred,
}
/*ARGSUSED*/
-static int
+int
kqueue_ioctl(struct file *fp, u_long cmd, void *data,
struct ucred *active_cred, struct thread *td)
{
@@ -1599,7 +1618,7 @@ kqueue_ioctl(struct file *fp, u_long cmd, void *data,
}
/*ARGSUSED*/
-static int
+int
kqueue_poll(struct file *fp, int events, struct ucred *active_cred,
struct thread *td)
{
@@ -1626,7 +1645,7 @@ kqueue_poll(struct file *fp, int events, struct ucred *active_cred,
}
/*ARGSUSED*/
-static int
+int
kqueue_stat(struct file *fp, struct stat *st, struct ucred *active_cred,
struct thread *td)
{
@@ -1644,7 +1663,7 @@ kqueue_stat(struct file *fp, struct stat *st, struct ucred *active_cred,
}
/*ARGSUSED*/
-static int
+int
kqueue_close(struct file *fp, struct thread *td)
{
struct kqueue *kq = fp->f_data;
OpenPOWER on IntegriCloud