syscall messaging 3: Expand the 'header' that goes in front of the syscall
[dragonfly.git] / sys / kern / kern_event.c
index 420a623..ae0fe56 100644 (file)
@@ -24,6 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/kern/kern_event.c,v 1.2.2.9 2003/05/08 07:47:16 kbyanc Exp $
+ * $DragonFly: src/sys/kern/kern_event.c,v 1.9 2003/07/30 00:19:14 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -46,6 +47,7 @@
 #include <sys/sysctl.h>
 #include <sys/sysproto.h>
 #include <sys/uio.h>
+#include <sys/file2.h>
 
 #include <vm/vm_zone.h>
 
@@ -53,21 +55,23 @@ MALLOC_DEFINE(M_KQUEUE, "kqueue", "memory for kqueue system");
 
 static int     kqueue_scan(struct file *fp, int maxevents,
                    struct kevent *ulistp, const struct timespec *timeout,
-                   struct proc *p);
+                   struct proc *p, int *res);
 static int     kqueue_read(struct file *fp, struct uio *uio,
-                   struct ucred *cred, int flags, struct proc *p);
+                   struct ucred *cred, int flags, struct thread *td);
 static int     kqueue_write(struct file *fp, struct uio *uio,
-                   struct ucred *cred, int flags, struct proc *p);
+                   struct ucred *cred, int flags, struct thread *td);
 static int     kqueue_ioctl(struct file *fp, u_long com, caddr_t data,
-                   struct proc *p);
+                   struct thread *td);
 static int     kqueue_poll(struct file *fp, int events, struct ucred *cred,
-                   struct proc *p);
+                   struct thread *td);
 static int     kqueue_kqfilter(struct file *fp, struct knote *kn);
-static int     kqueue_stat(struct file *fp, struct stat *st, struct proc *p);
-static int     kqueue_close(struct file *fp, struct proc *p);
+static int     kqueue_stat(struct file *fp, struct stat *st, struct thread *td);
+static int     kqueue_close(struct file *fp, struct thread *td);
 static void    kqueue_wakeup(struct kqueue *kq);
 
 static struct fileops kqueueops = {
+       NULL,   /* port */
+       0,      /* autoq */
        kqueue_read,
        kqueue_write,
        kqueue_ioctl,
@@ -78,7 +82,7 @@ static struct fileops kqueueops = {
 };
 
 static void    knote_attach(struct knote *kn, struct filedesc *fdp);
-static void    knote_drop(struct knote *kn, struct proc *p);
+static void    knote_drop(struct knote *kn, struct thread *td);
 static void    knote_enqueue(struct knote *kn);
 static void    knote_dequeue(struct knote *kn);
 static void    knote_init(void);
@@ -139,7 +143,6 @@ static struct filterops *sysfilt_ops[] = {
 static int
 filt_fileattach(struct knote *kn)
 {
-       
        return (fo_kqfilter(kn->kn_fp, kn));
 }
 
@@ -189,7 +192,7 @@ filt_procattach(struct knote *kn)
        }
        if (p == NULL)
                return (ESRCH);
-       if (! PRISON_CHECK(curproc, p))
+       if (! PRISON_CHECK(curproc->p_ucred, p->p_ucred))
                return (EACCES);
 
        kn->kn_ptr.p_proc = p;
@@ -356,8 +359,9 @@ filt_timer(struct knote *kn, long hint)
 }
 
 int
-kqueue(struct proc *p, struct kqueue_args *uap)
+kqueue(struct kqueue_args *uap)
 {
+       struct proc *p = curproc;
        struct filedesc *fdp = p->p_fd;
        struct kqueue *kq;
        struct file *fp;
@@ -372,33 +376,28 @@ kqueue(struct proc *p, struct kqueue_args *uap)
        kq = malloc(sizeof(struct kqueue), M_KQUEUE, M_WAITOK | M_ZERO);
        TAILQ_INIT(&kq->kq_head);
        fp->f_data = (caddr_t)kq;
-       p->p_retval[0] = fd;
+       uap->sysmsg_result = fd;
        if (fdp->fd_knlistsize < 0)
                fdp->fd_knlistsize = 0;         /* this process has a kq */
        kq->kq_fdp = fdp;
        return (error);
 }
 
-#ifndef _SYS_SYSPROTO_H_
-struct kevent_args {
-       int     fd;
-       const struct kevent *changelist;
-       int     nchanges;
-       struct  kevent *eventlist;
-       int     nevents;
-       const struct timespec *timeout;
-};
-#endif
 int
-kevent(struct proc *p, struct kevent_args *uap)
+kevent(struct kevent_args *uap)
 {
-       struct filedesc* fdp = p->p_fd;
+       struct thread *td = curthread;
+       struct proc *p = td->td_proc;
+       struct filedesc *fdp;
        struct kevent *kevp;
        struct kqueue *kq;
        struct file *fp = NULL;
        struct timespec ts;
        int i, n, nerrors, error;
 
+       KKASSERT(p);
+       fdp = p->p_fd;
+
         if (((u_int)uap->fd) >= fdp->fd_nfiles ||
             (fp = fdp->fd_ofiles[uap->fd]) == NULL ||
            (fp->f_type != DTYPE_KQUEUE))
@@ -425,7 +424,7 @@ kevent(struct proc *p, struct kevent_args *uap)
                for (i = 0; i < n; i++) {
                        kevp = &kq->kq_kev[i];
                        kevp->flags &= ~EV_SYSFLAGS;
-                       error = kqueue_register(kq, kevp, p);
+                       error = kqueue_register(kq, kevp, td);
                        if (error) {
                                if (uap->nevents != 0) {
                                        kevp->flags = EV_ERROR;
@@ -445,20 +444,20 @@ kevent(struct proc *p, struct kevent_args *uap)
                uap->changelist += n;
        }
        if (nerrors) {
-               p->p_retval[0] = nerrors;
+               uap->sysmsg_result = nerrors;
                error = 0;
                goto done;
        }
 
-       error = kqueue_scan(fp, uap->nevents, uap->eventlist, uap->timeout, p);
+       error = kqueue_scan(fp, uap->nevents, uap->eventlist, uap->timeout, p, &uap->sysmsg_result);
 done:
        if (fp != NULL)
-               fdrop(fp, p);
+               fdrop(fp, p->p_thread);
        return (error);
 }
 
 int
-kqueue_register(struct kqueue *kq, struct kevent *kev, struct proc *p)
+kqueue_register(struct kqueue *kq, struct kevent *kev, struct thread *td)
 {
        struct filedesc *fdp = kq->kq_fdp;
        struct filterops *fops;
@@ -541,7 +540,7 @@ kqueue_register(struct kqueue *kq, struct kevent *kev, struct proc *p)
 
                        knote_attach(kn, fdp);
                        if ((error = fops->f_attach(kn)) != 0) {
-                               knote_drop(kn, p);
+                               knote_drop(kn, td);
                                goto done;
                        }
                } else {
@@ -562,7 +561,7 @@ kqueue_register(struct kqueue *kq, struct kevent *kev, struct proc *p)
 
        } else if (kev->flags & EV_DELETE) {
                kn->kn_fop->f_detach(kn);
-               knote_drop(kn, p);
+               knote_drop(kn, td);
                goto done;
        }
 
@@ -584,14 +583,15 @@ kqueue_register(struct kqueue *kq, struct kevent *kev, struct proc *p)
 
 done:
        if (fp != NULL)
-               fdrop(fp, p);
+               fdrop(fp, td);
        return (error);
 }
 
 static int
 kqueue_scan(struct file *fp, int maxevents, struct kevent *ulistp,
-       const struct timespec *tsp, struct proc *p)
+       const struct timespec *tsp, struct proc *p, int *res)
 {
+       struct thread *td = p->p_thread;
        struct kqueue *kq = (struct kqueue *)fp->f_data;
        struct kevent *kevp;
        struct timeval atv, rtv, ttv;
@@ -641,7 +641,7 @@ start:
                        error = EWOULDBLOCK;
                } else {
                        kq->kq_state |= KQ_SLEEP;
-                       error = tsleep(kq, PSOCK | PCATCH, "kqread", timeout);
+                       error = tsleep(kq, PCATCH, "kqread", timeout);
                }
                splx(s);
                if (error == 0)
@@ -683,7 +683,7 @@ start:
                        kq->kq_count--;
                        splx(s);
                        kn->kn_fop->f_detach(kn);
-                       knote_drop(kn, p);
+                       knote_drop(kn, td);
                        s = splhigh();
                } else if (kn->kn_flags & EV_CLEAR) {
                        kn->kn_data = 0;
@@ -712,7 +712,7 @@ done:
        if (nkev != 0)
                error = copyout((caddr_t)&kq->kq_kev, (caddr_t)ulistp,
                    sizeof(struct kevent) * nkev);
-        p->p_retval[0] = maxevents - count;
+        *res = maxevents - count;
        return (error);
 }
 
@@ -723,7 +723,7 @@ done:
 /*ARGSUSED*/
 static int
 kqueue_read(struct file *fp, struct uio *uio, struct ucred *cred,
-       int flags, struct proc *p)
+       int flags, struct thread *td)
 {
        return (ENXIO);
 }
@@ -731,21 +731,21 @@ kqueue_read(struct file *fp, struct uio *uio, struct ucred *cred,
 /*ARGSUSED*/
 static int
 kqueue_write(struct file *fp, struct uio *uio, struct ucred *cred,
-        int flags, struct proc *p)
+        int flags, struct thread *td)
 {
        return (ENXIO);
 }
 
 /*ARGSUSED*/
 static int
-kqueue_ioctl(struct file *fp, u_long com, caddr_t data, struct proc *p)
+kqueue_ioctl(struct file *fp, u_long com, caddr_t data, struct thread *td)
 {
        return (ENOTTY);
 }
 
 /*ARGSUSED*/
 static int
-kqueue_poll(struct file *fp, int events, struct ucred *cred, struct proc *p)
+kqueue_poll(struct file *fp, int events, struct ucred *cred, struct thread *td)
 {
        struct kqueue *kq = (struct kqueue *)fp->f_data;
        int revents = 0;
@@ -755,7 +755,7 @@ kqueue_poll(struct file *fp, int events, struct ucred *cred, struct proc *p)
                 if (kq->kq_count) {
                         revents |= events & (POLLIN | POLLRDNORM);
                } else {
-                        selrecord(p, &kq->kq_sel);
+                        selrecord(td, &kq->kq_sel);
                        kq->kq_state |= KQ_SEL;
                }
        }
@@ -765,7 +765,7 @@ kqueue_poll(struct file *fp, int events, struct ucred *cred, struct proc *p)
 
 /*ARGSUSED*/
 static int
-kqueue_stat(struct file *fp, struct stat *st, struct proc *p)
+kqueue_stat(struct file *fp, struct stat *st, struct thread *td)
 {
        struct kqueue *kq = (struct kqueue *)fp->f_data;
 
@@ -778,13 +778,16 @@ kqueue_stat(struct file *fp, struct stat *st, struct proc *p)
 
 /*ARGSUSED*/
 static int
-kqueue_close(struct file *fp, struct proc *p)
+kqueue_close(struct file *fp, struct thread *td)
 {
+       struct proc *p = td->td_proc;
        struct kqueue *kq = (struct kqueue *)fp->f_data;
-       struct filedesc *fdp = p->p_fd;
+       struct filedesc *fdp;
        struct knote **knp, *kn, *kn0;
        int i;
 
+       KKASSERT(p);
+       fdp = p->p_fd;
        for (i = 0; i < fdp->fd_knlistsize; i++) {
                knp = &SLIST_FIRST(&fdp->fd_knlist[i]);
                kn = *knp;
@@ -792,7 +795,7 @@ kqueue_close(struct file *fp, struct proc *p)
                        kn0 = SLIST_NEXT(kn, kn_link);
                        if (kq == kn->kn_kq) {
                                kn->kn_fop->f_detach(kn);
-                               fdrop(kn->kn_fp, p);
+                               fdrop(kn->kn_fp, td);
                                knote_free(kn);
                                *knp = kn0;
                        } else {
@@ -857,13 +860,13 @@ knote(struct klist *list, long hint)
  * remove all knotes from a specified klist
  */
 void
-knote_remove(struct proc *p, struct klist *list)
+knote_remove(struct thread *td, struct klist *list)
 {
        struct knote *kn;
 
        while ((kn = SLIST_FIRST(list)) != NULL) {
                kn->kn_fop->f_detach(kn);
-               knote_drop(kn, p);
+               knote_drop(kn, td);
        }
 }
 
@@ -876,7 +879,7 @@ knote_fdclose(struct proc *p, int fd)
        struct filedesc *fdp = p->p_fd;
        struct klist *list = &fdp->fd_knlist[fd];
 
-       knote_remove(p, list);
+       knote_remove(p->p_thread, list);
 }
 
 static void
@@ -920,11 +923,13 @@ done:
  * while calling fdrop and free.
  */
 static void
-knote_drop(struct knote *kn, struct proc *p)
+knote_drop(struct knote *kn, struct thread *td)
 {
-        struct filedesc *fdp = p->p_fd;
+        struct filedesc *fdp;
        struct klist *list;
 
+       KKASSERT(td->td_proc);
+        fdp = td->td_proc->p_fd;
        if (kn->kn_fop->f_isfd)
                list = &fdp->fd_knlist[kn->kn_id];
        else
@@ -934,7 +939,7 @@ knote_drop(struct knote *kn, struct proc *p)
        if (kn->kn_status & KN_QUEUED)
                knote_dequeue(kn);
        if (kn->kn_fop->f_isfd)
-               fdrop(kn->kn_fp, p);
+               fdrop(kn->kn_fp, td);
        knote_free(kn);
 }