dumping ground for random patches and texts
 help / color / mirror / Atom feed
* [PATCH] sendmsg_nonblock "exception: false"
@ 2015-06-02  2:35 Eric Wong
  0 siblings, 0 replies; only message in thread
From: Eric Wong @ 2015-06-02  2:35 UTC (permalink / raw)
  To: spew

---
 ext/socket/ancdata.c         | 23 +++++++++++++++++++----
 test/socket/test_nonblock.rb |  1 +
 2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/ext/socket/ancdata.c b/ext/socket/ancdata.c
index 277a1e8..5459218 100644
--- a/ext/socket/ancdata.c
+++ b/ext/socket/ancdata.c
@@ -3,6 +3,7 @@
 #include <time.h>
 
 int rsock_cmsg_cloexec_state = -1; /* <0: unknown, 0: ignored, >0: working */
+static VALUE sym_exception, sym_wait_writable;
 
 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
 static VALUE rb_cAncillaryData;
@@ -1133,6 +1134,7 @@ bsock_sendmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock)
     VALUE data, vflags, dest_sockaddr;
     struct msghdr mh;
     struct iovec iov;
+    VALUE opts = Qnil;
 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
     VALUE controls = Qnil;
     VALUE controls_str = 0;
@@ -1140,6 +1142,7 @@ bsock_sendmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock)
 #endif
     int flags;
     ssize_t ss;
+    int ex = 1;
 
     GetOpenFile(sock, fptr);
 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
@@ -1151,11 +1154,15 @@ bsock_sendmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock)
     if (argc == 0)
         rb_raise(rb_eArgError, "mesg argument required");
 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
-    rb_scan_args(argc, argv, "12*", &data, &vflags, &dest_sockaddr, &controls);
+    rb_scan_args(argc, argv, "12*:", &data, &vflags, &dest_sockaddr, &controls,
+                 &opts);
 #else
-    rb_scan_args(argc, argv, "12", &data, &vflags, &dest_sockaddr);
+    rb_scan_args(argc, argv, "12:", &data, &vflags, &dest_sockaddr, &opts);
 #endif
 
+    if (!NIL_P(opts) && Qfalse == rb_hash_lookup2(opts, sym_exception, Qundef))
+	ex = 0;
+
     StringValue(data);
 
     if (!NIL_P(controls)) {
@@ -1287,8 +1294,13 @@ bsock_sendmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock)
             rb_io_check_closed(fptr);
             goto retry;
         }
-        if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN))
-            rb_readwrite_sys_fail(RB_IO_WAIT_WRITABLE, "sendmsg(2) would block");
+        if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN)) {
+	    if (ex) {
+		rb_readwrite_sys_fail(RB_IO_WAIT_WRITABLE,
+			              "sendmsg(2) would block");
+	    }
+	    return sym_wait_writable;
+	}
 	rb_sys_fail("sendmsg(2)");
     }
 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
@@ -1839,4 +1851,7 @@ rsock_init_ancdata(void)
     rb_define_method(rb_cAncillaryData, "ipv6_pktinfo_addr", ancillary_ipv6_pktinfo_addr, 0);
     rb_define_method(rb_cAncillaryData, "ipv6_pktinfo_ifindex", ancillary_ipv6_pktinfo_ifindex, 0);
 #endif
+#undef rb_intern
+    sym_exception = ID2SYM(rb_intern("exception"));
+    sym_wait_writable = ID2SYM(rb_intern("wait_writable"));
 }
diff --git a/test/socket/test_nonblock.rb b/test/socket/test_nonblock.rb
index 4b1f209..11bdb9c 100644
--- a/test/socket/test_nonblock.rb
+++ b/test/socket/test_nonblock.rb
@@ -282,6 +282,7 @@ class TestSocketNonblock < Test::Unit::TestCase
         assert_raises(IO::WaitWritable) do
           loop { s1.sendmsg_nonblock(buf) }
         end
+        assert_equal :wait_writable, s1.sendmsg_nonblock(buf, exception: false)
       end
     else
       skip "UNIXSocket.pair(:SEQPACKET) not implemented on this platform"
-- 
EW


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2015-06-02  2:35 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-02  2:35 [PATCH] sendmsg_nonblock "exception: false" Eric Wong

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).