PageRenderTime 54ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/Chapter 6/MockChat/lib/ruby/1.8/open3.rb

https://github.com/panesofglass/ironrubyinaction
Ruby | 101 lines | 49 code | 8 blank | 44 comment | 5 complexity | 80a98a19b072ba9a9e3860fae3db2b23 MD5 | raw file
  1. #
  2. # = open3.rb: Popen, but with stderr, too
  3. #
  4. # Author:: Yukihiro Matsumoto
  5. # Documentation:: Konrad Meyer
  6. #
  7. # Open3 gives you access to stdin, stdout, and stderr when running other
  8. # programs.
  9. #
  10. #
  11. # Open3 grants you access to stdin, stdout, and stderr when running another
  12. # program. Example:
  13. #
  14. # require "open3"
  15. # include Open3
  16. #
  17. # stdin, stdout, stderr = popen3('nroff -man')
  18. #
  19. # Open3.popen3 can also take a block which will receive stdin, stdout and
  20. # stderr as parameters. This ensures stdin, stdout and stderr are closed
  21. # once the block exits. Example:
  22. #
  23. # require "open3"
  24. #
  25. # Open3.popen3('nroff -man') { |stdin, stdout, stderr| ... }
  26. #
  27. module Open3
  28. #
  29. # Open stdin, stdout, and stderr streams and start external executable.
  30. # Non-block form:
  31. #
  32. # require 'open3'
  33. #
  34. # [stdin, stdout, stderr] = Open3.popen3(cmd)
  35. #
  36. # Block form:
  37. #
  38. # require 'open3'
  39. #
  40. # Open3.popen3(cmd) { |stdin, stdout, stderr| ... }
  41. #
  42. # The parameter +cmd+ is passed directly to Kernel#exec.
  43. #
  44. def popen3(*cmd)
  45. pw = IO::pipe # pipe[0] for read, pipe[1] for write
  46. pr = IO::pipe
  47. pe = IO::pipe
  48. pid = fork{
  49. # child
  50. fork{
  51. # grandchild
  52. pw[1].close
  53. STDIN.reopen(pw[0])
  54. pw[0].close
  55. pr[0].close
  56. STDOUT.reopen(pr[1])
  57. pr[1].close
  58. pe[0].close
  59. STDERR.reopen(pe[1])
  60. pe[1].close
  61. exec(*cmd)
  62. }
  63. exit!(0)
  64. }
  65. pw[0].close
  66. pr[1].close
  67. pe[1].close
  68. Process.waitpid(pid)
  69. pi = [pw[1], pr[0], pe[0]]
  70. pw[1].sync = true
  71. if defined? yield
  72. begin
  73. return yield(*pi)
  74. ensure
  75. pi.each{|p| p.close unless p.closed?}
  76. end
  77. end
  78. pi
  79. end
  80. module_function :popen3
  81. end
  82. if $0 == __FILE__
  83. a = Open3.popen3("nroff -man")
  84. Thread.start do
  85. while line = gets
  86. a[0].print line
  87. end
  88. a[0].close
  89. end
  90. while line = a[1].gets
  91. print ":", line
  92. end
  93. end