Class: Vagrant::Util::IO
- Inherits:
-
Object
- Object
- Vagrant::Util::IO
- Defined in:
- lib/vagrant/util/io.rb
Constant Summary collapse
- READ_CHUNK_SIZE =
The chunk size for reading from subprocess IO.
4096
Class Method Summary collapse
-
.read_until_block(io) ⇒ String
Reads data from an IO object while it can, returning the data it reads.
Class Method Details
.read_until_block(io) ⇒ String
Reads data from an IO object while it can, returning the data it reads. When it encounters a case when it can't read anymore, it returns the data.
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/vagrant/util/io.rb', line 14 def self.read_until_block(io) data = "" while true begin if Platform.windows? # Windows doesn't support non-blocking reads on # file descriptors or pipes so we have to get # a bit more creative. # Check if data is actually ready on this IO device. # We have to do this since `readpartial` will actually block # until data is available, which can cause blocking forever # in some cases. results = ::IO.select([io], nil, nil, 1.0) break if !results || results[0].empty? # Read! data << io.readpartial(READ_CHUNK_SIZE).encode("UTF-8", Encoding.default_external) else # Do a simple non-blocking read on the IO object data << io.read_nonblock(READ_CHUNK_SIZE) end rescue Exception => e # The catch-all rescue here is to support multiple Ruby versions, # since we use some Ruby 1.9 specific exceptions. breakable = false if e.is_a?(EOFError) # An `EOFError` means this IO object is done! breakable = true elsif defined?(::IO::WaitReadable) && e.is_a?(::IO::WaitReadable) # IO::WaitReadable is only available on Ruby 1.9+ # An IO::WaitReadable means there may be more IO but this # IO object is not ready to be read from yet. No problem, # we read as much as we can, so we break. breakable = true elsif e.is_a?(Errno::EAGAIN) # Otherwise, we just look for the EAGAIN error which should be # all that IO::WaitReadable does in Ruby 1.9. breakable = true end # Break out if we're supposed to. Otherwise re-raise the error # because it is a real problem. break if breakable raise end end data end |