about summary refs log tree commit homepage
path: root/ext/kgio/kgio_ext.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/kgio/kgio_ext.c')
-rw-r--r--ext/kgio/kgio_ext.c56
1 files changed, 55 insertions, 1 deletions
diff --git a/ext/kgio/kgio_ext.c b/ext/kgio/kgio_ext.c
index 03b30e5..8829eae 100644
--- a/ext/kgio/kgio_ext.c
+++ b/ext/kgio/kgio_ext.c
@@ -3,6 +3,8 @@
 #include <stdio.h>
 /* true if TCP Fast Open is usable */
 unsigned kgio_tfo;
+static VALUE eErrno_EPIPE, eErrno_ECONNRESET;
+static ID id_set_backtrace;
 
 static void tfo_maybe(void)
 {
@@ -34,11 +36,63 @@ static void tfo_maybe(void)
 #endif
 }
 
+void kgio_raise_empty_bt(VALUE err, const char *msg)
+{
+        VALUE exc = rb_exc_new2(err, msg);
+        VALUE bt = rb_ary_new();
+
+        rb_funcall(exc, id_set_backtrace, 1, bt);
+        rb_exc_raise(exc);
+}
+
+void kgio_wr_sys_fail(const char *msg)
+{
+        switch (errno) {
+        case EPIPE:
+                errno = 0;
+                kgio_raise_empty_bt(eErrno_EPIPE, msg);
+        case ECONNRESET:
+                errno = 0;
+                kgio_raise_empty_bt(eErrno_ECONNRESET, msg);
+        }
+        rb_sys_fail(msg);
+}
+
+void kgio_rd_sys_fail(const char *msg)
+{
+        if (errno == ECONNRESET) {
+                errno = 0;
+                kgio_raise_empty_bt(eErrno_ECONNRESET, msg);
+        }
+        rb_sys_fail(msg);
+}
+
 void Init_kgio_ext(void)
 {
+        VALUE mKgio = rb_define_module("Kgio");
+        VALUE mPipeMethods = rb_define_module_under(mKgio, "PipeMethods");
+        VALUE mSocketMethods = rb_define_module_under(mKgio, "SocketMethods");
+        VALUE mWaiters = rb_define_module_under(mKgio, "DefaultWaiters");
+
+        id_set_backtrace = rb_intern("set_backtrace");
+        eErrno_EPIPE = rb_const_get(rb_mErrno, rb_intern("EPIPE"));
+        eErrno_ECONNRESET = rb_const_get(rb_mErrno, rb_intern("ECONNRESET"));
+
+        /*
+         * Returns the client IP address of the socket as a string
+         * (e.g. "127.0.0.1" or "::1").
+         * This is always the value of the Kgio::LOCALHOST constant
+         * for UNIX domain sockets.
+         */
+        rb_define_attr(mSocketMethods, "kgio_addr", 1, 1);
+        rb_include_module(mPipeMethods, mWaiters);
+        rb_include_module(mSocketMethods, mWaiters);
+
         tfo_maybe();
         init_kgio_wait();
-        init_kgio_read_write();
+        init_kgio_read();
+        init_kgio_write();
+        init_kgio_writev();
         init_kgio_connect();
         init_kgio_accept();
         init_kgio_autopush();