diff options
author | Darren Tucker <dtucker@zip.com.au> | 2007-06-25 19:04:12 +1000 |
---|---|---|
committer | Darren Tucker <dtucker@zip.com.au> | 2007-06-25 19:04:12 +1000 |
commit | ab17f7d67b2decbd8561977a47fec55a9e74337e (patch) | |
tree | e5bcf37b44eaa8f043a01af31393351675c77055 | |
parent | 132367f76f3529b3f4d530a38a4988ec296a3d3f (diff) |
- 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@
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | atomicio.c | 24 |
2 files changed, 25 insertions, 5 deletions
@@ -12,6 +12,10 @@ | |||
12 | when waiting for the multiplex exit status, read until the master end | 12 | when waiting for the multiplex exit status, read until the master end |
13 | writes an entire int of data *and* closes the client_fd; fixes mux | 13 | writes an entire int of data *and* closes the client_fd; fixes mux |
14 | regression spotted by dtucker, ok dtucker@ | 14 | regression spotted by dtucker, ok dtucker@ |
15 | - djm@cvs.openbsd.org 2007/06/19 02:04:43 | ||
16 | [atomicio.c] | ||
17 | if the fd passed to atomicio/atomiciov() is non blocking, then poll() to | ||
18 | avoid a spin if it is not yet ready for reading/writing; ok dtucker@ | ||
15 | 19 | ||
16 | 20070614 | 20 | 20070614 |
17 | - (dtucker) [cipher-ctr.c umac.c openbsd-compat/openssl-compat.h] Move the | 21 | - (dtucker) [cipher-ctr.c umac.c openbsd-compat/openssl-compat.h] Move the |
@@ -3087,4 +3091,4 @@ | |||
3087 | OpenServer 6 and add osr5bigcrypt support so when someone migrates | 3091 | OpenServer 6 and add osr5bigcrypt support so when someone migrates |
3088 | passwords between UnixWare and OpenServer they will still work. OK dtucker@ | 3092 | passwords between UnixWare and OpenServer they will still work. OK dtucker@ |
3089 | 3093 | ||
3090 | $Id: ChangeLog,v 1.4705 2007/06/25 08:59:17 dtucker Exp $ | 3094 | $Id: ChangeLog,v 1.4706 2007/06/25 09:04:12 dtucker Exp $ |
diff --git a/atomicio.c b/atomicio.c index f651a292c..253139e99 100644 --- a/atomicio.c +++ b/atomicio.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: atomicio.c,v 1.23 2006/08/03 03:34:41 deraadt Exp $ */ | 1 | /* $OpenBSD: atomicio.c,v 1.24 2007/06/19 02:04:43 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2006 Damien Miller. All rights reserved. | 3 | * Copyright (c) 2006 Damien Miller. All rights reserved. |
4 | * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved. | 4 | * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved. |
@@ -30,9 +30,11 @@ | |||
30 | 30 | ||
31 | #include <sys/param.h> | 31 | #include <sys/param.h> |
32 | #include <sys/uio.h> | 32 | #include <sys/uio.h> |
33 | #include <sys/poll.h> | ||
33 | 34 | ||
34 | #include <errno.h> | 35 | #include <errno.h> |
35 | #include <string.h> | 36 | #include <string.h> |
37 | #include <unistd.h> | ||
36 | 38 | ||
37 | #include "atomicio.h" | 39 | #include "atomicio.h" |
38 | 40 | ||
@@ -45,17 +47,24 @@ atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n) | |||
45 | char *s = _s; | 47 | char *s = _s; |
46 | size_t pos = 0; | 48 | size_t pos = 0; |
47 | ssize_t res; | 49 | ssize_t res; |
50 | struct pollfd pfd; | ||
48 | 51 | ||
52 | pfd.fd = fd; | ||
53 | pfd.events = f == read ? POLLIN : POLLOUT; | ||
49 | while (n > pos) { | 54 | while (n > pos) { |
50 | res = (f) (fd, s + pos, n - pos); | 55 | res = (f) (fd, s + pos, n - pos); |
51 | switch (res) { | 56 | switch (res) { |
52 | case -1: | 57 | case -1: |
53 | #ifdef EWOULDBLOCK | 58 | #ifdef EWOULDBLOCK |
54 | if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) | 59 | if (errno == EINTR || errno == EWOULDBLOCK) |
55 | #else | 60 | #else |
56 | if (errno == EINTR || errno == EAGAIN) | 61 | if (errno == EINTR) |
57 | #endif | 62 | #endif |
58 | continue; | 63 | continue; |
64 | if (errno == EAGAIN) { | ||
65 | (void)poll(&pfd, 1, -1); | ||
66 | continue; | ||
67 | } | ||
59 | return 0; | 68 | return 0; |
60 | case 0: | 69 | case 0: |
61 | errno = EPIPE; | 70 | errno = EPIPE; |
@@ -77,6 +86,7 @@ atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd, | |||
77 | size_t pos = 0, rem; | 86 | size_t pos = 0, rem; |
78 | ssize_t res; | 87 | ssize_t res; |
79 | struct iovec iov_array[IOV_MAX], *iov = iov_array; | 88 | struct iovec iov_array[IOV_MAX], *iov = iov_array; |
89 | struct pollfd pfd; | ||
80 | 90 | ||
81 | if (iovcnt > IOV_MAX) { | 91 | if (iovcnt > IOV_MAX) { |
82 | errno = EINVAL; | 92 | errno = EINVAL; |
@@ -85,12 +95,18 @@ atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd, | |||
85 | /* Make a copy of the iov array because we may modify it below */ | 95 | /* Make a copy of the iov array because we may modify it below */ |
86 | memcpy(iov, _iov, iovcnt * sizeof(*_iov)); | 96 | memcpy(iov, _iov, iovcnt * sizeof(*_iov)); |
87 | 97 | ||
98 | pfd.fd = fd; | ||
99 | pfd.events = f == readv ? POLLIN : POLLOUT; | ||
88 | for (; iovcnt > 0 && iov[0].iov_len > 0;) { | 100 | for (; iovcnt > 0 && iov[0].iov_len > 0;) { |
89 | res = (f) (fd, iov, iovcnt); | 101 | res = (f) (fd, iov, iovcnt); |
90 | switch (res) { | 102 | switch (res) { |
91 | case -1: | 103 | case -1: |
92 | if (errno == EINTR || errno == EAGAIN) | 104 | if (errno == EINTR) |
93 | continue; | 105 | continue; |
106 | if (errno == EAGAIN) { | ||
107 | (void)poll(&pfd, 1, -1); | ||
108 | continue; | ||
109 | } | ||
94 | return 0; | 110 | return 0; |
95 | case 0: | 111 | case 0: |
96 | errno = EPIPE; | 112 | errno = EPIPE; |