multi_pipe_extensions.rb 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. # frozen_string_literal: false
  2. # Fix adapted from https://github.com/thoughtbot/terrapin/pull/5
  3. module Terrapin
  4. module MultiPipeExtensions
  5. def read
  6. read_streams(@stdout_in, @stderr_in)
  7. end
  8. def close_read
  9. begin
  10. @stdout_in.close
  11. rescue IOError
  12. # Do nothing
  13. end
  14. begin
  15. @stderr_in.close
  16. rescue IOError
  17. # Do nothing
  18. end
  19. end
  20. def read_streams(output, error)
  21. @stdout_output = ''
  22. @stderr_output = ''
  23. read_fds = [output, error]
  24. until read_fds.empty?
  25. to_read, = IO.select(read_fds)
  26. if to_read.include?(output)
  27. @stdout_output << read_stream(output)
  28. read_fds.delete(output) if output.closed?
  29. end
  30. if to_read.include?(error)
  31. @stderr_output << read_stream(error)
  32. read_fds.delete(error) if error.closed?
  33. end
  34. end
  35. end
  36. def read_stream(io)
  37. result = ''
  38. begin
  39. while (partial_result = io.read_nonblock(8192))
  40. result << partial_result
  41. end
  42. rescue EOFError, Errno::EPIPE
  43. io.close
  44. rescue Errno::EINTR, Errno::EWOULDBLOCK, Errno::EAGAIN
  45. # Do nothing
  46. end
  47. result
  48. end
  49. end
  50. end
  51. Terrapin::CommandLine::MultiPipe.prepend(Terrapin::MultiPipeExtensions)