| 970 | } |
| 971 | |
| 972 | int |
| 973 | kern_kqueue(struct thread *td, int flags, struct filecaps *fcaps) |
| 974 | { |
| 975 | struct filedesc *fdp; |
| 976 | struct kqueue *kq; |
| 977 | struct file *fp; |
| 978 | struct ucred *cred; |
| 979 | int fd, error; |
| 980 | |
| 981 | fdp = td->td_proc->p_fd; |
| 982 | cred = td->td_ucred; |
| 983 | if (!chgkqcnt(cred->cr_ruidinfo, 1, lim_cur(td, RLIMIT_KQUEUES))) |
| 984 | return (ENOMEM); |
| 985 | |
| 986 | error = falloc_caps(td, &fp, &fd, flags, fcaps); |
| 987 | if (error != 0) { |
| 988 | chgkqcnt(cred->cr_ruidinfo, -1, 0); |
| 989 | return (error); |
| 990 | } |
| 991 | |
| 992 | /* An extra reference on `fp' has been held for us by falloc(). */ |
| 993 | kq = malloc(sizeof *kq, M_KQUEUE, M_WAITOK | M_ZERO); |
| 994 | kqueue_init(kq); |
| 995 | kq->kq_fdp = fdp; |
| 996 | kq->kq_cred = crhold(cred); |
| 997 | |
| 998 | FILEDESC_XLOCK(fdp); |
| 999 | TAILQ_INSERT_HEAD(&fdp->fd_kqlist, kq, kq_list); |
| 1000 | FILEDESC_XUNLOCK(fdp); |
| 1001 | |
| 1002 | finit(fp, FREAD | FWRITE, DTYPE_KQUEUE, kq, &kqueueops); |
| 1003 | fdrop(fp, td); |
| 1004 | |
| 1005 | td->td_retval[0] = fd; |
| 1006 | return (0); |
| 1007 | } |
| 1008 | |
| 1009 | struct g_kevent_args { |
| 1010 | int fd; |
no test coverage detected