Improve handling of zero length writes.

This commit is contained in:
Samuel Williams 2022-05-09 23:44:44 +12:00
parent 4efccd28e4
commit 1589ac6291
Notes: git 2022-05-28 12:44:45 +09:00

26
io.c
View File

@ -1607,7 +1607,7 @@ io_binwrite_string_internal(rb_io_t *fptr, const char *ptr, long length)
fptr->wbuf.off += (int)result; fptr->wbuf.off += (int)result;
fptr->wbuf.len -= (int)result; fptr->wbuf.len -= (int)result;
return 0L; result = 0;
} }
return result; return result;
@ -1664,21 +1664,19 @@ io_binwrite_string(VALUE arg)
// Write as much as possible: // Write as much as possible:
long result = (long)io_binwrite_string_internal(p->fptr, ptr, remaining); long result = (long)io_binwrite_string_internal(p->fptr, ptr, remaining);
// Finished: // It's possible that write can return 0 which implies we should wait for the file descriptor to be writable.
if (result == remaining) { if (result == 0) errno = EAGAIN;
break;
}
if (result >= 0) { if (result > 0) {
if (result == remaining) break;
ptr += result; ptr += result;
remaining -= result; remaining -= result;
errno = EAGAIN;
} }
// Wait for it to become writable: // Wait for it to become writable:
if (rb_io_maybe_wait_writable(errno, p->fptr->self, Qnil)) { else if (rb_io_maybe_wait_writable(errno, p->fptr->self, Qnil)) {
rb_io_check_closed(p->fptr); rb_io_check_closed(p->fptr);
} else { }
else {
// The error was unrelated to waiting for it to become writable, so we fail: // The error was unrelated to waiting for it to become writable, so we fail:
return -1; return -1;
} }
@ -1908,7 +1906,9 @@ io_binwritev_internal(VALUE arg)
while (remaining) { while (remaining) {
long result = rb_writev_internal(fptr, iov, iovcnt); long result = rb_writev_internal(fptr, iov, iovcnt);
if (result >= 0) { if (result == 0) errno = EAGAIN;
if (result > 0) {
offset += result; offset += result;
if (fptr->wbuf.ptr && fptr->wbuf.len) { if (fptr->wbuf.ptr && fptr->wbuf.len) {
if (offset < (size_t)fptr->wbuf.len) { if (offset < (size_t)fptr->wbuf.len) {
@ -5151,7 +5151,9 @@ finish_writeconv(rb_io_t *fptr, int noalloc)
size_t remaining = dp-ds; size_t remaining = dp-ds;
long result = rb_write_internal(fptr, ds, remaining); long result = rb_write_internal(fptr, ds, remaining);
if (result >= 0) { if (result == 0) errno = EAGAIN;
if (result > 0) {
ds += result; ds += result;
if ((size_t)result == remaining) break; if ((size_t)result == remaining) break;
} }