From: Walton Hoops Date: 2011-02-17T12:33:22+09:00 Subject: Re: Reading/writing to spawned process On 02/16/2011 02:14 PM, Joel F. wrote: > Yeah it's a bit funky. I tried on the ruby I use at work: > > ruby 1.9.2p136 (2010-12-25) [i386-mingw32] > > which turns out is the same of yours. This one has nread and ready? > both implemented, but both broken. My version at home that I was using > before was slightly older I think...so it's probably the case that > IO/wait is a work in progress and with each version they make it > slightly less damaged, lol. > > If on Windows you didn't see them, it might be that you forgot the > 'require IO/wait'. These methods belong to the IO method, but I think > you need the require to "extend" the IO class (can't remember the word > for Ruby modifying classes, but you know what I mean). > > It's probably just best to stick with IO.stat.size for now. It's not an > obvious way to express things, but its worked so far. AHHH! It's io/wait! I tried require 'io' with no luck, and my quick greps didn't help me (I wasn't grepping against the C source), so I wasn't sure where it was supposed to be defined. I think I can shed a little more light now. On Arch Linux with Ruby-1.9.2-136: ruby-1.9.2-p136 :002 > require 'open3' => true ruby-1.9.2-p136 :003 > require 'io/wait' => true ruby-1.9.2-p136 :004 > input, output, err = Open3.popen3('echo foo') => [#, #, #, #] ruby-1.9.2-p136 :005 > output.ready? => true ruby-1.9.2-p136 :006 > err.ready? => false ruby-1.9.2-p136 :007 > output.nread => 4 ruby-1.9.2-p136 :008 > exit On Windows Vista with Ruby-1.9.2-136: C:\Users\Walton Hoops>irb irb(main):001:0> require 'io/wait' => true irb(main):002:0> require 'open3' => true irb(main):003:0> input, output, err = Open3.popen3('echo foo') => [#, #, #, #] irb(main):004:0> output.ready? => nil irb(main):005:0> output.nread => 0 irb(main):006:0> output.stat.size => 5 irb(main):007:0> output.read => "foo\n" irb(main):008:0> exit Note: nil from ready? and 0 from nread are both meant to indicate no information is available (taken from the C comments) So it quite clearly is Windows related. After reading through wait.c (https://github.com/ruby/ruby/blob/trunk/ext/io/wait/wait.c) I am thinking that on Windows the ioctl functions (which are what io/wait uses) only works on socketed IO, which the results from popen3 are not (notice the FIONREAD_POSSIBLE_P macro is checking to see if the argument is a win32 socket). I have very little expierience with the win32 APIs though so it might be worth confirming that with someone more knowledgeable. I hope that helps, or at least sheds some light on things. Walton