Park Heesob wrote:
> 
> Hi,
> 
> "Gilles Filippini" <gilles.filippini / free.fr> wrote in message
> news:3D30AAF9.96186571 / free.fr...
> > Hi all,
> >
> > I need someone shed some light on the following problem.
> >
> > Here is the culprit script:
> > #--------------------------
> > output = IO.pipe
> > old_out = $defout.dup
> > old_out.sync = true
> > $defout = output[1]
> > thread = Thread.new {
> > old_out.puts("@@@@ 1")
> > while not output[0].eof?
> > old_out.puts("@@@@ 2")
> > select([output[0]])
> > old_out.write(output[0].read)
> > end
> > output[0].close
> > }
> > puts `cat #{ARGV[0]}`
> > output[1].close
> > thread.join
> > #--------------------------
> >
> > Try this script with a text file for the first argument:
> > - if the file's size is less than - say - 8 ko, the script works fine.
> > - if the file's size is more than - say - 10 ko, ruby hangs on the
> >   while statement.
> > What could be the reason for this behavior ?
> >
> 
> It's probably beause pipe's buffer size is 8192 bytes
> 
> Try this:
> ===============================
> output = IO.pipe
> old_out = $defout.dup
> old_out.sync = true
> $defout = output[1]
> output[1].sync = true
> thread = Thread.new {
> old_out.puts("@@@@ 1")
> while not output[0].eof?
> old_out.puts("@@@@ 2")
> select([output[0]])
> old_out.write(output[0].read)
> end
> output[0].close
> }
> `cat #{ARGV[0]}`.each_byte {|x| print x.chr}
> output[1].close
> thread.join
> ==================================

Yes, it works. But it it far too slow. Moreover, I intend to use this
scheme to redirect standard output. Thus I shouldn't touch the cat
statement.

Anyway, looking at the man pages for write(2) and fcntl(2), I've found:

require "fcntl"
output[1].fcntl(Fcntl::F_SETFL, File::NONBLOCK)

And that works great!
Thanks for your answer which gave me the idea to look at those man
pages.

_gilles.