Merge pull request #4853 from woodruffw/error-pipe-check-closed

utils/fork: Check if error pipe is closed
This commit is contained in:
William Woodruff 2018-09-19 10:00:01 -04:00 committed by GitHub
commit 2246780f0b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 11 additions and 6 deletions

View File

@ -620,7 +620,7 @@ class ChildProcessError < RuntimeError
@inner_class = Object.const_get inner["json_class"] @inner_class = Object.const_get inner["json_class"]
super <<~EOS super <<~EOS
An exception occured within a build process: An exception occured within a child process:
#{inner_class}: #{inner["m"]} #{inner_class}: #{inner["m"]}
EOS EOS

View File

@ -12,6 +12,8 @@ module Utils
# when we rescue this in `FormulaInstaller#build`. # when we rescue this in `FormulaInstaller#build`.
BuildError.new(nil, child_error.inner["cmd"], BuildError.new(nil, child_error.inner["cmd"],
child_error.inner["args"], child_error.inner["env"]) child_error.inner["args"], child_error.inner["env"])
elsif child_error.inner_class == Interrupt
Interrupt.new
else else
# Everything other error in the child just becomes a RuntimeError. # Everything other error in the child just becomes a RuntimeError.
RuntimeError.new(child_error.message) RuntimeError.new(child_error.message)
@ -48,6 +50,7 @@ module Utils
write.puts error_hash.to_json write.puts error_hash.to_json
write.close write.close
exit! exit!
else else
exit!(true) exit!(true)
@ -64,21 +67,23 @@ module Utils
socket.close socket.close
end end
write.close write.close
# Each line on the error pipe contains a JSON-serialized exception. data = read.read
# We read the first, since only one is necessary for a failure.
data = read.gets
read.close read.close
Process.wait(pid) unless socket.nil? Process.wait(pid) unless socket.nil?
# 130 is the exit status for a process interrupted via Ctrl-C.
# We handle it here because of the possibility of an interrupted process terminating
# without writing its Interrupt exception to the error pipe.
raise Interrupt if $CHILD_STATUS.exitstatus == 130
if data && !data.empty? if data && !data.empty?
error_hash = JSON.parse(data) unless data.nil? || data.empty? error_hash = JSON.parse(data.lines.first)
e = ChildProcessError.new(error_hash) e = ChildProcessError.new(error_hash)
raise rewrite_child_error(e) raise rewrite_child_error(e)
end end
raise Interrupt if $CHILD_STATUS.exitstatus == 130
raise "Forked child process failed: #{$CHILD_STATUS}" unless $CHILD_STATUS.success? raise "Forked child process failed: #{$CHILD_STATUS}" unless $CHILD_STATUS.success?
end end
end end