From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS43289 178.17.160.0/20 X-Spam-Status: No, score=-2.6 required=3.0 tests=BAYES_00,RCVD_IN_MSPIKE_BL, RCVD_IN_MSPIKE_ZBI,RCVD_IN_XBL,SPF_FAIL,SPF_HELO_FAIL shortcircuit=no autolearn=no autolearn_force=no version=3.4.0 Received: from 80x24.org (178-17-170-212.static.host [178.17.170.212]) by dcvr.yhbt.net (Postfix) with ESMTP id 417E220960 for ; Fri, 14 Apr 2017 01:54:39 +0000 (UTC) From: Eric Wong To: sleepy-penguin@bogomips.org Subject: [PATCH] kqueue: ensure close-on-exec flag is set Date: Fri, 14 Apr 2017 01:54:36 +0000 Message-Id: <20170414015436.18476-1-e@80x24.org> List-Id: Calling IO::new apparently does not set the close-on-exec flag in Ruby 2.x (tested with 2.2.6 on FreeBSD), so we must set it ourselves. It's not a huge deal to be missing close-on-exec for kqueue, since kqueue already has close-on-fork behavior(!) and it's rare for a process using kqueue to exec without forking, first. --- ext/sleepy_penguin/kqueue.c | 6 +++++- test/test_kqueue.rb | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ext/sleepy_penguin/kqueue.c b/ext/sleepy_penguin/kqueue.c index 430bc88..d7e8d8e 100644 --- a/ext/sleepy_penguin/kqueue.c +++ b/ext/sleepy_penguin/kqueue.c @@ -110,6 +110,7 @@ static VALUE s_new(VALUE klass) { VALUE rv; int fd = kqueue(); + int flags; if (fd < 0) { /* @@ -122,9 +123,12 @@ static VALUE s_new(VALUE klass) rb_sys_fail("kqueue"); } + flags = fcntl(fd, F_GETFD); + if (flags != -1) + fcntl(fd, F_SETFD, flags | FD_CLOEXEC); + rv = INT2FIX(fd); - /* This will set FD_CLOEXEC on Ruby 2.0.0+: */ return rb_call_super(1, &rv); } diff --git a/test/test_kqueue.rb b/test/test_kqueue.rb index ae3203d..9d853c1 100644 --- a/test/test_kqueue.rb +++ b/test/test_kqueue.rb @@ -6,6 +6,7 @@ class TestKqueue < Test::Unit::TestCase def test_kqueue kq = Kqueue.new assert_kind_of IO, kq.to_io + assert_predicate kq.to_io, :close_on_exec? rd, wr = IO.pipe ev = Kevent[rd.fileno, EvFilt::READ, Ev::ADD|Ev::ONESHOT, 0, 0, rd] thr = Thread.new do -- EW