From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS47066 71.19.144.0/20 X-Spam-Status: No, score=-1.9 required=3.0 tests=AWL,BAYES_00 shortcircuit=no autolearn=unavailable version=3.3.2 X-Original-To: normalperson@yhbt.net Received: from zedshaw2.xen.prgmr.com (zedshaw2.xen.prgmr.com [71.19.156.177]) by dcvr.yhbt.net (Postfix) with ESMTP id C67F11F435 for ; Sat, 13 Apr 2013 19:54:42 +0000 (UTC) Received: from zedshaw2.xen.prgmr.com (unknown [IPv6:::1]) by zedshaw2.xen.prgmr.com (Postfix) with ESMTP id B93CA73DE6 for ; Sat, 13 Apr 2013 19:55:24 +0000 (UTC) MIME-Version: 1.0 Date: Sat, 13 Apr 2013 19:54:24 +0000 From: Eric Wong List-Archive: List-Help: List-Id: List-Post: List-Subscribe: List-Unsubscribe: Message-Id: <1365882864-13256-4-git-send-email-normalperson@yhbt.net> Precedence: list References: <1365882864-13256-1-git-send-email-normalperson@yhbt.net> Sender: sleepy.penguin@librelist.org Subject: [sleepy.penguin] [PATCH 3/3] set close-on-exec by default under Ruby 2.0 To: sleepy.penguin@librelist.org Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 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. --- ext/sleepy_penguin/epoll.c | 3 ++- ext/sleepy_penguin/eventfd.c | 2 +- ext/sleepy_penguin/extconf.rb | 1 + ext/sleepy_penguin/inotify.c | 2 +- ext/sleepy_penguin/signalfd.c | 5 +++-- ext/sleepy_penguin/sleepy_penguin.h | 7 ++++++- ext/sleepy_penguin/timerfd.c | 6 +++--- ext/sleepy_penguin/util.c | 4 ++-- test/test_epoll.rb | 6 +++++- test/test_eventfd.rb | 5 +++++ test/test_inotify.rb | 5 +++++ test/test_timerfd.rb | 5 +++++ 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_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 @@ def test_new_cloexec 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 @@ def test_constants 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 @@ def teardown 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 @@ def test_constants 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 -- 1.8.2.1.367.gc875ca7