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
This commit is contained in:
parent
71a7ef31d7
commit
08524bc594
26
io.c
26
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);
|
||||
|
@ -1236,6 +1236,16 @@ class TestIO < Test::Unit::TestCase
|
||||
open(file, "rb") do |r|
|
||||
assert_equal([line, line, "\n"], r.readlines)
|
||||
end
|
||||
|
||||
line = "x"*99+"\n"
|
||||
open(file, "wb") do |w|
|
||||
w.write(line*81) # 8100 bytes
|
||||
assert_equal(100, w.write("a"*99, "\n"))
|
||||
end
|
||||
open(file, "rb") do |r|
|
||||
81.times {assert_equal(line, r.gets)}
|
||||
assert_equal("a"*99+"\n", r.gets)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user