diff options
Diffstat (limited to 'sys/kern/sys_pipe.c')
-rw-r--r-- | sys/kern/sys_pipe.c | 67 |
1 files changed, 31 insertions, 36 deletions
diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c index ac7416eb1df..3e36d581fd4 100644 --- a/sys/kern/sys_pipe.c +++ b/sys/kern/sys_pipe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sys_pipe.c,v 1.43 2002/03/14 01:27:04 millert Exp $ */ +/* $OpenBSD: sys_pipe.c,v 1.44 2003/09/23 16:51:12 millert Exp $ */ /* * Copyright (c) 1996 John S. Dyson @@ -46,6 +46,7 @@ #include <sys/syscallargs.h> #include <sys/event.h> #include <sys/lock.h> +#include <sys/poll.h> #include <uvm/uvm_extern.h> @@ -57,13 +58,13 @@ int pipe_read(struct file *, off_t *, struct uio *, struct ucred *); int pipe_write(struct file *, off_t *, struct uio *, struct ucred *); int pipe_close(struct file *, struct proc *); -int pipe_select(struct file *, int which, struct proc *); +int pipe_poll(struct file *, int events, struct proc *); int pipe_kqfilter(struct file *fp, struct knote *kn); int pipe_ioctl(struct file *, u_long, caddr_t, struct proc *); int pipe_stat(struct file *fp, struct stat *ub, struct proc *p); static struct fileops pipeops = { - pipe_read, pipe_write, pipe_ioctl, pipe_select, pipe_kqfilter, + pipe_read, pipe_write, pipe_ioctl, pipe_poll, pipe_kqfilter, pipe_stat, pipe_close }; @@ -540,7 +541,7 @@ retrywrite: /* * We have no more space and have something to offer, - * wake up selects. + * wake up select/poll. */ pipeselwakeup(wpipe); @@ -587,8 +588,7 @@ retrywrite: if (error == 0) microtime(&wpipe->pipe_mtime); /* - * We have something to offer, - * wake up select. + * We have something to offer, wake up select/poll. */ if (wpipe->pipe_buffer.cnt) pipeselwakeup(wpipe); @@ -638,48 +638,43 @@ pipe_ioctl(fp, cmd, data, p) } int -pipe_select(fp, which, p) +pipe_poll(fp, events, p) struct file *fp; - int which; + int events; struct proc *p; { struct pipe *rpipe = (struct pipe *)fp->f_data; struct pipe *wpipe; + int revents = 0; wpipe = rpipe->pipe_peer; - switch (which) { - - case FREAD: + if (events & (POLLIN | POLLRDNORM)) { if ((rpipe->pipe_buffer.cnt > 0) || - (rpipe->pipe_state & PIPE_EOF)) { - return (1); - } - selrecord(p, &rpipe->pipe_sel); - rpipe->pipe_state |= PIPE_SEL; - break; + (rpipe->pipe_state & PIPE_EOF)) + revents |= events & (POLLIN | POLLRDNORM); + } - case FWRITE: - if ((wpipe == NULL) || - (wpipe->pipe_state & PIPE_EOF) || - ((wpipe->pipe_buffer.size - wpipe->pipe_buffer.cnt) >= PIPE_BUF)) { - return (1); - } - selrecord(p, &wpipe->pipe_sel); - wpipe->pipe_state |= PIPE_SEL; - break; + /* NOTE: POLLHUP and POLLOUT/POLLWRNORM are mutually exclusive */ + if ((rpipe->pipe_state & PIPE_EOF) || + (wpipe == NULL) || + (wpipe->pipe_state & PIPE_EOF)) + revents |= POLLHUP; + else if (events & (POLLOUT | POLLWRNORM)) { + if ((wpipe->pipe_buffer.size - wpipe->pipe_buffer.cnt) >= PIPE_BUF) + revents |= events & (POLLOUT | POLLWRNORM); + } - case 0: - if ((rpipe->pipe_state & PIPE_EOF) || - (wpipe == NULL) || - (wpipe->pipe_state & PIPE_EOF)) { - return (1); + if (revents == 0) { + if (events & (POLLIN | POLLRDNORM)) { + selrecord(p, &rpipe->pipe_sel); + rpipe->pipe_state |= PIPE_SEL; + } + if (events & (POLLOUT | POLLWRNORM)) { + selrecord(p, &wpipe->pipe_sel); + wpipe->pipe_state |= PIPE_SEL; } - - selrecord(p, &rpipe->pipe_sel); - rpipe->pipe_state |= PIPE_SEL; - break; } - return (0); + return (revents); } int |