summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1996-05-18 08:53:12 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1996-05-18 08:53:12 +0000
commit49b93a47757d509217c0ac5cb322971163f11208 (patch)
tree7474054ada7215748743da21419ed71d1c3f2818 /sys
parent3abfcc0df93dc31551516b068e3e407eafba0784 (diff)
poll() as a system call
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/sys_generic.c124
-rw-r--r--sys/kern/syscalls.master5
-rw-r--r--sys/sys/poll.h49
3 files changed, 176 insertions, 2 deletions
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
index 9c5fbe7cd00..ffb8235b251 100644
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sys_generic.c,v 1.4 1996/05/07 05:52:01 deraadt Exp $ */
+/* $OpenBSD: sys_generic.c,v 1.5 1996/05/18 08:53:09 deraadt Exp $ */
/* $NetBSD: sys_generic.c,v 1.24 1996/03/29 00:25:32 cgd Exp $ */
/*
@@ -53,6 +53,7 @@
#include <sys/kernel.h>
#include <sys/stat.h>
#include <sys/malloc.h>
+#include <sys/poll.h>
#ifdef KTRACE
#include <sys/ktrace.h>
#endif
@@ -62,6 +63,7 @@
int selscan __P((struct proc *, fd_set *, fd_set *, int, register_t *));
int seltrue __P((dev_t, int, struct proc *));
+void pollscan __P((struct proc *, struct pollfd *, int, register_t *));
/*
* Read system call.
@@ -757,3 +759,123 @@ selwakeup(sip)
splx(s);
}
}
+
+void
+pollscan(p, pl, nfd, retval)
+ struct proc *p;
+ struct pollfd *pl;
+ int nfd;
+ register_t *retval;
+{
+ register struct filedesc *fdp = p->p_fd;
+ register int msk, i;
+ struct file *fp;
+ int n = 0;
+ static int flag[3] = { FREAD, FWRITE, 0 };
+ static int pflag[3] = { POLLIN|POLLRDNORM, POLLOUT, POLLERR };
+
+ /*
+ * XXX: We need to implement the rest of the flags.
+ */
+ for (i = 0; i < nfd; i++) {
+ fp = fdp->fd_ofiles[pl[i].fd];
+ if (fp == NULL) {
+ if (pl[i].events & POLLNVAL) {
+ pl[i].revents |= POLLNVAL;
+ n++;
+ }
+ continue;
+ }
+ for (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;
+ n++;
+ }
+ }
+ }
+ }
+ *retval = n;
+}
+
+/*
+ * We are using the same mechanism as select only we encode/decode args
+ * differently.
+ */
+int
+sys_poll(p, v, retval)
+ register struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct sys_poll_args *uap = v;
+ size_t sz = sizeof(struct pollfd) * SCARG(uap, nfds);
+ struct pollfd *pl;
+ int msec = SCARG(uap, timeout);
+ struct timeval atv;
+ int timo, ncoll, i, s, error, error2;
+ extern int nselcoll, selwait;
+
+ pl = (struct pollfd *) malloc(sz, M_TEMP, M_WAITOK);
+
+ if ((error = copyin(SCARG(uap, fds), pl, sz)) != 0)
+ goto bad;
+
+ for (i = 0; i < SCARG(uap, nfds); i++)
+ pl[i].revents = 0;
+
+ if (msec != -1) {
+ atv.tv_sec = msec / 1000;
+ atv.tv_usec = (msec - (atv.tv_sec * 1000)) * 1000;
+
+ if (itimerfix(&atv)) {
+ error = EINVAL;
+ goto done;
+ }
+ s = splclock();
+ timeradd(&atv, &time, &atv);
+ timo = hzto(&atv);
+ /*
+ * Avoid inadvertently sleeping forever.
+ */
+ if (timo == 0)
+ timo = 1;
+ splx(s);
+ } else
+ timo = 0;
+
+retry:
+ ncoll = nselcoll;
+ p->p_flag |= P_SELECT;
+ pollscan(p, pl, SCARG(uap, nfds), retval);
+ if (*retval)
+ goto done;
+ s = splhigh();
+ if (timo && timercmp(&time, &atv, >=)) {
+ splx(s);
+ goto done;
+ }
+ if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) {
+ splx(s);
+ goto retry;
+ }
+ p->p_flag &= ~P_SELECT;
+ error = tsleep((caddr_t)&selwait, PSOCK | PCATCH, "poll", timo);
+ splx(s);
+ if (error == 0)
+ goto retry;
+
+done:
+ p->p_flag &= ~P_SELECT;
+ /* poll is not restarted after signals... */
+ if (error == ERESTART)
+ error = EINTR;
+ if (error == EWOULDBLOCK)
+ error = 0;
+ if ((error2 = copyout(pl, SCARG(uap, fds), sz)) != 0)
+ error = error2;
+bad:
+ free((char *) pl, M_TEMP);
+ return (error);
+}
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
index 8f5c8934aea..c1767a2de19 100644
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -1,4 +1,4 @@
- $OpenBSD: syscalls.master,v 1.8 1996/05/02 13:09:50 deraadt Exp $
+ $OpenBSD: syscalls.master,v 1.9 1996/05/18 08:53:10 deraadt Exp $
; $NetBSD: syscalls.master,v 1.32 1996/04/23 10:24:21 mycroft Exp $
; @(#)syscalls.master 8.2 (Berkeley) 1/13/94
@@ -37,6 +37,7 @@
#include <sys/signal.h>
#include <sys/mount.h>
#include <sys/syscallargs.h>
+#include <sys/poll.h>
; Reserved/unimplemented system calls in the range 0-150 inclusive
; are reserved for use in future Berkeley releases.
@@ -452,3 +453,5 @@
250 STD { int sys_minherit(caddr_t addr, size_t len, \
int inherit); }
251 STD { int sys_rfork(int flags); }
+252 STD { int sys_poll(struct pollfd *fds, unsigned long nfds, \
+ int timeout); }
diff --git a/sys/sys/poll.h b/sys/sys/poll.h
new file mode 100644
index 00000000000..97160d848c2
--- /dev/null
+++ b/sys/sys/poll.h
@@ -0,0 +1,49 @@
+/* $OpenBSD: poll.h,v 1.1 1996/05/18 08:53:08 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1996 Theo de Raadt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_POLL_H_
+#define _SYS_POLL_H_
+
+struct pollfd {
+ int fd;
+ short events;
+ short revents;
+};
+
+#define POLLIN 0x0001
+#define POLLPRI 0x0002
+#define POLLOUT 0x0004
+#define POLLERR 0x0008
+#define POLLHUP 0x0010
+#define POLLNVAL 0x0020
+#define POLLRDNORM 0x0040
+#define POLLRDBAND 0x0080
+#define POLLWRBAND 0x0100
+
+#endif /* !_SYS_POLL_H_ */