summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2003-09-23 16:51:15 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2003-09-23 16:51:15 +0000
commit6bb276a1685d8546283d224a3d249c66cc329264 (patch)
tree5e1c80d6cad38a8a82f5832e1e315103e7029eb9 /sys/kern
parent96675671ec2520ade2f83b31563ab4da72bd443d (diff)
Replace select backends with poll backends. selscan() and pollscan()
now call the poll backend. With this change we implement greater poll(2) functionality instead of emulating it via the select backend. Adapted from NetBSD and including some changes from FreeBSD. Tested by many, deraadt@ OK
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_event.c17
-rw-r--r--sys/kern/spec_vnops.c17
-rw-r--r--sys/kern/subr_log.c24
-rw-r--r--sys/kern/sys_generic.c71
-rw-r--r--sys/kern/sys_pipe.c67
-rw-r--r--sys/kern/sys_socket.c61
-rw-r--r--sys/kern/tty.c43
-rw-r--r--sys/kern/tty_pty.c85
-rw-r--r--sys/kern/tty_tty.c12
-rw-r--r--sys/kern/vfs_vnops.c16
10 files changed, 194 insertions, 219 deletions
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index b5d265159d7..368bc6c79b6 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_event.c,v 1.20 2003/08/15 20:32:18 tedu Exp $ */
+/* $OpenBSD: kern_event.c,v 1.21 2003/09/23 16:51:12 millert Exp $ */
/*-
* Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org>
@@ -48,6 +48,7 @@
#include <sys/stat.h>
#include <sys/uio.h>
#include <sys/mount.h>
+#include <sys/poll.h>
#include <sys/syscallargs.h>
int kqueue_scan(struct file *fp, int maxevents,
@@ -60,7 +61,7 @@ int kqueue_write(struct file *fp, off_t *poff, struct uio *uio,
struct ucred *cred);
int kqueue_ioctl(struct file *fp, u_long com, caddr_t data,
struct proc *p);
-int kqueue_select(struct file *fp, int which, struct proc *p);
+int kqueue_poll(struct file *fp, int events, struct proc *p);
int kqueue_kqfilter(struct file *fp, struct knote *kn);
int kqueue_stat(struct file *fp, struct stat *st, struct proc *p);
int kqueue_close(struct file *fp, struct proc *p);
@@ -70,7 +71,7 @@ struct fileops kqueueops = {
kqueue_read,
kqueue_write,
kqueue_ioctl,
- kqueue_select,
+ kqueue_poll,
kqueue_kqfilter,
kqueue_stat,
kqueue_close
@@ -700,22 +701,22 @@ kqueue_ioctl(struct file *fp, u_long com, caddr_t data, struct proc *p)
/*ARGSUSED*/
int
-kqueue_select(struct file *fp, int which, struct proc *p)
+kqueue_poll(struct file *fp, int events, struct proc *p)
{
struct kqueue *kq = (struct kqueue *)fp->f_data;
- int res = 0;
+ int revents = 0;
int s = splnet();
- if (which == FREAD) {
+ if (events & (POLLIN | POLLRDNORM)) {
if (kq->kq_count) {
- res = 1;
+ revents |= events & (POLLIN | POLLRDNORM);
} else {
selrecord(p, &kq->kq_sel);
kq->kq_state |= KQ_SEL;
}
}
splx(s);
- return (res);
+ return (revents);
}
/*ARGSUSED*/
diff --git a/sys/kern/spec_vnops.c b/sys/kern/spec_vnops.c
index f945ef378ca..c3e675b5905 100644
--- a/sys/kern/spec_vnops.c
+++ b/sys/kern/spec_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: spec_vnops.c,v 1.26 2003/06/02 23:28:11 millert Exp $ */
+/* $OpenBSD: spec_vnops.c,v 1.27 2003/09/23 16:51:13 millert Exp $ */
/* $NetBSD: spec_vnops.c,v 1.29 1996/04/22 01:42:38 christos Exp $ */
/*
@@ -47,6 +47,7 @@
#include <sys/file.h>
#include <sys/disklabel.h>
#include <sys/lockf.h>
+#include <sys/poll.h>
#include <miscfs/specfs/specdev.h>
@@ -78,7 +79,7 @@ struct vnodeopv_entry_desc spec_vnodeop_entries[] = {
{ &vop_write_desc, spec_write }, /* write */
{ &vop_lease_desc, spec_lease_check }, /* lease */
{ &vop_ioctl_desc, spec_ioctl }, /* ioctl */
- { &vop_select_desc, spec_select }, /* select */
+ { &vop_poll_desc, spec_poll }, /* poll */
{ &vop_kqfilter_desc, spec_kqfilter }, /* kqfilter */
{ &vop_revoke_desc, spec_revoke }, /* revoke */
{ &vop_fsync_desc, spec_fsync }, /* fsync */
@@ -450,14 +451,12 @@ spec_ioctl(v)
/* ARGSUSED */
int
-spec_select(v)
+spec_poll(v)
void *v;
{
- struct vop_select_args /* {
+ struct vop_poll_args /* {
struct vnode *a_vp;
- int a_which;
- int a_fflags;
- struct ucred *a_cred;
+ int a_events;
struct proc *a_p;
} */ *ap = v;
register dev_t dev;
@@ -465,11 +464,11 @@ spec_select(v)
switch (ap->a_vp->v_type) {
default:
- return (1); /* XXX */
+ return (seltrue(ap->a_vp->v_rdev, ap->a_events, ap->a_p));
case VCHR:
dev = ap->a_vp->v_rdev;
- return (*cdevsw[major(dev)].d_select)(dev, ap->a_which, ap->a_p);
+ return (*cdevsw[major(dev)].d_poll)(dev, ap->a_events, ap->a_p);
}
}
/* ARGSUSED */
diff --git a/sys/kern/subr_log.c b/sys/kern/subr_log.c
index 292bf55e35f..98eb65c87ca 100644
--- a/sys/kern/subr_log.c
+++ b/sys/kern/subr_log.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: subr_log.c,v 1.10 2003/07/21 22:44:50 tedu Exp $ */
+/* $OpenBSD: subr_log.c,v 1.11 2003/09/23 16:51:12 millert Exp $ */
/* $NetBSD: subr_log.c,v 1.11 1996/03/30 22:24:44 christos Exp $ */
/*
@@ -46,6 +46,7 @@
#include <sys/signalvar.h>
#include <sys/syslog.h>
#include <sys/conf.h>
+#include <sys/poll.h>
#define LOG_RDPRI (PZERO + 1)
@@ -178,25 +179,22 @@ logread(dev, uio, flag)
/*ARGSUSED*/
int
-logselect(dev, rw, p)
+logpoll(dev, events, p)
dev_t dev;
- int rw;
+ int events;
struct proc *p;
{
+ int revents = 0;
int s = splhigh();
- switch (rw) {
-
- case FREAD:
- if (msgbufp->msg_bufr != msgbufp->msg_bufx) {
- splx(s);
- return (1);
- }
- selrecord(p, &logsoftc.sc_selp);
- break;
+ if (events & (POLLIN | POLLRDNORM)) {
+ if (msgbufp->msg_bufr != msgbufp->msg_bufx)
+ revents |= events & (POLLIN | POLLRDNORM);
+ else
+ selrecord(p, &logsoftc.sc_selp);
}
splx(s);
- return (0);
+ return (revents);
}
int
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
index 3a668bac241..713de532eaa 100644
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sys_generic.c,v 1.45 2003/09/01 18:06:03 henning Exp $ */
+/* $OpenBSD: sys_generic.c,v 1.46 2003/09/23 16:51:12 millert Exp $ */
/* $NetBSD: sys_generic.c,v 1.24 1996/03/29 00:25:32 cgd Exp $ */
/*
@@ -767,7 +767,7 @@ selscan(p, ibits, obits, nfd, retval)
register fd_mask bits;
struct file *fp;
int ni, n = 0;
- static int flag[3] = { FREAD, FWRITE, 0 };
+ static const int flag[3] = { POLLIN, POLLOUT, POLLPRI };
/*
* if nfd > FD_SETSIZE then the fd_set's contain nfd bits (rounded
@@ -788,7 +788,7 @@ selscan(p, ibits, obits, nfd, retval)
if ((fp = fd_getfile(fdp, fd)) == NULL)
return (EBADF);
FREF(fp);
- if ((*fp->f_ops->fo_select)(fp, flag[msk], p)) {
+ if ((*fp->f_ops->fo_poll)(fp, flag[msk], p)) {
FD_SET(fd, pobits);
n++;
}
@@ -802,13 +802,13 @@ selscan(p, ibits, obits, nfd, retval)
/*ARGSUSED*/
int
-seltrue(dev, flag, p)
+seltrue(dev, events, p)
dev_t dev;
- int flag;
+ int events;
struct proc *p;
{
- return (1);
+ return (events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
}
/*
@@ -871,39 +871,25 @@ pollscan(p, pl, nfd, retval)
int nfd;
register_t *retval;
{
- register struct filedesc *fdp = p->p_fd;
- register int msk, i;
+ struct filedesc *fdp = p->p_fd;
struct file *fp;
- int x, n = 0;
- static int flag[3] = { FREAD, FWRITE, 0 };
- static int pflag[3] = { POLLIN|POLLRDNORM, POLLOUT, POLLERR };
+ int i, n = 0;
- /*
- * XXX: We need to implement the rest of the flags.
- */
- for (i = 0; i < nfd; i++) {
+ for (i = 0; i < nfd; i++, pl++) {
/* Check the file descriptor. */
- if (pl[i].fd < 0) {
- pl[i].revents = 0;
+ if (pl->fd < 0) {
+ pl->revents = 0;
continue;
}
- if ((fp = fd_getfile(fdp, pl[i].fd)) == NULL) {
- pl[i].revents = POLLNVAL;
+ if ((fp = fd_getfile(fdp, pl->fd)) == NULL) {
+ pl->revents = POLLNVAL;
n++;
continue;
}
FREF(fp);
- for (x = msk = 0; msk < 3; msk++) {
- if (pl[i].events & pflag[msk]) {
- if ((*fp->f_ops->fo_select)(fp, flag[msk], p)) {
- pl[i].revents |= pflag[msk] &
- pl[i].events;
- x++;
- }
- }
- }
+ pl->revents = (*fp->f_ops->fo_poll)(fp, pl->events, p);
FRELE(fp);
- if (x)
+ if (pl->revents != 0)
n++;
}
*retval = n;
@@ -921,7 +907,7 @@ sys_poll(struct proc *p, void *v, register_t *retval)
struct pollfd pfds[4], *pl = pfds;
int msec = SCARG(uap, timeout);
struct timeval atv;
- int timo, ncoll, i, s, error, error2;
+ int timo, ncoll, i, s, error;
extern int nselcoll, selwait;
u_int nfds;
@@ -946,7 +932,7 @@ sys_poll(struct proc *p, void *v, register_t *retval)
for (i = 0; i < nfds; i++)
pl[i].revents = 0;
- if (msec != -1) {
+ if (msec != INFTIM) {
atv.tv_sec = msec / 1000;
atv.tv_usec = (msec - (atv.tv_sec * 1000)) * 1000;
@@ -966,7 +952,7 @@ retry:
pollscan(p, pl, nfds, retval);
if (*retval)
goto done;
- if (msec != -1) {
+ if (msec != INFTIM) {
/*
* We have to recalculate the timeout on every retry.
*/
@@ -987,16 +973,21 @@ retry:
done:
p->p_flag &= ~P_SELECT;
- /* poll is not restarted after signals... */
- if (error == ERESTART)
+ /*
+ * NOTE: poll(2) is not restarted after a signal and EWOULDBLOCK is
+ * ignored (since the whole point is to see what would block).
+ */
+ switch (error) {
+ case ERESTART:
error = EINTR;
- if (error == EWOULDBLOCK)
- error = 0;
- if ((error2 = copyout(pl, SCARG(uap, fds), sz)) != 0)
- error = error2;
+ break;
+ case EWOULDBLOCK:
+ case 0:
+ error = copyout(pl, SCARG(uap, fds), sz);
+ break;
+ }
bad:
if (pl != pfds)
- free((char *) pl, M_TEMP);
+ free(pl, M_TEMP);
return (error);
}
-
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
diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c
index 3f598f425fe..4c367c31de7 100644
--- a/sys/kern/sys_socket.c
+++ b/sys/kern/sys_socket.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sys_socket.c,v 1.8 2003/06/02 23:28:06 millert Exp $ */
+/* $OpenBSD: sys_socket.c,v 1.9 2003/09/23 16:51:12 millert Exp $ */
/* $NetBSD: sys_socket.c,v 1.13 1995/08/12 23:59:09 mycroft Exp $ */
/*
@@ -41,13 +41,14 @@
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/ioctl.h>
+#include <sys/poll.h>
#include <sys/stat.h>
#include <net/if.h>
#include <net/route.h>
struct fileops socketops = {
- soo_read, soo_write, soo_ioctl, soo_select, soo_kqfilter,
+ soo_read, soo_write, soo_ioctl, soo_poll, soo_kqfilter,
soo_stat, soo_close
};
@@ -139,45 +140,39 @@ soo_ioctl(fp, cmd, data, p)
}
int
-soo_select(fp, which, p)
+soo_poll(fp, events, p)
struct file *fp;
- int which;
+ int events;
struct proc *p;
{
- register struct socket *so = (struct socket *)fp->f_data;
- register int s = splsoftnet();
-
- switch (which) {
+ struct socket *so = (struct socket *)fp->f_data;
+ int revents = 0;
+ int s = splsoftnet();
- case FREAD:
- if (soreadable(so)) {
- splx(s);
- return (1);
- }
- selrecord(p, &so->so_rcv.sb_sel);
- so->so_rcv.sb_flags |= SB_SEL;
- break;
-
- case FWRITE:
- if (sowriteable(so)) {
- splx(s);
- return (1);
+ if (events & (POLLIN | POLLRDNORM)) {
+ if (soreadable(so))
+ revents |= events & (POLLIN | POLLRDNORM);
+ }
+ if (events & (POLLOUT | POLLWRNORM)) {
+ if (sowriteable(so))
+ revents |= events & (POLLOUT | POLLWRNORM);
+ }
+ if (events & (POLLPRI | POLLRDBAND)) {
+ if (so->so_oobmark || (so->so_state & SS_RCVATMARK))
+ revents |= events & (POLLPRI | POLLRDBAND);
+ }
+ if (revents == 0) {
+ if (events & (POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND)) {
+ selrecord(p, &so->so_rcv.sb_sel);
+ so->so_rcv.sb_flags |= SB_SEL;
}
- selrecord(p, &so->so_snd.sb_sel);
- so->so_snd.sb_flags |= SB_SEL;
- break;
-
- case 0:
- if (so->so_oobmark || (so->so_state & SS_RCVATMARK)) {
- splx(s);
- return (1);
+ if (events & (POLLOUT | POLLWRNORM)) {
+ selrecord(p, &so->so_snd.sb_sel);
+ so->so_snd.sb_flags |= SB_SEL;
}
- selrecord(p, &so->so_rcv.sb_sel);
- so->so_rcv.sb_flags |= SB_SEL;
- break;
}
splx(s);
- return (0);
+ return (revents);
}
int
diff --git a/sys/kern/tty.c b/sys/kern/tty.c
index 924b686d74a..1a86d45a0d6 100644
--- a/sys/kern/tty.c
+++ b/sys/kern/tty.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tty.c,v 1.60 2003/08/23 19:21:15 deraadt Exp $ */
+/* $OpenBSD: tty.c,v 1.61 2003/09/23 16:51:12 millert Exp $ */
/* $NetBSD: tty.c,v 1.68.4.2 1996/06/06 16:04:52 thorpej Exp $ */
/*-
@@ -56,6 +56,7 @@
#include <sys/resourcevar.h>
#include <sys/sysctl.h>
#include <sys/pool.h>
+#include <sys/poll.h>
#include <sys/namei.h>
@@ -1026,35 +1027,35 @@ ttioctl(tp, cmd, data, flag, p)
}
int
-ttselect(device, rw, p)
+ttpoll(device, events, p)
dev_t device;
- int rw;
+ int events;
struct proc *p;
{
- register struct tty *tp;
- int nread, s;
+ struct tty *tp;
+ int revents, s;
tp = (*cdevsw[major(device)].d_tty)(device);
+ revents = 0;
s = spltty();
- switch (rw) {
- case FREAD:
- nread = ttnread(tp);
- if (nread > 0 || (!ISSET(tp->t_cflag, CLOCAL) &&
- !ISSET(tp->t_state, TS_CARR_ON)))
- goto win;
- selrecord(p, &tp->t_rsel);
- break;
- case FWRITE:
- if (tp->t_outq.c_cc <= tp->t_lowat) {
-win: splx(s);
- return (1);
- }
- selrecord(p, &tp->t_wsel);
- break;
+ if (events & (POLLIN | POLLRDNORM)) {
+ if (ttnread(tp) > 0 || (!ISSET(tp->t_cflag, CLOCAL) &&
+ !ISSET(tp->t_state, TS_CARR_ON)))
+ revents |= events & (POLLIN | POLLRDNORM);
+ }
+ if (events & (POLLOUT | POLLWRNORM)) {
+ if (tp->t_outq.c_cc <= tp->t_lowat)
+ revents |= events & (POLLOUT | POLLWRNORM);
+ }
+ if (revents == 0) {
+ if (events & (POLLIN | POLLRDNORM))
+ selrecord(p, &tp->t_rsel);
+ if (events & (POLLOUT | POLLWRNORM))
+ selrecord(p, &tp->t_wsel);
}
splx(s);
- return (0);
+ return (revents);
}
struct filterops ttyread_filtops =
diff --git a/sys/kern/tty_pty.c b/sys/kern/tty_pty.c
index 7cbb13a523a..6cb8615f724 100644
--- a/sys/kern/tty_pty.c
+++ b/sys/kern/tty_pty.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tty_pty.c,v 1.14 2003/07/22 01:03:12 mickey Exp $ */
+/* $OpenBSD: tty_pty.c,v 1.15 2003/09/23 16:51:12 millert Exp $ */
/* $NetBSD: tty_pty.c,v 1.33.4.1 1996/06/02 09:08:11 mrg Exp $ */
/*
@@ -50,6 +50,7 @@
#include <sys/signalvar.h>
#include <sys/uio.h>
#include <sys/conf.h>
+#include <sys/poll.h>
#define BUFSIZ 100 /* Chunk size iomoved to/from user */
@@ -233,7 +234,7 @@ ptswrite(dev, uio, flag)
/*
* Start output on pseudo-tty.
- * Wake up process selecting or sleeping for input from controlling tty.
+ * Wake up process polling or sleeping for input from controlling tty.
*/
void
ptsstart(tp)
@@ -501,58 +502,52 @@ block:
}
int
-ptcselect(dev, rw, p)
- dev_t dev;
- int rw;
- struct proc *p;
+ptcpoll(dev_t dev, int events, struct proc *p)
{
- register struct pt_softc *pti = &pt_softc[minor(dev)];
- register struct tty *tp = pti->pt_tty;
- int s;
+ struct pt_softc *pti = &pt_softc[minor(dev)];
+ struct tty *tp = pti->pt_tty;
+ int revents = 0, s;
- if ((tp->t_state&TS_CARR_ON) == 0)
- return (1);
- switch (rw) {
+ if (!ISSET(tp->t_state, TS_CARR_ON))
+ return (POLLHUP);
+
+ if (!ISSET(tp->t_state, TS_ISOPEN))
+ goto notopen;
- case FREAD:
+ if (events & (POLLIN | POLLRDNORM)) {
/*
- * Need to block timeouts (ttrstart).
+ * Need to protect access to t_outq
*/
s = spltty();
- if ((tp->t_state&TS_ISOPEN) &&
- tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0) {
- splx(s);
- return (1);
- }
+ if ((tp->t_outq.c_cc && !ISSET(tp->t_state, TS_TTSTOP)) ||
+ ((pti->pt_flags & PF_PKT) && pti->pt_send) ||
+ ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl))
+ revents |= events & (POLLIN | POLLRDNORM);
splx(s);
- /* FALLTHROUGH */
-
- case 0: /* exceptional */
- if ((tp->t_state&TS_ISOPEN) &&
- (((pti->pt_flags & PF_PKT) && pti->pt_send) ||
- ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl)))
- return (1);
- selrecord(p, &pti->pt_selr);
- break;
-
-
- case FWRITE:
- if (tp->t_state&TS_ISOPEN) {
- if (pti->pt_flags & PF_REMOTE) {
- if (tp->t_canq.c_cc == 0)
- return (1);
- } else {
- if (tp->t_rawq.c_cc + tp->t_canq.c_cc < TTYHOG-2)
- return (1);
- if (tp->t_canq.c_cc == 0 && ISSET(tp->t_lflag, ICANON))
- return (1);
- }
- }
- selrecord(p, &pti->pt_selw);
- break;
+ }
+ if (events & (POLLOUT | POLLWRNORM)) {
+ if ((pti->pt_flags & PF_REMOTE) ?
+ (tp->t_canq.c_cc == 0) :
+ ((tp->t_rawq.c_cc + tp->t_canq.c_cc < TTYHOG - 2) ||
+ (tp->t_canq.c_cc == 0 && ISSET(tp->t_lflag, ICANON))))
+ revents |= events & (POLLOUT | POLLWRNORM);
+ }
+ if (events & (POLLPRI | POLLRDBAND)) {
+ /* If in packet or user control mode, check for data. */
+ if (((pti->pt_flags & PF_PKT) && pti->pt_send) ||
+ ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl))
+ revents |= events & (POLLPRI | POLLRDBAND);
+ }
+ if (revents == 0) {
+notopen:
+ if (events & (POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND))
+ selrecord(p, &pti->pt_selr);
+ if (events & (POLLOUT | POLLWRNORM))
+ selrecord(p, &pti->pt_selw);
}
- return (0);
+
+ return (revents);
}
void
diff --git a/sys/kern/tty_tty.c b/sys/kern/tty_tty.c
index 6c09bf4dbad..2c6ea90231b 100644
--- a/sys/kern/tty_tty.c
+++ b/sys/kern/tty_tty.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tty_tty.c,v 1.7 2003/06/02 23:28:06 millert Exp $ */
+/* $OpenBSD: tty_tty.c,v 1.8 2003/09/23 16:51:12 millert Exp $ */
/* $NetBSD: tty_tty.c,v 1.13 1996/03/30 22:24:46 christos Exp $ */
/*-
@@ -143,14 +143,14 @@ cttyioctl(dev, cmd, addr, flag, p)
/*ARGSUSED*/
int
-cttyselect(dev, flag, p)
+cttypoll(dev, events, p)
dev_t dev;
- int flag;
+ int events;
struct proc *p;
{
struct vnode *ttyvp = cttyvp(p);
- if (ttyvp == NULL)
- return (1); /* try operation to get EOF/failure */
- return (VOP_SELECT(ttyvp, flag, FREAD|FWRITE, NOCRED, p));
+ if (ttyvp == NULL) /* try operation to get EOF/failure */
+ return (seltrue(dev, events, p));
+ return (VOP_POLL(ttyvp, events, p));
}
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index 04354256017..bcef263c4a9 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_vnops.c,v 1.43 2003/07/21 22:44:50 tedu Exp $ */
+/* $OpenBSD: vfs_vnops.c,v 1.44 2003/09/23 16:51:12 millert Exp $ */
/* $NetBSD: vfs_vnops.c,v 1.20 1996/02/04 02:18:41 christos Exp $ */
/*
@@ -50,6 +50,7 @@
#include <sys/ioctl.h>
#include <sys/tty.h>
#include <sys/cdio.h>
+#include <sys/poll.h>
#include <uvm/uvm_extern.h>
@@ -57,14 +58,14 @@ int vn_read(struct file *fp, off_t *off, struct uio *uio,
struct ucred *cred);
int vn_write(struct file *fp, off_t *off, struct uio *uio,
struct ucred *cred);
-int vn_select(struct file *fp, int which, struct proc *p);
+int vn_poll(struct file *fp, int events, struct proc *p);
int vn_kqfilter(struct file *fp, struct knote *kn);
int vn_closefile(struct file *fp, struct proc *p);
int vn_ioctl(struct file *fp, u_long com, caddr_t data,
struct proc *p);
struct fileops vnops =
- { vn_read, vn_write, vn_ioctl, vn_select, vn_kqfilter, vn_statfile,
+ { vn_read, vn_write, vn_ioctl, vn_poll, vn_kqfilter, vn_statfile,
vn_closefile };
/*
@@ -467,17 +468,16 @@ vn_ioctl(fp, com, data, p)
}
/*
- * File table vnode select routine.
+ * File table vnode poll routine.
*/
int
-vn_select(fp, which, p)
+vn_poll(fp, events, p)
struct file *fp;
- int which;
+ int events;
struct proc *p;
{
- return (VOP_SELECT(((struct vnode *)fp->f_data), which, fp->f_flag,
- fp->f_cred, p));
+ return (VOP_POLL(((struct vnode *)fp->f_data), events, p));
}
/*