summaryrefslogtreecommitdiff
path: root/atomicio.c
diff options
context:
space:
mode:
Diffstat (limited to 'atomicio.c')
-rw-r--r--atomicio.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/atomicio.c b/atomicio.c
index f651a292c..f32ff85ba 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.25 2007/06/25 12:02:27 dtucker 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.
@@ -32,7 +32,11 @@
32#include <sys/uio.h> 32#include <sys/uio.h>
33 33
34#include <errno.h> 34#include <errno.h>
35#ifdef HAVE_POLL_H
36#include <poll.h>
37#endif
35#include <string.h> 38#include <string.h>
39#include <unistd.h>
36 40
37#include "atomicio.h" 41#include "atomicio.h"
38 42
@@ -45,17 +49,24 @@ atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n)
45 char *s = _s; 49 char *s = _s;
46 size_t pos = 0; 50 size_t pos = 0;
47 ssize_t res; 51 ssize_t res;
52 struct pollfd pfd;
48 53
54 pfd.fd = fd;
55 pfd.events = f == read ? POLLIN : POLLOUT;
49 while (n > pos) { 56 while (n > pos) {
50 res = (f) (fd, s + pos, n - pos); 57 res = (f) (fd, s + pos, n - pos);
51 switch (res) { 58 switch (res) {
52 case -1: 59 case -1:
53#ifdef EWOULDBLOCK 60#ifdef EWOULDBLOCK
54 if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) 61 if (errno == EINTR || errno == EWOULDBLOCK)
55#else 62#else
56 if (errno == EINTR || errno == EAGAIN) 63 if (errno == EINTR)
57#endif 64#endif
58 continue; 65 continue;
66 if (errno == EAGAIN) {
67 (void)poll(&pfd, 1, -1);
68 continue;
69 }
59 return 0; 70 return 0;
60 case 0: 71 case 0:
61 errno = EPIPE; 72 errno = EPIPE;
@@ -77,6 +88,7 @@ atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd,
77 size_t pos = 0, rem; 88 size_t pos = 0, rem;
78 ssize_t res; 89 ssize_t res;
79 struct iovec iov_array[IOV_MAX], *iov = iov_array; 90 struct iovec iov_array[IOV_MAX], *iov = iov_array;
91 struct pollfd pfd;
80 92
81 if (iovcnt > IOV_MAX) { 93 if (iovcnt > IOV_MAX) {
82 errno = EINVAL; 94 errno = EINVAL;
@@ -85,12 +97,22 @@ 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 */ 97 /* Make a copy of the iov array because we may modify it below */
86 memcpy(iov, _iov, iovcnt * sizeof(*_iov)); 98 memcpy(iov, _iov, iovcnt * sizeof(*_iov));
87 99
100 pfd.fd = fd;
101 pfd.events = f == readv ? POLLIN : POLLOUT;
88 for (; iovcnt > 0 && iov[0].iov_len > 0;) { 102 for (; iovcnt > 0 && iov[0].iov_len > 0;) {
89 res = (f) (fd, iov, iovcnt); 103 res = (f) (fd, iov, iovcnt);
90 switch (res) { 104 switch (res) {
91 case -1: 105 case -1:
92 if (errno == EINTR || errno == EAGAIN) 106#ifdef EWOULDBLOCK
107 if (errno == EINTR || errno == EWOULDBLOCK)
108#else
109 if (errno == EINTR)
110#endif
93 continue; 111 continue;
112 if (errno == EAGAIN) {
113 (void)poll(&pfd, 1, -1);
114 continue;
115 }
94 return 0; 116 return 0;
95 case 0: 117 case 0:
96 errno = EPIPE; 118 errno = EPIPE;