summaryrefslogtreecommitdiff
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
parent3abfcc0df93dc31551516b068e3e407eafba0784 (diff)
poll() as a system call
-rw-r--r--include/poll.h7
-rw-r--r--lib/libc/sys/Makefile.inc13
-rw-r--r--lib/libc/sys/poll.2199
-rw-r--r--sys/kern/sys_generic.c124
-rw-r--r--sys/kern/syscalls.master5
-rw-r--r--sys/sys/poll.h49
6 files changed, 389 insertions, 8 deletions
diff --git a/include/poll.h b/include/poll.h
new file mode 100644
index 00000000000..dfc7dc21aa2
--- /dev/null
+++ b/include/poll.h
@@ -0,0 +1,7 @@
+/* $OpenBSD: poll.h,v 1.1 1996/05/18 08:53:07 deraadt Exp $ */
+
+/*
+ * Typical poll() implimentations expect poll.h to be in /usr/include.
+ * However this is not a convenient place for the real definitions.
+ */
+#include <sys/poll.h>
diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc
index 0f308371e19..179e6a92ab8 100644
--- a/lib/libc/sys/Makefile.inc
+++ b/lib/libc/sys/Makefile.inc
@@ -100,12 +100,13 @@ MAN+= accept.2 access.2 acct.2 adjtime.2 bind.2 brk.2 chdir.2 chflags.2 \
listen.2 lseek.2 mkdir.2 mkfifo.2 mknod.2 madvise.2 mincore.2 \
minherit.2 mlock.2 \
mmap.2 mount.2 mprotect.2 msync.2 munmap.2 nfssvc.2 open.2 pathconf.2 \
- pipe.2 profil.2 ptrace.2 quotactl.2 read.2 readlink.2 reboot.2 recv.2 \
- rename.2 revoke.2 rfork.2 rmdir.2 select.2 send.2 setgroups.2 setpgid.2 \
- setsid.2 setuid.2 shutdown.2 sigaction.2 sigaltstack.2 sigpending.2 \
- sigprocmask.2 sigreturn.2 sigstack.2 sigsuspend.2 socket.2 \
- socketpair.2 stat.2 statfs.2 swapon.2 symlink.2 sync.2 sysarch.2 \
- syscall.2 truncate.2 umask.2 unlink.2 utimes.2 vfork.2 wait.2 write.2
+ pipe.2 profil.2 poll.2 ptrace.2 quotactl.2 read.2 readlink.2 reboot.2 \
+ recv.2 rename.2 revoke.2 rfork.2 rmdir.2 select.2 send.2 setgroups.2 \
+ setpgid.2 setsid.2 setuid.2 shutdown.2 sigaction.2 sigaltstack.2 \
+ sigpending.2 sigprocmask.2 sigreturn.2 sigstack.2 sigsuspend.2 \
+ socket.2 socketpair.2 stat.2 statfs.2 swapon.2 symlink.2 sync.2 \
+ sysarch.2 syscall.2 truncate.2 umask.2 unlink.2 utimes.2 vfork.2 \
+ wait.2 write.2
MAN+= msgctl.2 shmctl.2 shmat.2 semop.2 semget.2 semctl.2 msgsnd.2 msgrcv.2 \
msgget.2 shmget.2
diff --git a/lib/libc/sys/poll.2 b/lib/libc/sys/poll.2
new file mode 100644
index 00000000000..f07df83eaec
--- /dev/null
+++ b/lib/libc/sys/poll.2
@@ -0,0 +1,199 @@
+.\"
+.\" Copyright (c) 1994 Jason R. Thorpe
+.\" 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. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by Jason R. Thorpe.
+.\" 4. 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
+.\"
+.Dd December 13, 1994
+.Dt POLL 2
+.Os
+.Sh NAME
+.Nm poll
+.Nd synchronous I/O multiplexing
+.Sh SYNOPSIS
+.Fd #include <poll.h>
+.Ft int
+.Fn poll "struct pollfd *fds" "int nfds" "int timeout"
+.Sh DESCRIPTION
+.Fn Poll
+provides a mechanism for reporting I/O conditions across a set of file
+descriptors.
+.Pp
+The arguments are as follows:
+.Bl -tag -width timeout
+.It Pa fds
+Points to an array of
+.Nm pollfd
+structures, which are defined as:
+.Bd -literal -offset indent
+struct pollfd {
+ int fd;
+ short events;
+ short revents;
+};
+.Ed
+.Pp
+The
+.Pa fd
+member is an open file descriptor. The
+.Pa events
+and
+.Pa revents
+members are bitmasks of conditions to monitor and conditions found,
+respectively.
+.It Pa nfds
+The number of
+.Nm pollfd
+structures in the array.
+.It Pa timeout
+Maximum interval to wait for the poll to complete, in milliseconds. If
+this value is 0, then
+.Fn poll
+will return immediately. If this value is less than 0,
+.Fn poll
+will block indefinitely until a condition is found.
+.El
+.Pp
+The calling process sets the
+.Pa events
+bitmask and
+.Fn poll
+sets the
+.Pa revents
+bitmask. Each call to
+.Fn poll
+resets the
+.Pa revents
+bitmask for accuracy. The condition flags in the bitmasks are defined as:
+.Bl -tag -width POLLRDNORM
+.It Nm POLLIN
+Data is available on the file descriptor for reading.
+.It Nm POLLNORM
+Same as
+.Nm POLLIN .
+.It Nm POLLPRI
+Same as
+.Nm POLLIN .
+.It Nm POLLOUT
+Data can be written to the file descriptor without blocking.
+.It Nm POLLERR
+This flag is not used in this implementation and is provided only for source
+code compatibility.
+.It Nm POLLHUP
+The file descriptor was valid before the polling process and invalid after.
+Presumably, this means that the file descriptor was closed sometime during
+the poll.
+.It Nm POLLNVAL
+The corresponding file descriptor is invalid.
+.It Nm POLLRDNORM
+Same as
+.Nm POLLIN .
+.It Nm POLLRDBAND
+Same as
+.Nm POLLIN .
+.It Nm POLLWRNORM
+Same as
+.Nm POLLOUT .
+.It Nm POLLWRBAND
+Same as
+.Nm POLLOUT .
+.It Nm POLLMSG
+This flag is not used in this implementation and is provided only for source
+code compatibility.
+.El
+.Pp
+All flags except
+.Nm POLLIN ,
+.Nm POLLOUT ,
+and their synonyms are for use only in the
+.Pa revents
+member of the
+.Nm pollfd
+structure. An attempt to set any of these flags in the
+.Pa events
+member will generate an error condition.
+.Pp
+In addition to I/O multiplexing,
+.Fn poll
+can be used to generate simple timeouts. This functionality may be achieved
+by passing a NULL pointer for
+.Pa fds .
+.Sh WARNINGS
+Since this implementation is a wrapper around
+.Fn select ,
+functionality is limited to such. There is no differentiation between
+standard and priority messages in the read or write queues.
+.Pp
+The
+.Nm POLLHUP
+flag is only a close approximation and may not always be accurate.
+.Sh RETURN VALUES
+Upon error,
+.Fn poll
+returns a -1 and sets the global variable
+.Pa errno
+to indicate the error. If the timeout interval was reached before any events
+occurred, a 0 is returned. Otherwise,
+.Fn poll
+returns the number of file descriptors for which
+.Pa revents
+is non-zero.
+.Sh ERRORS
+.Fn Poll
+will fail if:
+.Bl -tag -width "EINVAL "
+.It Bq Er EINVAL
+.Pa nfds
+was either a negative number or greater than the number of available
+file descriptors.
+.It Bq Er EINVAL
+An invalid flags was set in the
+.Pa events
+member of the
+.Nm pollfd
+structure.
+.It Bq Er EINVAL
+The timeout passed to
+.Fn select
+was too large.
+.It Bq Er EAGAIN
+Resource allocation failed inside of
+.Fn poll .
+Subsequent calls to
+.Fn poll
+may succeed.
+.It Bq Er EINTR
+.Fn Select
+caught a signal during the polling process.
+.El
+.Sh SEE ALSO
+.Xr sysconf 3 ,
+.Xr select 2
+.Sh HISTORY
+A
+.Fn poll
+system call appeared in
+.At V
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_ */