[前][次][番号順一覧][スレッド一覧]

ruby-changes:28097

From: akr <ko1@a...>
Date: Sat, 6 Apr 2013 11:39:56 +0900 (JST)
Subject: [ruby-changes:28097] akr:r40149 (trunk): * ext/socket: Improve socket exception message to show socket address.

akr	2013-04-06 11:39:44 +0900 (Sat, 06 Apr 2013)

  New Revision: 40149

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=40149

  Log:
    * ext/socket: Improve socket exception message to show socket address.
      [ruby-core:45617] [Feature #6583] proposed Eric Hodel.
    
    * ext/socket/rubysocket.h (rsock_sys_fail_host_port): Declared.
      (rsock_sys_fail_path): Ditto.
      (rsock_sys_fail_sockaddr): Ditto.
    
    * ext/socket/udpsocket.c (udp_connect): Use rsock_sys_fail_host_port.
      (udp_bind): Ditto.
      (udp_send): Ditto.
    
    * ext/socket/init.c (rsock_init_sock): Specify a string for rb_sys_fail
      argument.
      (make_fd_nonblock): Ditto.
      (rsock_s_accept): Ditto.
    
    * ext/socket/ipsocket.c (init_inetsock_internal): Use
      rsock_sys_fail_host_port.
    
    * ext/socket/socket.c (rsock_sys_fail_host_port): Defined.
      (rsock_sys_fail_path): Ditto.
      (rsock_sys_fail_sockaddr): Ditto.
      (setup_domain_and_type): Use rsock_sys_fail_sockaddr.
      (sock_connect_nonblock): Ditto.
      (sock_bind): Ditto.
      (sock_gethostname): Specify a string for rb_sys_fail argument.
      (socket_s_ip_address_list): Ditto.
    
    * ext/socket/basicsocket.c (bsock_shutdown): Specify a string for
      rb_sys_fail argument.
      (bsock_setsockopt): Use rsock_sys_fail_path.
      (bsock_getsockopt): Ditto.
      (bsock_getpeereid): Refine the argument for rb_sys_fail.
    
    * ext/socket/unixsocket.c (rsock_init_unixsock): Use
      rsock_sys_fail_path.
      (unix_path): Ditto.
      (unix_send_io): Ditto.
      (unix_recv_io): Ditto.
      (unix_addr): Ditto.
      (unix_peeraddr): Ditto.

  Modified files:
    trunk/ChangeLog
    trunk/ext/socket/basicsocket.c
    trunk/ext/socket/init.c
    trunk/ext/socket/ipsocket.c
    trunk/ext/socket/rubysocket.h
    trunk/ext/socket/socket.c
    trunk/ext/socket/udpsocket.c
    trunk/ext/socket/unixsocket.c
    trunk/test/socket/test_socket.rb
    trunk/test/socket/test_tcp.rb
    trunk/test/socket/test_udp.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 40148)
+++ ChangeLog	(revision 40149)
@@ -1,3 +1,47 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sat Apr  6 11:39:19 2013  Tanaka Akira  <akr@f...>
+
+	* ext/socket: Improve socket exception message to show socket address.
+	  [ruby-core:45617] [Feature #6583] proposed Eric Hodel.
+
+	* ext/socket/rubysocket.h (rsock_sys_fail_host_port): Declared.
+	  (rsock_sys_fail_path): Ditto.
+	  (rsock_sys_fail_sockaddr): Ditto.
+
+	* ext/socket/udpsocket.c (udp_connect): Use rsock_sys_fail_host_port.
+	  (udp_bind): Ditto.
+	  (udp_send): Ditto.
+
+	* ext/socket/init.c (rsock_init_sock): Specify a string for rb_sys_fail
+	  argument.
+	  (make_fd_nonblock): Ditto.
+	  (rsock_s_accept): Ditto.
+
+	* ext/socket/ipsocket.c (init_inetsock_internal): Use
+	  rsock_sys_fail_host_port.
+
+	* ext/socket/socket.c (rsock_sys_fail_host_port): Defined.
+	  (rsock_sys_fail_path): Ditto.
+	  (rsock_sys_fail_sockaddr): Ditto.
+	  (setup_domain_and_type): Use rsock_sys_fail_sockaddr.
+	  (sock_connect_nonblock): Ditto.
+	  (sock_bind): Ditto.
+	  (sock_gethostname): Specify a string for rb_sys_fail argument.
+	  (socket_s_ip_address_list): Ditto.
+
+	* ext/socket/basicsocket.c (bsock_shutdown): Specify a string for
+	  rb_sys_fail argument.
+	  (bsock_setsockopt): Use rsock_sys_fail_path.
+	  (bsock_getsockopt): Ditto.
+	  (bsock_getpeereid): Refine the argument for rb_sys_fail.
+
+	* ext/socket/unixsocket.c (rsock_init_unixsock): Use
+	  rsock_sys_fail_path.
+	  (unix_path): Ditto.
+	  (unix_send_io): Ditto.
+	  (unix_recv_io): Ditto.
+	  (unix_addr): Ditto.
+	  (unix_peeraddr): Ditto.
+
 Sat Apr  6 11:23:18 2013  Hiroshi Shirosaki  <h.shirosaki@g...>
 
 	* test/ruby/test_require.rb (TestRequire#test_require_nonascii_path):
Index: ext/socket/rubysocket.h
===================================================================
--- ext/socket/rubysocket.h	(revision 40148)
+++ ext/socket/rubysocket.h	(revision 40149)
@@ -333,4 +333,8 @@ void rsock_init_addrinfo(void); https://github.com/ruby/ruby/blob/trunk/ext/socket/rubysocket.h#L333
 void rsock_init_sockopt(void);
 void rsock_init_socket_init(void);
 
+void rsock_sys_fail_host_port(const char *, VALUE, VALUE);
+void rsock_sys_fail_path(const char *, VALUE);
+void rsock_sys_fail_sockaddr(const char *, VALUE, VALUE);
+
 #endif
Index: ext/socket/udpsocket.c
===================================================================
--- ext/socket/udpsocket.c	(revision 40148)
+++ ext/socket/udpsocket.c	(revision 40149)
@@ -93,7 +93,7 @@ udp_connect(VALUE sock, VALUE host, VALU https://github.com/ruby/ruby/blob/trunk/ext/socket/udpsocket.c#L93
     arg.fd = fptr->fd;
     ret = rb_ensure(udp_connect_internal, (VALUE)&arg,
 		    rsock_freeaddrinfo, (VALUE)arg.res);
-    if (!ret) rb_sys_fail("connect(2)");
+    if (!ret) rsock_sys_fail_host_port("connect(2)", host, port);
     return INT2FIX(0);
 }
 
@@ -126,7 +126,9 @@ udp_bind(VALUE sock, VALUE host, VALUE p https://github.com/ruby/ruby/blob/trunk/ext/socket/udpsocket.c#L126
 	return INT2FIX(0);
     }
     freeaddrinfo(res0);
-    rb_sys_fail("bind(2)");
+
+    rsock_sys_fail_host_port("bind(2)", host, port);
+
     return INT2FIX(0);
 }
 
@@ -187,7 +189,7 @@ udp_send(int argc, VALUE *argv, VALUE so https://github.com/ruby/ruby/blob/trunk/ext/socket/udpsocket.c#L189
 	}
     }
     freeaddrinfo(res0);
-    rb_sys_fail("sendto(2)");
+    rsock_sys_fail_host_port("sendto(2)", host, port);
     return INT2FIX(n);
 }
 
Index: ext/socket/init.c
===================================================================
--- ext/socket/init.c	(revision 40148)
+++ ext/socket/init.c	(revision 40149)
@@ -47,7 +47,7 @@ rsock_init_sock(VALUE sock, int fd) https://github.com/ruby/ruby/blob/trunk/ext/socket/init.c#L47
     struct stat sbuf;
 
     if (fstat(fd, &sbuf) < 0)
-        rb_sys_fail(0);
+        rb_sys_fail("fstat(2)");
     rb_update_max_fd(fd);
     if (!S_ISSOCK(sbuf.st_mode))
         rb_raise(rb_eArgError, "not a socket file descriptor");
@@ -475,14 +475,14 @@ make_fd_nonblock(int fd) https://github.com/ruby/ruby/blob/trunk/ext/socket/init.c#L475
 #ifdef F_GETFL
     flags = fcntl(fd, F_GETFL);
     if (flags == -1) {
-        rb_sys_fail(0);
+        rb_sys_fail("fnctl(2)");
     }
 #else
     flags = 0;
 #endif
     flags |= O_NONBLOCK;
     if (fcntl(fd, F_SETFL, flags) == -1) {
-        rb_sys_fail(0);
+        rb_sys_fail("fnctl(2)");
     }
 }
 
@@ -590,7 +590,7 @@ rsock_s_accept(VALUE klass, int fd, stru https://github.com/ruby/ruby/blob/trunk/ext/socket/init.c#L590
 	    retry = 0;
 	    goto retry;
 	}
-	rb_sys_fail(0);
+	rb_sys_fail("accept(2)");
     }
     rb_update_max_fd(fd2);
     if (!klass) return INT2NUM(fd2);
Index: ext/socket/ipsocket.c
===================================================================
--- ext/socket/ipsocket.c	(revision 40148)
+++ ext/socket/ipsocket.c	(revision 40149)
@@ -43,7 +43,7 @@ init_inetsock_internal(struct inetsock_a https://github.com/ruby/ruby/blob/trunk/ext/socket/ipsocket.c#L43
 {
     int type = arg->type;
     struct addrinfo *res;
-    int fd, status = 0;
+    int fd, status = 0, local = 0;
     const char *syscall = 0;
 
     arg->remote.res = rsock_addrinfo(arg->remote.host, arg->remote.serv, SOCK_STREAM,
@@ -81,6 +81,7 @@ init_inetsock_internal(struct inetsock_a https://github.com/ruby/ruby/blob/trunk/ext/socket/ipsocket.c#L81
 	else {
 	    if (arg->local.res) {
 		status = bind(fd, arg->local.res->ai_addr, arg->local.res->ai_addrlen);
+		local = status;
 		syscall = "bind(2)";
 	    }
 
@@ -99,7 +100,17 @@ init_inetsock_internal(struct inetsock_a https://github.com/ruby/ruby/blob/trunk/ext/socket/ipsocket.c#L100
 	    break;
     }
     if (status < 0) {
-	rb_sys_fail(syscall);
+	VALUE host, port;
+
+	if (local < 0) {
+	    host = arg->local.host;
+	    port = arg->local.serv;
+	} else {
+	    host = arg->remote.host;
+	    port = arg->remote.serv;
+	}
+
+	rsock_sys_fail_host_port(syscall, host, port);
     }
 
     arg->fd = -1;
Index: ext/socket/socket.c
===================================================================
--- ext/socket/socket.c	(revision 40148)
+++ ext/socket/socket.c	(revision 40149)
@@ -10,6 +10,40 @@ https://github.com/ruby/ruby/blob/trunk/ext/socket/socket.c#L10
 
 #include "rubysocket.h"
 
+static VALUE sock_s_unpack_sockaddr_in(VALUE, VALUE);
+
+void
+rsock_sys_fail_host_port(const char *mesg, VALUE host, VALUE port)
+{
+    VALUE message;
+
+    port = rb_String(port);
+
+    message = rb_sprintf("%s for \"%s\" port %s",
+	    mesg, StringValueCStr(host), StringValueCStr(port));
+
+    rb_sys_fail_str(message);
+}
+
+void
+rsock_sys_fail_path(const char *mesg, VALUE path)
+{
+    VALUE message = rb_sprintf("%s for \"%s\"",
+	    mesg, StringValueCStr(path));
+
+    rb_sys_fail_str(message);
+}
+
+void
+rsock_sys_fail_sockaddr(const char *mesg, VALUE sock, VALUE addr)
+{
+    VALUE host_port = sock_s_unpack_sockaddr_in(sock, addr);
+
+    rsock_sys_fail_host_port(mesg,
+	    RARRAY_PTR(host_port)[1],
+	    RARRAY_PTR(host_port)[0]);
+}
+
 static void
 setup_domain_and_type(VALUE domain, int *dv, VALUE type, int *tv)
 {
@@ -313,7 +347,7 @@ sock_connect(VALUE sock, VALUE addr) https://github.com/ruby/ruby/blob/trunk/ext/socket/socket.c#L347
     fd = fptr->fd;
     n = rsock_connect(fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_LENINT(addr), 0);
     if (n < 0) {
-	rb_sys_fail("connect(2)");
+	rsock_sys_fail_sockaddr("connect(2)", sock, addr);
     }
 
     return INT2FIX(n);
@@ -375,7 +409,7 @@ sock_connect_nonblock(VALUE sock, VALUE https://github.com/ruby/ruby/blob/trunk/ext/socket/socket.c#L409
     if (n < 0) {
         if (errno == EINPROGRESS)
             rb_mod_sys_fail(rb_mWaitWritable, "connect(2) would block");
-	rb_sys_fail("connect(2)");
+	rsock_sys_fail_sockaddr("connect(2)", sock, addr);
     }
 
     return INT2FIX(n);
@@ -475,7 +509,7 @@ sock_bind(VALUE sock, VALUE addr) https://github.com/ruby/ruby/blob/trunk/ext/socket/socket.c#L509
     SockAddrStringValue(addr);
     GetOpenFile(sock, fptr);
     if (bind(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_LENINT(addr)) < 0)
-	rb_sys_fail("bind(2)");
+	rsock_sys_fail_sockaddr("bind(2)", sock, addr);
 
     return INT2FIX(0);
 }
@@ -910,7 +944,7 @@ sock_gethostname(VALUE obj) https://github.com/ruby/ruby/blob/trunk/ext/socket/socket.c#L944
 
     rb_secure(3);
     if (gethostname(buf, (int)sizeof buf - 1) < 0)
-	rb_sys_fail("gethostname");
+	rb_sys_fail("gethostname(3)");
 
     buf[sizeof buf - 1] = '\0';
     return rb_str_new2(buf);
@@ -1608,7 +1642,7 @@ socket_s_ip_address_list(VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/socket/socket.c#L1642
 
     fd = socket(AF_INET, SOCK_DGRAM, 0);
     if (fd == -1)
-        rb_sys_fail("socket");
+        rb_sys_fail("socket(2)");
 
     memset(&ln, 0, sizeof(ln));
     ln.lifn_family = AF_UNSPEC;
@@ -1678,7 +1712,7 @@ socket_s_ip_address_list(VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/socket/socket.c#L1712
 
     fd = socket(AF_INET, SOCK_DGRAM, 0);
     if (fd == -1)
-        rb_sys_fail("socket");
+        rb_sys_fail("socket(2)");
 
     bufsize = sizeof(initbuf);
     buf = initbuf;
Index: ext/socket/basicsocket.c
===================================================================
--- ext/socket/basicsocket.c	(revision 40148)
+++ ext/socket/basicsocket.c	(revision 40149)
@@ -80,7 +80,7 @@ bsock_shutdown(int argc, VALUE *argv, VA https://github.com/ruby/ruby/blob/trunk/ext/socket/basicsocket.c#L80
     }
     GetOpenFile(sock, fptr);
     if (shutdown(fptr->fd, how) == -1)
-	rb_sys_fail(0);
+	rb_sys_fail("shutdown(2)");
 
     return INT2FIX(0);
 }
@@ -249,7 +249,7 @@ bsock_setsockopt(int argc, VALUE *argv, https://github.com/ruby/ruby/blob/trunk/ext/socket/basicsocket.c#L249
 
     rb_io_check_closed(fptr);
     if (setsockopt(fptr->fd, level, option, v, vlen) < 0)
-	rb_sys_fail_path(fptr->pathv);
+        rsock_sys_fail_path("setsockopt(2)", fptr->pathv);
 
     return INT2FIX(0);
 }
@@ -330,7 +330,7 @@ bsock_getsockopt(VALUE sock, VALUE lev, https://github.com/ruby/ruby/blob/trunk/ext/socket/basicsocket.c#L330
     rb_io_check_closed(fptr);
 
     if (getsockopt(fptr->fd, level, option, buf, &len) < 0)
-	rb_sys_fail_path(fptr->pathv);
+	rsock_sys_fail_path("getsockopt(2)", fptr->pathv);
 
     return rsock_sockopt_new(family, level, option, rb_str_new(buf, len));
 }
@@ -429,7 +429,7 @@ bsock_getpeereid(VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/socket/basicsocket.c#L429
     gid_t egid;
     GetOpenFile(self, fptr);
     if (getpeereid(fptr->fd, &euid, &egid) == -1)
-	rb_sys_fail("getpeereid");
+	rb_sys_fail("getpeereid(3)");
     return rb_assoc_new(UIDT2NUM(euid), GIDT2NUM(egid));
 #elif defined(SO_PEERCRED) /* GNU/Linux */
     rb_io_t *fptr;
@@ -445,7 +445,7 @@ bsock_getpeereid(VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/socket/basicsocket.c#L445
     VALUE ret;
     GetOpenFile(self, fptr);
     if (getpeerucred(fptr->fd, &uc) == -1)
-	rb_sys_fail("getpeerucred");
+	rb_sys_fail("getpeerucred(3C)");
     ret = rb_assoc_new(UIDT2NUM(ucred_geteuid(uc)), GIDT2NUM(ucred_getegid(uc)));
     ucred_free(uc);
     return ret;
Index: ext/socket/unixsocket.c
===================================================================
--- ext/socket/unixsocket.c	(revision 40148)
+++ ext/socket/unixsocket.c	(revision 40149)
@@ -36,7 +36,7 @@ rsock_init_unixsock(VALUE sock, VALUE pa https://github.com/ruby/ruby/blob/trunk/ext/socket/unixsocket.c#L36
     SafeStringValue(path);
     fd = rsock_socket(AF_UNIX, SOCK_STREAM, 0);
     if (fd < 0) {
-	rb_sys_fail("socket(2)");
+	rsock_sys_fail_path("socket(2)", path);
     }
 
     INIT_SOCKADDR_UN(&sockaddr, sizeof(struct sockaddr_un));
@@ -65,13 +65,13 @@ rsock_init_unixsock(VALUE sock, VALUE pa https://github.com/ruby/ruby/blob/trunk/ext/socket/unixsocket.c#L65
 
     if (status < 0) {
 	close(fd);
-	rb_sys_fail_str(rb_inspect(path));
+        rsock_sys_fail_path("connect(2)", path);
     }
 
     if (server) {
 	if (listen(fd, SOMAXCONN) < 0) {
 	    close(fd);
-	    rb_sys_fail("listen(2)");
+            rsock_sys_fail_path("listen(2)", path);
 	}
     }
 
@@ -121,7 +121,7 @@ unix_path(VALUE sock) https://github.com/ruby/ruby/blob/trunk/ext/socket/unixsocket.c#L121
 	socklen_t len = (socklen_t)sizeof(addr);
 	socklen_t len0 = len;
 	if (getsockname(fptr->fd, (struct sockaddr*)&addr, &len) < 0)
-	    rb_sys_fail(0);
+            rsock_sys_fail_path("getsockname(2)", fptr->pathv);
         if (len0 < len) len = len0;
 	fptr->pathv = rb_obj_freeze(rsock_unixpath_str(&addr, len));
     }
@@ -255,7 +255,7 @@ unix_send_io(VALUE sock, VALUE val) https://github.com/ruby/ruby/blob/trunk/ext/socket/unixsocket.c#L255
     arg.fd = fptr->fd;
     while ((int)BLOCKING_REGION_FD(sendmsg_blocking, &arg) == -1) {
 	if (!rb_io_wait_writable(arg.fd))
-	    rb_sys_fail("sendmsg(2)");
+	    rsock_sys_fail_path("sendmsg(2)", fptr->pathv);
     }
 
     return Qnil;
@@ -343,7 +343,7 @@ unix_recv_io(int argc, VALUE *argv, VALU https://github.com/ruby/ruby/blob/trunk/ext/socket/unixsocket.c#L343
     arg.fd = fptr->fd;
     while ((int)BLOCKING_REGION_FD(recvmsg_blocking, &arg) == -1) {
 	if (!rb_io_wait_readable(arg.fd))
-	    rb_sys_fail("recvmsg(2)");
+	    rsock_sys_fail_path("recvmsg(2)", fptr->pathv);
     }
 
 #if FD_PASSING_BY_MSG_CONTROL
@@ -430,7 +430,7 @@ unix_addr(VALUE sock) https://github.com/ruby/ruby/blob/trunk/ext/socket/unixsocket.c#L430
     GetOpenFile(sock, fptr);
 
     if (getsockname(fptr->fd, (struct sockaddr*)&addr, &len) < 0)
-	rb_sys_fail("getsockname(2)");
+        rsock_sys_fail_path("getsockname(2)", fptr->pathv);
     if (len0 < len) len = len0;
     return rsock_unixaddr(&addr, len);
 }
@@ -458,7 +458,7 @@ unix_peeraddr(VALUE sock) https://github.com/ruby/ruby/blob/trunk/ext/socket/unixsocket.c#L458
     GetOpenFile(sock, fptr);
 
     if (getpeername(fptr->fd, (struct sockaddr*)&addr, &len) < 0)
-	rb_sys_fail("getpeername(2)");
+        rsock_sys_fail_path("getpeername(2)", fptr->pathv);
     if (len0 < len) len = len0;
     return rsock_unixaddr(&addr, len);
 }
Index: test/socket/test_tcp.rb
===================================================================
--- test/socket/test_tcp.rb	(revision 40148)
+++ test/socket/test_tcp.rb	(revision 40149)
@@ -6,6 +6,23 @@ end https://github.com/ruby/ruby/blob/trunk/test/socket/test_tcp.rb#L6
 
 
 class TestSocket_TCPSocket < Test::Unit::TestCase
+  def test_initialize_failure
+    s = TCPServer.new("localhost", nil)
+    server_port = s.addr[1]
+
+    c = TCPSocket.new("localhost", server_port)
+    client_port = c.addr[1]
+
+    begin
+      # TCPServer.new uses SO_REUSEADDR so we must create a failure on the
+      # local address.
+      TCPSocket.new("localhost", server_port, "localhost", client_port)
+      flunk "expected SystemCallError"
+    rescue SystemCallError => e
+      assert_match "for \"localhost\" port #{client_port}", e.message
+    end
+  end
+
   def test_recvfrom
     svr = TCPServer.new("localhost", 0)
     th = Thread.new {
Index: test/socket/test_socket.rb
===================================================================
--- test/socket/test_socket.rb	(revision 40148)
+++ test/socket/test_socket.rb	(revision 40149)
@@ -70,6 +70,22 @@ class TestSocket < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/socket/test_socket.rb#L70
     }
   end
 
+  def test_bind
+    Socket.open(Socket::AF_INET, Socket::SOCK_STREAM, 0) {|bound|
+      bound.bind(Socket.sockaddr_in(0, "127.0.0.1"))
+      addr = bound.getsockname
+      port, = Socket.unpack_sockaddr_in(addr)
+
+      Socket.open(Socket::AF_INET, Socket::SOCK_STREAM, 0) {|s|
+        e = assert_raises(Errno::EADDRINUSE) do
+          s.bind(Socket.sockaddr_in(port, "127.0.0.1"))
+        end
+
+        assert_match "bind(2) for \"127.0.0.1\" port #{port}", e.message
+      }
+    }
+  end
+
   def test_getaddrinfo
     # This should not send a DNS query because AF_UNIX.
     assert_raise(SocketError) { Socket.getaddrinfo("www.kame.net", 80, "AF_UNIX") }
Index: test/socket/test_udp.rb
===================================================================
--- test/socket/test_udp.rb	(revision 40148)
+++ test/socket/test_udp.rb	(revision 40149)
@@ -36,4 +36,30 @@ class TestSocket_UDPSocket < Test::Unit: https://github.com/ruby/ruby/blob/trunk/test/socket/test_udp.rb#L36
       s.bind(host, 2000)
     }
   end
+
+  def test_bind_addrinuse
+    host = "127.0.0.1"
+    port = 2001
+
+    in_use = UDPSocket.new
+    in_use.bind(host, port)
+
+    s = UDPSocket.new
+    
+    e = assert_raises(Errno::EADDRINUSE) do
+      s.bind(host, port)
+    end
+
+    assert_match "bind(2) for \"#{host}\" port #{port}", e.message
+  end
+
+  def test_send_too_long
+    u = UDPSocket.new
+
+    e = assert_raises Errno::EMSGSIZE do
+      u.send "\0" * 100_000, 0, "127.0.0.1", 7 # echo
+    end
+
+    assert_match 'for "127.0.0.1" port 7', e.message
+  end
 end if defined?(UDPSocket)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]