PageRenderTime 47ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/support/popen.rb

https://github.com/elmer/babushka
Ruby | 38 lines | 32 code | 6 blank | 0 comment | 2 complexity | 21a7b6aa8cdd05e6427eaf3388cc8082 MD5 | raw file
  1. module Babushka
  2. module Open3
  3. def popen3 cmd, &block
  4. pipes = { :in => IO::pipe, :out => IO::pipe, :err => IO::pipe }
  5. near = { :in => pipes[:in][1], :out => pipes[:out][0], :err => pipes[:err][0] }
  6. far = { :in => pipes[:in][0], :out => pipes[:out][1], :err => pipes[:err][1] }
  7. pid = fork {
  8. reopen_pipe_for :read, pipes[:in], STDIN
  9. reopen_pipe_for :write, pipes[:out], STDOUT
  10. reopen_pipe_for :write, pipes[:err], STDERR
  11. exec *cmd
  12. }
  13. far.values.each &:close
  14. near.values.each {|p| p.sync = true }
  15. begin
  16. yield near[:in], near[:out], near[:err]
  17. Process.waitpid2(pid).last.exitstatus
  18. ensure
  19. near.values.each {|p| p.close unless p.closed? }
  20. end
  21. end
  22. private
  23. def reopen_pipe_for task, pipe, io
  24. to_close = pipe[task == :read ? 1 : 0]
  25. to_reopen = pipe[task == :read ? 0 : 1]
  26. to_close.close
  27. io.reopen to_reopen
  28. to_reopen.close
  29. end
  30. module_function :popen3, :reopen_pipe_for
  31. end
  32. end