From fc95889d3f9bb9129d8c46025bd3ca2847c0b557 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 14 Apr 2017 01:54:36 +0000 Subject: kqueue: ensure close-on-exec flag is set 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 -- cgit v1.2.3-24-ge0c7