about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2013-04-13 11:29:33 +0000
committerEric Wong <normalperson@yhbt.net>2013-04-13 11:29:33 +0000
commit92b55d65af197218b7653018847b14141cd393de (patch)
tree1e91f6287bdd57c77f8e0bc7c4173c4034e5cb9c
parent856e3e6706a9ab40047eff22f0ddc9dd40ecdde2 (diff)
downloadsleepy_penguin-92b55d65af197218b7653018847b14141cd393de.tar.gz
Ruby 2.0 creates file descriptors with the close-on-exec flag
specified by default.  Unless a user specifies flags explicitly,
assume the default is to set the close-on-exec.

This does not change behavior of Ruby 1.9 and earlier.
-rw-r--r--ext/sleepy_penguin/epoll.c3
-rw-r--r--ext/sleepy_penguin/eventfd.c2
-rw-r--r--ext/sleepy_penguin/extconf.rb1
-rw-r--r--ext/sleepy_penguin/inotify.c2
-rw-r--r--ext/sleepy_penguin/signalfd.c5
-rw-r--r--ext/sleepy_penguin/sleepy_penguin.h7
-rw-r--r--ext/sleepy_penguin/timerfd.c6
-rw-r--r--ext/sleepy_penguin/util.c4
-rw-r--r--test/test_epoll.rb6
-rw-r--r--test/test_eventfd.rb5
-rw-r--r--test/test_inotify.rb5
-rw-r--r--test/test_timerfd.rb5
12 files changed, 39 insertions, 12 deletions
diff --git a/ext/sleepy_penguin/epoll.c b/ext/sleepy_penguin/epoll.c
index 46183ca..ca19786 100644
--- a/ext/sleepy_penguin/epoll.c
+++ b/ext/sleepy_penguin/epoll.c
@@ -96,7 +96,8 @@ out:
  */
 static VALUE s_new(VALUE klass, VALUE _flags)
 {
-        int flags = rb_sp_get_flags(klass, _flags);
+        int default_flags = RB_SP_CLOEXEC(EPOLL_CLOEXEC);
+        int flags = rb_sp_get_flags(klass, _flags, default_flags);
         int fd = epoll_create1(flags);
         VALUE rv;
 
diff --git a/ext/sleepy_penguin/eventfd.c b/ext/sleepy_penguin/eventfd.c
index 3ba8397..1713fdd 100644
--- a/ext/sleepy_penguin/eventfd.c
+++ b/ext/sleepy_penguin/eventfd.c
@@ -27,7 +27,7 @@ static VALUE s_new(int argc, VALUE *argv, VALUE klass)
 
         rb_scan_args(argc, argv, "11", &_initval, &_flags);
         initval = NUM2UINT(_initval);
-        flags = rb_sp_get_flags(klass, _flags);
+        flags = rb_sp_get_flags(klass, _flags, RB_SP_CLOEXEC(EFD_CLOEXEC));
 
         fd = eventfd(initval, flags);
         if (fd == -1) {
diff --git a/ext/sleepy_penguin/extconf.rb b/ext/sleepy_penguin/extconf.rb
index 46aeb00..bd12570 100644
--- a/ext/sleepy_penguin/extconf.rb
+++ b/ext/sleepy_penguin/extconf.rb
@@ -15,4 +15,5 @@ have_func('rb_thread_blocking_region')
 have_func('rb_thread_io_blocking_region')
 have_func('rb_thread_fd_close')
 have_func('rb_update_max_fd')
+have_func('rb_fd_fix_cloexec')
 create_makefile('sleepy_penguin_ext')
diff --git a/ext/sleepy_penguin/inotify.c b/ext/sleepy_penguin/inotify.c
index 01862ae..6155507 100644
--- a/ext/sleepy_penguin/inotify.c
+++ b/ext/sleepy_penguin/inotify.c
@@ -27,7 +27,7 @@ static VALUE s_new(int argc, VALUE *argv, VALUE klass)
         int fd;
 
         rb_scan_args(argc, argv, "01", &_flags);
-        flags = rb_sp_get_flags(klass, _flags);
+        flags = rb_sp_get_flags(klass, _flags, RB_SP_CLOEXEC(IN_CLOEXEC));
 
         fd = inotify_init1(flags);
         if (fd == -1) {
diff --git a/ext/sleepy_penguin/signalfd.c b/ext/sleepy_penguin/signalfd.c
index c2c9419..ac5db68 100644
--- a/ext/sleepy_penguin/signalfd.c
+++ b/ext/sleepy_penguin/signalfd.c
@@ -92,7 +92,8 @@ static VALUE update_bang(int argc, VALUE *argv, VALUE self)
         int rc;
 
         rb_scan_args(argc, argv, "02", &vmask, &vflags);
-        flags = NIL_P(vflags) ? cur_flags(fd) : rb_sp_get_flags(self, vflags);
+        flags = NIL_P(vflags) ? cur_flags(fd)
+                                : rb_sp_get_flags(self, vflags, 0);
         value2sigset(&mask, vmask);
 
         rc = signalfd(fd, &mask, flags);
@@ -128,7 +129,7 @@ static VALUE s_new(int argc, VALUE *argv, VALUE klass)
         int fd;
 
         rb_scan_args(argc, argv, "02", &vmask, &vflags);
-        flags = rb_sp_get_flags(klass, vflags);
+        flags = rb_sp_get_flags(klass, vflags, RB_SP_CLOEXEC(SFD_CLOEXEC));
         value2sigset(&mask, vmask);
 
         fd = signalfd(-1, &mask, flags);
diff --git a/ext/sleepy_penguin/sleepy_penguin.h b/ext/sleepy_penguin/sleepy_penguin.h
index 86c6e5f..a839e83 100644
--- a/ext/sleepy_penguin/sleepy_penguin.h
+++ b/ext/sleepy_penguin/sleepy_penguin.h
@@ -14,7 +14,7 @@
 
 extern size_t rb_sp_l1_cache_line_size;
 unsigned rb_sp_get_uflags(VALUE klass, VALUE flags);
-int rb_sp_get_flags(VALUE klass, VALUE flags);
+int rb_sp_get_flags(VALUE klass, VALUE flags, int default_flags);
 int rb_sp_io_closed(VALUE io);
 int rb_sp_fileno(VALUE io);
 void rb_sp_set_nonblock(int fd);
@@ -69,6 +69,11 @@ static inline VALUE fake_blocking_region(VALUE (*fn)(void *), void *data)
 #define NODOC_CONST(klass,name,value) \
   rb_define_const((klass),(name),(value))
 
+#ifdef HAVE_RB_FD_FIX_CLOEXEC
+#  define RB_SP_CLOEXEC(flag) (flag)
+#else
+#  define RB_SP_CLOEXEC(flag) (0)
+#endif
 
 typedef int rb_sp_waitfn(int fd);
 int rb_sp_wait(rb_sp_waitfn waiter, VALUE obj, int *fd);
diff --git a/ext/sleepy_penguin/timerfd.c b/ext/sleepy_penguin/timerfd.c
index b9e3999..33ef8a7 100644
--- a/ext/sleepy_penguin/timerfd.c
+++ b/ext/sleepy_penguin/timerfd.c
@@ -26,8 +26,8 @@ static VALUE s_new(int argc, VALUE *argv, VALUE klass)
         int fd;
 
         rb_scan_args(argc, argv, "02", &cid, &fl);
-        clockid = NIL_P(cid) ? CLOCK_MONOTONIC : rb_sp_get_flags(klass, cid);
-        flags = rb_sp_get_flags(klass, fl);
+        clockid = NIL_P(cid) ? CLOCK_MONOTONIC : rb_sp_get_flags(klass, cid, 0);
+        flags = rb_sp_get_flags(klass, fl, RB_SP_CLOEXEC(TFD_CLOEXEC));
 
         fd = timerfd_create(clockid, flags);
         if (fd == -1) {
@@ -66,7 +66,7 @@ static VALUE itimerspec2ary(struct itimerspec *its)
 static VALUE settime(VALUE self, VALUE fl, VALUE interval, VALUE value)
 {
         int fd = rb_sp_fileno(self);
-        int flags = rb_sp_get_flags(self, fl);
+        int flags = rb_sp_get_flags(self, fl, 0);
         struct itimerspec old, new;
 
         value2timespec(&new.it_interval, interval);
diff --git a/ext/sleepy_penguin/util.c b/ext/sleepy_penguin/util.c
index 4ae702d..2423af6 100644
--- a/ext/sleepy_penguin/util.c
+++ b/ext/sleepy_penguin/util.c
@@ -5,10 +5,10 @@ static VALUE klass_for(VALUE klass)
         return (TYPE(klass) == T_CLASS) ? klass : CLASS_OF(klass);
 }
 
-int rb_sp_get_flags(VALUE klass, VALUE flags)
+int rb_sp_get_flags(VALUE klass, VALUE flags, int default_flags)
 {
         switch (TYPE(flags)) {
-        case T_NIL: return 0;
+        case T_NIL: return default_flags;
         case T_FIXNUM: return FIX2INT(flags);
         case T_BIGNUM: return NUM2INT(flags);
         case T_SYMBOL:
diff --git a/test/test_epoll.rb b/test/test_epoll.rb
index 1a99dfd..a55a4c3 100644
--- a/test/test_epoll.rb
+++ b/test/test_epoll.rb
@@ -358,7 +358,11 @@ class TestEpoll < Test::Unit::TestCase
   def test_new
     @ep.close
     io = Epoll.new.to_io
-    assert_equal 0, io.fcntl(Fcntl::F_GETFD)
+    if RUBY_VERSION.to_f >= 2.0
+      assert_equal 1, io.fcntl(Fcntl::F_GETFD)
+    else
+      assert_equal 0, io.fcntl(Fcntl::F_GETFD)
+    end
   end
 
   def test_delete
diff --git a/test/test_eventfd.rb b/test/test_eventfd.rb
index 84ee307..f04def3 100644
--- a/test/test_eventfd.rb
+++ b/test/test_eventfd.rb
@@ -20,6 +20,11 @@ class TestEventFD < Test::Unit::TestCase
   def test_new
     efd = EventFD.new 0
     assert_kind_of(IO, efd)
+    if RUBY_VERSION.to_f >= 2.0
+      assert_equal 1, efd.fcntl(Fcntl::F_GETFD)
+    else
+      assert_equal 0, efd.fcntl(Fcntl::F_GETFD)
+    end
   end
 
   def test_new_nonblock
diff --git a/test/test_inotify.rb b/test/test_inotify.rb
index b50a83b..ae6b8ba 100644
--- a/test/test_inotify.rb
+++ b/test/test_inotify.rb
@@ -17,6 +17,11 @@ class TestInotify < Test::Unit::TestCase
   def test_new
     @ino = Inotify.new
     assert_kind_of(IO, ino)
+    if RUBY_VERSION.to_f >= 2.0
+      assert_equal 1, ino.fcntl(Fcntl::F_GETFD)
+    else
+      assert_equal 0, ino.fcntl(Fcntl::F_GETFD)
+    end
   end
 
   def test_constants
diff --git a/test/test_timerfd.rb b/test/test_timerfd.rb
index 7e102c4..e8dc321 100644
--- a/test/test_timerfd.rb
+++ b/test/test_timerfd.rb
@@ -15,6 +15,11 @@ class TestTimerFD < Test::Unit::TestCase
   def test_create
     tfd = TimerFD.new
     assert_kind_of(IO, tfd)
+    if RUBY_VERSION.to_f >= 2.0
+      assert_equal 1, tfd.fcntl(Fcntl::F_GETFD)
+    else
+      assert_equal 0, tfd.fcntl(Fcntl::F_GETFD)
+    end
   end
 
   def test_create_nonblock