Commit 6faa04e8 authored by danielsdeleo's avatar danielsdeleo
Browse files

Handle ESRCH when getting pgid of a zombie on OS X

parent a6b99167
......@@ -6,5 +6,6 @@
* Enabled travis.
* Added error? to check if the command ran successfully. MIXLIB-18.
* Remove GC.disable hack for non-ruby 1.8.8
* Handle ESRCH from getpgid of a zombie on OS X
## Last Release: 1.3.0 (12/03/2013)
......@@ -63,7 +63,7 @@ module Mixlib
# CHEF-3390: Marshall.load on Ruby < 1.8.7p369 also has a GC bug related
# to Marshall.load, so try disabling GC first.
propagate_pre_exec_failure
@child_pgid = -Process.getpgid(@child_pid)
get_child_pgid
@result = nil
@execution_time = 0
......@@ -107,6 +107,18 @@ module Mixlib
private
def get_child_pgid
# The behavior of Process.getpgid (see also getpgid(2) ) when the
# argument is the pid of a zombie isn't well specified. On Linux it
# works, on OS X it returns ESRCH (which ruby turns into Errno::ESRCH).
#
# If the child dies very quickly, @child_pid may be a zombie, so handle
# ESRCH here.
@child_pgid = -Process.getpgid(@child_pid)
rescue Errno::ESRCH
@child_pgid = nil
end
def set_user
if user
Process.euid = uid
......@@ -137,6 +149,10 @@ module Mixlib
# Process group id of the child. Returned as a negative value so you can
# put it directly in arguments to kill, wait, etc.
#
# This may be nil if the child dies before the parent can query the
# system for its pgid (on some systems it is an error to get the pgid of
# a zombie).
def child_pgid
@child_pgid
end
......
......@@ -843,6 +843,25 @@ describe Mixlib::ShellOut do
end
end
context "when the child process dies immediately" do
let(:cmd) { [ 'exit' ] }
it "handles ESRCH from getpgid of a zombie" do
Process.stub(:setsid) { exit!(4) }
# there is a small race condition here if the child doesn't get
# scheduled and call exit! before the parent can call getpgid, so run
# this a few times to make sure we've created the reproduction case
# correctly.
5.times do
s = Mixlib::ShellOut.new(cmd)
s.run_command # should not raise Errno::ESRCH
end
end
end
context 'with subprocess that takes longer than timeout' do
def ruby_wo_shell(code)
parts = %w[ruby]
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment