Chaining processes, Process.waitpid


#1

Hello,

for chaining processes in a way, that the output of one process feeds
the input of another one like in that example …

#\

transformation ‘foo’ -> ‘fee’ -> ‘tee’:

chain_processes(lambda { exec(‘echo’, ‘foo’) },
lambda { exec(‘sed’, ‘s|o|e|g’) }) do
system(‘sed’, ‘s|f|t|g’)
end
#//

… I came to that solution:

#\
def chain_processes(*processes, &block)
saved_stdin = $stdin.clone
threads = []
this, *remaining = processes + (block ? [ block ] : [])
while [] != remaining
rd, wr = IO.pipe
child = fork
if !child
rd.close
$stdout.reopen(wr)
exit this[]
end
wr.close
$stdin.reopen(rd)
threads << Thread.new { Process.waitpid(child) }
this, *remaining = remaining
end

this[]
threads.each { |t| t.join }
$stdin.reopen(saved_stdin)
end
#//

That seems also to work without Process.waitpid(child). When is it
really necessary to wait for the children? How should an example look
like which breaks without using Process.waitpid or Process.wait?

Regards
Thomas