diff --git a/Library/Homebrew/cmd/postinstall.rb b/Library/Homebrew/cmd/postinstall.rb index 8e145d3fde..d677ecc1e2 100644 --- a/Library/Homebrew/cmd/postinstall.rb +++ b/Library/Homebrew/cmd/postinstall.rb @@ -1,5 +1,34 @@ +require "sandbox" + module Homebrew def postinstall - ARGV.formulae.each { |f| f.run_post_install } + ARGV.formulae.each { |f| run_post_install(f) } + end + + def run_post_install(formula) + args = %W[ + nice #{RUBY_PATH} + -W0 + -I #{HOMEBREW_LIBRARY_PATH} + -- + #{HOMEBREW_LIBRARY_PATH}/postinstall.rb + #{formula.path} + ].concat(ARGV.options_only) + + Utils.safe_fork do + if Sandbox.available? && ARGV.sandbox? + sandbox = Sandbox.new + sandbox.allow_write_temp_and_cache + sandbox.allow_write_log(formula) + sandbox.allow_write_cellar(formula) + sandbox.allow_write_path HOMEBREW_PREFIX + sandbox.deny_write_path HOMEBREW_LIBRARY + sandbox.deny_write_path HOMEBREW_REPOSITORY/".git" + sandbox.deny_write HOMEBREW_BREW_FILE + sandbox.exec(*args) + else + exec(*args) + end + end end end diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb index ff9d6b0af3..efd15d47db 100644 --- a/Library/Homebrew/formula_installer.rb +++ b/Library/Homebrew/formula_installer.rb @@ -9,6 +9,7 @@ require 'cleaner' require 'formula_cellar_checks' require 'install_renamed' require 'cmd/tap' +require 'cmd/postinstall' require 'hooks/bottles' require 'debrew' require 'sandbox' @@ -586,7 +587,7 @@ class FormulaInstaller end def post_install - formula.run_post_install + Homebrew.run_post_install(formula) rescue Exception => e opoo "The post-install step did not complete successfully" puts "You can try again using `brew postinstall #{formula.name}`" diff --git a/Library/Homebrew/postinstall.rb b/Library/Homebrew/postinstall.rb new file mode 100644 index 0000000000..14e578128b --- /dev/null +++ b/Library/Homebrew/postinstall.rb @@ -0,0 +1,21 @@ +old_trap = trap("INT") { exit! 130 } + +require "global" +require "debrew" +require "fcntl" +require "socket" + +begin + error_pipe = UNIXSocket.open(ENV["HOMEBREW_ERROR_PIPE"], &:recv_io) + error_pipe.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) + + trap("INT", old_trap) + + formula = ARGV.formulae.first + formula.extend(Debrew::Formula) if ARGV.debug? + formula.run_post_install +rescue Exception => e + Marshal.dump(e, error_pipe) + error_pipe.close + exit! 1 +end