diff options
-rw-r--r-- | include/poll.h | 7 | ||||
-rw-r--r-- | lib/libc/sys/Makefile.inc | 13 | ||||
-rw-r--r-- | lib/libc/sys/poll.2 | 199 | ||||
-rw-r--r-- | sys/kern/sys_generic.c | 124 | ||||
-rw-r--r-- | sys/kern/syscalls.master | 5 | ||||
-rw-r--r-- | sys/sys/poll.h | 49 |
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_ */ |