From ab17f7d67b2decbd8561977a47fec55a9e74337e Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Mon, 25 Jun 2007 19:04:12 +1000 Subject: - djm@cvs.openbsd.org 2007/06/19 02:04:43 [atomicio.c] if the fd passed to atomicio/atomiciov() is non blocking, then poll() to avoid a spin if it is not yet ready for reading/writing; ok dtucker@ --- atomicio.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'atomicio.c') diff --git a/atomicio.c b/atomicio.c index f651a292c..253139e99 100644 --- a/atomicio.c +++ b/atomicio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: atomicio.c,v 1.23 2006/08/03 03:34:41 deraadt Exp $ */ +/* $OpenBSD: atomicio.c,v 1.24 2007/06/19 02:04:43 djm Exp $ */ /* * Copyright (c) 2006 Damien Miller. All rights reserved. * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved. @@ -30,9 +30,11 @@ #include #include +#include #include #include +#include #include "atomicio.h" @@ -45,17 +47,24 @@ atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n) char *s = _s; size_t pos = 0; ssize_t res; + struct pollfd pfd; + pfd.fd = fd; + pfd.events = f == read ? POLLIN : POLLOUT; while (n > pos) { res = (f) (fd, s + pos, n - pos); switch (res) { case -1: #ifdef EWOULDBLOCK - if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) + if (errno == EINTR || errno == EWOULDBLOCK) #else - if (errno == EINTR || errno == EAGAIN) + if (errno == EINTR) #endif continue; + if (errno == EAGAIN) { + (void)poll(&pfd, 1, -1); + continue; + } return 0; case 0: errno = EPIPE; @@ -77,6 +86,7 @@ atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd, size_t pos = 0, rem; ssize_t res; struct iovec iov_array[IOV_MAX], *iov = iov_array; + struct pollfd pfd; if (iovcnt > IOV_MAX) { errno = EINVAL; @@ -85,12 +95,18 @@ atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd, /* Make a copy of the iov array because we may modify it below */ memcpy(iov, _iov, iovcnt * sizeof(*_iov)); + pfd.fd = fd; + pfd.events = f == readv ? POLLIN : POLLOUT; for (; iovcnt > 0 && iov[0].iov_len > 0;) { res = (f) (fd, iov, iovcnt); switch (res) { case -1: - if (errno == EINTR || errno == EAGAIN) + if (errno == EINTR) continue; + if (errno == EAGAIN) { + (void)poll(&pfd, 1, -1); + continue; + } return 0; case 0: errno = EPIPE; -- cgit v1.2.3 From 9e223240ac65e5662bf4d48945198fba80e9f886 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Mon, 25 Jun 2007 19:06:53 +1000 Subject: - (dtucker) [atomicio.c] Test for EWOULDBLOCK in atomiciov to match atomicio. --- ChangeLog | 4 +++- atomicio.c | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'atomicio.c') diff --git a/ChangeLog b/ChangeLog index 43d5e365b..9deb7bde2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -20,6 +20,8 @@ [channels.c] Correct test for window updates every three packets; prevents sending window updates for every single packet. ok markus@ + - (dtucker) [atomicio.c] Test for EWOULDBLOCK in atomiciov to match + atomicio. 20070614 - (dtucker) [cipher-ctr.c umac.c openbsd-compat/openssl-compat.h] Move the @@ -3095,4 +3097,4 @@ OpenServer 6 and add osr5bigcrypt support so when someone migrates passwords between UnixWare and OpenServer they will still work. OK dtucker@ -$Id: ChangeLog,v 1.4707 2007/06/25 09:04:46 dtucker Exp $ +$Id: ChangeLog,v 1.4708 2007/06/25 09:06:53 dtucker Exp $ diff --git a/atomicio.c b/atomicio.c index 253139e99..79dba9f29 100644 --- a/atomicio.c +++ b/atomicio.c @@ -101,7 +101,11 @@ atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd, res = (f) (fd, iov, iovcnt); switch (res) { case -1: +#ifdef EWOULDBLOCK + if (errno == EINTR || errno == EWOULDBLOCK) +#else if (errno == EINTR) +#endif continue; if (errno == EAGAIN) { (void)poll(&pfd, 1, -1); -- cgit v1.2.3 From dc4a779fbbefd662e1b0b4dd2417329826ff264f Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Mon, 25 Jun 2007 22:08:10 +1000 Subject: - dtucker@cvs.openbsd.org 2007/06/25 12:02:27 [atomicio.c] Include like the man page says rather than . ok djm@ --- ChangeLog | 5 ++++- atomicio.c | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'atomicio.c') diff --git a/ChangeLog b/ChangeLog index 9deb7bde2..1552f8ce0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -20,6 +20,9 @@ [channels.c] Correct test for window updates every three packets; prevents sending window updates for every single packet. ok markus@ + - dtucker@cvs.openbsd.org 2007/06/25 12:02:27 + [atomicio.c] + Include like the man page says rather than . ok djm@ - (dtucker) [atomicio.c] Test for EWOULDBLOCK in atomiciov to match atomicio. @@ -3097,4 +3100,4 @@ OpenServer 6 and add osr5bigcrypt support so when someone migrates passwords between UnixWare and OpenServer they will still work. OK dtucker@ -$Id: ChangeLog,v 1.4708 2007/06/25 09:06:53 dtucker Exp $ +$Id: ChangeLog,v 1.4709 2007/06/25 12:08:10 dtucker Exp $ diff --git a/atomicio.c b/atomicio.c index 79dba9f29..afe3444c9 100644 --- a/atomicio.c +++ b/atomicio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: atomicio.c,v 1.24 2007/06/19 02:04:43 djm Exp $ */ +/* $OpenBSD: atomicio.c,v 1.25 2007/06/25 12:02:27 dtucker Exp $ */ /* * Copyright (c) 2006 Damien Miller. All rights reserved. * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved. @@ -30,9 +30,9 @@ #include #include -#include #include +#include #include #include -- cgit v1.2.3 From febf0f5668f997c63210b3dbd50ce5443b0f6aea Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Mon, 25 Jun 2007 22:15:12 +1000 Subject: - (dtucker) [atomicio.c configure.ac openbsd-compat/Makefile.in openbsd-compat/bsd-poll.{c,h} openbsd-compat/openbsd-compat.h] Add an implementation of poll() built on top of select(2). Code from OpenNTPD with changes suggested by djm. ok djm@ --- ChangeLog | 6 ++- atomicio.c | 2 + configure.ac | 6 ++- openbsd-compat/Makefile.in | 4 +- openbsd-compat/bsd-poll.c | 117 ++++++++++++++++++++++++++++++++++++++++ openbsd-compat/bsd-poll.h | 61 +++++++++++++++++++++ openbsd-compat/openbsd-compat.h | 3 +- 7 files changed, 193 insertions(+), 6 deletions(-) create mode 100644 openbsd-compat/bsd-poll.c create mode 100644 openbsd-compat/bsd-poll.h (limited to 'atomicio.c') diff --git a/ChangeLog b/ChangeLog index 1552f8ce0..27815ba33 100644 --- a/ChangeLog +++ b/ChangeLog @@ -25,6 +25,10 @@ Include like the man page says rather than . ok djm@ - (dtucker) [atomicio.c] Test for EWOULDBLOCK in atomiciov to match atomicio. + - (dtucker) [atomicio.c configure.ac openbsd-compat/Makefile.in + openbsd-compat/bsd-poll.{c,h} openbsd-compat/openbsd-compat.h] + Add an implementation of poll() built on top of select(2). Code from + OpenNTPD with changes suggested by djm. ok djm@ 20070614 - (dtucker) [cipher-ctr.c umac.c openbsd-compat/openssl-compat.h] Move the @@ -3100,4 +3104,4 @@ OpenServer 6 and add osr5bigcrypt support so when someone migrates passwords between UnixWare and OpenServer they will still work. OK dtucker@ -$Id: ChangeLog,v 1.4709 2007/06/25 12:08:10 dtucker Exp $ +$Id: ChangeLog,v 1.4710 2007/06/25 12:15:12 dtucker Exp $ diff --git a/atomicio.c b/atomicio.c index afe3444c9..f32ff85ba 100644 --- a/atomicio.c +++ b/atomicio.c @@ -32,7 +32,9 @@ #include #include +#ifdef HAVE_POLL_H #include +#endif #include #include diff --git a/configure.ac b/configure.ac index 143c164a9..689724133 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.381 2007/06/11 04:15:43 djm Exp $ +# $Id: configure.ac,v 1.382 2007/06/25 12:15:12 dtucker Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -15,7 +15,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org) -AC_REVISION($Revision: 1.381 $) +AC_REVISION($Revision: 1.382 $) AC_CONFIG_SRCDIR([ssh.c]) AC_CONFIG_HEADER(config.h) @@ -205,6 +205,7 @@ AC_CHECK_HEADERS( \ netgroup.h \ pam/pam_appl.h \ paths.h \ + poll.h \ pty.h \ readpassphrase.h \ rpc/types.h \ @@ -1267,6 +1268,7 @@ AC_CHECK_FUNCS( \ ogetaddrinfo \ openlog_r \ openpty \ + poll \ prctl \ pstat \ readpassphrase \ diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in index 9f06605d7..b44a7851e 100644 --- a/openbsd-compat/Makefile.in +++ b/openbsd-compat/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.40 2006/08/30 17:24:41 djm Exp $ +# $Id: Makefile.in,v 1.41 2007/06/25 12:15:13 dtucker Exp $ sysconfdir=@sysconfdir@ piddir=@piddir@ @@ -18,7 +18,7 @@ LDFLAGS=-L. @LDFLAGS@ OPENBSD=base64.o basename.o bindresvport.o daemon.o dirname.o getcwd.o getgrouplist.o getopt.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sha2.o sigact.o strlcat.o strlcpy.o strmode.o strsep.o strtonum.o strtoll.o strtoul.o vis.o -COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-snprintf.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o +COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-snprintf.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o diff --git a/openbsd-compat/bsd-poll.c b/openbsd-compat/bsd-poll.c new file mode 100644 index 000000000..836882eea --- /dev/null +++ b/openbsd-compat/bsd-poll.c @@ -0,0 +1,117 @@ +/* $Id: bsd-poll.c,v 1.1 2007/06/25 12:15:13 dtucker Exp $ */ + +/* + * Copyright (c) 2004, 2005, 2007 Darren Tucker (dtucker at zip com au). + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" +#if !defined(HAVE_POLL) && defined(HAVE_SELECT) + +#ifdef HAVE_SYS_SELECT_H +# include +#endif + +#include +#include "bsd-poll.h" + +/* + * A minimal implementation of poll(2), built on top of select(2). + * + * Only supports POLLIN and POLLOUT flags in pfd.events, and POLLIN, POLLOUT + * and POLLERR flags in revents. + * + * Supports pfd.fd = -1 meaning "unused" although it's not standard. + */ + +int +poll(struct pollfd *fds, nfds_t nfds, int timeout) +{ + nfds_t i; + int saved_errno, ret, fd, maxfd = 0; + fd_set *readfds = NULL, *writefds = NULL, *exceptfds = NULL; + size_t nmemb; + struct timeval tv, *tvp = NULL; + + for (i = 0; i < nfds; i++) { + if (fd >= FD_SETSIZE) { + errno = EINVAL; + return -1; + } + maxfd = MAX(maxfd, fds[i].fd); + } + + nmemb = howmany(maxfd + 1 , NFDBITS); + if ((readfds = calloc(nmemb, sizeof(fd_mask))) == NULL || + (writefds = calloc(nmemb, sizeof(fd_mask))) == NULL || + (exceptfds = calloc(nmemb, sizeof(fd_mask))) == NULL) { + saved_errno = ENOMEM; + ret = -1; + goto out; + } + + /* populate event bit vectors for the events we're interested in */ + for (i = 0; i < nfds; i++) { + fd = fds[i].fd; + if (fd == -1) + continue; + if (fds[i].events & POLLIN) { + FD_SET(fd, readfds); + FD_SET(fd, exceptfds); + } + if (fds[i].events & POLLOUT) { + FD_SET(fd, writefds); + FD_SET(fd, exceptfds); + } + } + + /* poll timeout is msec, select is timeval (sec + usec) */ + if (timeout >= 0) { + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + tvp = &tv; + } + + ret = select(maxfd + 1, readfds, writefds, exceptfds, tvp); + saved_errno = errno; + + /* scan through select results and set poll() flags */ + for (i = 0; i < nfds; i++) { + fd = fds[i].fd; + fds[i].revents = 0; + if (fd == -1) + continue; + if (FD_ISSET(fd, readfds)) { + fds[i].revents |= POLLIN; + } + if (FD_ISSET(fd, writefds)) { + fds[i].revents |= POLLOUT; + } + if (FD_ISSET(fd, exceptfds)) { + fds[i].revents |= POLLERR; + } + } + +out: + if (readfds != NULL) + free(readfds); + if (writefds != NULL) + free(writefds); + if (exceptfds != NULL) + free(exceptfds); + if (ret == -1) + errno = saved_errno; + return ret; +} +#endif diff --git a/openbsd-compat/bsd-poll.h b/openbsd-compat/bsd-poll.h new file mode 100644 index 000000000..dcbb9ca40 --- /dev/null +++ b/openbsd-compat/bsd-poll.h @@ -0,0 +1,61 @@ +/* $OpenBSD: poll.h,v 1.11 2003/12/10 23:10:08 millert 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. + * + * 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. + */ + +/* OPENBSD ORIGINAL: sys/sys/poll.h */ + +#if !defined(HAVE_POLL) && !defined(HAVE_POLL_H) +#ifndef _COMPAT_POLL_H_ +#define _COMPAT_POLL_H_ + +typedef struct pollfd { + int fd; + short events; + short revents; +} pollfd_t; + +typedef unsigned int nfds_t; + +#define POLLIN 0x0001 +#define POLLOUT 0x0004 +#define POLLERR 0x0008 +#if 0 +/* the following are currently not implemented */ +#define POLLPRI 0x0002 +#define POLLHUP 0x0010 +#define POLLNVAL 0x0020 +#define POLLRDNORM 0x0040 +#define POLLNORM POLLRDNORM +#define POLLWRNORM POLLOUT +#define POLLRDBAND 0x0080 +#define POLLWRBAND 0x0100 +#endif + +#define INFTIM (-1) /* not standard */ + +int poll(struct pollfd *, nfds_t, int); +#endif /* !_COMPAT_POLL_H_ */ +#endif /* !HAVE_POLL_H */ diff --git a/openbsd-compat/openbsd-compat.h b/openbsd-compat/openbsd-compat.h index aac2e6cbc..6406af19d 100644 --- a/openbsd-compat/openbsd-compat.h +++ b/openbsd-compat/openbsd-compat.h @@ -1,4 +1,4 @@ -/* $Id: openbsd-compat.h,v 1.42 2006/09/03 12:44:50 dtucker Exp $ */ +/* $Id: openbsd-compat.h,v 1.43 2007/06/25 12:15:13 dtucker Exp $ */ /* * Copyright (c) 1999-2003 Damien Miller. All rights reserved. @@ -140,6 +140,7 @@ int writev(int, struct iovec *, int); /* Home grown routines */ #include "bsd-misc.h" #include "bsd-waitpid.h" +#include "bsd-poll.h" #ifndef HAVE_GETPEEREID int getpeereid(int , uid_t *, gid_t *); -- cgit v1.2.3