summaryrefslogtreecommitdiff
path: root/io.c
diff options
context:
space:
mode:
authorSamuel Williams <samuel.williams@oriontransfer.co.nz>2021-06-20 11:05:15 +1200
committerSamuel Williams <samuel.williams@oriontransfer.co.nz>2021-06-22 22:48:57 +1200
commitfcc6fd23ec779a2421154bad441e168e4c6d4194 (patch)
tree989e3f125c8759854d8a3e8f82ed81b812c163f0 /io.c
parent45e65f302b663b2c6ab69df06d3b6f219c1797b2 (diff)
Rework `sysread` to use blocking `read_internal_locktmp`.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/4592
Diffstat (limited to 'io.c')
-rw-r--r--io.c18
1 files changed, 6 insertions, 12 deletions
diff --git a/io.c b/io.c
index 7db0560e71..7033fe6b96 100644
--- a/io.c
+++ b/io.c
@@ -5349,30 +5349,24 @@ rb_io_sysread(int argc, VALUE *argv, VALUE io)
rb_raise(rb_eIOError, "sysread for buffered IO");
}
- /*
- * FIXME: removing rb_thread_wait_fd() here changes sysread semantics
- * on non-blocking IOs. However, it's still currently possible
- * for sysread to raise Errno::EAGAIN if another thread read()s
- * the IO after we return from rb_thread_wait_fd() but before
- * we call read()
- */
- rb_io_wait(fptr->self, RB_INT2NUM(RUBY_IO_READABLE), Qnil);
-
rb_io_check_closed(fptr);
io_setstrbuf(&str, ilen);
+ iis.th = rb_thread_current();
iis.fd = fptr->fd;
- iis.nonblock = 1; /* for historical reasons, maybe (see above) */
+ iis.nonblock = 0;
iis.buf = RSTRING_PTR(str);
iis.capa = ilen;
n = read_internal_locktmp(str, &iis);
if (n < 0) {
- rb_sys_fail_path(fptr->pathv);
+ rb_sys_fail_path(fptr->pathv);
}
+
io_set_read_length(str, n, shrinkable);
+
if (n == 0 && ilen > 0) {
- rb_eof_error();
+ rb_eof_error();
}
return str;