# Author:: Nicolas Pouillard . # Copyright:: Copyright (c) 2004, 2005 Uttk team. All rights reserved. # License:: LGPL # $Id: /w/fey/uttk/trunk/lib/uttk/strategies/CmdBase.rb 21844 2006-02-17T17:26:59.771162Z pouillar $ module Uttk module Strategies class CmdBase < IOBased include Abstract # # Constructor # def initialize ( *a, &b ) super @my_exit, @pid, @my_status = nil, nil, nil end # # Methods # def run_impl begin cmd = mk_command cmd.gsub!("\n", ' ') @log[:running] = cmd @pid = Kernel.fork do unless @input.nil? or @input_in_args STDIN.reopen(@input.my.open('r')) end STDOUT.reopen(@output.my.open('w')) unless @output.nil? STDERR.reopen(@error.my.open('w')) unless @error.nil? Dir.chdir(@dir.to_s) if @dir begin son_hook exec(cmd) rescue Exception => ex @log.exception_raised_during_exec = ex exit! 127 end end father_hook waitpid fail('exception raised during exec') if @my_exit == 127 end end protected :run_impl def son_hook end protected :son_hook def father_hook end protected :father_hook def abort_hook unless @pid.nil? begin Process.kill('-KILL', -@pid) waitpid rescue Errno::ESRCH @log.already_killed = @pid end end @my_exit = 134 # Common status returned by sh on a SIGABRT super end protected :abort_hook def waitpid return if @pid.nil? or not @my_status.nil? Process.waitpid(@pid) @my_status = $? @my_exit = @my_status.exitstatus end protected :waitpid def mk_command cmd = @command.to_s.dup cmd += ' %a' if cmd !~ /%a/ and @args cmd.gsub!(/%a/, @args.to_s) if @args if cmd =~ /%i/ and @input and @input.my cmd.gsub!(/%i/, @input.my.to_s) @input_in_args = true else @input_in_args = false end cmd end protected :mk_command def epilogue waitpid super end # # Attributes # attr_reader :my_exit, :my_status, :pid attribute :command, 'the command to execute', :mandatory, [String, Pathname, Array] attribute :dir, 'the directory where to launch the command', [String, Pathname] attribute :args, 'the arguments for the command', [Array, String, Numeric] end # class CmdBase end # module Strategies end # module Uttk