Reading/writing to spawned process

Hi,

I’d like to spawn a process, then write some stuff to it, then read
stuff from it, then write more, then read more, etc etc. (Ruby 1.9 and
Windows)

The way that I’ve done this is something like:


require ‘open3’
require ‘io/wait’

input, output, err = Open3.popen3(‘cmd’)
input.puts ‘echo hi’
output.read(output.stat.size)
input.puts ‘echo bye’
output.read(output.stat.size)

This seems mostly okay, but I have a couple questions.

  1. In IO/wait, there’s a method called “ready?”. If I call “ready?” in
    this program, it returns false even when stat.size indicates that there
    actually IS in fact data to be read. I’m having trouble understanding
    it.
  2. In IO/wait, there’s a method called “nread”. However, if I call
    output.methods.sort, it’s not there and I cant use it. I see “ready?”
    and “wait”, but no “nread”.
  3. I’m sure I’m not the first bozo to complain about the
    documentation…but the primary documentation for ruby’s standard
    libraries (ruby-doc.org) is pretty sucky. I’m just feeling frustrated
    atm. It took me a lot of hours to come up with the little code that I
    have >_<. Is there an alternative site that has more meaningful
    documentation?

I just signed up for the ruby documentation mailing list so I can make
some suggestions…but is there maybe an easier way? It would be nice
if there was just some form that I could fill out and say “on this page
it says X, but it would be more helpful if it said Y”. Or even a wiki
version of the API.

:frowning:
joel

On 2/12/2011 6:03 PM, Joel F. wrote:

require ‘io/wait’

  1. In IO/wait, there’s a method called “ready?”. If I call “ready?” in
    this program, it returns false even when stat.size indicates that there
    actually IS in fact data to be read. I’m having trouble understanding
    it.
  2. In IO/wait, there’s a method called “nread”. However, if I call
    output.methods.sort, it’s not there and I cant use it. I see “ready?”
    and “wait”, but no “nread”.
    That’s odd, when I try on 1.9.2 on Windows, there is no ready?, wait, or
    nread methods, though they all show a class of IO. My Ruby:
    C:\Users\walton.hoops>ruby --version
    ruby 1.9.2p136 (2010-12-25) [i386-mingw32]

When I get home I’ll try to remember to test on Linux. It could be an
OS specific thing.

  1. I’m sure I’m not the first bozo to complain about the
    documentation…but the primary documentation for ruby’s standard
    libraries (ruby-doc.org) is pretty sucky. I’m just feeling frustrated
    atm. It took me a lot of hours to come up with the little code that I
    have>_<. Is there an alternative site that has more meaningful
    documentation?
    No, your not. Personally I recommend rdoc.info over ruby-doc.org. It is
    the same documentation, but in my opinion it’s much better organized.
    I just signed up for the ruby documentation mailing list so I can make
    some suggestions…but is there maybe an easier way? It would be nice
    if there was just some form that I could fill out and say “on this page
    it says X, but it would be more helpful if it said Y”. Or even a wiki
    version of the API.
    Not that I am aware of. Actually the best way to get these kinds of
    changes through would be to clone the repository and submit a
    documentation patch.

Hope that helps some

Walton

Thanks for being such a mensch Walton. I like the fact that on rdoc I
can actually navigate up the tree of libraries and classes.

On 2/15/2011 1:08 PM, Joel F. wrote:

Thanks for being such a mensch Walton. I like the fact that on rdoc I
can actually navigate up the tree of libraries and classes.

No problem at all! Just as a follow up, I’ve tested under 1.8.7, 1.9.1
and 1.9.2 on Ubuntu and could find no ready? method. I also dug through
the source a bit without any luck there. To be honest I’m kind of at a
loss here. You might try posting a question on the ruby-core mailing
list to see if they can shed some light on what’s going on here.

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 class, 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.

On 02/16/2011 02:14 PM, Joel F. wrote:

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’)
=> [#<IO:fd 4>, #<IO:fd 5>, #<IO:fd 7>, #<Thread:0x00000001d93388
run>]
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 H.>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’)
=> [#<IO:fd 4>, #<IO:fd 5>, #<IO:fd 7>, #<Thread:0x2a42210 run>]
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

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs