From: nobu.nokada@... Date: 2003-01-24T10:31:23+09:00 Subject: Re: exit status, stderr and stdout --Multipart_Fri_Jan_24_10:31:22_2003-1 Content-Type: text/plain; charset=US-ASCII Hi, At Fri, 24 Jan 2003 08:33:11 +0900, Daniel Bretoi wrote: > In perl, I was able to do this, > > my $pid = open3($wtr, $rdr, $err, "ls ---"); > waitpid($pid,WNOHANG); > warn $? >> 8; > > however, looking at the code for open3.rb it doesn't seem possible to > capture the pid (infact, it seems to be completely discarded). Sorry, I've forgotten that I'm using modified version of open3.rb, due to get rid of that very problem. --Multipart_Fri_Jan_24_10:31:22_2003-1 Content-Type: text/x-ruby; charset=US-ASCII Content-Disposition: attachment; filename="open3.rb" Content-Transfer-Encoding: 7bit # Usage: # require "open3" # # in, out, err = Open3.popen3('nroff -man') # or # include Open3 # in, out, err = popen3('nroff -man') # module Open3 class Process < Module def initialize(cmd, error = true) super(&nil) writer = IO::pipe # pipe[0] for read, pipe[1] for write reader = IO::pipe error = IO::pipe if error pid = fork do # child writer[1].close STDIN.reopen(writer[0]) writer[0].close reader[0].close STDOUT.reopen(reader[1]) reader[1].close if error error[0].close STDERR.reopen(error[1]) error[1].close end exec(*cmd) exit! end writer[0].close reader[1].close error[1].close if error cmd = self writer, reader, error = writer[1], reader[0], error[0] define_method(:pid) {|| pid} define_method(:command) {|| cmd} define_method(:writer) {|| writer} define_method(:reader) {|| reader} define_method(:error) {|| error} extend(self) pi = [reader, writer] pi << error if error pi.each {|p| p.extend(self)} if defined? yield begin return yield(*pi) ensure pi.each {|p| p.close unless p.closed?} begin Process.waitpid(pid); rescue Errno::ECHILD; end end end ObjectSpace.define_finalizer(self, self.class.finalizer(pid)) end def wait status = Process.waitpid(@pid) ObjectSpace.undefine_finalizer(self) status rescue Errno::ECHILD nil end def self.finalizer(pid) proc {begin Process.waitpid(pid); rescue Errno::ECHILD; end} end end #[stdin, stdout, stderr] = popen3(command); def popen3(*cmd) p = Process.new(cmd) [p.writer, p.reader, p.error] end module_function :popen3 end if $0 == __FILE__ def test a = Open3.popen3("nroff -man") Thread.start do while line = gets a[0].print line end a[0].close end pid = a[1].pid system("ps", $$.to_s, pid.to_s) while line = a[1].gets print ":", line end a.clear a = nil pid end pid = test system("ps", $$.to_s, pid.to_s) GC.start system("ps", $$.to_s, pid.to_s) end --Multipart_Fri_Jan_24_10:31:22_2003-1 Content-Type: text/plain; charset=US-ASCII -- Nobu Nakada --Multipart_Fri_Jan_24_10:31:22_2003-1--