X-Git-Url: http://andersk.mit.edu/gitweb/gssapi-openssh.git/blobdiff_plain/9108f8d92b8e2b4b5fe61eb8e419bf94ba216d44..77fa2ab46721bcc01b898b7df0aa85c170931c06:/openssh/atomicio.c diff --git a/openssh/atomicio.c b/openssh/atomicio.c index f651a29..a6b2d12 100644 --- a/openssh/atomicio.c +++ b/openssh/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.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. @@ -32,7 +32,15 @@ #include #include +#ifdef HAVE_POLL_H +#include +#else +# ifdef HAVE_SYS_POLL_H +# include +# endif +#endif #include +#include #include "atomicio.h" @@ -45,17 +53,20 @@ 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) -#else - if (errno == EINTR || errno == EAGAIN) -#endif + if (errno == EINTR) + continue; + if (errno == EAGAIN || errno == EWOULDBLOCK) { + (void)poll(&pfd, 1, -1); continue; + } return 0; case 0: errno = EPIPE; @@ -77,6 +88,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 +97,22 @@ 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)); +#ifndef BROKEN_READV_COMPARISON + pfd.fd = fd; + pfd.events = f == readv ? POLLIN : POLLOUT; +#endif 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 || errno == EWOULDBLOCK) { +#ifndef BROKEN_READV_COMPARISON + (void)poll(&pfd, 1, -1); +#endif + continue; + } return 0; case 0: errno = EPIPE;