mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4572 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
		
			
				
	
	
		
			70 lines
		
	
	
	
		
			1.2 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			70 lines
		
	
	
	
		
			1.2 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
# open3.rb: Spawn a program like popen, but with stderr, too. You might also
 | 
						|
# want to use this if you want to bypass the shell. (By passing multiple args,
 | 
						|
# which IO#popen does not allow)
 | 
						|
#
 | 
						|
# Usage:
 | 
						|
#	require "open3"
 | 
						|
#
 | 
						|
#      stdin, stdout, stderr = Open3.popen3('nroff -man')
 | 
						|
#  or
 | 
						|
#	include Open3
 | 
						|
#      stdin, stdout, stderr = popen3('nroff -man')
 | 
						|
 | 
						|
module Open3
 | 
						|
  #[stdin, stdout, stderr] = popen3(command);
 | 
						|
  def popen3(*cmd)
 | 
						|
    pw = IO::pipe   # pipe[0] for read, pipe[1] for write
 | 
						|
    pr = IO::pipe
 | 
						|
    pe = IO::pipe
 | 
						|
 | 
						|
    pid = fork{
 | 
						|
      # child
 | 
						|
      fork{
 | 
						|
	# grandchild
 | 
						|
	pw[1].close
 | 
						|
	STDIN.reopen(pw[0])
 | 
						|
	pw[0].close
 | 
						|
 | 
						|
	pr[0].close
 | 
						|
	STDOUT.reopen(pr[1])
 | 
						|
	pr[1].close
 | 
						|
 | 
						|
	pe[0].close
 | 
						|
	STDERR.reopen(pe[1])
 | 
						|
	pe[1].close
 | 
						|
 | 
						|
	exec(*cmd)
 | 
						|
      }
 | 
						|
      exit!
 | 
						|
    }
 | 
						|
 | 
						|
    pw[0].close
 | 
						|
    pr[1].close
 | 
						|
    pe[1].close
 | 
						|
    Process.waitpid(pid)
 | 
						|
    pi = [pw[1], pr[0], pe[0]]
 | 
						|
    pw[1].sync = true
 | 
						|
    if defined? yield
 | 
						|
      begin
 | 
						|
	return yield(*pi)
 | 
						|
      ensure
 | 
						|
	pi.each{|p| p.close unless p.closed?}
 | 
						|
      end
 | 
						|
    end
 | 
						|
    pi
 | 
						|
  end
 | 
						|
  module_function :popen3
 | 
						|
end
 | 
						|
 | 
						|
if $0 == __FILE__
 | 
						|
  a = Open3.popen3("nroff -man")
 | 
						|
  Thread.start do
 | 
						|
    while line = gets
 | 
						|
      a[0].print line
 | 
						|
    end
 | 
						|
    a[0].close
 | 
						|
  end
 | 
						|
  while line = a[1].gets
 | 
						|
    print ":", line
 | 
						|
  end
 | 
						|
end
 |