Module: Open4
- Defined in:
- lib/open4.rb,
lib/open4-0.4.0.rb
Defined Under Namespace
Classes: Error, SpawnError
Class Method Summary collapse
- .background(cmd, opts = {}) ⇒ Object
-
.bg ⇒ Object
–}}}.
-
.open4 ⇒ Object
–}}}.
- .popen4(*cmd) ⇒ Object
-
.spawn(cmd, opts = {}) ⇒ Object
–}}}.
-
.version ⇒ Object
–{{{.
Class Method Details
.background(cmd, opts = {}) ⇒ Object
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/open4.rb', line 155 def background cmd, opts = {} #--{{{ require 'thread' q = Queue.new opts['pid'] = opts[:pid] = q thread = Thread.new(cmd, opts){|cmd, opts| spawn cmd, opts} pid = q.pop sc = class << thread; self; end sc.module_eval { define_method(:pid){ pid } define_method(:spawn_status){ @spawn_status ||= value } define_method(:exitstatus){ spawn_status.exitstatus } } thread #--}}} end |
.bg ⇒ Object
–}}}
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/open4.rb', line 171 def background cmd, opts = {} #--{{{ require 'thread' q = Queue.new opts['pid'] = opts[:pid] = q thread = Thread.new(cmd, opts){|cmd, opts| spawn cmd, opts} pid = q.pop sc = class << thread; self; end sc.module_eval { define_method(:pid){ pid } define_method(:spawn_status){ @spawn_status ||= value } define_method(:exitstatus){ spawn_status.exitstatus } } thread #--}}} end |
.open4 ⇒ Object
–}}}
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/open4.rb', line 72 def popen4(*cmd) #--{{{ pw, pr, pe, ps = IO.pipe, IO.pipe, IO.pipe, IO.pipe verbose = $VERBOSE begin $VERBOSE = nil 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 "exec failed!" 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 end pw.last.sync = true pi = [pw.last, pr.first, pe.first] if defined? yield begin yield(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 |
.popen4(*cmd) ⇒ Object
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/open4.rb', line 9 def popen4(*cmd) #--{{{ pw, pr, pe, ps = IO.pipe, IO.pipe, IO.pipe, IO.pipe verbose = $VERBOSE begin $VERBOSE = nil 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 "exec failed!" 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 end pw.last.sync = true pi = [pw.last, pr.first, pe.first] if defined? yield begin yield(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 |
.spawn(cmd, opts = {}) ⇒ Object
–}}}
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/open4.rb', line 90 def spawn cmd, opts = {} #--{{{ getopt = 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 ignore_exit_failure = getopt[ 'ignore_exit_failure', getopt['quiet', false] ] ignore_exec_failure = getopt[ 'ignore_exec_failure', !getopt['raise', true] ] exitstatus = getopt[ %w( exitstatus exit_status status ), 0 ] stdin = getopt[ ['stdin', 'in', '0', 0] ] stdout = getopt[ ['stdout', 'out', '1', 1] ] stderr = getopt[ ['stderr', 'err', '2', 2] ] pid = getopt[ 'pid' ] started = false status = begin popen4(cmd) do |c, i, o, e| started = true if pid.respond_to? '<<' pid << c end it = Thread.new(i,stdin) do |i,stdin| if stdin if stdin.respond_to? :each stdin.each{|buf| i << buf} elsif stdin.respond_to? :read i << stdin.read else i << stdin.to_s end end i.close end ot = Thread.new(o,stdout){|o,stdout| o.each{|buf| stdout << buf if stdout}} et = Thread.new(e,stderr){|e,stderr| e.each{|buf| stderr << buf if stderr}} it.join ot.join if ot et.join if et 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 (status.exitstatus == exitstatus)) status #--}}} end |
.version ⇒ Object
–{{{
5 6 7 |
# File 'lib/open4.rb', line 5 def self.version '0.4.0' end |