Much better CTRL-C handling
Let's not show weird error messages when user interrupts during various stages of brew initialization. Tested by doing `for x in $(brew search); do brew install $x; done` and pressing CTRL-C at random short intervals.
This commit is contained in:
parent
fb8c7e0aaf
commit
20ce16a3ff
@ -1,51 +1,54 @@
|
||||
#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
|
||||
#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby -W0
|
||||
|
||||
# This script is called by formula_installer as a separate instance.
|
||||
# Rationale: Formula can use __END__, Formula can change ENV
|
||||
# Thrown exceptions are propogated back to the parent process over a pipe
|
||||
|
||||
require 'global'
|
||||
STD_TRAP = trap("INT") { exit! 130 } # no backtrace thanks
|
||||
|
||||
at_exit do
|
||||
# the whole of everything must be run in at_exit because the formula has to
|
||||
# be the run script as __END__ must work for *that* formula.
|
||||
main
|
||||
end
|
||||
|
||||
error_pipe = nil
|
||||
require 'global'
|
||||
|
||||
begin
|
||||
# The main Homebrew process expects to eventually see EOF on the error
|
||||
# pipe in FormulaInstaller#build. However, if any child process fails to
|
||||
# terminate (i.e, fails to close the descriptor), this won't happen, and
|
||||
# the installer will hang. Set close-on-exec to prevent this.
|
||||
# Whether it is *wise* to launch daemons from formulae is a separate
|
||||
# question altogether.
|
||||
if ENV['HOMEBREW_ERROR_PIPE']
|
||||
require 'fcntl'
|
||||
error_pipe = IO.new(ENV['HOMEBREW_ERROR_PIPE'].to_i, 'w')
|
||||
error_pipe.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
|
||||
end
|
||||
def main
|
||||
# The main Homebrew process expects to eventually see EOF on the error
|
||||
# pipe in FormulaInstaller#build. However, if any child process fails to
|
||||
# terminate (i.e, fails to close the descriptor), this won't happen, and
|
||||
# the installer will hang. Set close-on-exec to prevent this.
|
||||
# Whether it is *wise* to launch daemons from formulae is a separate
|
||||
# question altogether.
|
||||
if ENV['HOMEBREW_ERROR_PIPE']
|
||||
require 'fcntl'
|
||||
error_pipe = IO.new(ENV['HOMEBREW_ERROR_PIPE'].to_i, 'w')
|
||||
error_pipe.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
|
||||
end
|
||||
|
||||
raise $! if $! # an exception was already thrown when parsing the formula
|
||||
raise $! if $! # an exception was already thrown when parsing the formula
|
||||
|
||||
require 'hardware'
|
||||
require 'keg'
|
||||
trap("INT", STD_TRAP) # restore default CTRL-C handler
|
||||
|
||||
# Force any future invocations of sudo to require the user's password to be
|
||||
# re-entered. This is in-case any build script call sudo. Certainly this is
|
||||
# can be inconvenient for the user. But we need to be safe.
|
||||
system "/usr/bin/sudo -k"
|
||||
require 'hardware'
|
||||
require 'keg'
|
||||
|
||||
install(Formula.factory($0))
|
||||
rescue Exception => e
|
||||
unless error_pipe.nil?
|
||||
Marshal.dump(e, error_pipe)
|
||||
error_pipe.close
|
||||
exit! 1
|
||||
else
|
||||
onoe e
|
||||
puts e.backtrace
|
||||
exit! 2
|
||||
end
|
||||
# Force any future invocations of sudo to require the user's password to be
|
||||
# re-entered. This is in-case any build script call sudo. Certainly this is
|
||||
# can be inconvenient for the user. But we need to be safe.
|
||||
system "/usr/bin/sudo -k"
|
||||
|
||||
install(Formula.factory($0))
|
||||
rescue Exception => e
|
||||
unless error_pipe.nil?
|
||||
Marshal.dump(e, error_pipe)
|
||||
error_pipe.close
|
||||
exit! 1
|
||||
else
|
||||
onoe e
|
||||
puts e.backtrace
|
||||
exit! 2
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -238,6 +238,7 @@ class FormulaInstaller
|
||||
Process.wait
|
||||
data = read.read
|
||||
raise Marshal.load(data) unless data.nil? or data.empty?
|
||||
raise Interrupt if $?.exitstatus == 130
|
||||
raise "Suspicious installation failure" unless $?.success?
|
||||
end
|
||||
|
||||
@ -266,15 +267,18 @@ class FormulaInstaller
|
||||
end
|
||||
|
||||
keg = Keg.new(f.prefix)
|
||||
keg.link
|
||||
rescue Exception => e
|
||||
onoe "The `brew link` step did not complete successfully."
|
||||
puts "The formula built, but is not symlinked into #{HOMEBREW_PREFIX}."
|
||||
puts "You can try again using `brew link #{f.name}`."
|
||||
keg.unlink
|
||||
|
||||
ohai e, e.backtrace if ARGV.debug?
|
||||
@show_summary_heading = true
|
||||
begin
|
||||
keg.link
|
||||
rescue Exception => e
|
||||
onoe "The `brew link` step did not complete successfully"
|
||||
puts "The formula built, but is not symlinked into #{HOMEBREW_PREFIX}"
|
||||
puts "You can try again using `brew link #{f.name}'"
|
||||
ohai e, e.backtrace if ARGV.debug?
|
||||
@show_summary_heading = true
|
||||
ignore_interrupts{ keg.unlink }
|
||||
raise unless e.kind_of? RuntimeError
|
||||
end
|
||||
end
|
||||
|
||||
def fix_install_names
|
||||
|
||||
@ -217,7 +217,7 @@ def inreplace path, before=nil, after=nil
|
||||
end
|
||||
|
||||
def ignore_interrupts
|
||||
std_trap = trap("INT") {}
|
||||
std_trap = trap("INT") { puts "One sec, just cleaning up" }
|
||||
yield
|
||||
ensure
|
||||
trap("INT", std_trap)
|
||||
|
||||
4
bin/brew
4
bin/brew
@ -1,6 +1,8 @@
|
||||
#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby -W0
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
std_trap = trap("INT") { exit! 130 } # no backtrace thanks
|
||||
|
||||
HOMEBREW_BREW_FILE = ENV['HOMEBREW_BREW_FILE'] = File.expand_path(__FILE__)
|
||||
|
||||
require 'pathname'
|
||||
@ -49,6 +51,8 @@ rescue LoadError => e
|
||||
end
|
||||
|
||||
begin
|
||||
trap("INT", std_trap) # restore default CTRL-C handler
|
||||
|
||||
aliases = {'ls' => :list,
|
||||
'homepage' => :home,
|
||||
'-S' => :search,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user