From b93dc848835f93efc100cde2d3056512e7ddf557 Mon Sep 17 00:00:00 2001 From: normal Date: Sun, 8 Jul 2018 00:02:27 +0000 Subject: signal.c: preserve trap(:CHLD, "IGNORE") behavior with SIGCHLD We need to preserve "IGNORE" behavior from Ruby 2.5 and earlier. We can't rely on SA_NOCLDWAIT any more, since we always need system() and MJIT to work; so we fake that behavior using dedicated reaper (currently in timer-thread). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63879 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- test/ruby/test_signal.rb | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'test') diff --git a/test/ruby/test_signal.rb b/test/ruby/test_signal.rb index 9003ce1acf..f242a2dc4c 100644 --- a/test/ruby/test_signal.rb +++ b/test/ruby/test_signal.rb @@ -326,4 +326,47 @@ class TestSignal < Test::Unit::TestCase end end; end + + def test_sigchld_ignore + skip 'no SIGCHLD' unless Signal.list['CHLD'] + old = trap(:CHLD, 'IGNORE') + cmd = [ EnvUtil.rubybin, '--disable=gems', '-e' ] + assert(system(*cmd, 'exit!(0)'), 'no ECHILD') + t0 = Process.clock_gettime(Process::CLOCK_MONOTONIC) + IO.pipe do |r, w| + pid = spawn(*cmd, "STDIN.read", in: r) + nb = Process.wait(pid, Process::WNOHANG) + th = Thread.new(Thread.current) do |parent| + Thread.pass until parent.stop? # wait for parent to Process.wait + w.close + end + assert_raise(Errno::ECHILD) { Process.wait(pid) } + assert_nil nb + end + + IO.pipe do |r, w| + pids = 3.times.map { spawn(*cmd, 'exit!', out: w) } + w.close + zombies = pids.dup + assert_nil r.read(1), 'children dead' + + Timeout.timeout(3) do + zombies.delete_if do |pid| + begin + Process.kill(0, pid) + false + rescue Errno::ESRCH + true + end + end while zombies[0] + end + assert_predicate zombies, :empty?, 'zombies leftover' + + pids.each do |pid| + assert_raise(Errno::ECHILD) { Process.waitpid(pid) } + end + end + ensure + trap(:CHLD, old) + end end -- cgit v1.2.3