diff options
author | Samuel Williams <[email protected]> | 2022-05-09 23:44:44 +1200 |
---|---|---|
committer | Samuel Williams <[email protected]> | 2022-05-28 15:44:18 +1200 |
commit | 1589ac6291d6bf9caa8f237c6d143dd26526b579 (patch) | |
tree | 87280b6bb3423f3b92d78117a4b442956e0bffb0 /io.c | |
parent | 4efccd28e4b257fb1c8f97781d0b5b1c42c1d9fa (diff) |
Improve handling of zero length writes.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/5419
Diffstat (limited to 'io.c')
-rw-r--r-- | io.c | 26 |
1 files changed, 14 insertions, 12 deletions
@@ -1607,7 +1607,7 @@ io_binwrite_string_internal(rb_io_t *fptr, const char *ptr, long length) fptr->wbuf.off += (int)result; fptr->wbuf.len -= (int)result; - return 0L; + result = 0; } return result; @@ -1664,21 +1664,19 @@ io_binwrite_string(VALUE arg) // Write as much as possible: long result = (long)io_binwrite_string_internal(p->fptr, ptr, remaining); - // Finished: - if (result == remaining) { - break; - } + // It's possible that write can return 0 which implies we should wait for the file descriptor to be writable. + if (result == 0) errno = EAGAIN; - if (result >= 0) { + if (result > 0) { + if (result == remaining) break; ptr += result; remaining -= result; - errno = EAGAIN; } - // 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); - } else { + } + else { // The error was unrelated to waiting for it to become writable, so we fail: return -1; } @@ -1908,7 +1906,9 @@ io_binwritev_internal(VALUE arg) while (remaining) { long result = rb_writev_internal(fptr, iov, iovcnt); - if (result >= 0) { + if (result == 0) errno = EAGAIN; + + if (result > 0) { offset += result; if (fptr->wbuf.ptr && 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; long result = rb_write_internal(fptr, ds, remaining); - if (result >= 0) { + if (result == 0) errno = EAGAIN; + + if (result > 0) { ds += result; if ((size_t)result == remaining) break; } |