Class: Wopen3::Opener
- Inherits:
-
Object
- Object
- Wopen3::Opener
- Defined in:
- lib/wopen3.rb
Constant Summary collapse
- READ =
0
- WRITE =
1
Instance Method Summary collapse
-
#initialize(*cmd) ⇒ Opener
constructor
A new instance of Opener.
Constructor Details
#initialize(*cmd) ⇒ Opener
Returns a new instance of Opener.
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 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/wopen3.rb', line 36 def initialize *cmd write_pipe = IO::pipe read_pipe = IO::pipe error_pipe = IO::pipe pid = fork do # in child write_pipe[WRITE].close STDIN.reopen(write_pipe[READ]) # file descriptor duplicated here write_pipe[READ].close # must close in order for parent to # see EOF read_pipe[READ].close STDOUT.reopen(read_pipe[WRITE]) read_pipe[WRITE].close error_pipe[READ].close STDERR.reopen(error_pipe[WRITE]) error_pipe[WRITE].close exec(*cmd) # will raise SystemCallError if command can't be executed # (eg Errno::NOENT) exit! # should never get here end # in parent write_pipe[READ].close read_pipe[WRITE].close error_pipe[WRITE].close pipes = [write_pipe[WRITE], read_pipe[READ], error_pipe[READ]] write_pipe[WRITE].sync = true if defined? yield begin result = yield(*pipes) Process.waitpid(pid) # global $? gets set here return result ensure pipes.each { |pipe| pipe.close unless pipe.closed? } end end # can't wait immediately (will hang); wait once garbage collection # destroys/finalizes this instance ObjectSpace.define_finalizer(self, proc { Process.waitpid(pid) }) pipes end |