diff options
author | dchagin <dchagin@FreeBSD.org> | 2016-01-09 16:39:15 +0000 |
---|---|---|
committer | dchagin <dchagin@FreeBSD.org> | 2016-01-09 16:39:15 +0000 |
commit | b6688c70e9ec109f6468205ab8e4bf8a760871f8 (patch) | |
tree | 63a6225c9b71adb9b52d77576dfc9d55d1c615f9 /sys/kern/kern_event.c | |
parent | a95b158e60a1b9ea3ee39e786c0afae59fe94f5e (diff) | |
download | FreeBSD-src-b6688c70e9ec109f6468205ab8e4bf8a760871f8.zip FreeBSD-src-b6688c70e9ec109f6468205ab8e4bf8a760871f8.tar.gz |
MFC r283440:
For future use in the Linuxulator:
1. Add a kern_kqueue() counterpart for kqueue() with flags parameter.
2. Be a bit secure. To avoid a double fp lookup add a kern_kevent_fp()
counterpart for kern_kevent() with file pointer parameter instead
of file descriptor an pass the buck to it.
Suggested by: mjg [2]
Diffstat (limited to 'sys/kern/kern_event.c')
-rw-r--r-- | sys/kern/kern_event.c | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index dae1d54..e665a8e 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -731,13 +731,20 @@ filt_usertouch(struct knote *kn, struct kevent *kev, u_long type) int sys_kqueue(struct thread *td, struct kqueue_args *uap) { + + return (kern_kqueue(td, 0)); +} + +int +kern_kqueue(struct thread *td, int flags) +{ struct filedesc *fdp; struct kqueue *kq; struct file *fp; int fd, error; fdp = td->td_proc->p_fd; - error = falloc(td, &fp, &fd, 0); + error = falloc(td, &fp, &fd, flags); if (error) goto done2; @@ -863,12 +870,9 @@ int kern_kevent(struct thread *td, int fd, 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; + struct file *fp; + int error; cap_rights_init(&rights); if (nchanges > 0) @@ -879,9 +883,24 @@ kern_kevent(struct thread *td, int fd, int nchanges, int nevents, if (error != 0) return (error); + error = kern_kevent_fp(td, fp, nchanges, nevents, k_ops, timeout); + fdrop(fp, td); + + return (error); +} + +int +kern_kevent_fp(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; + int i, n, nerrors, error; + error = kqueue_acquire(fp, &kq); if (error != 0) - goto done_norel; + return (error); nerrors = 0; @@ -921,8 +940,6 @@ kern_kevent(struct thread *td, int fd, int nchanges, int nevents, error = kqueue_scan(kq, nevents, k_ops, timeout, keva, td); done: kqueue_release(kq, 0); -done_norel: - fdrop(fp, td); return (error); } |