I now understand this properly. Doing `write_end.close_on_exec = true` like in Nicholas' example fixes the issue (doing it on the read end is a good idea too).
The reason that #each_line didn't return until the pipe was broken is that starting another process via childprocess did a fork, which duplicated the file handles for the pipe, so when I closed the write end of the pipe I had only closed one of the two copies. Since childprocess does fork+exec in the child, setting close_on_exec means my parent process is left with the only reference to the write end, and closing that will let the read end know it's reached EOF (and that #each_line should gracefully return). The first few examples of this spec demonstrate the issue: https://github.com/chrisberkhout/pvc/blob/e0c79d286a306963f045243d4eb87e3531d5869c/spec/ruby/pipe_io_spec.rb Florian, cod looks great for handling higher level IPC. In this case I just want to hook up streams and don't care about passing objects over them, so the built in stuff is enough. Cheers, Chris On Wed, Jan 23, 2013 at 11:30 AM, Chris Berkhout <[email protected]> wrote: > Hi ROROers, > > I'm trying to build something on top the ChildProcess gem that makes > it as easy in Ruby to pipe stuff between processes (and Ruby blocks), > as it is in the shell. > > It's basically working. To see it in action: > clone https://gist.github.com/4600139 pipes-gist && cd pipes-gist > gem install childprocess > ruby ./pipes.rb > > But, I wonder if someone can explain pipes to me a bit more... > > Calling IO.pipe creates a read and a write end: > r, w = IO.pipe > > I'm reading from the read end like this: > r.each_line { |line| puts "this came out of the pipe: #{line}" } > > When I'm done I close the write end: > w.close > > And I would expect that to send an EOF through the pipe, which > #each_line would see and cause it to stop (or yield the last partial > line). > > But it doesn't. #each_line never finishes. It keeps going until the > read end of the pipe is closed, and when that happens it raises an > IOError (... stream closed). > > Is there no more graceful way to close a pipe? > > Cheers, > Chris -- You received this message because you are subscribed to the Google Groups "Ruby or Rails Oceania" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/rails-oceania?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
