Ah. You're right, of course. I could have sworn that I tried using pipe.close_write before and the problem remained, but apparently I was mistaken. Notes: - "cat" was just to prove a point - the real issue was with "sendmail", but it seems to have the same solution. My brief overview made me think session was not suited for sendmail, but perhaps I was wrong about that too? I'll check it out. - the use of timeout was just to allow the test to exit when the hang occurred. I didn't realize it fails on w32. Is it Timeout that fails, or just when timeout is combined with IO reads? Thanks again! -Payton ara.t.howard / noaa.gov wrote: > On Tue, 31 Jan 2006, Payton Swick wrote: > >> How does one check a pipe (created using IO.popen) to see if there is >> input waiting without using IO#eof or reading from the pipe? Doing >> either of these seems to hang forever if the pipe is empty. > > > harp:~ > cat a.rb > IO.popen("cat", "r+") do |pipe| > pipe.puts 42 > pipe.close_write > puts pipe.read > end > > > harp:~ > ruby a.rb > 42 > > > > consider that cat reads stdin until eof is found. > >> Here's an example: >> >> require 'timeout' >> IO.popen("cat", "r+") do |pipe| >> # pipe.puts "hello world" # Uncomment this to prevent hang below. > > > not really - only the first one. continue to read an you'll still > hang. this > is because cat is still waiting on more stdin or eof. so you must send > more or > close the write end of the pipe to send eof. > >> Timeout::timeout(2) do > > > never mix timeout with reads. it fails on windoze - if you care. > >> if not pipe.eof? # This will hang if the pipe is empty. > > > because cat is waiting for stdin and is not finsihed - cat will only > close it's > stdout when it's done and it's only done when it's stdin has all been read. > man 1 cat. > >> p pipe.getc >> end >> end >> end > > > > if you are on *nix you'll find my session module much easier to use: > > harp:~ > gem install session > Attempting local installation of 'session' > Local gem file not found: session*.gem > Attempting remote installation of 'session' > Updating Gem source index for: http://gems.rubyforge.org > Successfully installed session-2.4.0 > harp:~ > cat a.rb > require "rubygems" > require "session" > require "stringio" > > > sh = Session::new > > stdin = "42" > stdout = StringIO::new > stderr = StringIO::new > > sh.execute "cat", "stdin" => stdin, "stdout" => stdout, "stderr" => > stderr > > puts stdout > > > harp:~ > ruby a.rb > 42 > > > session can also be made to be thread-safe (eg use with timeout) if > needed. see docs for more. > > > kind regards. > > > > -a