diff options
author | Eric Wong <e@80x24.org> | 2017-04-14 01:54:36 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2017-04-14 23:27:37 +0000 |
commit | fc95889d3f9bb9129d8c46025bd3ca2847c0b557 (patch) | |
tree | 7efb7ebdb0b36d8128d26cecfbd4b774a3ed7715 | |
parent | 00492c434ea26696ab3c9be5a2b5020fb02f7d32 (diff) | |
download | sleepy_penguin-fc95889d3f9bb9129d8c46025bd3ca2847c0b557.tar.gz |
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.
-rw-r--r-- | ext/sleepy_penguin/kqueue.c | 6 | ||||
-rw-r--r-- | test/test_kqueue.rb | 1 |
2 files changed, 6 insertions, 1 deletions
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 |