module MJ; module Tools module SubProcess class CoreDumpError < StandardError; end module ClassMethods # Executes command # # Executes the given command and yields each line of output. # Returns +$?+ . def execute( command, wd = ENV["HOME"], env = nil ) cwd ||= Dir.getwd logger.trace "(#{wd}) > #{command} 2>&1" if !$noop adjust_environment( wd, env ) { IO.popen( "#{command} 2>&1" ) { |f| begin while line = f.readline if line.start_with?( "error:" ) logger.error line.chomp elsif line.start_with?( "warning:" ) logger.warn line.chomp elsif line.start_with?( "trace:" ) logger.trace line.chomp elsif line.start_with?( "info:" ) logger.info line.chomp else logger.verbose line.chomp end yield line.chomp if block_given? end rescue EOFError # Expected. Do nothing end } if $?.coredump? or $?.signaled? raise CoreDumpError, "Command '#{command}' core dumped because of signal #{$?.termsig}!" end logger.trace "= #{$?.exitstatus}" return $?.exitstatus } else adjust_environment( wd, env ) { logger.trace "= 0 # noop" } return 0 end end # Helper method to adjust LANG to "C" def adjust_environment( wd=nil, env=nil, lang="C" ) if wd and !$noop cwd = Dir.getwd Dir.chdir(wd) end # Set the environment the user wants oldenv = Hash.new if env env.each do |var, value| oldenv[var] = ENV[var] logger.verbose "#{var} = #{value}" ENV[var] = value end end # Save old LANG setting and switch to 'C' oldlang = ENV['LANG'] ENV['LANG'] = lang yield # Reset the old LANG setting ENV['LANG'] = oldlang # Reset our changes to ENV oldenv.each do |var, value| ENV[var] = value end # Reset the current working directory if wd and !$noop Dir.chdir(cwd) end end end ######### protected ######### def self.included( klass ) klass.extend( ClassMethods ) end end end; end