IO::WantRead and IO::WantWrite module for nonblocking exceptions

IO::WantRead e$B$He(B IO::WantWrite e$B$H$$$&%b%8%e!<%k$r:n$C$F!"e(B
EAGAIN e$B$de(B EWOULDBLOCK e$B$J$I$,H/@8$7$?$H$-$K!"Nc30%%V%8%'%/%He(B
e$B$Ke(B extend e$B$7$F$
$/$N$O$I$&$G$7$g$&$+!#e(B

e$BM}M3$O$U$?$D$"$j$^$9!#e(B

  • rescue Errno::EAGAIN, Errno::EWOULDBLOCK e$B$HJB$Y$k$N$OLLE]e(B

    nonblocking I/O e$B$G$N%(%i!<$re(B rescue e$B$9$k$H$-$O!"$3$&$d$C$Fe(B
    e$B$U$?$DJB$Y$k$N$,9T57$,NI$$$H$5$l$F$$$^$9$,!"e(Bruby e$BB&$G!"e(B
    read_nonblock e$B$G5/$-$?e(B EAGAIN e$B$He(B EWOULDBLOCK e$B$Ge(B
    IO::WantRead e$B$re(B extend e$B$7$F$*$1$P!"e(B
    rescue IO::WantRead
    e$B$H$$$&$R$H$D=q$1$P:Q$`$h$&$K$J$j$^$9!#e(B

    e$B$^$?!"e(Bread_nonblock e$B$He(B write_nonblock e$B$G$Oe(B EAGAIN
    e$B$He(B
    EWOULDBLOCK e$B$G$9$,!“e(Bconnect_nonblock e$B$G$Oe(B EINPROGRESS,
    accept_nonblock e$B$G$Oe(B … e$B$J$I$H$$$&:Y$+$$$3$H$r3P$($J$/$Fe(B
    e$B:Q$`$h$&$K$J$j$^$9!#e(BIO::WantRead e$B$+e(B IO::WantWrite e$B$re(B
    rescue e$B$7$F!”$=$l$KBP1~$7$Fe(B IO.select e$B$Ne(B read e$B$+e(B
    write e$B$Ge(B
    e$BBT$F$P$$$$$o$1$G$9!#e(B

  • openssl e$B$Ne(B read_nonblock e$B$N>l9g!"e(Bread e$B$He(B write
    e$B$N$I$A$i$re(B
    e$BBT$D$Y$-$+$o$+$i$J$$e(B

    1.9.2 e$B$G$Oe(B openssl e$B$Ke(B read_nonblock
    e$B$,$“$j!”<BAu$H$7$F$Oe(B
    openssl e$B$Ne(B nonblocking I/O e$B$r;H$&$o$1$G$9$,!“$3$l$OFbIt$Ge(B
    read(2) e$B$@$1$G$J$/e(B write(2) e$B$r9T$&2DG=@-$,$”$k$h$&$G$9!#$=e(B
    e$B$7$F!“e(Bwrite(2) e$B$,%V%m%C%/$7$=$&$J$H$-$H$$$&$N$b$”$j$($k$oe(B
    e$B$1$G!“$=$N$H$-$K$O%V%m%C%/$;$:$K%(%i!<$K$J$k$o$1$G$9$,!”$=e(B
    e$B$N$H$-$K%"%W%j%1!<%7%g%s$Oe(B writable e$B$K$J$k$N$rBT$C$F$d$j$Je(B
    e$B$*$5$J$1$l$P$J$j$^$;$s!#e(B

    /docs/faq.html

    e$B8=:_$Oe(B read(2) e$B$G%V%m%C%/$7$=$&$J$H$-$be(B write(2)
    e$B$G%V%m%Ce(B
    e$B%/$7$=$&$J$H$-$be(B Errno::EWOULDBLOCK e$BNc30$,H/@8$9$k$N$G!"e(B
    readable e$B$K$J$k$N$rBT$D$+e(B writable e$B$K$J$k$N$rBT$D$+$rNc30e(B
    e$B$N%/%i%9$G6hJL$9$k$3$H$O$G$-$^$;$s!#e(B

    read_nonblock e$B$Ge(B EWOULDBLOCK e$B$K$J$C$?$+$i$H$$$C$Fe(B readable
    e$B$K$J$k$N$rBT$D$H!“=hM}$,?J$^$J$/$J$k2DG=@-$,$”$j$^$9!#e(B

    e$B$3$3$G$I$A$i$rBT$D$Y$-$+$K1~$8$Fe(B IO::WantRead e$B$He(B
    IO::WantWrite e$B$rNc30$Ke(B extend e$B$7$F$*$1$P!"6hJL$9$k$3$H$,=Pe(B
    e$BMh$^$9!#e(B

    e$B$J$!"e(Bopenssl e$B$N%(%i!<$OFbItE$K$Oe(B SSL_ERROR_WANT_READ
    e$B$He(B
    SSL_ERROR_WANT_WRITE e$B$G!"e(BWantRead, WantWrite e$B$H$$$&L>A0$Oe(B
    e$B$3$3$KM3Mh$7$F$$$^$9!#e(B

e$B$H$$$&$o$1$G$I$&$G$7$g$&$+!#e(B

% svn diff --diff-cmd diff -x ‘-u -p’
Index: include/ruby/ruby.h

— include/ruby/ruby.h (revision 22781)
+++ include/ruby/ruby.h (working copy)
@@ -979,6 +979,7 @@ PRINTF_ARGS(NORETURN(void rb_raise(VALUE
PRINTF_ARGS(NORETURN(void rb_fatal(const char*, …)), 1, 2);
PRINTF_ARGS(NORETURN(void rb_bug(const char*, …)), 1, 2);
NORETURN(void rb_sys_fail(const char*));
+NORETURN(void rb_sys_fail_with_mod(VALUE, const char*));
NORETURN(void rb_iter_break(void));
NORETURN(void rb_exit(int));
NORETURN(void rb_notimplement(void));
@@ -1033,6 +1034,8 @@ RUBY_EXTERN VALUE rb_mFileTest;
RUBY_EXTERN VALUE rb_mGC;
RUBY_EXTERN VALUE rb_mMath;
RUBY_EXTERN VALUE rb_mProcess;
+RUBY_EXTERN VALUE rb_mWantRead;
+RUBY_EXTERN VALUE rb_mWantWrite;

RUBY_EXTERN VALUE rb_cBasicObject;
RUBY_EXTERN VALUE rb_cObject;
Index: io.c

— io.c (revision 22781)
+++ io.c (working copy)
@@ -110,6 +110,8 @@ extern void Init_File(void);
VALUE rb_cIO;
VALUE rb_eEOFError;
VALUE rb_eIOError;
+VALUE rb_mWantRead;
+VALUE rb_mWantWrite;

VALUE rb_stdin, rb_stdout, rb_stderr;
VALUE rb_deferr; /* rescue VIM plugin */
@@ -1755,7 +1757,7 @@ io_getpartial(int argc, VALUE *argv, VAL
if (!nonblock && rb_io_wait_readable(fptr->fd))
goto again;
if (nonblock && errno == EWOULDBLOCK)

  •            rb_sys_fail("WANT_READ");
    
  •            rb_sys_fail_with_mod(rb_mWantRead, "WANT_READ");
           rb_sys_fail_path(fptr->pathv);
       }
    

    else if (n == 0) {
    @@ -1956,7 +1958,7 @@ rb_io_write_nonblock(VALUE io, VALUE str

    if (n == -1) {
    if (errno == EWOULDBLOCK)

  •        rb_sys_fail("WANT_WRITE");
    
  •        rb_sys_fail_with_mod(rb_mWantWrite, "WANT_WRITE");
       rb_sys_fail_path(fptr->pathv);
    
    }

@@ -8635,6 +8637,9 @@ Init_IO(void)
rb_cIO = rb_define_class(“IO”, rb_cObject);
rb_include_module(rb_cIO, rb_mEnumerable);

  • rb_mWantRead = rb_define_module_under(rb_cIO, “WantRead”);
  • rb_mWantWrite = rb_define_module_under(rb_cIO, “WantWrite”);

#if 0
/* This is necessary only for forcing rdoc handle File::open */
rb_define_singleton_method(rb_cFile, “open”, rb_io_s_open, -1);
Index: ext/openssl/ossl_ssl.c

— ext/openssl/ossl_ssl.c (revision 22781)
+++ ext/openssl/ossl_ssl.c (working copy)
@@ -1115,14 +1115,14 @@ ossl_ssl_read_internal(int argc, VALUE *
case SSL_ERROR_WANT_WRITE:
if (nonblock) {
errno = EWOULDBLOCK;

  •                rb_sys_fail("SSL_ERROR_WANT_WRITE");
    
  •                rb_sys_fail_with_mod(rb_mWantWrite, 
    

“SSL_ERROR_WANT_WRITE”);
}
rb_io_wait_writable(FPTR_TO_FD(fptr));
continue;
case SSL_ERROR_WANT_READ:
if (nonblock) {
errno = EWOULDBLOCK;

  •                rb_sys_fail("SSL_ERROR_WANT_READ");
    
  •                rb_sys_fail_with_mod(rb_mWantRead, 
    

“SSL_ERROR_WANT_READ”);
}
rb_io_wait_readable(FPTR_TO_FD(fptr));
continue;
Index: ext/socket/init.c

— ext/socket/init.c (revision 22781)
+++ ext/socket/init.c (working copy)
@@ -200,7 +200,7 @@ rsock_s_recvfrom_nonblock(VALUE sock, in
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
case EWOULDBLOCK:
#endif

  •        rb_sys_fail("recvfrom(2) WANT_READ");
    
  •        rb_sys_fail_with_mod(rb_mWantRead, "recvfrom(2) 
    

WANT_READ");
}
rb_sys_fail(“recvfrom(2)”);
}
@@ -472,7 +472,7 @@ rsock_s_accept_nonblock(VALUE klass, rb_
#if defined EPROTO
case EPROTO:
#endif

  •        rb_sys_fail("accept(2) WANT_READ");
    
  •        rb_sys_fail_with_mod(rb_mWantRead, "accept(2) WANT_READ");
    
    }
    rb_sys_fail(“accept(2)”);
    }
    Index: ext/socket/socket.c
    ===================================================================
    — ext/socket/socket.c (revision 22781)
    +++ ext/socket/socket.c (working copy)
    @@ -312,7 +312,7 @@ sock_connect_nonblock(VALUE sock, VALUE
    n = connect(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr),
    RSTRING_LEN(addr));
    if (n < 0) {
    if (errno == EINPROGRESS)
  •        rb_sys_fail("connect(2) WANT_WRITE");
    
  •        rb_sys_fail_with_mod(rb_mWantWrite, "connect(2) 
    

WANT_WRITE");
rb_sys_fail(“connect(2)”);
}

Index: ext/socket/ancdata.c

— ext/socket/ancdata.c (revision 22781)
+++ ext/socket/ancdata.c (working copy)
@@ -1280,7 +1280,7 @@ bsock_sendmsg_internal(int argc, VALUE *

 if (ss == -1) {
     if (nonblock && errno == EWOULDBLOCK)
  •        rb_sys_fail("sendmsg(2) WANT_WRITE");
    
  •        rb_sys_fail_with_mod(rb_mWantWrite, "sendmsg(2) 
    

WANT_WRITE");
rb_sys_fail(“sendmsg(2)”);
}

@@ -1565,7 +1565,7 @@ bsock_recvmsg_internal(int argc, VALUE *

 if (ss == -1) {
     if (nonblock && errno == EWOULDBLOCK)
  •        rb_sys_fail("recvmsg(2) WANT_READ");
    
  •        rb_sys_fail_with_mod(rb_mWantRead, "recvmsg(2) WANT_READ");
    

#if defined(HAVE_ST_MSG_CONTROL)
if (!gc_done && (errno == EMFILE || errno == EMSGSIZE)) {
/*
Index: error.c

— error.c (revision 22781)
+++ error.c (working copy)
@@ -1129,8 +1129,8 @@ rb_fatal(const char *fmt, …)
rb_exc_fatal(rb_exc_new3(rb_eFatal, mesg));
}

-void
-rb_sys_fail(const char *mesg)
+static VALUE
+make_errno_exc(const char *mesg)
{
int n = errno;
VALUE arg;
@@ -1141,7 +1141,21 @@ rb_sys_fail(const char *mesg)
}

 arg = mesg ? rb_str_new2(mesg) : Qnil;
  • rb_exc_raise(rb_class_new_instance(1, &arg, get_syserr(n)));
  • return rb_class_new_instance(1, &arg, get_syserr(n));
    +}

+void
+rb_sys_fail(const char *mesg)
+{

  • rb_exc_raise(make_errno_exc(mesg));
    +}

+void
+rb_sys_fail_with_mod(VALUE mod, const char *mesg)
+{

  • VALUE exc = make_errno_exc(mesg);
  • rb_extend_object(exc, mod);
  • rb_exc_raise(exc);
    }

void
Index: test/openssl/test_pair.rb

— test/openssl/test_pair.rb (revision 22781)
+++ test/openssl/test_pair.rb (working copy)
@@ -147,7 +147,7 @@ class OpenSSL::TestPair < Test::Unit::Te
def test_read_nonblock
ssl_pair {|s1, s2|
err = nil

  •  assert_raise(Errno::EWOULDBLOCK) {
    
  •  assert_raise(IO::WantRead) {
       begin
         s2.read_nonblock(10)
       ensure
    

Index: test/openssl/test_ssl.rb

— test/openssl/test_ssl.rb (revision 22781)
+++ test/openssl/test_ssl.rb (working copy)
@@ -172,12 +172,12 @@ class OpenSSL::TestSSL < Test::Unit::Tes
ssl = OpenSSL::SSL::SSLSocket.new(sock)
ssl.sync_close = true
ssl.connect

  •  assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK) { 
    

ssl.read_nonblock(100) }

  •  assert_raise(IO::WantRead) { ssl.read_nonblock(100) }
     ssl.write("abc\n")
     IO.select [ssl]
     assert_equal('a', ssl.read_nonblock(1))
     assert_equal("bc\n", ssl.read_nonblock(100))
    
  •  assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK) { 
    

ssl.read_nonblock(100) }

  •  assert_raise(IO::WantRead) { ssl.read_nonblock(100) }
    
    }
    end

Index: test/socket/test_nonblock.rb

— test/socket/test_nonblock.rb (revision 22781)
+++ test/socket/test_nonblock.rb (working copy)
@@ -12,13 +12,13 @@ class TestSocketNonblock < Test::Unit::T
serv = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
serv.bind(Socket.sockaddr_in(0, “127.0.0.1”))
serv.listen(5)

  • assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK) {
    serv.accept_nonblock }
  • assert_raise(IO::WantRead) { serv.accept_nonblock }
    c = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
    c.connect(serv.getsockname)
    begin
    s, sockaddr = serv.accept_nonblock
  • rescue Errno::EWOULDBLOCK
  •  IO.select nil, [serv]
    
  • rescue IO::WantRead
  •  IO.select [serv]
     s, sockaddr = serv.accept_nonblock
    
    end
    assert_equal(Socket.unpack_sockaddr_in(c.getsockname),
    Socket.unpack_sockaddr_in(sockaddr))
    @@ -57,8 +57,8 @@ class TestSocketNonblock < Test::Unit::T
    u1 = UDPSocket.new
    u2 = UDPSocket.new
    u1.bind(“127.0.0.1”, 0)
  • assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK) {
    u1.recvfrom_nonblock(100) }
  • assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK, Errno::EINVAL) {
    u2.recvfrom_nonblock(100) }
  • assert_raise(IO::WantRead) { u1.recvfrom_nonblock(100) }
  • assert_raise(IO::WantRead, Errno::EINVAL) {
    u2.recvfrom_nonblock(100) }
    u2.send(“aaa”, 0, u1.getsockname)
    IO.select [u1]
    mesg, inet_addr = u1.recvfrom_nonblock(100)
    @@ -67,7 +67,7 @@ class TestSocketNonblock < Test::Unit::T
    af, port, host, addr = inet_addr
    u2_port, u2_addr = Socket.unpack_sockaddr_in(u2.getsockname)
    assert_equal(u2_port, port)
  • assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK) {
    u1.recvfrom_nonblock(100) }
  • assert_raise(IO::WantRead) { u1.recvfrom_nonblock(100) }
    u2.send(“”, 0, u1.getsockname)
    assert_nothing_raised(“cygwin 1.5.19 has a problem to send an empty
    UDP packet. [ruby-dev:28915]”) {
    timeout(1) { IO.select [u1] }
    @@ -83,13 +83,13 @@ class TestSocketNonblock < Test::Unit::T
    u1 = UDPSocket.new
    u2 = UDPSocket.new
    u1.bind(“127.0.0.1”, 0)
  • assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK) {
    u1.recv_nonblock(100) }
  • assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK, Errno::EINVAL) {
    u2.recv_nonblock(100) }
  • assert_raise(IO::WantRead) { u1.recv_nonblock(100) }
  • assert_raise(IO::WantRead, Errno::EINVAL) { u2.recv_nonblock(100) }
    u2.send(“aaa”, 0, u1.getsockname)
    IO.select [u1]
    mesg = u1.recv_nonblock(100)
    assert_equal(“aaa”, mesg)
  • assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK) {
    u1.recv_nonblock(100) }
  • assert_raise(IO::WantRead) { u1.recv_nonblock(100) }
    u2.send(“”, 0, u1.getsockname)
    assert_nothing_raised(“cygwin 1.5.19 has a problem to send an empty
    UDP packet. [ruby-dev:28915]”) {
    timeout(1) { IO.select [u1] }
    @@ -105,8 +105,8 @@ class TestSocketNonblock < Test::Unit::T
    s1 = Socket.new(Socket::AF_INET, Socket::SOCK_DGRAM, 0)
    s1.bind(Socket.sockaddr_in(0, “127.0.0.1”))
    s2 = Socket.new(Socket::AF_INET, Socket::SOCK_DGRAM, 0)
  • assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK) {
    s1.recvfrom_nonblock(100) }
  • assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK, Errno::EINVAL) {
    s2.recvfrom_nonblock(100) }
  • assert_raise(IO::WantRead) { s1.recvfrom_nonblock(100) }
  • assert_raise(IO::WantRead, Errno::EINVAL) {
    s2.recvfrom_nonblock(100) }
    s2.send(“aaa”, 0, s1.getsockname)
    IO.select [s1]
    mesg, sockaddr = s1.recvfrom_nonblock(100)
    @@ -140,13 +140,13 @@ class TestSocketNonblock < Test::Unit::T

def test_tcp_recv_nonblock
c, s = tcp_pair

  • assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK) {
    c.recv_nonblock(100) }
  • assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK) {
    s.recv_nonblock(100) }
  • assert_raise(IO::WantRead) { c.recv_nonblock(100) }
  • assert_raise(IO::WantRead) { s.recv_nonblock(100) }
    c.write(“abc”)
    IO.select [s]
    assert_equal(“a”, s.recv_nonblock(1))
    assert_equal(“bc”, s.recv_nonblock(100))
  • assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK) {
    s.recv_nonblock(100) }
  • assert_raise(IO::WantRead) { s.recv_nonblock(100) }
    ensure
    c.close if c
    s.close if s
    @@ -154,13 +154,13 @@ class TestSocketNonblock < Test::Unit::T

def test_read_nonblock
c, s = tcp_pair

  • assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK) {
    c.read_nonblock(100) }
  • assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK) {
    s.read_nonblock(100) }
  • assert_raise(IO::WantRead) { c.read_nonblock(100) }
  • assert_raise(IO::WantRead) { s.read_nonblock(100) }
    c.write(“abc”)
    IO.select [s]
    assert_equal(“a”, s.read_nonblock(1))
    assert_equal(“bc”, s.read_nonblock(100))
  • assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK) {
    s.read_nonblock(100) }
  • assert_raise(IO::WantRead) { s.read_nonblock(100) }
    ensure
    c.close if c
    s.close if s
    @@ -175,7 +175,7 @@ class TestSocketNonblock < Test::Unit::T
    ret = c.write_nonblock(str)
    assert_operator(ret, :>, 0)
    loop {
  •  assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK) {
    
  •  assert_raise(IO::WantWrite) {
       loop {
         ret = c.write_nonblock(str)
         assert_operator(ret, :>, 0)
    

@@ -196,7 +196,7 @@ class TestSocketNonblock < Test::Unit::T
loop {
c.sendmsg_nonblock(“a” * 100000)
}

  •  rescue Errno::EWOULDBLOCK
    
  •  rescue IO::WantWrite
       assert_match(/WANT_WRITE/, $!.message)
     end
    
    }
    @@ -206,7 +206,7 @@ class TestSocketNonblock < Test::Unit::T
    tcp_pair {|c, s|
    begin
    c.recvmsg_nonblock(4096)
  •  rescue Errno::EWOULDBLOCK
    
  •  rescue IO::WantRead
       assert_match(/WANT_READ/, $!.message)
     end
    
    }
    @@ -216,7 +216,7 @@ class TestSocketNonblock < Test::Unit::T
    tcp_pair {|c, s|
    begin
    c.recv_nonblock(4096)
  •  rescue Errno::EWOULDBLOCK
    
  •  rescue IO::WantRead
       assert_match(/WANT_READ/, $!.message)
     end
    
    }
    @@ -243,7 +243,7 @@ class TestSocketNonblock < Test::Unit::T
    port = serv.local_address.ip_port
    begin
    s, _ = serv.accept_nonblock
  • rescue Errno::EWOULDBLOCK, Errno::ECONNABORTED, Errno::EPROTO
  • rescue IO::WantRead
    assert_match(/WANT_READ/, $!.message)
    end
    ensure
    Index: test/socket/test_addrinfo.rb
    ===================================================================
    — test/socket/test_addrinfo.rb (revision 22781)
    +++ test/socket/test_addrinfo.rb (working copy)
    @@ -236,7 +236,7 @@ class TestSocketAddrinfo < Test::Unit::T
    c.connect(serv.local_address)
    begin
    ret = serv.accept_nonblock
  • rescue Errno::EAGAIN, Errno::EWOULDBLOCK, Errno::ECONNABORTED,
    Errno::EPROTO, Errno::EINTR
  • rescue IO::WantRead, Errno::EINTR
    IO.select([serv])
    retry
    end
    @@ -299,7 +299,7 @@ class TestSocketAddrinfo < Test::Unit::T
    s2.send(“test-socket-recvfrom”, 0, s1.getsockname)
    begin
    data, ai = s1.recvfrom_nonblock(100)
  • rescue Errno::EWOULDBLOCK
  • rescue IO::WantRead
    IO.select([s1])
    retry
    end

e$B!Ve(BWantReade$B!W$H!Ve(BWantWritee$B!W$O1Q8lE*$K$A$g$C$HHyL/$JLL$,$"$k$N$G!"e(B
e$BL>A0$K$D$$$F$O0l2se(B ruby-core
e$B$G5DO@$7$?J}$,$$$$$+$b$7$l$^$;$s!#e(B

e$B$h$m$7$/$*4j$$$7$^$9!#e(B Martin.

At 18:48 09/03/05, you wrote:

read_nonblock e$B$G5/$-$?e(B EAGAIN e$B$He(B EWOULDBLOCK e$B$Ge(B

e$B$3$3$G$I$A$i$rBT$D$Y$-$+$K1~$8$Fe(B IO::WantRead e$B$He(B
Index: include/ruby/ruby.h
NORETURN(void rb_notimplement(void));

VALUE rb_deferr; /* rescue VIM plugin */

@@ -1115,14 +1115,14 @@ ossl_ssl_read_internal(int argc, VALUE *
errno = EWOULDBLOCK;
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
#endif
n = connect(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr),
— ext/socket/ancdata.c (revision 22781)
@@ -1565,7 +1565,7 @@ bsock_recvmsg_internal(int argc, VALUE *
— error.c (revision 22781)
int n = errno;
+rb_sys_fail(const char *mesg)
}

  •  assert_raise(Errno::EWOULDBLOCK) {
    ssl.sync_close = true
    
    end
  • assert_raise(IO::WantRead) { serv.accept_nonblock }
    assert_equal(Socket.unpack_sockaddr_in(c.getsockname),
  • assert_raise(IO::WantRead, Errno::EINVAL) { u2.recvfrom_nonblock(100) }
    u2.send(“”, 0, u1.getsockname)
  • assert_raise(IO::WantRead) { u1.recv_nonblock(100) }
    timeout(1) { IO.select [u1] }
    s2.send(“aaa”, 0, s1.getsockname)
    c.write(“abc”)
    def test_read_nonblock
  • assert_raise(IO::WantRead) { s.read_nonblock(100) }
    ret = c.write_nonblock(str)
    @@ -206,7 +206,7 @@ class TestSocketNonblock < Test::Unit::T
    begin
  • rescue Errno::EWOULDBLOCK, Errno::ECONNABORTED, Errno::EPROTO
    begin
    data, ai = s1.recvfrom_nonblock(100)
  • rescue Errno::EWOULDBLOCK
  • rescue IO::WantRead
    IO.select([s1])
    retry
    end

    [e$BEDCfe(B e$BE/e(B][e$B$?$J$+e(B e$B$"$-$ie(B][Tanaka A.]

#-#-# Martin J. Du"rst, Assoc. Professor, Aoyama Gakuin University
#-#-# http://www.sw.it.aoyama.ac.jp mailto:[email protected]