Reading/writing to spawned process

J

Joel F.

Hi,

I'd like to spawn a process, then write some stuff to it, then read from
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.

:(
joel
 
W

Walton Hoops

Hi,

I'd like to spawn a process, then write some stuff to it, then read from
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".
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.
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?
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
 
J

Joel F.

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.
 
W

Walton Hoops

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.
 
J

Joel F.

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.
 
W

Walton Hoops

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')
=> [#<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 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')
=> [#<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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,967
Messages
2,570,148
Members
46,694
Latest member
LetaCadwal

Latest Threads

Top