Marshal install.rb exceptions back to the parent process

Using an error pipe.

The use of ENV[HOMEBREW_ERROR_PIPE] feels wrong, but I wasn't sure how else to
proxy the file descriptor to the child process since the fork immediately
calls exec.
This commit is contained in:
Max Howell 2009-10-24 15:57:23 +01:00
parent fc9ea77bb3
commit ffe4f25d87
2 changed files with 23 additions and 12 deletions

View File

@ -137,9 +137,16 @@ def install f
puts
rescue Exception => e
#TODO propogate exception back to brew script
onoe e
puts e.backtrace
if ENV['HOMEBREW_ERROR_PIPE']
pipe = IO.new(ENV['HOMEBREW_ERROR_PIPE'].to_i, 'w')
Marshal.dump(e, pipe)
pipe.close
exit! 1
else
onoe e
puts e.backtrace
exit! 2
end
end

View File

@ -163,17 +163,21 @@ begin
# the easiest way to do this
# 2. formulae have access to __END__ the only way to allow this is
# to make the formula script the executed script
pid=fork
if pid.nil?
exec '/usr/bin/ruby', '-I', homebrew_rubylib_path, '-rinstall', f.path, '--', *ARGV.options
else
Process.wait pid
end
#FIXME I don't think $? represents the exit code from the child fork…
exit! $? if $? != 0 # exception in other brew will be visible on screen
read, write = IO.pipe
# I'm guessing this is not a good way to do this, but I'm no UNIX guru
ENV['HOMEBREW_ERROR_PIPE'] = write.to_i.to_s
if not fork
read.close
exec '/usr/bin/ruby', '-I', homebrew_rubylib_path, '-rinstall', f.path, '--', *ARGV.options
else
write.close
data = read.read
raise Marshal.load(data) unless data.nil? or data.empty?
Process.wait
end
end
end
when 'up', 'update'
require 'update'