Class SystemUniversal
In: lib/systemu.rb
Parent: Object
SystemUniversal dot/f_0.png

Methods

child_program   child_setup   getopts   new   new_thread   quietly   relay   systemu   tmpdir   version  

Constants

VERSION = '1.2.0' unless defined? SystemUniversal::VERSION

Public Class methods

instance methods

[Source]

    # File lib/systemu.rb, line 44
44:   def initialize argv, opts = {}, &block
45:     getopt = getopts opts
46: 
47:     @argv = argv
48:     @block = block
49: 
50:     @stdin = getopt[ ['stdin', 'in', '0', 0] ]
51:     @stdout = getopt[ ['stdout', 'out', '1', 1] ]
52:     @stderr = getopt[ ['stderr', 'err', '2', 2] ]
53:     @env = getopt[ 'env' ]
54:     @cwd = getopt[ 'cwd' ]
55: 
56:     @host = getopt[ 'host', self.class.host ]
57:     @ppid = getopt[ 'ppid', self.class.ppid ]
58:     @pid = getopt[ 'pid', self.class.pid ]
59:     @ruby = getopt[ 'ruby', self.class.ruby ]
60:   end

Public Instance methods

[Source]

     # File lib/systemu.rb, line 164
164:   def child_program config
165:     "PIPE = STDOUT.dup\nbegin\nrequire 'yaml'\n\nconfig = YAML.load(IO.read('\#{ config }'))\n\nargv = config['argv']\nenv = config['env']\ncwd = config['cwd']\nstdin = config['stdin']\nstdout = config['stdout']\nstderr = config['stderr']\n\nDir.chdir cwd if cwd\nenv.each{|k,v| ENV[k.to_s] = v.to_s} if env\n\nSTDIN.reopen stdin\nSTDOUT.reopen stdout\nSTDERR.reopen stderr\n\nPIPE.puts \"pid: \\\#{ Process.pid }\"\nPIPE.flush                        ### the process is ready yo!\nPIPE.close\n\nexec *argv\nrescue Exception => e\nPIPE.write Marshal.dump(e) rescue nil\nexit 42\nend\n"
166:   end

[Source]

     # File lib/systemu.rb, line 126
126:   def child_setup tmp
127:     stdin = File.expand_path(File.join(tmp, 'stdin'))
128:     stdout = File.expand_path(File.join(tmp, 'stdout'))
129:     stderr = File.expand_path(File.join(tmp, 'stderr'))
130:     program = File.expand_path(File.join(tmp, 'program'))
131:     config = File.expand_path(File.join(tmp, 'config'))
132: 
133:     if @stdin
134:       open(stdin, 'w'){|f| relay @stdin => f}
135:     else
136:       FileUtils.touch stdin
137:     end
138:     FileUtils.touch stdout
139:     FileUtils.touch stderr
140: 
141:     c = {}
142:     c['argv'] = @argv
143:     c['env'] = @env
144:     c['cwd'] = @cwd
145:     c['stdin'] = stdin 
146:     c['stdout'] = stdout 
147:     c['stderr'] = stderr 
148:     c['program'] = program 
149:     open(config, 'w'){|f| YAML.dump c, f}
150: 
151:     open(program, 'w'){|f| f.write child_program(config)}
152: 
153:     c
154:   end

[Source]

     # File lib/systemu.rb, line 235
235:   def getopts opts = {}
236:     lambda do |*args|
237:       keys, default, ignored = args
238:       catch('opt') do
239:         [keys].flatten.each do |key|
240:           [key, key.to_s, key.to_s.intern].each do |key|
241:             throw 'opt', opts[key] if opts.has_key?(key)
242:           end
243:         end
244:         default
245:       end
246:     end
247:   end

[Source]

     # File lib/systemu.rb, line 115
115:   def new_thread cid, block 
116:     q = Queue.new
117:     Thread.new(cid) do |cid| 
118:       current = Thread.current 
119:       current.abort_on_exception = true
120:       q.push current 
121:       block.call cid
122:     end
123:     q.pop
124:   end

[Source]

     # File lib/systemu.rb, line 156
156:   def quietly
157:     v = $VERBOSE
158:     $VERBOSE = nil
159:     yield
160:   ensure
161:     $VERBOSE = v
162:   end

[Source]

     # File lib/systemu.rb, line 199
199:   def relay srcdst
200:     src, dst, ignored = srcdst.to_a.first
201:     if src.respond_to? 'read'
202:       while((buf = src.read(8192))); dst << buf; end
203:     else
204:       src.each{|buf| dst << buf}
205:     end
206:   end

[Source]

     # File lib/systemu.rb, line 62
 62:   def systemu
 63:     tmpdir do |tmp|
 64:       c = child_setup tmp
 65:       status = nil
 66: 
 67:       begin
 68:         thread = nil
 69: 
 70:         quietly{
 71:           IO.popen "#{ @ruby } #{ c['program'] }", 'r+' do |pipe|
 72:             line = pipe.gets
 73:             case line
 74:               when %r/^pid: \d+$/
 75:                 cid = Integer line[%r/\d+/] 
 76:               else
 77:                 begin
 78:                   buf = pipe.read
 79:                   buf = "#{ line }#{ buf }"
 80:                   e = Marshal.load buf
 81:                   raise unless Exception === e
 82:                   raise e
 83:                 rescue
 84:                   raise "wtf?\n#{ buf }\n"
 85:                 end
 86:             end
 87:             thread = new_thread cid, @block if @block
 88:             pipe.read rescue nil
 89:           end
 90:         }
 91:         status = $?
 92:       ensure
 93:         if thread
 94:           begin
 95:             class << status
 96:               attr 'thread'
 97:             end
 98:             status.instance_eval{ @thread = thread }
 99:           rescue
100:             42
101:           end
102:         end
103:       end
104: 
105:       if @stdout or @stderr
106:         open(c['stdout']){|f| relay f => @stdout} if @stdout
107:         open(c['stderr']){|f| relay f => @stderr} if @stderr
108:         status
109:       else
110:         [status, IO.read(c['stdout']), IO.read(c['stderr'])]
111:       end
112:     end
113:   end

[Source]

     # File lib/systemu.rb, line 208
208:   def tmpdir d = Dir.tmpdir, max = 42, &b
209:     i = -1 and loop{
210:       i += 1
211: 
212:       tmp = File.join d, "systemu_#{ @host }_#{ @ppid }_#{ @pid }_#{ rand }_#{ i += 1 }"
213: 
214:       begin
215:         Dir.mkdir tmp 
216:       rescue Errno::EEXIST
217:         raise if i >= max 
218:         next
219:       end
220: 
221:       break(
222:         if b
223:           begin
224:             b.call tmp
225:           ensure
226:             FileUtils.rm_rf tmp unless SystemU.turd 
227:           end
228:         else
229:           tmp
230:         end
231:       )
232:     }
233:   end

[Source]

    # File lib/systemu.rb, line 18
18:   def version() SystemUniversal::VERSION end

[Validate]