Feature #6154 » eagain_readwrite.diff
| include/ruby/ruby.h (working copy) | ||
|---|---|---|
|
NORETURN(void rb_sys_fail_str(VALUE));
|
||
|
NORETURN(void rb_mod_sys_fail(VALUE, const char*));
|
||
|
NORETURN(void rb_mod_sys_fail_str(VALUE, VALUE));
|
||
|
NORETURN(void rb_readwrite_sys_fail(int, const char*));
|
||
|
NORETURN(void rb_iter_break(void));
|
||
|
NORETURN(void rb_iter_break_value(VALUE));
|
||
|
NORETURN(void rb_exit(int));
|
||
| io.c (working copy) | ||
|---|---|---|
|
VALUE rb_eIOError;
|
||
|
VALUE rb_mWaitReadable;
|
||
|
VALUE rb_mWaitWritable;
|
||
|
extern VALUE rb_eEAGAIN;
|
||
|
extern VALUE rb_eEWOULDBLOCK;
|
||
|
extern VALUE rb_eEINPROGRESS;
|
||
|
static VALUE rb_eEAGAINWaitReadable;
|
||
|
static VALUE rb_eEAGAINWaitWritable;
|
||
|
static VALUE rb_eEWOULDBLOCKWaitReadable;
|
||
|
static VALUE rb_eEWOULDBLOCKWaitWritable;
|
||
|
static VALUE rb_eEINPROGRESSWaitWritable;
|
||
|
static VALUE rb_eEINPROGRESSWaitReadable;
|
||
|
VALUE rb_stdin, rb_stdout, rb_stderr;
|
||
|
VALUE rb_deferr; /* rescue VIM plugin */
|
||
|
static VALUE orig_stdout, orig_stderr;
|
||
| ... | ... | |
|
}
|
||
|
}
|
||
|
void
|
||
|
rb_readwrite_sys_fail(int writable, const char *mesg);
|
||
|
static VALUE
|
||
|
io_getpartial(int argc, VALUE *argv, VALUE io, int nonblock)
|
||
|
{
|
||
| ... | ... | |
|
if (!nonblock && rb_io_wait_readable(fptr->fd))
|
||
|
goto again;
|
||
|
if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN))
|
||
|
rb_mod_sys_fail(rb_mWaitReadable, "read would block");
|
||
|
rb_readwrite_sys_fail(0, "read would block");
|
||
|
rb_sys_fail_path(fptr->pathv);
|
||
|
}
|
||
|
}
|
||
| ... | ... | |
|
if (n == -1) {
|
||
|
if (errno == EWOULDBLOCK || errno == EAGAIN)
|
||
|
rb_mod_sys_fail(rb_mWaitWritable, "write would block");
|
||
|
rb_readwrite_sys_fail(1, "write would block");
|
||
|
rb_sys_fail_path(fptr->pathv);
|
||
|
}
|
||
| ... | ... | |
|
return rb_io_write(argf_write_io(argf), str);
|
||
|
}
|
||
|
void
|
||
|
rb_readwrite_sys_fail(int writable, const char *mesg)
|
||
|
{
|
||
|
VALUE arg;
|
||
|
int n = errno;
|
||
|
arg = mesg ? rb_str_new2(mesg) : Qnil;
|
||
|
if (writable) {
|
||
|
switch (n) {
|
||
|
case EAGAIN:
|
||
|
rb_exc_raise(rb_class_new_instance(1, &arg, rb_eEAGAINWaitWritable));
|
||
|
break;
|
||
|
#if EAGAIN != EWOULDBLOCK
|
||
|
case EWOULDBLOCK:
|
||
|
rb_exc_raise(rb_class_new_instance(1, &arg, rb_eEWOULDBLOCKWaitWritable));
|
||
|
break;
|
||
|
#endif
|
||
|
case EINPROGRESS:
|
||
|
rb_exc_raise(rb_class_new_instance(1, &arg, rb_eEINPROGRESSWaitWritable));
|
||
|
break;
|
||
|
default:
|
||
|
rb_mod_sys_fail_str(rb_mWaitWritable, arg);
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
switch (n) {
|
||
|
case EAGAIN:
|
||
|
rb_exc_raise(rb_class_new_instance(1, &arg, rb_eEAGAINWaitReadable));
|
||
|
break;
|
||
|
#if EAGAIN != EWOULDBLOCK
|
||
|
case EWOULDBLOCK:
|
||
|
rb_exc_raise(rb_class_new_instance(1, &arg, rb_eEWOULDBLOCKWaitReadable));
|
||
|
break;
|
||
|
#endif
|
||
|
case EINPROGRESS:
|
||
|
rb_exc_raise(rb_class_new_instance(1, &arg, rb_eEINPROGRESSWaitReadable));
|
||
|
break;
|
||
|
default:
|
||
|
rb_mod_sys_fail_str(rb_mWaitReadable, arg);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
/*
|
||
|
* Document-class: IOError
|
||
|
*
|
||
| ... | ... | |
|
rb_mWaitReadable = rb_define_module_under(rb_cIO, "WaitReadable");
|
||
|
rb_mWaitWritable = rb_define_module_under(rb_cIO, "WaitWritable");
|
||
|
rb_eEAGAINWaitReadable = rb_define_class_under(rb_cIO, "EAGAINWaitReadable", rb_eEAGAIN);
|
||
|
rb_include_module(rb_eEAGAINWaitReadable, rb_mWaitReadable);
|
||
|
rb_eEAGAINWaitWritable = rb_define_class_under(rb_cIO, "EAGAINWaitWritable", rb_eEAGAIN);
|
||
|
rb_include_module(rb_eEAGAINWaitWritable, rb_mWaitWritable);
|
||
|
if (EAGAIN == EWOULDBLOCK) {
|
||
|
rb_eEWOULDBLOCKWaitReadable = rb_eEAGAINWaitReadable;
|
||
|
rb_define_const(rb_cIO, "EWOULDBLOCKWaitReadable", rb_eEAGAINWaitReadable);
|
||
|
rb_eEWOULDBLOCKWaitWritable = rb_eEAGAINWaitWritable;
|
||
|
rb_define_const(rb_cIO, "EWOULDBLOCKWaitWritable", rb_eEAGAINWaitWritable);
|
||
|
} else {
|
||
|
rb_eEWOULDBLOCKWaitReadable = rb_define_class_under(rb_cIO, "EWOULDBLOCKRWaiteadable", rb_eEWOULDBLOCK);
|
||
|
rb_include_module(rb_eEWOULDBLOCKWaitReadable, rb_mWaitReadable);
|
||
|
rb_eEWOULDBLOCKWaitWritable = rb_define_class_under(rb_cIO, "EWOULDBLOCKWaitWritable", rb_eEWOULDBLOCK);
|
||
|
rb_include_module(rb_eEWOULDBLOCKWaitWritable, rb_mWaitWritable);
|
||
|
}
|
||
|
rb_eEINPROGRESSWaitReadable = rb_define_class_under(rb_cIO, "EINPROGRESSWaitReadable", rb_eEINPROGRESS);
|
||
|
rb_include_module(rb_eEINPROGRESSWaitReadable, rb_mWaitReadable);
|
||
|
rb_eEINPROGRESSWaitWritable = rb_define_class_under(rb_cIO, "EINPROGRESSWaitWritable", rb_eEINPROGRESS);
|
||
|
rb_include_module(rb_eEINPROGRESSWaitWritable, rb_mWaitWritable);
|
||
|
#if 0
|
||
|
/* This is necessary only for forcing rdoc handle File::open */
|
||
| ext/openssl/ossl_ssl.c (working copy) | ||
|---|---|---|
|
VALUE cSSLContext;
|
||
|
VALUE cSSLSocket;
|
||
|
static VALUE eSSLErrorWaitReadable;
|
||
|
static VALUE eSSLErrorWaitWritable;
|
||
|
#define ossl_sslctx_set_cert(o,v) rb_iv_set((o),"@cert",(v))
|
||
|
#define ossl_sslctx_set_key(o,v) rb_iv_set((o),"@key",(v))
|
||
|
#define ossl_sslctx_set_client_ca(o,v) rb_iv_set((o),"@client_ca",(v))
|
||
| ... | ... | |
|
write_would_block(int nonblock)
|
||
|
{
|
||
|
if (nonblock) {
|
||
|
VALUE exc = ossl_exc_new(eSSLError, "write would block");
|
||
|
rb_extend_object(exc, rb_mWaitWritable);
|
||
|
VALUE exc = ossl_exc_new(eSSLErrorWaitReadable, "write would block");
|
||
|
rb_exc_raise(exc);
|
||
|
}
|
||
|
}
|
||
| ... | ... | |
|
read_would_block(int nonblock)
|
||
|
{
|
||
|
if (nonblock) {
|
||
|
VALUE exc = ossl_exc_new(eSSLError, "read would block");
|
||
|
rb_extend_object(exc, rb_mWaitReadable);
|
||
|
VALUE exc = ossl_exc_new(eSSLErrorWaitReadable, "read would block");
|
||
|
rb_exc_raise(exc);
|
||
|
}
|
||
|
}
|
||
| ... | ... | |
|
* Generic error class raised by SSLSocket and SSLContext.
|
||
|
*/
|
||
|
eSSLError = rb_define_class_under(mSSL, "SSLError", eOSSLError);
|
||
|
eSSLErrorWaitReadable = rb_define_class_under(mSSL, "SSLErrorWaitReadable", eSSLError);
|
||
|
rb_include_module(eSSLErrorWaitReadable, rb_mWaitReadable);
|
||
|
eSSLErrorWaitWritable = rb_define_class_under(mSSL, "SSLErrorWaitWritable", eSSLError);
|
||
|
rb_include_module(eSSLErrorWaitWritable, rb_mWaitWritable);
|
||
|
Init_ossl_ssl_session();
|
||
| ext/socket/init.c (working copy) | ||
|---|---|---|
|
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
|
||
|
case EWOULDBLOCK:
|
||
|
#endif
|
||
|
rb_mod_sys_fail(rb_mWaitReadable, "recvfrom(2) would block");
|
||
|
rb_readwrite_sys_fail(0, "recvfrom(2) would block");
|
||
|
}
|
||
|
rb_sys_fail("recvfrom(2)");
|
||
|
}
|
||
| ... | ... | |
|
#if defined EPROTO
|
||
|
case EPROTO:
|
||
|
#endif
|
||
|
rb_mod_sys_fail(rb_mWaitReadable, "accept(2) would block");
|
||
|
rb_readwrite_sys_fail(0, "accept(2) would block");
|
||
|
}
|
||
|
rb_sys_fail("accept(2)");
|
||
|
}
|
||
| ext/socket/socket.c (working copy) | ||
|---|---|---|
|
n = connect(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_LENINT(addr));
|
||
|
if (n < 0) {
|
||
|
if (errno == EINPROGRESS)
|
||
|
rb_mod_sys_fail(rb_mWaitWritable, "connect(2) would block");
|
||
|
rb_readwrite_sys_fail(1, "connect(2) would block");
|
||
|
rb_sys_fail("connect(2)");
|
||
|
}
|
||
| ext/socket/ancdata.c (working copy) | ||
|---|---|---|
|
if (ss == -1) {
|
||
|
if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN))
|
||
|
rb_mod_sys_fail(rb_mWaitWritable, "sendmsg(2) would block");
|
||
|
rb_readwrite_sys_fail(1, "sendmsg(2) would block");
|
||
|
rb_sys_fail("sendmsg(2)");
|
||
|
}
|
||
| ... | ... | |
|
if (ss == -1) {
|
||
|
if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN))
|
||
|
rb_mod_sys_fail(rb_mWaitReadable, "recvmsg(2) would block");
|
||
|
rb_readwrite_sys_fail(0, "recvmsg(2) would block");
|
||
|
#if defined(HAVE_ST_MSG_CONTROL)
|
||
|
if (!gc_done && (errno == EMFILE || errno == EMSGSIZE)) {
|
||
|
/*
|
||
| error.c (working copy) | ||
|---|---|---|
|
#define WEXITSTATUS(status) (status)
|
||
|
#endif
|
||
|
VALUE rb_eEAGAIN;
|
||
|
VALUE rb_eEWOULDBLOCK;
|
||
|
VALUE rb_eEINPROGRESS;
|
||
|
extern const char ruby_description[];
|
||
|
#define REPORTBUG_MSG \
|
||
| ... | ... | |
|
if (!st_lookup(syserr_tbl, n, &error)) {
|
||
|
error = rb_define_class_under(rb_mErrno, name, rb_eSystemCallError);
|
||
|
|
||
|
/* capture nonblock errnos for WaitReadable/WaitWritable subclasses */
|
||
|
switch (n) {
|
||
|
case EAGAIN:
|
||
|
rb_eEAGAIN = error;
|
||
|
|
||
|
#if EAGAIN != EWOULDBLOCK
|
||
|
break;
|
||
|
case EWOULDBLOCK:
|
||
|
#endif
|
||
|
rb_eEWOULDBLOCK = error;
|
||
|
break;
|
||
|
case EINPROGRESS:
|
||
|
rb_eEINPROGRESS = error;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
rb_define_const(error, "Errno", INT2NUM(n));
|
||
|
st_add_direct(syserr_tbl, n, error);
|
||
|
}
|
||
| test/openssl/test_pair.rb (working copy) | ||
|---|---|---|
|
def test_read_nonblock
|
||
|
ssl_pair {|s1, s2|
|
||
|
err = nil
|
||
|
assert_raise(OpenSSL::SSL::SSLError) {
|
||
|
assert_raise(OpenSSL::SSL::SSLErrorWaitReadable) {
|
||
|
begin
|
||
|
s2.read_nonblock(10)
|
||
|
ensure
|
||
| test/socket/test_unix.rb (working copy) | ||
|---|---|---|
|
def test_dgram_pair
|
||
|
s1, s2 = UNIXSocket.pair(Socket::SOCK_DGRAM)
|
||
|
assert_raise(Errno::EAGAIN) { s1.recv_nonblock(10) }
|
||
|
begin
|
||
|
s1.recv_nonblock(10)
|
||
|
fail
|
||
|
rescue => e
|
||
|
assert(IO::EAGAINWaitReadable === e)
|
||
|
assert(IO::WaitReadable === e)
|
||
|
end
|
||
|
s2.send("", 0)
|
||
|
s2.send("haha", 0)
|
||
|
s2.send("", 0)
|
||
| ... | ... | |
|
assert_equal("haha", s1.recv(10))
|
||
|
assert_equal("", s1.recv(10))
|
||
|
assert_equal("", s1.recv(10))
|
||
|
assert_raise(Errno::EAGAIN) { s1.recv_nonblock(10) }
|
||
|
assert_raise(IO::EAGAINWaitReadable) { s1.recv_nonblock(10) }
|
||
|
ensure
|
||
|
s1.close if s1
|
||
|
s2.close if s2
|
||
- « Previous
- 1
- 2
- 3
- 4
- Next »