0

I'm trying to open a Ruby script that prompts for stuff with popen3, for testing purposes.

I need to be able to type into the STDIN of the proccess and inspect the outputs. So far I have this:

require 'open3'
def run(executable, opts = {})
  Signal.trap('CLD') do
    puts 'STDIN:', @stdout.readlines
    # @stderr.rewind
    puts 'STDERR:', @stderr.readlines
    # got EOF, trying to rewind gives me 'Errno::ESPIPE: Illegal seek'

    [@stdin, @stdout, @stderr].each &:close
  end

  @stdin, @stdout, @stderr, @thread = Open3.popen3(executable)
  @status = @thread.value
end

Have been trying for days, my brain is melting.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
ichigolas
  • 7,595
  • 27
  • 50
  • I advise you to do this only as a last effort - if possible, use the same library your software is using instead of lunch the other process and try to deal with it. – fotanus Oct 07 '13 at 18:03
  • Yeah, it proved to be really hard (and time consuming). However, I'll answer if I can. – ichigolas Oct 07 '13 at 18:09
  • readlines "blocks" until it reads all input, so...probably use something else... – rogerdpack Dec 02 '13 at 22:42

1 Answers1

0

The things you are allowed to do in a signal handler are very limited. For example, you are not allowed to do I/O in a signal handler. Signal handlers are notoriously easy to do wrong.

What do you think about using Open3.capture*? It avoids all blocks/race conditions when reading from stdout and stderr at the same time. Besides, it allows you to pass data for stdin. Use the keyword argument :stdin_data!

hagello
  • 2,843
  • 2
  • 27
  • 37