lib/rbbt/util/cmd.rb in rbbt-util-5.21.38 vs lib/rbbt/util/cmd.rb in rbbt-util-5.21.39

- old
+ new

@@ -51,32 +51,35 @@ sout, serr, sin = Misc.pipe, Misc.pipe, Misc.pipe pid = fork { begin + Misc.purge_pipes(sin.last,sout.last,serr.last) + sin.last.close sout.first.close serr.first.close - io = in_content - while IO === io - io.join if io.respond_to?(:join) and not io.joined? - io.close if io.respond_to?(:close) and not io.closed? - io = nil + if IO === in_content + in_content.close if in_content.respond_to?(:close) and not in_content.closed? + in_content.join if in_content.respond_to?(:join) and not in_content.joined? end - STDIN.reopen sin.first - sin.first.close STDERR.reopen serr.last serr.last.close + STDIN.reopen sin.first + sin.first.close + STDOUT.reopen sout.last sout.last.close + STDOUT.sync = STDERR.sync = true - + + exec(ENV, cmd) exit(-1) rescue Exception Log.debug{ "ProcessFailed: #{$!.message}" } if log @@ -87,77 +90,84 @@ sin.first.close sout.last.close serr.last.close + sin = sin.last sout = sout.first serr = serr.first - + Log.debug{"CMD: [#{pid}] #{cmd}" if log} if in_content.respond_to?(:read) - Thread.new do + in_thread = Thread.new do |parent| begin - loop do - break if in_content.closed? - block = in_content.read Misc::BLOCK_SIZE - break if block.nil? or block.empty? - sin.write block + begin + while c = in_content.readpartial(Misc::BLOCK_SIZE) + sin << c + end + rescue EOFError end + sin.close unless sin.closed? - sin.close unless sin.closed? - in_content.join if in_content.respond_to? :join and not dont_close_in - in_content.close unless in_content.closed? or dont_close_in + unless dont_close_in + in_content.close unless in_content.closed? + in_content.join if in_content.respond_to? :join + end rescue + parent.raise $! Process.kill "INT", pid - raise $! + ensure + sin.close unless sin.closed? end end else + in_thread = nil sin.close end if no_wait pids = [] else pids = [pid] end + if pipe - Thread.new do + err_thread = Thread.new do while line = serr.gets Log.log line, stderr if Integer === stderr and log end serr.close end - ConcurrentStream.setup sout, :pids => pids, :autojoin => no_wait, :no_fail => no_fail + ConcurrentStream.setup sout, :pids => pids, :threads => [in_thread, err_thread].compact, :autojoin => no_wait, :no_fail => no_fail sout else err = "" Thread.new do while not serr.eof? err << serr.gets if Integer === stderr end - serr.close - end + serr.close + end - ConcurrentStream.setup sout, :pids => pids, :autojoin => no_wait, :no_fail => no_fail + ConcurrentStream.setup sout, :pids => pids, :threads => [in_thread, err_thread].compact, :autojoin => no_wait, :no_fail => no_fail - out = StringIO.new sout.read - sout.close unless sout.closed? + out = StringIO.new sout.read + sout.close unless sout.closed? - Process.waitpid pid + Process.waitpid pid - if not $?.success? and not no_fail - raise ProcessFailed.new "Command [#{pid}] #{cmd} failed with error status #{$?.exitstatus}.\n#{err}" - else - Log.log err, stderr if Integer === stderr and log - end + if not $?.success? and not no_fail + raise ProcessFailed.new "Command [#{pid}] #{cmd} failed with error status #{$?.exitstatus}.\n#{err}" + else + Log.log err, stderr if Integer === stderr and log + end - out + out end end end