Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IO.select broken with output stream from Open3.popen3 #1783

Closed
mhoran opened this issue Jul 3, 2014 · 3 comments
Closed

IO.select broken with output stream from Open3.popen3 #1783

mhoran opened this issue Jul 3, 2014 · 3 comments
Milestone

Comments

@mhoran
Copy link

mhoran commented Jul 3, 2014

IO.select does not wait for data to be readable, nor does it respect the timeout when reading from an output stream provided by `Open3.popen3'.

require 'open3'
path = "test.txt"
File.open(path, 'w') { |f| f.write('Z' * ARGV[0].to_i) }
STDOUT.write "Starting..."
Open3.popen3('cat', path) do |stdin, stdout, stderr|
  stdin.close
  while !stdout.eof? && IO.select([stdout], nil, nil, 1)
    stdout.read_nonblock 1
  end
end

This results in the following error on my Linux box, and Travis CI:

ruby -Xerrno.backtrace=true test.rb 1024
Starting...IO::EAGAINWaitReadable: Resource temporarily unavailable - 
  read_nonblock at org/jruby/RubyIO.java:2856
         (root) at test.rb:8
         popen3 at org/jruby/RubyIO.java:4433
         popen3 at /home/mhoran/.rbenv/versions/jruby-1.7.10/lib/ruby/1.9/open3.rb:74
         (root) at test.rb:5

If I first pipe the output of stderr to the write end of an IO.pipe, the program works as expected:

require 'open3'
path = "test.txt"
File.open(path, 'w') { |f| f.write('Z' * ARGV[0].to_i) }
STDOUT.write "Starting..."
Open3.popen3('cat', path) do |stdin, stdout, stderr|
  stdin.close
  read, write = IO.pipe
  Thread.new { IO.copy_stream(stdout, write); write.close }
  while !read.eof? && IO.select([read], nil, nil, 1)
    read.read_nonblock 1
  end
end

In actual usage, I'm just using IO.select to determine if there's content ready to be read, along with a timeout to ensure that the application quits if data is not available. However, there seems to be a fundamental issue with output forwarding given IO.pipe works as expected.

@mhoran
Copy link
Author

mhoran commented Jul 3, 2014

See thoughtbot/capybara-webkit#651 for an example of actual usage, additional discussion, and failing tests.

@gucki
Copy link

gucki commented Sep 11, 2014

Was just hit by this bug as well. Is there any workaround? All I tried so far failed, because other methods like capture3 etc. are also buggy. Also IO#read_nonblock always retuns Errno::EWOULDBLOCK, even if there's data to read and even if the socket is already closed.

@kares
Copy link
Member

kares commented Jun 22, 2017

works fine in 9K (checked >= 9.1.7.0), JRuby 1.7.x is EOL ... likely won't fix there.

@kares kares closed this as completed Jun 22, 2017
@kares kares added this to the Won't Fix milestone Jun 22, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants