about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2012-03-07 10:27:46 +0000
committerEric Wong <normalperson@yhbt.net>2012-03-07 10:28:43 +0000
commitf2a1b8e5f3b9b9ba0c8593bab6d58def3b75e6a4 (patch)
tree610866b6a7982eb5544638b3db4e461b361d35ec
parenta2ae924fb1c372cc559a59feca40780a9a37ba33 (diff)
downloadruby_io_splice-f2a1b8e5f3b9b9ba0c8593bab6d58def3b75e6a4.tar.gz
The uname comparison is fragile and we can better
detect this during the Init_* function by just using
a pipe.
-rw-r--r--ext/io_splice/io_splice_ext.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/ext/io_splice/io_splice_ext.c b/ext/io_splice/io_splice_ext.c
index cbbdbfc..4c713d1 100644
--- a/ext/io_splice/io_splice_ext.c
+++ b/ext/io_splice/io_splice_ext.c
@@ -10,7 +10,7 @@
 #include <sys/uio.h>
 #include <limits.h>
 #include <alloca.h>
-#include <sys/utsname.h>
+#include <unistd.h>
 
 static VALUE sym_EAGAIN;
 #define WAITALL 0x4000000
@@ -621,10 +621,28 @@ static VALUE set_pipe_size(VALUE self, VALUE size)
         return size;
 }
 
+static int can_mod_pipe_size(void)
+{
+        int fds[2];
+        int rc = pipe(fds);
+
+        if (rc == 0) {
+                rc = fcntl(fds[0], F_GETPIPE_SZ);
+                rc = rc < 0 ? 0 : 1;
+
+                (void)close(fds[0]);
+                (void)close(fds[1]);
+        } else {
+                /* weird error, but don't raise during init */
+                rc = 0;
+        }
+        errno = 0;
+        return rc;
+}
+
 void Init_io_splice_ext(void)
 {
         VALUE mSplice = rb_define_module_under(rb_cIO, "Splice");
-        struct utsname utsname;
 
         rb_define_singleton_method(rb_cIO, "splice", my_splice, -1);
         rb_define_singleton_method(rb_cIO, "trysplice", trysplice, -1);
@@ -698,12 +716,7 @@ void Init_io_splice_ext(void)
          */
         rb_define_const(mSplice, "MAX_AT_ONCE", SIZET2NUM(MAX_AT_ONCE));
 
-
-        if (uname(&utsname) == -1)
-                rb_sys_fail("uname");
-
-        /* includes 2.6.35-rc[1-6] */
-        if (strcmp(utsname.release, "2.6.35") >= 0) {
+        if (can_mod_pipe_size()) {
                 rb_define_method(rb_cIO, "pipe_size", pipe_size, 0);
                 rb_define_method(rb_cIO, "pipe_size=", set_pipe_size, 1);