diff --git a/spec/ruby/optional/capi/ext/io_spec.c b/spec/ruby/optional/capi/ext/io_spec.c index 40069bd54b..1b47830fa4 100644 --- a/spec/ruby/optional/capi/ext/io_spec.c +++ b/spec/ruby/optional/capi/ext/io_spec.c @@ -218,6 +218,17 @@ VALUE io_spec_rb_io_close(VALUE self, VALUE io) { } #endif +/* + * this is needed to ensure rb_io_wait_*able functions behave + * predictably because errno may be set to unexpected values + * otherwise. + */ +static VALUE io_spec_errno_set(VALUE self, VALUE val) { + int e = NUM2INT(val); + errno = e; + return val; +} + void Init_io_spec(void) { VALUE cls = rb_define_class("CApiIOSpecs", rb_cObject); @@ -296,6 +307,8 @@ void Init_io_spec(void) { #ifdef HAVE_RB_CLOEXEC_OPEN rb_define_method(cls, "rb_cloexec_open", io_spec_rb_cloexec_open, 3); #endif + + rb_define_method(cls, "errno=", io_spec_errno_set, 1); } #ifdef __cplusplus diff --git a/spec/ruby/optional/capi/io_spec.rb b/spec/ruby/optional/capi/io_spec.rb index 466bfe5a41..a832c6a93b 100644 --- a/spec/ruby/optional/capi/io_spec.rb +++ b/spec/ruby/optional/capi/io_spec.rb @@ -236,6 +236,7 @@ describe "C-API IO function" do describe "rb_io_wait_writable" do it "returns false if there is no error condition" do + @o.errno = 0 @o.rb_io_wait_writable(@w_io).should be_false end @@ -254,6 +255,7 @@ describe "C-API IO function" do platform_is_not :windows do describe "rb_io_wait_readable" do it "returns false if there is no error condition" do + @o.errno = 0 @o.rb_io_wait_readable(@r_io, false).should be_false end @@ -271,6 +273,7 @@ describe "C-API IO function" do @w_io.write "rb_io_wait_readable" end + @o.errno = Errno::EAGAIN.new.errno @o.rb_io_wait_readable(@r_io, true).should be_true @o.instance_variable_get(:@read_data).should == "rb_io_wait_re"