From aed607fa413622b314ac82a827682dae2487418a Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 2 Apr 2011 14:57:20 -0700 Subject: [PATCH] clobber errno before syscalls for BasicSocket#read We don't want old errnos being leftover and affecting the error check for EOF --- ext/socket_dontwait/socket_dontwait_ext.c | 5 ++++- test/test_socket_dontwait.rb | 35 +++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/ext/socket_dontwait/socket_dontwait_ext.c b/ext/socket_dontwait/socket_dontwait_ext.c index 2a261a3..7598596 100644 --- a/ext/socket_dontwait/socket_dontwait_ext.c +++ b/ext/socket_dontwait/socket_dontwait_ext.c @@ -164,8 +164,10 @@ static VALUE readpartial(int argc, VALUE *argv, VALUE io) static VALUE recv_all(void *arg) { struct io_args *a = arg; - long n = (long)recv(a->fd, a->ptr, a->len, MSG_WAITALL); + long n; + errno = 0; + n = (long)recv(a->fd, a->ptr, a->len, MSG_WAITALL); if (n >= 0) { a->ptr += n; a->len -= n; @@ -231,6 +233,7 @@ static VALUE xread(int argc, VALUE *argv, VALUE io) return a.buf; /* try to read as much as possible without blocking */ + errno = 0; do n = (long)recv(a.fd, a.ptr, a.len, MSG_DONTWAIT); while (n > 0 && (a.ptr += n) && (a.len -= n) > 0); diff --git a/test/test_socket_dontwait.rb b/test/test_socket_dontwait.rb index e8c18db..82d8f79 100644 --- a/test/test_socket_dontwait.rb +++ b/test/test_socket_dontwait.rb @@ -20,6 +20,9 @@ ORIGINAL_SOCKET = ENV['ORIGINAL_SOCKET'].to_i != 0 require(ORIGINAL_SOCKET ? 'socket' : 'socket_dontwait') class TestSocketDontwait < Test::Unit::TestCase + BS = ENV['bs'] ? ENV['bs'].to_i : 16384 + COUNT = ENV['count'] ? ENV['count'].to_i : 100000 + def setup @rd, @wr = UNIXSocket.pair end @@ -265,4 +268,36 @@ class TestSocketDontwait < Test::Unit::TestCase assert_nothing_raised { @wr.sync = false } assert @wr.sync end unless ORIGINAL_SOCKET + + def read_loop(io) + rbuf = "" + bs = BS + n = bs * COUNT + while io.read(bs, rbuf) + n -= rbuf.size + end + 0 == n + end + + def write_loop(io) + buf = " " * BS + n = 0 + COUNT.times do + n += io.write buf + end + io.close + n == COUNT * BS + end + + def test_read_write_loop_fork + pid = fork do + @wr.close + exit read_loop(@rd) + end + @rd.close + rv = write_loop(@wr) + assert rv + _, status = Process.waitpid2(pid) + assert status.success? + end end -- 2.11.4.GIT