Feature #10532 ยป 0001-accept_nonblock-supports-exception-false.patch
ext/socket/init.c | ||
---|---|---|
#endif
|
||
int rsock_do_not_reverse_lookup = 1;
|
||
static VALUE sym_exception, sym_wait_readable;
|
||
void
|
||
rsock_raise_socket_error(const char *reason, int error)
|
||
... | ... | |
return ret;
|
||
}
|
||
VALUE
|
||
rsock_s_accept_nonblock(VALUE klass, rb_io_t *fptr, struct sockaddr *sockaddr, socklen_t *len)
|
||
rsock_s_accept_nonblock(int argc, VALUE *argv, VALUE klass, rb_io_t *fptr,
|
||
struct sockaddr *sockaddr, socklen_t *len)
|
||
{
|
||
int fd2;
|
||
int ex = 1;
|
||
VALUE opts = Qnil;
|
||
rb_scan_args(argc, argv, "0:", &opts);
|
||
if (!NIL_P(opts) && Qfalse == rb_hash_aref(opts, sym_exception))
|
||
ex = 0;
|
||
rb_secure(3);
|
||
rb_io_set_nonblock(fptr);
|
||
... | ... | |
#if defined EPROTO
|
||
case EPROTO:
|
||
#endif
|
||
if (!ex)
|
||
return sym_wait_readable;
|
||
rb_readwrite_sys_fail(RB_IO_WAIT_READABLE, "accept(2) would block");
|
||
}
|
||
rb_sys_fail("accept(2)");
|
||
... | ... | |
rsock_init_addrinfo();
|
||
rsock_init_sockifaddr();
|
||
rsock_init_socket_constants();
|
||
#undef rb_intern
|
||
sym_exception = ID2SYM(rb_intern("exception"));
|
||
sym_wait_readable = ID2SYM(rb_intern("wait_readable"));
|
||
}
|
ext/socket/rubysocket.h | ||
---|---|---|
int rsock_connect(int fd, const struct sockaddr *sockaddr, int len, int socks);
|
||
VALUE rsock_s_accept(VALUE klass, int fd, struct sockaddr *sockaddr, socklen_t *len);
|
||
VALUE rsock_s_accept_nonblock(VALUE klass, rb_io_t *fptr, struct sockaddr *sockaddr, socklen_t *len);
|
||
VALUE rsock_s_accept_nonblock(int argc, VALUE *argv, VALUE klass, rb_io_t *fptr, struct sockaddr *sockaddr, socklen_t *len);
|
||
VALUE rsock_sock_listen(VALUE sock, VALUE log);
|
||
VALUE rsock_sockopt_new(int family, int level, int optname, VALUE data);
|
ext/socket/socket.c | ||
---|---|---|
* * Socket#accept
|
||
*/
|
||
static VALUE
|
||
sock_accept_nonblock(VALUE sock)
|
||
sock_accept_nonblock(int argc, VALUE *argv, VALUE sock)
|
||
{
|
||
rb_io_t *fptr;
|
||
VALUE sock2;
|
||
union_sockaddr buf;
|
||
struct sockaddr *addr = &buf.addr;
|
||
socklen_t len = (socklen_t)sizeof buf;
|
||
GetOpenFile(sock, fptr);
|
||
sock2 = rsock_s_accept_nonblock(rb_cSocket, fptr, &buf.addr, &len);
|
||
sock2 = rsock_s_accept_nonblock(argc, argv, rb_cSocket, fptr, addr, &len);
|
||
if (SYMBOL_P(sock2)) /* :wait_readable */
|
||
return sock2;
|
||
return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len));
|
||
}
|
||
... | ... | |
rb_define_method(rb_cSocket, "bind", sock_bind, 1);
|
||
rb_define_method(rb_cSocket, "listen", rsock_sock_listen, 1);
|
||
rb_define_method(rb_cSocket, "accept", sock_accept, 0);
|
||
rb_define_method(rb_cSocket, "accept_nonblock", sock_accept_nonblock, 0);
|
||
rb_define_method(rb_cSocket, "accept_nonblock", sock_accept_nonblock, -1);
|
||
rb_define_method(rb_cSocket, "sysaccept", sock_sysaccept, 0);
|
||
rb_define_method(rb_cSocket, "recvfrom", sock_recvfrom, -1);
|
ext/socket/tcpserver.c | ||
---|---|---|
* * Socket#accept
|
||
*/
|
||
static VALUE
|
||
tcp_accept_nonblock(VALUE sock)
|
||
tcp_accept_nonblock(int argc, VALUE *argv, VALUE sock)
|
||
{
|
||
rb_io_t *fptr;
|
||
union_sockaddr from;
|
||
... | ... | |
GetOpenFile(sock, fptr);
|
||
fromlen = (socklen_t)sizeof(from);
|
||
return rsock_s_accept_nonblock(rb_cTCPSocket, fptr, &from.addr, &fromlen);
|
||
return rsock_s_accept_nonblock(argc, argv, rb_cTCPSocket, fptr, &from.addr, &fromlen);
|
||
}
|
||
/*
|
||
... | ... | |
*/
|
||
rb_cTCPServer = rb_define_class("TCPServer", rb_cTCPSocket);
|
||
rb_define_method(rb_cTCPServer, "accept", tcp_accept, 0);
|
||
rb_define_method(rb_cTCPServer, "accept_nonblock", tcp_accept_nonblock, 0);
|
||
rb_define_method(rb_cTCPServer, "accept_nonblock", tcp_accept_nonblock, -1);
|
||
rb_define_method(rb_cTCPServer, "sysaccept", tcp_sysaccept, 0);
|
||
rb_define_method(rb_cTCPServer, "initialize", tcp_svr_init, -1);
|
||
rb_define_method(rb_cTCPServer, "listen", rsock_sock_listen, 1); /* in socket.c */
|
ext/socket/unixserver.c | ||
---|---|---|
* * Socket#accept
|
||
*/
|
||
static VALUE
|
||
unix_accept_nonblock(VALUE sock)
|
||
unix_accept_nonblock(int argc, VALUE *argv, VALUE sock)
|
||
{
|
||
rb_io_t *fptr;
|
||
struct sockaddr_un from;
|
||
... | ... | |
GetOpenFile(sock, fptr);
|
||
fromlen = (socklen_t)sizeof(from);
|
||
return rsock_s_accept_nonblock(rb_cUNIXSocket, fptr,
|
||
return rsock_s_accept_nonblock(argc, argv, rb_cUNIXSocket, fptr,
|
||
(struct sockaddr *)&from, &fromlen);
|
||
}
|
||
... | ... | |
rb_cUNIXServer = rb_define_class("UNIXServer", rb_cUNIXSocket);
|
||
rb_define_method(rb_cUNIXServer, "initialize", unix_svr_init, 1);
|
||
rb_define_method(rb_cUNIXServer, "accept", unix_accept, 0);
|
||
rb_define_method(rb_cUNIXServer, "accept_nonblock", unix_accept_nonblock, 0);
|
||
rb_define_method(rb_cUNIXServer, "accept_nonblock", unix_accept_nonblock, -1);
|
||
rb_define_method(rb_cUNIXServer, "sysaccept", unix_sysaccept, 0);
|
||
rb_define_method(rb_cUNIXServer, "listen", rsock_sock_listen, 1); /* in socket.c */
|
||
#endif
|
test/socket/test_nonblock.rb | ||
---|---|---|
serv.bind(Socket.sockaddr_in(0, "127.0.0.1"))
|
||
serv.listen(5)
|
||
assert_raise(IO::WaitReadable) { serv.accept_nonblock }
|
||
assert_equal :wait_readable, serv.accept_nonblock(exception: false)
|
||
assert_raise(IO::WaitReadable) { serv.accept_nonblock(exception: true) }
|
||
c = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
|
||
c.connect(serv.getsockname)
|
||
begin
|
test/socket/test_tcp.rb | ||
---|---|---|
th.join
|
||
}
|
||
end
|
||
def test_accept_nonblock
|
||
svr = TCPServer.new("localhost", 0)
|
||
assert_raises(IO::WaitReadable) { svr.accept_nonblock }
|
||
assert_equal :wait_readable, svr.accept_nonblock(exception: false)
|
||
assert_raises(IO::WaitReadable) { svr.accept_nonblock(exception: true) }
|
||
end
|
||
end if defined?(TCPSocket)
|
test/socket/test_unix.rb | ||
---|---|---|
assert(s0.closed?)
|
||
end
|
||
def test_accept_nonblock
|
||
bound_unix_socket(UNIXServer) {|serv, path|
|
||
assert_raises(IO::WaitReadable) { serv.accept_nonblock }
|
||
assert_raises(IO::WaitReadable) { serv.accept_nonblock(exception: true) }
|
||
assert_equal :wait_readable, serv.accept_nonblock(exception: false)
|
||
}
|
||
end
|
||
end if defined?(UNIXSocket) && /cygwin/ !~ RUBY_PLATFORM
|
||
-
|