summaryrefslogtreecommitdiff
path: root/io.c
diff options
context:
space:
mode:
authorSamuel Williams <samuel.williams@oriontransfer.co.nz>2022-05-09 23:44:44 +1200
committerSamuel Williams <samuel.williams@oriontransfer.co.nz>2022-05-28 15:44:18 +1200
commit1589ac6291d6bf9caa8f237c6d143dd26526b579 (patch)
tree87280b6bb3423f3b92d78117a4b442956e0bffb0 /io.c
parent4efccd28e4b257fb1c8f97781d0b5b1c42c1d9fa (diff)
downloadruby-1589ac6291d6bf9caa8f237c6d143dd26526b579.tar.gz
Improve handling of zero length writes.
Diffstat (limited to 'io.c')
-rw-r--r--io.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/io.c b/io.c
index 30fb42d932..21c5d21c65 100644
--- a/io.c
+++ b/io.c
@@ -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;
}