avoid uname() for pipe size modification checks
authorEric Wong <normalperson@yhbt.net>
Wed, 7 Mar 2012 10:27:46 +0000 (7 10:27 +0000)
committerEric Wong <normalperson@yhbt.net>
Wed, 7 Mar 2012 10:28:43 +0000 (7 10:28 +0000)
The uname comparison is fragile and we can better
detect this during the Init_* function by just using
a pipe.

ext/io_splice/io_splice_ext.c

index cbbdbfc..4c713d1 100644 (file)
@@ -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);