From 988ca60565a5ba6661f7215026f008afebcf7aee Mon Sep 17 00:00:00 2001 From: tenderlove Date: Mon, 26 Aug 2013 22:41:44 +0000 Subject: * io.c (io_read_nonblock): support non-blocking reads without raising exceptions. As in: `io.read_nonblock(size, exception: false)` [ruby-core:38666] [Feature #5138] * ext/openssl/ossl_ssl.c (ossl_ssl_read_internal): ditto * ext/stringio/stringio.c (strio_sysread): ditto * io.c (rb_io_write_nonblock): support non-blocking writes without raising an exception. * ext/openssl/ossl_ssl.c (ossl_ssl_write_internal): ditto * test/openssl/test_pair.rb (class OpenSSL): tests * test/ruby/test_io.rb (class TestIO): ditto * test/socket/test_nonblock.rb (class TestSocketNonblock): ditto * test/stringio/test_stringio.rb (class TestStringIO): ditto git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42695 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/stringio/stringio.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-) (limited to 'ext/stringio') diff --git a/ext/stringio/stringio.c b/ext/stringio/stringio.c index ef3df832b8..5c2c64ca03 100644 --- a/ext/stringio/stringio.c +++ b/ext/stringio/stringio.c @@ -119,6 +119,8 @@ typedef char strio_flags_check[(STRIO_READABLE/FMODE_READABLE == STRIO_WRITABLE/ #define READABLE(strio) STRIO_MODE_SET_P(strio, READABLE) #define WRITABLE(strio) STRIO_MODE_SET_P(strio, WRITABLE) +static VALUE sym_exception; + static struct StringIO* readable(VALUE strio) { @@ -1327,7 +1329,6 @@ strio_read(int argc, VALUE *argv, VALUE self) * call-seq: * strio.sysread(integer[, outbuf]) -> string * strio.readpartial(integer[, outbuf]) -> string - * strio.read_nonblock(integer[, outbuf]) -> string * * Similar to #read, but raises +EOFError+ at end of string instead of * returning +nil+, as well as IO#sysread does. @@ -1342,8 +1343,50 @@ strio_sysread(int argc, VALUE *argv, VALUE self) return val; } +/* + * call-seq: + * strio.read_nonblock(integer[, outbuf [, opts]]) -> string + * + * Similar to #read, but raises +EOFError+ at end of string unless the + * +exception: false+ option is passed in. + */ +static VALUE +strio_read_nonblock(int argc, VALUE *argv, VALUE self) +{ + VALUE opts = Qnil; + int no_exception = 0; + + rb_scan_args(argc, argv, "11:", NULL, NULL, &opts); + + if (!NIL_P(opts)) { + argc--; + + if (Qfalse == rb_hash_aref(opts, sym_exception)) + no_exception = 1; + } + + VALUE val = strio_read(argc, argv, self); + if (NIL_P(val)) { + if (no_exception) + return Qnil; + else + rb_eof_error(); + } + + return val; +} + #define strio_syswrite rb_io_write +static VALUE +strio_syswrite_nonblock(int argc, VALUE *argv, VALUE self) +{ + VALUE str; + + rb_scan_args(argc, argv, "10:", &str, NULL); + return strio_syswrite(self, str); +} + #define strio_isatty strio_false #define strio_pid strio_nil @@ -1542,7 +1585,7 @@ Init_stringio() rb_define_method(mReadable, "readline", strio_readline, -1); rb_define_method(mReadable, "sysread", strio_sysread, -1); rb_define_method(mReadable, "readpartial", strio_sysread, -1); - rb_define_method(mReadable, "read_nonblock", strio_sysread, -1); + rb_define_method(mReadable, "read_nonblock", strio_read_nonblock, -1); rb_include_module(StringIO, mReadable); } { @@ -1552,7 +1595,9 @@ Init_stringio() rb_define_method(mWritable, "printf", strio_printf, -1); rb_define_method(mWritable, "puts", strio_puts, -1); rb_define_method(mWritable, "syswrite", strio_syswrite, 1); - rb_define_method(mWritable, "write_nonblock", strio_syswrite, 1); + rb_define_method(mWritable, "write_nonblock", strio_syswrite_nonblock, -1); rb_include_module(StringIO, mWritable); } + + sym_exception = ID2SYM(rb_intern("exception")); } -- cgit v1.2.3