From: Robert Klemme Date: 2003-05-20T01:05:29+09:00 Subject: Re: select strange behavier "Simon Strandgaard" <0bz63fz3m1qt3001@sneakemail.com> schrieb im Newsbeitrag news:pan.2003.05.19.01.12.43.69731@sneakemail.com... > replacement for 'Kernel#system' which captures all output. > This is the *almost* final version.. this may have others interest :-) > Warning: 'stdin' is not yet supported. > > Suggestions for improvements is welcome. Some minor (see lines without leading "> ") and a question: did you check that this works on windows, too? I recently ran into a problem with pipes on windows. Apparently they can't be used for multiplexing... > def system(command, *args) > #todo: stdin > r1, w1 = IO.pipe # stdout > r2, w2 = IO.pipe # stderr thread = Thread.new(r1,w1,r2,w2) do |r1,w1,r2,w2| fdes = [r1, r2] > loop do > #puts "waiting" > res = select(fdes, nil, nil, nil)[0] > #p res > if res.include?(r1) > #puts "r1" > unless r1.eof > Redir.instance.write_out r1.read > else > #puts "kill r1" > fdes.delete r1 > thread.kill if fdes == [] > end > end > if res.include?(r2) > #puts "r2" > unless r2.eof > Redir.instance.write_error r2.read > else > #puts "kill r2" > fdes.delete r2 > thread.kill if fdes == [] > end > end > end > end > pid = Kernel.fork do > r1.close; r2.close > $defout.reopen(w1); $stdout.reopen(w1); $stderr.reopen(w2) > exec(command, *args) > # todo: should I care closing w1+w2 correctly? > end > w1.close; w2.close > status = Process.waitpid2(pid, 0) > # wait until EOF on both pipes (r1+r2) > thread.join > r1.close; r2.close > > #$? = status[1] # not possible (status[1] == 0) > end And I'd try to put the "close" calls into "ensure" blocks where possible. Regards robert