Ruby help - controlling stdin, stdout

J

James Smith

OK, I have a main Ruby program, which i would like to be able to execute
other ruby programs from. I would like the main ruby program to simulate
the actions of a command prompt (i'm using windows) i.e. i would like
the main program to print out output from the running program and to
know when input is needed.

I have the following:

IO.popen("ruby other_program", "r+") do |f|

# i can read and write to "other_program" here, however i want the main
program to be prompted when the "other_program" is waiting for input

So, i think i need to override the STDIN and STOUT of the process in the
"other_program", however i'm not sure how to do this, can anyone help
please?
 
G

greg

There is a good chance that you are taking the wrong approach to
solving this problem. You should give more details about what you are
trying to accomplish.
 
J

James Smith

greg said:
There is a good chance that you are taking the wrong approach to
solving this problem. You should give more details about what you are
trying to accomplish.

I am creating a rails application that allows users to create ruby
programs and save them to file. I now need to be able to run the users
programs. I am able to run the user programs and read the output that is
displayed from the program, however when the user program blocks waiting
for input (i.e. 'gets' is called) I need to be able to signal to the
rails program before blocking so that something can be written to the
STDIN buffer for the user program to read.

I have access to the user programs so could input some code into that,
which would take over the STDIN and STDOUT of the process, however i am
not sure how to do this.. and I am using windows

any ideas?
 
G

greg

watch out for security issues... there is no a sandbox in the latest
1.9 source ...

Can't you just write to the program's STDIN before it calls gets
anyways?

otherwise, you can monitor STDOUT for some kind of signal

alias_method :gets :__old_gets__
def gets
puts "WAITING_FOR_INPUT"
__old_gets__
end

I have not tried to do signal trapping, but instead of checking for a
special sequence on STDOUT you could try to send signals back and
forth.

This could be done by inserting a require statement, or by using a
launcher program.
Instead of creating a separate ruby process, you can run the other
programs from a launcher. In the launcher program just put
load #{user_program}
In the launcher program you can also modify $LOAD_PATH and ENV['PATH']
if you need.
One problem you may encounter with this approach is that the call stack
will have one more entry than expected- this could break things that do
not expect another level in caller(), or if the user program makes a
check like if $0 == __FILE__ before executing.
 

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

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,814
Latest member
SpicetreeDigital

Latest Threads

Top