# File lib/open4-vendor.rb, line 384 def alive pid #--{{{ pid = Integer pid begin Process.kill 0, pid true rescue Errno::ESRCH false end #--}}} end
# File lib/open4-vendor.rb, line 336 def background arg, *argv #--{{{ require 'thread' q = Queue.new opts = { 'pid' => q, :pid => q } case argv.last when Hash argv.last.update opts else argv.push opts end thread = Thread.new(arg, argv){|arg, argv| spawn arg, *argv} sc = class << thread; self; end sc.module_eval { define_method(:pid){ @pid ||= q.pop } define_method(:spawn_status){ @spawn_status ||= value } define_method(:exitstatus){ @exitstatus ||= spawn_status.exitstatus } } thread #--}}} end
# File lib/open4-vendor.rb, line 330 def chdir cwd, &block return(block.call Dir.pwd) unless cwd Dir.chdir cwd, &block end
# File lib/open4-vendor.rb, line 181 def getopts opts = {} #--{{{ lambda do |*args| keys, default, ignored = args catch('opt') do [keys].flatten.each do |key| [key, key.to_s, key.to_s.intern].each do |key| throw 'opt', opts[key] if opts.has_key?(key) end end default end end #--}}} end
# File lib/open4-vendor.rb, line 361 def maim pid, opts = {} #--{{{ getopt = getopts opts sigs = getopt[ 'signals', %(SIGTERM SIGQUIT SIGKILL) ] suspend = getopt[ 'suspend', 4 ] pid = Integer pid existed = false sigs.each do |sig| begin Process.kill sig, pid existed = true rescue Errno::ESRCH return(existed ? nil : true) end return true unless alive? pid sleep suspend return true unless alive? pid end return(not alive?(pid)) #--}}} end
# File lib/open4-vendor.rb, line 167 def new_thread *a, &b #--{{{ cur = Thread.current Thread.new(*a) do |*a| begin b[*a] rescue Exception => e cur.raise e end end #--}}} end
# File lib/open4-vendor.rb, line 13 def popen4(*cmd, &b) #--{{{ pw, pr, pe, ps = IO.pipe, IO.pipe, IO.pipe, IO.pipe verbose = $VERBOSE begin $VERBOSE = nil ps.first.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) ps.last.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) cid = fork { pw.last.close STDIN.reopen pw.first pw.first.close pr.first.close STDOUT.reopen pr.last pr.last.close pe.first.close STDERR.reopen pe.last pe.last.close STDOUT.sync = STDERR.sync = true begin exec(*cmd) raise 'forty-two' rescue Exception => e Marshal.dump(e, ps.last) ps.last.flush end ps.last.close unless (ps.last.closed?) exit! } ensure $VERBOSE = verbose end [pw.first, pr.last, pe.last, ps.last].each{|fd| fd.close} begin e = Marshal.load ps.first raise(Exception === e ? e : "unknown failure!") rescue EOFError # If we get an EOF error, then the exec was successful 42 ensure ps.first.close end pw.last.sync = true pi = [pw.last, pr.first, pe.first] if b begin b[cid, *pi] Process.waitpid2(cid).last ensure pi.each{|fd| fd.close unless fd.closed?} end else [cid, pw.last, pr.first, pe.first] end #--}}} end
# File lib/open4-vendor.rb, line 198 def relay src, dst = nil, t = nil #--{{{ send_dst = if dst.respond_to?(:call) lambda{|buf| dst.call(buf)} else lambda{|buf| dst << buf} end unless src.nil? if src.respond_to? :gets while buf = to(t){ src.gets } send_dst[buf] end elsif src.respond_to? :each q = Queue.new th = nil timer_set = lambda do |t| th = new_thread{ to(t){ q.pop } } end timer_cancel = lambda do |t| th.kill if th rescue nil end timer_set[t] begin src.each do |buf| timer_cancel[t] send_dst[buf] timer_set[t] end ensure timer_cancel[t] end elsif src.respond_to? :read buf = to(t){ src.read } send_dst[buf] else buf = to(t){ src.to_s } send_dst[buf] end end #--}}} end
# File lib/open4-vendor.rb, line 249 def spawn arg, *argv #--{{{ argv.unshift(arg) opts = ((argv.size > 1 and Hash === argv.last) ? argv.pop : {}) argv.flatten! cmd = argv.join(' ') getopt = getopts opts ignore_exit_failure = getopt[ 'ignore_exit_failure', getopt['quiet', false] ] ignore_exec_failure = getopt[ 'ignore_exec_failure', !getopt['raise', true] ] exitstatus = getopt[ %( exitstatus exit_status status ) ] stdin = getopt[ %( stdin in i 0 ) << 0 ] stdout = getopt[ %( stdout out o 1 ) << 1 ] stderr = getopt[ %( stderr err e 2 ) << 2 ] pid = getopt[ 'pid' ] timeout = getopt[ %( timeout spawn_timeout ) ] stdin_timeout = getopt[ %( stdin_timeout ) ] stdout_timeout = getopt[ %( stdout_timeout io_timeout ) ] stderr_timeout = getopt[ %( stderr_timeout ) ] status = getopt[ %( status ) ] cwd = getopt[ %( cwd dir ) ] exitstatus = case exitstatus when TrueClass, FalseClass ignore_exit_failure = true if exitstatus [0] else [*(exitstatus || 0)].map{|i| Integer i} end stdin ||= '' if stdin_timeout stdout ||= '' if stdout_timeout stderr ||= '' if stderr_timeout started = false status = begin chdir(cwd) do Timeout::timeout(timeout) do popen4(*argv) do |c, i, o, e| started = true %( replace pid= << push update ).each do |msg| break(pid.send(msg, c)) if pid.respond_to? msg end te = ThreadEnsemble.new c te.add_thread(i, stdin) do |i, stdin| relay stdin, i, stdin_timeout i.close rescue nil end te.add_thread(o, stdout) do |o, stdout| relay o, stdout, stdout_timeout end te.add_thread(e, stderr) do |o, stderr| relay e, stderr, stderr_timeout end te.run end end end rescue raise unless(not started and ignore_exec_failure) end raise SpawnError.new(cmd, status) unless (ignore_exit_failure or (status.nil? and ignore_exec_failure) or exitstatus.include?(status.exitstatus)) status #--}}} end
Generated with the Darkfish Rdoc Generator 2.