| Module | Open4 |
| In: |
lib/open4.rb
|
stolen directly from Open3::open3.rb!
open4.rb: Spawn a program like popen, but with stderr, and pid, too. You might also want to use this if you want to bypass the shell. (By passing multiple args, which IO#popen does not allow)
Usage:
require "open4"
stdin, stdout, stderr, pid = Open4.popen4('nroff -man')
or
include Open4
stdin, stdout, stderr, pid = popen4('nroff -man')
# File lib/open4.rb, line 18
18: def popen4(*cmd)
19: #--{{{
20: pw = IO::pipe # pipe[0] for read, pipe[1] for write
21: pr = IO::pipe
22: pe = IO::pipe
23:
24: verbose = $VERBOSE
25: begin
26: $VERBOSE = nil # shut up warning about forking in threads, world writable
27: # dirs, etc
28: cid =
29: fork{
30: # child
31: pw[1].close
32: STDIN.reopen(pw[0])
33: pw[0].close
34:
35: pr[0].close
36: STDOUT.reopen(pr[1])
37: pr[1].close
38:
39: pe[0].close
40: STDERR.reopen(pe[1])
41: pe[1].close
42:
43: STDOUT.sync = true
44: STDERR.sync = true
45:
46: exec(*cmd)
47: }
48: ensure
49: $VERBOSE = verbose
50: end
51:
52: pw[0].close
53: pr[1].close
54: pe[1].close
55: pi = [pw[1], pr[0], pe[0]]
56: pw[1].sync = true
57: if defined? yield
58: begin
59: yield(cid, *pi)
60: return(Process::waitpid2(cid).last)
61: ensure
62: pi.each{|p| p.close unless p.closed?}
63: end
64: end
65: [cid, pw[1], pr[0], pe[0]]
66: #--}}}
67: end