lib/rbbt/util/cmd.rb in rbbt-util-1.0.1 vs lib/rbbt/util/cmd.rb in rbbt-util-1.1.0

- old
+ new

@@ -1,24 +1,31 @@ require 'rbbt/util/misc' require 'rbbt/util/log' require 'stringio' module CMD - class CMDError < StandardError;end + class CMDError < RBBTError;end module SmartIO - def self.tie(io, pid = nil, post = nil) + def self.tie(io, pid = nil, cmd = "", post = nil) io.instance_eval{ @pid = pid + @cmd = cmd @post = post alias original_close close def close begin - Process.waitpid(@pid, Process::WNOHANG) if @pid + Process.waitpid(@pid) if @pid rescue end + if $? and not $?.success? + Log.debug "Raising exception" + exception = CMDError.new "Command [#{@pid}] #{@cmd} failed with error status #{$?.exitstatus}" + raise exception + end + @post.call if @post original_close end alias original_read read @@ -105,10 +112,12 @@ } sin.first.close sout.last.close serr.last.close + Log.debug "CMD: [#{pid}] #{cmd}" + case when String === in_content sin.last.write in_content sin.last.close when StringIO === in_content @@ -118,23 +127,42 @@ end sin.last.close end end - Thread.new do - while l = serr.first.gets - Log.log l, stderr if Integer === stderr + if pipe + Thread.new do + while l = serr.first.gets + Log.log l, stderr if Integer === stderr + end + serr.first.close end - serr.first.close - end - if pipe - SmartIO.tie sout.first, pid, post + SmartIO.tie sout.first, pid, cmd, post sout.first + else + err = "" + Thread.new do + while l = serr.first.gets + err << l if Integer === stderr + end + serr.first.close + end + out = StringIO.new sout.first.read - SmartIO.tie out + SmartIO.tie out, pid, cmd, post + Process.waitpid pid + + if not $?.success? + exception = CMDError.new "Command [#{pid}] #{cmd} failed with error status #{$?.exitstatus}" + exception.info = err if Integer === stderr and stderr >= Log.severity + raise exception + else + Log.log err, stderr if Integer === stderr + end + out end end end