diff options
author | jlemon <jlemon@FreeBSD.org> | 2000-04-16 18:53:38 +0000 |
---|---|---|
committer | jlemon <jlemon@FreeBSD.org> | 2000-04-16 18:53:38 +0000 |
commit | c41c876463ee8c302f06554537e0fb22a3fcdca4 (patch) | |
tree | d2f87a6af04c4f35f243bf580d099496a4131330 /sys | |
parent | f8f9ad64d408b963d98d0e11b37e871763557e95 (diff) | |
download | FreeBSD-src-c41c876463ee8c302f06554537e0fb22a3fcdca4.zip FreeBSD-src-c41c876463ee8c302f06554537e0fb22a3fcdca4.tar.gz |
Introduce kqueue() and kevent(), a kernel event notification facility.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/fs/fifofs/fifo_vnops.c | 86 | ||||
-rw-r--r-- | sys/kern/init_sysent.c | 4 | ||||
-rw-r--r-- | sys/kern/kern_descrip.c | 26 | ||||
-rw-r--r-- | sys/kern/kern_exec.c | 5 | ||||
-rw-r--r-- | sys/kern/kern_exit.c | 5 | ||||
-rw-r--r-- | sys/kern/kern_fork.c | 5 | ||||
-rw-r--r-- | sys/kern/kern_sig.c | 51 | ||||
-rw-r--r-- | sys/kern/sys_pipe.c | 67 | ||||
-rw-r--r-- | sys/kern/syscalls.c | 4 | ||||
-rw-r--r-- | sys/kern/syscalls.master | 5 | ||||
-rw-r--r-- | sys/kern/uipc_sockbuf.c | 2 | ||||
-rw-r--r-- | sys/kern/uipc_socket.c | 109 | ||||
-rw-r--r-- | sys/kern/uipc_socket2.c | 2 | ||||
-rw-r--r-- | sys/kern/uipc_syscalls.c | 4 | ||||
-rw-r--r-- | sys/kern/vfs_aio.c | 107 | ||||
-rw-r--r-- | sys/kern/vfs_vnops.c | 77 | ||||
-rw-r--r-- | sys/miscfs/fifofs/fifo_vnops.c | 86 | ||||
-rw-r--r-- | sys/sys/aio.h | 3 | ||||
-rw-r--r-- | sys/sys/file.h | 1 | ||||
-rw-r--r-- | sys/sys/filedesc.h | 7 | ||||
-rw-r--r-- | sys/sys/proc.h | 2 | ||||
-rw-r--r-- | sys/sys/select.h | 3 | ||||
-rw-r--r-- | sys/sys/selinfo.h | 3 | ||||
-rw-r--r-- | sys/sys/socketvar.h | 3 | ||||
-rw-r--r-- | sys/sys/syscall-hide.h | 4 | ||||
-rw-r--r-- | sys/sys/syscall.h | 6 | ||||
-rw-r--r-- | sys/sys/syscall.mk | 6 | ||||
-rw-r--r-- | sys/sys/sysproto.h | 15 | ||||
-rw-r--r-- | sys/sys/tty.h | 2 |
29 files changed, 682 insertions, 18 deletions
diff --git a/sys/fs/fifofs/fifo_vnops.c b/sys/fs/fifofs/fifo_vnops.c index b64f957..5bd13a7 100644 --- a/sys/fs/fifofs/fifo_vnops.c +++ b/sys/fs/fifofs/fifo_vnops.c @@ -46,6 +46,7 @@ #include <sys/filio.h> #include <sys/fcntl.h> #include <sys/file.h> +#include <sys/event.h> #include <sys/poll.h> #include <sys/un.h> #include <miscfs/fifofs/fifo.h> @@ -75,6 +76,17 @@ static int fifo_bmap __P((struct vop_bmap_args *)); static int fifo_pathconf __P((struct vop_pathconf_args *)); static int fifo_advlock __P((struct vop_advlock_args *)); +static int filt_fiforattach(struct knote *kn); +static void filt_fifordetach(struct knote *kn); +static int filt_fiforead(struct knote *kn, long hint); +static int filt_fifowattach(struct knote *kn); +static void filt_fifowdetach(struct knote *kn); +static int filt_fifowrite(struct knote *kn, long hint); + +struct filterops fifo_rwfiltops[] = { + { 1, filt_fiforattach, filt_fifordetach, filt_fiforead }, + { 1, filt_fifowattach, filt_fifowdetach, filt_fifowrite }, +}; vop_t **fifo_vnodeop_p; static struct vnodeopv_entry_desc fifo_vnodeop_entries[] = { @@ -343,6 +355,80 @@ fifo_ioctl(ap) return (0); } +static int +filt_fiforattach(struct knote *kn) +{ + struct vnode *vn = (struct vnode *)kn->kn_fp->f_data; + struct socket *so = (struct socket *)vn->v_fifoinfo->fi_readsock; + + SLIST_INSERT_HEAD(&so->so_rcv.sb_sel.si_note, kn, kn_selnext); + so->so_rcv.sb_flags |= SB_KNOTE; + return (0); +} + +static void +filt_fifordetach(struct knote *kn) +{ + struct vnode *vn = (struct vnode *)kn->kn_fp->f_data; + struct socket *so = (struct socket *)vn->v_fifoinfo->fi_readsock; + + SLIST_REMOVE(&so->so_rcv.sb_sel.si_note, kn, knote, kn_selnext); + if (SLIST_EMPTY(&so->so_rcv.sb_sel.si_note)) + so->so_rcv.sb_flags &= ~SB_KNOTE; +} + +static int +filt_fiforead(struct knote *kn, long hint) +{ + struct vnode *vn = (struct vnode *)kn->kn_fp->f_data; + struct socket *so = (struct socket *)vn->v_fifoinfo->fi_readsock; + + kn->kn_data = so->so_rcv.sb_cc; + if (so->so_state & SS_CANTRCVMORE) { + kn->kn_flags |= EV_EOF; + return (1); + } + kn->kn_flags &= ~EV_EOF; + return (kn->kn_data > 0); +} + +static int +filt_fifowattach(struct knote *kn) +{ + struct vnode *vn = (struct vnode *)kn->kn_fp->f_data; + struct socket *so = (struct socket *)vn->v_fifoinfo->fi_writesock; + + SLIST_INSERT_HEAD(&so->so_snd.sb_sel.si_note, kn, kn_selnext); + so->so_rcv.sb_flags |= SB_KNOTE; + return (0); +} + +static void +filt_fifowdetach(struct knote *kn) +{ + struct vnode *vn = (struct vnode *)kn->kn_fp->f_data; + struct socket *so = (struct socket *)vn->v_fifoinfo->fi_readsock; + + SLIST_REMOVE(&so->so_snd.sb_sel.si_note, kn, knote, kn_selnext); + if (SLIST_EMPTY(&so->so_snd.sb_sel.si_note)) + so->so_snd.sb_flags &= ~SB_KNOTE; +} + +static int +filt_fifowrite(struct knote *kn, long hint) +{ + struct vnode *vn = (struct vnode *)kn->kn_fp->f_data; + struct socket *so = (struct socket *)vn->v_fifoinfo->fi_readsock; + + kn->kn_data = sbspace(&so->so_snd); + if (so->so_state & SS_CANTSENDMORE) { + kn->kn_flags |= EV_EOF; + return (1); + } + kn->kn_flags &= ~EV_EOF; + return (kn->kn_data >= so->so_snd.sb_lowat); +} + /* ARGSUSED */ static int fifo_poll(ap) diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index 64722ba..7d3daa4 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/kern/syscalls.master,v 1.72 2000/01/19 06:01:07 rwatson Exp + * created from FreeBSD: src/sys/kern/syscalls.master,v 1.73 2000/04/03 06:36:14 alfred Exp */ #include "opt_compat.h" @@ -382,4 +382,6 @@ struct sysent sysent[] = { { 2, (sy_call_t *)aio_waitcomplete }, /* 359 = aio_waitcomplete */ { 3, (sy_call_t *)getresuid }, /* 360 = getresuid */ { 3, (sy_call_t *)getresgid }, /* 361 = getresgid */ + { 0, (sy_call_t *)kqueue }, /* 362 = kqueue */ + { 6, (sy_call_t *)kevent }, /* 363 = kevent */ }; diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 1de896e..f0095c97 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -56,6 +56,7 @@ #include <sys/malloc.h> #include <sys/unistd.h> #include <sys/resourcevar.h> +#include <sys/event.h> #include <vm/vm.h> #include <vm/vm_extern.h> @@ -504,6 +505,8 @@ close(p, uap) if (fd < fdp->fd_freefile) fdp->fd_freefile = fd; *pf = 0; + if (fd < fdp->fd_knlistsize) + knote_fdclose(p, fd); return (closef(fp, p)); } @@ -830,9 +833,7 @@ fdinit(p) newfdp->fd_fd.fd_ofiles = newfdp->fd_dfiles; newfdp->fd_fd.fd_ofileflags = newfdp->fd_dfileflags; newfdp->fd_fd.fd_nfiles = NDFILE; - - newfdp->fd_fd.fd_freefile = 0; - newfdp->fd_fd.fd_lastfile = 0; + newfdp->fd_fd.fd_knlistsize = -1; return (&newfdp->fd_fd); } @@ -899,6 +900,21 @@ fdcopy(p) newfdp->fd_nfiles = i; bcopy(fdp->fd_ofiles, newfdp->fd_ofiles, i * sizeof(struct file **)); bcopy(fdp->fd_ofileflags, newfdp->fd_ofileflags, i * sizeof(char)); + + /* + * kq descriptors cannot be copied. + */ + if (newfdp->fd_knlistsize != -1) { + fpp = newfdp->fd_ofiles; + for (i = newfdp->fd_lastfile; i-- >= 0; fpp++) + if (*fpp != NULL && (*fpp)->f_type == DTYPE_KQUEUE) + *fpp = NULL; + newfdp->fd_knlist = NULL; + newfdp->fd_knlistsize = -1; + newfdp->fd_knhash = NULL; + newfdp->fd_knhashmask = 0; + } + fpp = newfdp->fd_ofiles; for (i = newfdp->fd_lastfile; i-- >= 0; fpp++) if (*fpp != NULL) @@ -933,6 +949,10 @@ fdfree(p) vrele(fdp->fd_rdir); if (fdp->fd_jdir) vrele(fdp->fd_jdir); + if (fdp->fd_knlist) + FREE(fdp->fd_knlist, M_TEMP); + if (fdp->fd_knhash) + FREE(fdp->fd_knhash, M_TEMP); FREE(fdp, M_FILEDESC); } diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index ba88695..d9ae6a2 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -311,6 +311,11 @@ interpret: p->p_textvp = ndp->ni_vp; /* + * notify others that we exec'd + */ + KNOTE(&p->p_klist, NOTE_EXEC); + + /* * If tracing the process, trap to debugger so breakpoints * can be set before the program executes. */ diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 9c2005c..9115f97 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -307,6 +307,11 @@ exit1(p, rv) switchticks = ticks; /* + * notify interested parties of our demise. + */ + KNOTE(&p->p_klist, NOTE_EXIT); + + /* * Notify parent that we're gone. If parent has the PS_NOCLDWAIT * flag set, notify process 1 instead (and hope it will handle * this situation). diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index fc69d28..62296b2 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -509,6 +509,11 @@ again: PRELE(p1); /* + * tell any interested parties about the new process + */ + KNOTE(&p1->p_klist, NOTE_FORK | p2->p_pid); + + /* * Preserve synchronization semantics of vfork. If waiting for * child to exec or exit, set P_PPWAIT on child, and sleep on our * proc (in case of exit). diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index e3e0e59..52136d6 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -49,6 +49,7 @@ #include <sys/resourcevar.h> #include <sys/namei.h> #include <sys/vnode.h> +#include <sys/event.h> #include <sys/proc.h> #include <sys/pioctl.h> #include <sys/systm.h> @@ -81,6 +82,13 @@ static int sig_ffs __P((sigset_t *set)); static int sigprop __P((int sig)); static void stop __P((struct proc *)); +static int filt_sigattach(struct knote *kn); +static void filt_sigdetach(struct knote *kn); +static int filt_signal(struct knote *kn, long hint); + +struct filterops sig_filtops = + { 0, filt_sigattach, filt_sigdetach, filt_signal }; + static int kern_logsigexit = 1; SYSCTL_INT(_kern, KERN_LOGSIGEXIT, logsigexit, CTLFLAG_RW, &kern_logsigexit, 0, @@ -1002,6 +1010,8 @@ psignal(p, sig) panic("psignal signal number"); } + KNOTE(&p->p_klist, NOTE_SIGNAL | sig); + prop = sigprop(sig); /* @@ -1688,3 +1698,44 @@ pgsigio(sigio, sig, checkctty) psignal(p, sig); } } + +static int +filt_sigattach(struct knote *kn) +{ + struct proc *p = curproc; + + kn->kn_ptr.p_proc = p; + kn->kn_flags |= EV_CLEAR; /* automatically set */ + + /* XXX lock the proc here while adding to the list? */ + SLIST_INSERT_HEAD(&p->p_klist, kn, kn_selnext); + + return (0); +} + +static void +filt_sigdetach(struct knote *kn) +{ + struct proc *p = kn->kn_ptr.p_proc; + + SLIST_REMOVE(&p->p_klist, kn, knote, kn_selnext); +} + +/* + * signal knotes are shared with proc knotes, so we apply a mask to + * the hint in order to differentiate them from process hints. This + * could be avoided by using a signal-specific knote list, but probably + * isn't worth the trouble. + */ +static int +filt_signal(struct knote *kn, long hint) +{ + + if (hint & NOTE_SIGNAL) { + hint &= ~NOTE_SIGNAL; + + if (kn->kn_id == hint) + kn->kn_data++; + } + return (kn->kn_data != 0); +} diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c index a181b5a..be86883 100644 --- a/sys/kern/sys_pipe.c +++ b/sys/kern/sys_pipe.c @@ -65,6 +65,7 @@ #include <sys/pipe.h> #include <sys/vnode.h> #include <sys/uio.h> +#include <sys/event.h> #include <vm/vm.h> #include <vm/vm_param.h> @@ -100,6 +101,16 @@ static int pipe_ioctl __P((struct file *fp, u_long cmd, caddr_t data, struct pro static struct fileops pipeops = { pipe_read, pipe_write, pipe_ioctl, pipe_poll, pipe_stat, pipe_close }; +static int filt_pipeattach(struct knote *kn); +static void filt_pipedetach(struct knote *kn); +static int filt_piperead(struct knote *kn, long hint); +static int filt_pipewrite(struct knote *kn, long hint); + +struct filterops pipe_rwfiltops[] = { + { 1, filt_pipeattach, filt_pipedetach, filt_piperead }, + { 1, filt_pipeattach, filt_pipedetach, filt_pipewrite }, +}; + /* * Default pipe buffer size(s), this can be kind-of large now because pipe * space is pageable. The pipe code will try to maintain locality of @@ -316,6 +327,7 @@ pipeselwakeup(cpipe) } if ((cpipe->pipe_state & PIPE_ASYNC) && cpipe->pipe_sigio) pgsigio(cpipe->pipe_sigio, SIGIO, 0); + KNOTE(&cpipe->pipe_sel.si_note, 0); } /* ARGSUSED */ @@ -1159,3 +1171,58 @@ pipeclose(cpipe) zfree(pipe_zone, cpipe); } } + +static int +filt_pipeattach(struct knote *kn) +{ + struct pipe *rpipe = (struct pipe *)kn->kn_fp->f_data; + + SLIST_INSERT_HEAD(&rpipe->pipe_sel.si_note, kn, kn_selnext); + return (0); +} + +static void +filt_pipedetach(struct knote *kn) +{ + struct pipe *rpipe = (struct pipe *)kn->kn_fp->f_data; + + SLIST_REMOVE(&rpipe->pipe_sel.si_note, kn, knote, kn_selnext); +} + +/*ARGSUSED*/ +static int +filt_piperead(struct knote *kn, long hint) +{ + struct pipe *rpipe = (struct pipe *)kn->kn_fp->f_data; + struct pipe *wpipe = rpipe->pipe_peer; + + kn->kn_data = rpipe->pipe_buffer.cnt; + if ((kn->kn_data == 0) && (rpipe->pipe_state & PIPE_DIRECTW)) + kn->kn_data = rpipe->pipe_map.cnt; + + if ((rpipe->pipe_state & PIPE_EOF) || + (wpipe == NULL) || (wpipe->pipe_state & PIPE_EOF)) { + kn->kn_flags |= EV_EOF; + return (1); + } + return (kn->kn_data > 0); +} + +/*ARGSUSED*/ +static int +filt_pipewrite(struct knote *kn, long hint) +{ + struct pipe *rpipe = (struct pipe *)kn->kn_fp->f_data; + struct pipe *wpipe = rpipe->pipe_peer; + + if ((wpipe == NULL) || (wpipe->pipe_state & PIPE_EOF)) { + kn->kn_data = 0; + kn->kn_flags |= EV_EOF; + return (1); + } + kn->kn_data = wpipe->pipe_buffer.size - wpipe->pipe_buffer.cnt; + if ((wpipe->pipe_state & PIPE_DIRECTW) == 0) + kn->kn_data = 0; + + return (kn->kn_data >= PIPE_BUF); +} diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index f4afc98..71a63f7 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/kern/syscalls.master,v 1.72 2000/01/19 06:01:07 rwatson Exp + * created from FreeBSD: src/sys/kern/syscalls.master,v 1.73 2000/04/03 06:36:14 alfred Exp */ char *syscallnames[] = { @@ -369,4 +369,6 @@ char *syscallnames[] = { "aio_waitcomplete", /* 359 = aio_waitcomplete */ "getresuid", /* 360 = getresuid */ "getresgid", /* 361 = getresgid */ + "kqueue", /* 362 = kqueue */ + "kevent", /* 363 = kevent */ }; diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 89faed5..e4ba94a 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -515,3 +515,8 @@ 359 STD BSD { int aio_waitcomplete(struct aiocb **aiocbp, struct timespec *timeout); } 360 STD BSD { int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); } 361 STD BSD { int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); } +362 STD BSD { int kqueue(void); } +363 STD BSD { int kevent(int fd, \ + int nchanges, struct kevent **changelist, \ + int nevents, struct kevent *eventlist, \ + struct timespec *timeout); } diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c index 93d1fda..6184c23 100644 --- a/sys/kern/uipc_sockbuf.c +++ b/sys/kern/uipc_sockbuf.c @@ -51,6 +51,7 @@ #include <sys/signalvar.h> #include <sys/sysctl.h> #include <sys/aio.h> /* for aio_swake proto */ +#include <sys/event.h> int maxsockets; @@ -340,6 +341,7 @@ sowakeup(so, sb) (*so->so_upcall)(so, so->so_upcallarg, M_DONTWAIT); if (sb->sb_flags & SB_AIO) aio_swake(so, sb); + KNOTE(&sb->sb_sel.si_note, 0); } /* diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index e4433be..76495e1 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -40,8 +40,10 @@ #include <sys/malloc.h> #include <sys/mbuf.h> #include <sys/domain.h> +#include <sys/file.h> /* for struct knote */ #include <sys/kernel.h> #include <sys/malloc.h> +#include <sys/event.h> #include <sys/poll.h> #include <sys/proc.h> #include <sys/protosw.h> @@ -55,6 +57,22 @@ #include <machine/limits.h> +static int filt_sorattach(struct knote *kn); +static void filt_sordetach(struct knote *kn); +static int filt_soread(struct knote *kn, long hint); +static int filt_sowattach(struct knote *kn); +static void filt_sowdetach(struct knote *kn); +static int filt_sowrite(struct knote *kn, long hint); +static int filt_solisten(struct knote *kn, long hint); + +static struct filterops solisten_filtops = + { 1, filt_sorattach, filt_sordetach, filt_solisten }; + +struct filterops so_rwfiltops[] = { + { 1, filt_sorattach, filt_sordetach, filt_soread }, + { 1, filt_sowattach, filt_sowdetach, filt_sowrite }, +}; + struct vm_zone *socket_zone; so_gen_t so_gencnt; /* generation count for sockets */ @@ -1388,3 +1406,94 @@ sopoll(struct socket *so, int events, struct ucred *cred, struct proc *p) splx(s); return (revents); } + +static int +filt_sorattach(struct knote *kn) +{ + struct socket *so = (struct socket *)kn->kn_fp->f_data; + int s = splnet(); + + if (so->so_options & SO_ACCEPTCONN) + kn->kn_fop = &solisten_filtops; + SLIST_INSERT_HEAD(&so->so_rcv.sb_sel.si_note, kn, kn_selnext); + so->so_rcv.sb_flags |= SB_KNOTE; + splx(s); + return (0); +} + +static void +filt_sordetach(struct knote *kn) +{ + struct socket *so = (struct socket *)kn->kn_fp->f_data; + int s = splnet(); + + SLIST_REMOVE(&so->so_rcv.sb_sel.si_note, kn, knote, kn_selnext); + if (SLIST_EMPTY(&so->so_rcv.sb_sel.si_note)) + so->so_rcv.sb_flags &= ~SB_KNOTE; + splx(s); +} + +/*ARGSUSED*/ +static int +filt_soread(struct knote *kn, long hint) +{ + struct socket *so = (struct socket *)kn->kn_fp->f_data; + + kn->kn_data = so->so_rcv.sb_cc; + if (so->so_state & SS_CANTRCVMORE) { + kn->kn_flags |= EV_EOF; + return (1); + } + return (kn->kn_data > 0); +} + +static int +filt_sowattach(struct knote *kn) +{ + struct socket *so = (struct socket *)kn->kn_fp->f_data; + int s = splnet(); + + SLIST_INSERT_HEAD(&so->so_snd.sb_sel.si_note, kn, kn_selnext); + so->so_snd.sb_flags |= SB_KNOTE; + splx(s); + return (0); +} + +static void +filt_sowdetach(struct knote *kn) +{ + struct socket *so = (struct socket *)kn->kn_fp->f_data; + int s = splnet(); + + SLIST_REMOVE(&so->so_snd.sb_sel.si_note, kn, knote, kn_selnext); + if (SLIST_EMPTY(&so->so_snd.sb_sel.si_note)) + so->so_snd.sb_flags &= ~SB_KNOTE; + splx(s); +} + +/*ARGSUSED*/ +static int +filt_sowrite(struct knote *kn, long hint) +{ + struct socket *so = (struct socket *)kn->kn_fp->f_data; + + kn->kn_data = sbspace(&so->so_snd); + if (so->so_state & SS_CANTSENDMORE) { + kn->kn_flags |= EV_EOF; + return (1); + } + if (((so->so_state & SS_ISCONNECTED) == 0) && + (so->so_proto->pr_flags & PR_CONNREQUIRED)) + return (0); + return (kn->kn_data >= so->so_snd.sb_lowat); +} + +/*ARGSUSED*/ +static int +filt_solisten(struct knote *kn, long hint) +{ + struct socket *so = (struct socket *)kn->kn_fp->f_data; + + kn->kn_data = so->so_qlen - so->so_incqlen; + return (! TAILQ_EMPTY(&so->so_comp)); +} diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c index 93d1fda..6184c23 100644 --- a/sys/kern/uipc_socket2.c +++ b/sys/kern/uipc_socket2.c @@ -51,6 +51,7 @@ #include <sys/signalvar.h> #include <sys/sysctl.h> #include <sys/aio.h> /* for aio_swake proto */ +#include <sys/event.h> int maxsockets; @@ -340,6 +341,7 @@ sowakeup(so, sb) (*so->so_upcall)(so, so->so_upcallarg, M_DONTWAIT); if (sb->sb_flags & SB_AIO) aio_swake(so, sb); + KNOTE(&sb->sb_sel.si_note, 0); } /* diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index 268125f..298bbe1 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -46,6 +46,7 @@ #include <sys/sysproto.h> #include <sys/malloc.h> #include <sys/filedesc.h> +#include <sys/event.h> #include <sys/proc.h> #include <sys/fcntl.h> #include <sys/file.h> @@ -256,6 +257,9 @@ accept1(p, uap, compat) } else p->p_retval[0] = fd; + /* connection has been removed from the listen queue */ + KNOTE(&head->so_rcv.sb_sel.si_note, 0); + so->so_state &= ~SS_COMP; so->so_head = NULL; if (head->so_sigio != NULL) diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c index 28c33cc..0e91fdf 100644 --- a/sys/kern/vfs_aio.c +++ b/sys/kern/vfs_aio.c @@ -38,6 +38,7 @@ #include <sys/sysctl.h> #include <sys/vnode.h> #include <sys/conf.h> +#include <sys/event.h> #include <vm/vm.h> #include <vm/vm_extern.h> @@ -210,6 +211,13 @@ static int aio_fphysio(struct proc *p, struct aiocblist *aiocbe, int type); static int aio_qphysio(struct proc *p, struct aiocblist *iocb); static void aio_daemon(void *uproc); +static int filt_aioattach(struct knote *kn); +static void filt_aiodetach(struct knote *kn); +static int filt_aio(struct knote *kn, long hint); + +struct filterops aio_filtops = + { 0, filt_aioattach, filt_aiodetach, filt_aio }; + SYSINIT(aio, SI_SUB_VFS, SI_ORDER_ANY, aio_onceonly, NULL); static vm_zone_t kaio_zone = 0, aiop_zone = 0, aiocb_zone = 0, aiol_zone = 0; @@ -328,6 +336,9 @@ aio_free_entry(struct aiocblist *aiocbe) num_buf_aio--; } + /* aiocbe is going away, we need to destroy any knotes */ + knote_remove(p, &aiocbe->klist); + if ((ki->kaio_flags & KAIO_WAKEUP) || ((ki->kaio_flags & KAIO_RUNDOWN) && ((ki->kaio_buffer_count == 0) && (ki->kaio_queue_count == 0)))) { ki->kaio_flags &= ~KAIO_WAKEUP; @@ -806,6 +817,7 @@ aio_daemon(void *uproc) plist); } splx(s); + KNOTE(&aiocbe->klist, 0); if (aiocbe->jobflags & AIOCBLIST_RUNDOWN) { wakeup(aiocbe); @@ -933,7 +945,7 @@ aio_qphysio(struct proc *p, struct aiocblist *aiocbe) struct aio_liojob *lj; int fd; int s; - int cnt; + int cnt, notify; cb = &aiocbe->uaiocb; fdp = p->p_fd; @@ -1034,6 +1046,7 @@ aio_qphysio(struct proc *p, struct aiocblist *aiocbe) /* Perform transfer. */ DEV_STRATEGY(bp, 0); + notify = 0; s = splbio(); /* @@ -1059,9 +1072,12 @@ aio_qphysio(struct proc *p, struct aiocblist *aiocbe) TAILQ_REMOVE(&aio_bufjobs, aiocbe, list); TAILQ_REMOVE(&ki->kaio_bufqueue, aiocbe, plist); TAILQ_INSERT_TAIL(&ki->kaio_bufdone, aiocbe, plist); + notify = 1; } } splx(s); + if (notify) + KNOTE(&aiocbe->klist, 0); return 0; doerror: @@ -1174,7 +1190,7 @@ _aio_aqueue(struct proc *p, struct aiocb *job, struct aio_liojob *lj, int type) unsigned int fd; struct socket *so; int s; - int error; + int error = 0; int opcode; struct aiocblist *aiocbe; struct aioproclist *aiop; @@ -1187,6 +1203,7 @@ _aio_aqueue(struct proc *p, struct aiocb *job, struct aio_liojob *lj, int type) aiocbe->inputcharge = 0; aiocbe->outputcharge = 0; + SLIST_INIT(&aiocbe->klist); suword(&job->_aiocb_private.status, -1); suword(&job->_aiocb_private.error, 0); @@ -1272,6 +1289,45 @@ _aio_aqueue(struct proc *p, struct aiocb *job, struct aio_liojob *lj, int type) return EINVAL; } + /* + * XXX + * Figure out how to do this properly. This currently won't + * work on the alpha, since we're passing in a pointer via + * aio_lio_opcode, which is an int. + */ + { + struct kevent kev, *kevp; + struct kqueue *kq; + + kevp = (struct kevent *)job->aio_lio_opcode; + if (kevp == NULL) + goto no_kqueue; + + error = copyin((caddr_t)kevp, (caddr_t)&kev, sizeof(kev)); + if (error) + goto aqueue_fail; + + if ((u_int)kev.ident >= fdp->fd_nfiles || + (fp = fdp->fd_ofiles[kev.ident]) == NULL || + (fp->f_type != DTYPE_KQUEUE)) { + error = EBADF; + goto aqueue_fail; + } + kq = (struct kqueue *)fp->f_data; + kev.ident = (u_long)aiocbe; + kev.filter = EVFILT_AIO; + kev.flags = EV_ADD | EV_ENABLE | EV_FLAG1; + error = kqueue_register(kq, &kev, p); +aqueue_fail: + if (error) { + TAILQ_INSERT_HEAD(&aio_freejobs, aiocbe, list); + if (type == 0) + suword(&job->_aiocb_private.error, error); + return (error); + } +no_kqueue: + } + suword(&job->_aiocb_private.error, EINPROGRESS); aiocbe->uaiocb._aiocb_private.error = EINPROGRESS; aiocbe->userproc = p; @@ -1629,6 +1685,7 @@ aio_cancel(struct proc *p, struct aio_cancel_args *uap) cbe->uaiocb._aiocb_private.status=-1; cbe->uaiocb._aiocb_private.error=ECANCELED; cancelled++; +/* XXX cancelled, knote? */ if (cbe->uaiocb.aio_sigevent.sigev_notify == SIGEV_SIGNAL) psignal(cbe->userproc, cbe->uaiocb.aio_sigevent.sigev_signo); @@ -1667,6 +1724,7 @@ aio_cancel(struct proc *p, struct aio_cancel_args *uap) cbe->jobstate = JOBST_JOBFINISHED; cbe->uaiocb._aiocb_private.status = -1; cbe->uaiocb._aiocb_private.error = ECANCELED; +/* XXX cancelled, knote? */ if (cbe->uaiocb.aio_sigevent.sigev_notify == SIGEV_SIGNAL) psignal(cbe->userproc, cbe->uaiocb.aio_sigevent.sigev_signo); @@ -2173,7 +2231,8 @@ aio_physwakeup(struct buf *bp) TAILQ_REMOVE(&aio_bufjobs, aiocbe, list); TAILQ_REMOVE(&ki->kaio_bufqueue, aiocbe, plist); TAILQ_INSERT_TAIL(&ki->kaio_bufdone, aiocbe, plist); - + + KNOTE(&aiocbe->klist, 0); /* Do the wakeup. */ if (ki->kaio_flags & (KAIO_RUNDOWN|KAIO_WAKEUP)) { ki->kaio_flags &= ~KAIO_WAKEUP; @@ -2266,3 +2325,45 @@ aio_waitcomplete(struct proc *p, struct aio_waitcomplete_args *uap) } #endif /* VFS_AIO */ } + +static int +filt_aioattach(struct knote *kn) +{ + struct aiocblist *aiocbe = (struct aiocblist *)kn->kn_id; + + /* + * The aiocbe pointer must be validated before using it, so + * registration is restricted to the kernel; the user cannot + * set EV_FLAG1. + */ + if ((kn->kn_flags & EV_FLAG1) == 0) + return (EPERM); + kn->kn_flags &= ~EV_FLAG1; + + SLIST_INSERT_HEAD(&aiocbe->klist, kn, kn_selnext); + + return (0); +} + +static void +filt_aiodetach(struct knote *kn) +{ + struct aiocblist *aiocbe = (struct aiocblist *)kn->kn_id; + int s = splhigh(); /* XXX no clue, so overkill */ + + SLIST_REMOVE(&aiocbe->klist, kn, knote, kn_selnext); + splx(s); +} + +/*ARGSUSED*/ +static int +filt_aio(struct knote *kn, long hint) +{ + struct aiocblist *aiocbe = (struct aiocblist *)kn->kn_id; + + kn->kn_data = 0; /* XXX data returned? */ + if (aiocbe->jobstate != JOBST_JOBFINISHED) + return (0); + kn->kn_flags |= EV_EOF; + return (1); +} diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 9f1a387..705ac34 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -54,6 +54,9 @@ #include <sys/conf.h> #include <vm/vm_zone.h> +#include <ufs/ufs/quota.h> +#include <ufs/ufs/inode.h> + static int vn_closefile __P((struct file *fp, struct proc *p)); static int vn_ioctl __P((struct file *fp, u_long com, caddr_t data, struct proc *p)); @@ -68,6 +71,25 @@ static int vn_write __P((struct file *fp, struct uio *uio, struct fileops vnops = { vn_read, vn_write, vn_ioctl, vn_poll, vn_statfile, vn_closefile }; +static int filt_nullattach(struct knote *kn); +static int filt_vnattach(struct knote *kn); +static void filt_vndetach(struct knote *kn); +static int filt_vnode(struct knote *kn, long hint); +static int filt_vnread(struct knote *kn, long hint); + +struct filterops vn_filtops = + { 1, filt_vnattach, filt_vndetach, filt_vnode }; + +/* + * XXX + * filt_vnread is ufs-specific, so the attach routine should really + * switch out to different filterops based on the vn filetype + */ +struct filterops vn_rwfiltops[] = { + { 1, filt_vnattach, filt_vndetach, filt_vnread }, + { 1, filt_nullattach, NULL, NULL }, +}; + /* * Common code for vnode open operations. * Check permissions, and call the VOP_OPEN or VOP_CREATE routine. @@ -637,3 +659,58 @@ vn_closefile(fp, p) return (vn_close(((struct vnode *)fp->f_data), fp->f_flag, fp->f_cred, p)); } + +static int +filt_vnattach(struct knote *kn) +{ + struct vnode *vp; + + if (kn->kn_fp->f_type != DTYPE_VNODE && + kn->kn_fp->f_type != DTYPE_FIFO) + return (EBADF); + + vp = (struct vnode *)kn->kn_fp->f_data; + + simple_lock(&vp->v_pollinfo.vpi_lock); + SLIST_INSERT_HEAD(&vp->v_pollinfo.vpi_selinfo.si_note, kn, kn_selnext); + simple_unlock(&vp->v_pollinfo.vpi_lock); + + return (0); +} + +static void +filt_vndetach(struct knote *kn) +{ + struct vnode *vp = (struct vnode *)kn->kn_fp->f_data; + + simple_lock(&vp->v_pollinfo.vpi_lock); + SLIST_REMOVE(&vp->v_pollinfo.vpi_selinfo.si_note, + kn, knote, kn_selnext); + simple_unlock(&vp->v_pollinfo.vpi_lock); +} + +static int +filt_vnode(struct knote *kn, long hint) +{ + + if (kn->kn_sfflags & hint) + kn->kn_fflags |= hint; + return (kn->kn_fflags != 0); +} + +static int +filt_nullattach(struct knote *kn) +{ + return (ENXIO); +} + +/*ARGSUSED*/ +static int +filt_vnread(struct knote *kn, long hint) +{ + struct vnode *vp = (struct vnode *)kn->kn_fp->f_data; + struct inode *ip = VTOI(vp); + + kn->kn_data = ip->i_size - kn->kn_fp->f_offset; + return (kn->kn_data != 0); +} diff --git a/sys/miscfs/fifofs/fifo_vnops.c b/sys/miscfs/fifofs/fifo_vnops.c index b64f957..5bd13a7 100644 --- a/sys/miscfs/fifofs/fifo_vnops.c +++ b/sys/miscfs/fifofs/fifo_vnops.c @@ -46,6 +46,7 @@ #include <sys/filio.h> #include <sys/fcntl.h> #include <sys/file.h> +#include <sys/event.h> #include <sys/poll.h> #include <sys/un.h> #include <miscfs/fifofs/fifo.h> @@ -75,6 +76,17 @@ static int fifo_bmap __P((struct vop_bmap_args *)); static int fifo_pathconf __P((struct vop_pathconf_args *)); static int fifo_advlock __P((struct vop_advlock_args *)); +static int filt_fiforattach(struct knote *kn); +static void filt_fifordetach(struct knote *kn); +static int filt_fiforead(struct knote *kn, long hint); +static int filt_fifowattach(struct knote *kn); +static void filt_fifowdetach(struct knote *kn); +static int filt_fifowrite(struct knote *kn, long hint); + +struct filterops fifo_rwfiltops[] = { + { 1, filt_fiforattach, filt_fifordetach, filt_fiforead }, + { 1, filt_fifowattach, filt_fifowdetach, filt_fifowrite }, +}; vop_t **fifo_vnodeop_p; static struct vnodeopv_entry_desc fifo_vnodeop_entries[] = { @@ -343,6 +355,80 @@ fifo_ioctl(ap) return (0); } +static int +filt_fiforattach(struct knote *kn) +{ + struct vnode *vn = (struct vnode *)kn->kn_fp->f_data; + struct socket *so = (struct socket *)vn->v_fifoinfo->fi_readsock; + + SLIST_INSERT_HEAD(&so->so_rcv.sb_sel.si_note, kn, kn_selnext); + so->so_rcv.sb_flags |= SB_KNOTE; + return (0); +} + +static void +filt_fifordetach(struct knote *kn) +{ + struct vnode *vn = (struct vnode *)kn->kn_fp->f_data; + struct socket *so = (struct socket *)vn->v_fifoinfo->fi_readsock; + + SLIST_REMOVE(&so->so_rcv.sb_sel.si_note, kn, knote, kn_selnext); + if (SLIST_EMPTY(&so->so_rcv.sb_sel.si_note)) + so->so_rcv.sb_flags &= ~SB_KNOTE; +} + +static int +filt_fiforead(struct knote *kn, long hint) +{ + struct vnode *vn = (struct vnode *)kn->kn_fp->f_data; + struct socket *so = (struct socket *)vn->v_fifoinfo->fi_readsock; + + kn->kn_data = so->so_rcv.sb_cc; + if (so->so_state & SS_CANTRCVMORE) { + kn->kn_flags |= EV_EOF; + return (1); + } + kn->kn_flags &= ~EV_EOF; + return (kn->kn_data > 0); +} + +static int +filt_fifowattach(struct knote *kn) +{ + struct vnode *vn = (struct vnode *)kn->kn_fp->f_data; + struct socket *so = (struct socket *)vn->v_fifoinfo->fi_writesock; + + SLIST_INSERT_HEAD(&so->so_snd.sb_sel.si_note, kn, kn_selnext); + so->so_rcv.sb_flags |= SB_KNOTE; + return (0); +} + +static void +filt_fifowdetach(struct knote *kn) +{ + struct vnode *vn = (struct vnode *)kn->kn_fp->f_data; + struct socket *so = (struct socket *)vn->v_fifoinfo->fi_readsock; + + SLIST_REMOVE(&so->so_snd.sb_sel.si_note, kn, knote, kn_selnext); + if (SLIST_EMPTY(&so->so_snd.sb_sel.si_note)) + so->so_snd.sb_flags &= ~SB_KNOTE; +} + +static int +filt_fifowrite(struct knote *kn, long hint) +{ + struct vnode *vn = (struct vnode *)kn->kn_fp->f_data; + struct socket *so = (struct socket *)vn->v_fifoinfo->fi_readsock; + + kn->kn_data = sbspace(&so->so_snd); + if (so->so_state & SS_CANTSENDMORE) { + kn->kn_flags |= EV_EOF; + return (1); + } + kn->kn_flags &= ~EV_EOF; + return (kn->kn_data >= so->so_snd.sb_lowat); +} + /* ARGSUSED */ static int fifo_poll(ap) diff --git a/sys/sys/aio.h b/sys/sys/aio.h index e905c89..b6be86e 100644 --- a/sys/sys/aio.h +++ b/sys/sys/aio.h @@ -22,7 +22,6 @@ #include <sys/time.h> #include <sys/types.h> #include <sys/signal.h> -#include <sys/socketvar.h> /* * Returned by aio_cancel: @@ -168,11 +167,11 @@ struct aiocblist { struct aioproclist *jobaioproc;/* AIO process descriptor */ struct aio_liojob *lio; /* Optional lio job */ struct aiocb *uuaiocb; /* Pointer in userspace of aiocb */ + struct klist klist; /* list of knotes */ struct aiocb uaiocb; /* Kernel I/O control block */ }; void aio_proc_rundown(struct proc *p); - void aio_swake(struct socket *, struct sockbuf *); #endif diff --git a/sys/sys/file.h b/sys/sys/file.h index 7986425..7ad7a81 100644 --- a/sys/sys/file.h +++ b/sys/sys/file.h @@ -60,6 +60,7 @@ struct file { #define DTYPE_SOCKET 2 /* communications endpoint */ #define DTYPE_PIPE 3 /* pipe */ #define DTYPE_FIFO 4 /* fifo (named pipe) */ +#define DTYPE_KQUEUE 5 /* event queue */ short f_type; /* descriptor type */ short f_count; /* reference count */ short f_msgcount; /* references from message queue */ diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h index 43630ba..9b07cfe 100644 --- a/sys/sys/filedesc.h +++ b/sys/sys/filedesc.h @@ -56,6 +56,8 @@ #define NDFILE 20 #define NDEXTENT 50 /* 250 bytes in 256-byte alloc. */ +struct klist; + struct filedesc { struct file **fd_ofiles; /* file structures for open files */ char *fd_ofileflags; /* per-process open file flags */ @@ -67,6 +69,11 @@ struct filedesc { u_short fd_freefile; /* approx. next free file */ u_short fd_cmask; /* mask for file creation */ u_short fd_refcnt; /* reference count */ + + int fd_knlistsize; /* size of knlist */ + struct klist *fd_knlist; /* list of attached knotes */ + u_long fd_knhashmask; /* size of knhash */ + struct klist *fd_knhash; /* hash table for attached knotes */ }; /* diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 4e9ddde..d75f033 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -52,6 +52,7 @@ #include <sys/time.h> /* For structs itimerval, timeval. */ #endif #include <sys/ucred.h> +#include <sys/event.h> /* For struct klist */ /* * One structure allocated per session. @@ -205,6 +206,7 @@ struct proc { sigset_t p_oldsigmask; /* saved mask from before sigpause */ int p_sig; /* for core dump/debugger XXX */ u_long p_code; /* for core dump/debugger XXX */ + struct klist p_klist; /* knotes attached to this process */ /* End area that is zeroed on creation. */ #define p_endzero p_startcopy diff --git a/sys/sys/select.h b/sys/sys/select.h index 8f58d85..4909a34 100644 --- a/sys/sys/select.h +++ b/sys/sys/select.h @@ -37,12 +37,15 @@ #ifndef _SYS_SELECT_H_ #define _SYS_SELECT_H_ +#include <sys/event.h> /* for struct klist */ + /* * Used to maintain information about processes that wish to be * notified when I/O becomes possible. */ struct selinfo { pid_t si_pid; /* process to be notified */ + struct klist si_note; /* kernel note list */ short si_flags; /* see below */ }; #define SI_COLL 0x0001 /* collision occurred */ diff --git a/sys/sys/selinfo.h b/sys/sys/selinfo.h index 8f58d85..4909a34 100644 --- a/sys/sys/selinfo.h +++ b/sys/sys/selinfo.h @@ -37,12 +37,15 @@ #ifndef _SYS_SELECT_H_ #define _SYS_SELECT_H_ +#include <sys/event.h> /* for struct klist */ + /* * Used to maintain information about processes that wish to be * notified when I/O becomes possible. */ struct selinfo { pid_t si_pid; /* process to be notified */ + struct klist si_note; /* kernel note list */ short si_flags; /* see below */ }; #define SI_COLL 0x0001 /* collision occurred */ diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h index 1b6d94c..add6eb6 100644 --- a/sys/sys/socketvar.h +++ b/sys/sys/socketvar.h @@ -104,6 +104,7 @@ struct socket { #define SB_UPCALL 0x20 /* someone wants an upcall */ #define SB_NOINTR 0x40 /* operations not interruptible */ #define SB_AIO 0x80 /* AIO operations queued */ +#define SB_KNOTE 0x100 /* kernel note attached */ void (*so_upcall) __P((struct socket *, void *, int)); void *so_upcallarg; @@ -172,7 +173,7 @@ struct xsocket { * Do we need to notify the other side when I/O is possible? */ #define sb_notify(sb) (((sb)->sb_flags & (SB_WAIT | SB_SEL | SB_ASYNC | \ - SB_UPCALL | SB_AIO)) != 0) + SB_UPCALL | SB_AIO | SB_KNOTE)) != 0) /* * How much space is there in a socket buffer (so->so_snd or so->so_rcv)? diff --git a/sys/sys/syscall-hide.h b/sys/sys/syscall-hide.h index 29b849f..faf13ed 100644 --- a/sys/sys/syscall-hide.h +++ b/sys/sys/syscall-hide.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/kern/syscalls.master,v 1.72 2000/01/19 06:01:07 rwatson Exp + * created from FreeBSD: src/sys/kern/syscalls.master,v 1.73 2000/04/03 06:36:14 alfred Exp */ HIDE_POSIX(fork) @@ -279,3 +279,5 @@ HIDE_BSD(extattr_delete_file) HIDE_BSD(aio_waitcomplete) HIDE_BSD(getresuid) HIDE_BSD(getresgid) +HIDE_BSD(kqueue) +HIDE_BSD(kevent) diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h index fb2a49a..a8af2a8 100644 --- a/sys/sys/syscall.h +++ b/sys/sys/syscall.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/kern/syscalls.master,v 1.72 2000/01/19 06:01:07 rwatson Exp + * created from FreeBSD: src/sys/kern/syscalls.master,v 1.73 2000/04/03 06:36:14 alfred Exp */ #define SYS_syscall 0 @@ -284,4 +284,6 @@ #define SYS_aio_waitcomplete 359 #define SYS_getresuid 360 #define SYS_getresgid 361 -#define SYS_MAXSYSCALL 362 +#define SYS_kqueue 362 +#define SYS_kevent 363 +#define SYS_MAXSYSCALL 364 diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk index 54126ed..7477758 100644 --- a/sys/sys/syscall.mk +++ b/sys/sys/syscall.mk @@ -1,7 +1,7 @@ # FreeBSD system call names. # DO NOT EDIT-- this file is automatically generated. # $FreeBSD$ -# created from FreeBSD: src/sys/kern/syscalls.master,v 1.72 2000/01/19 06:01:07 rwatson Exp +# created from FreeBSD: src/sys/kern/syscalls.master,v 1.73 2000/04/03 06:36:14 alfred Exp MIASM = \ syscall.o \ exit.o \ @@ -234,4 +234,6 @@ MIASM = \ extattr_delete_file.o \ aio_waitcomplete.o \ getresuid.o \ - getresgid.o + getresgid.o \ + kqueue.o \ + kevent.o diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h index cbe86de..c36a64d 100644 --- a/sys/sys/sysproto.h +++ b/sys/sys/sysproto.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/kern/syscalls.master,v 1.72 2000/01/19 06:01:07 rwatson Exp + * created from FreeBSD: src/sys/kern/syscalls.master,v 1.73 2000/04/03 06:36:14 alfred Exp */ #ifndef _SYS_SYSPROTO_H_ @@ -1013,6 +1013,17 @@ struct getresgid_args { gid_t * egid; char egid_[PAD_(gid_t *)]; gid_t * sgid; char sgid_[PAD_(gid_t *)]; }; +struct kqueue_args { + register_t dummy; +}; +struct kevent_args { + int fd; char fd_[PAD_(int)]; + int nchanges; char nchanges_[PAD_(int)]; + struct kevent ** changelist; char changelist_[PAD_(struct kevent **)]; + int nevents; char nevents_[PAD_(int)]; + struct kevent * eventlist; char eventlist_[PAD_(struct kevent *)]; + struct timespec * timeout; char timeout_[PAD_(struct timespec *)]; +}; int nosys __P((struct proc *, struct nosys_args *)); void exit __P((struct proc *, struct rexit_args *)) __dead2; int fork __P((struct proc *, struct fork_args *)); @@ -1243,6 +1254,8 @@ int extattr_delete_file __P((struct proc *, struct extattr_delete_file_args *)); int aio_waitcomplete __P((struct proc *, struct aio_waitcomplete_args *)); int getresuid __P((struct proc *, struct getresuid_args *)); int getresgid __P((struct proc *, struct getresgid_args *)); +int kqueue __P((struct proc *, struct kqueue_args *)); +int kevent __P((struct proc *, struct kevent_args *)); #ifdef COMPAT_43 diff --git a/sys/sys/tty.h b/sys/sys/tty.h index 46b11ea..c6f4056 100644 --- a/sys/sys/tty.h +++ b/sys/sys/tty.h @@ -43,8 +43,8 @@ #define _SYS_TTY_H_ #include <sys/termios.h> -#include <sys/select.h> /* For struct selinfo. */ #include <sys/queue.h> +#include <sys/select.h> /* For struct selinfo. */ /* * Clists are character lists, which is a variable length linked list |