aboutsummaryrefslogtreecommitdiffstats
path: root/io.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-10-23 05:28:12 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-10-23 05:28:12 +0000
commit209f1e75308c78667a5a241d331dfa97ddfce864 (patch)
tree5415979281288379ef68db9efe01756d7edb5594 /io.c
parentf1950ffa079d3a69de2a254c00ed65ec4b6cd6f4 (diff)
downloadruby-209f1e75308c78667a5a241d331dfa97ddfce864.tar.gz
io.c: fix infinite retry
* io.c (io_binwritev): fix infinite retry when flushing buffered data. [Feature #9323] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60373 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'io.c')
-rw-r--r--io.c26
1 files changed, 13 insertions, 13 deletions
diff --git a/io.c b/io.c
index bcd792861e..61d6548dbb 100644
--- a/io.c
+++ b/io.c
@@ -1534,7 +1534,7 @@ io_binwritev(struct iovec *iov, int iovcnt, rb_io_t *fptr)
}
else {
iov++;
- iovcnt--;
+ if (!--iovcnt) return 0;
}
retry:
@@ -1557,25 +1557,25 @@ io_binwritev(struct iovec *iov, int iovcnt, rb_io_t *fptr)
fptr->wbuf.len -= r;
}
else {
+ written_len -= fptr->wbuf.len;
fptr->wbuf.off = 0;
fptr->wbuf.len = 0;
}
}
- if (written_len == total) return written_len;
+ if (written_len == total) return total;
- for (i = 0; i < iovcnt; i++) {
- if (r > (ssize_t)iov[i].iov_len) {
- r -= iov[i].iov_len;
- iov[i].iov_len = 0;
- }
- else {
- iov[i].iov_base = (char *)iov[i].iov_base + r;
- iov[i].iov_len -= r;
- break;
- }
+ while (r >= (ssize_t)iov->iov_len) {
+ /* iovcnt > 0 */
+ r -= iov->iov_len;
+ iov->iov_len = 0;
+ iov++;
+ if (!--iovcnt) return total;
+ /* defensive check: written_len should == total */
}
+ iov->iov_base = (char *)iov->iov_base + r;
+ iov->iov_len -= r;
- errno = EAGAIN;
+ errno = EAGAIN;
}
if (rb_io_wait_writable(fptr->fd)) {
rb_io_check_closed(fptr);