From: Jan Koprowski Date: 2007-12-06T17:41:07+09:00 Subject: Re: Using popen with 0,1,2,3,4 streams On 4 Gru, 17:58, Tim Pease wrote: > On Dec 3, 2007 5:32 PM, Judson Lester wrote: > > > > > Jan, > > > You might look at popen3 in the standard library. I don't think it quite > > does what you need (since it returns an array if three pipes: stdin, stdout > > and stderr for the subprocess) but the code is short if a little arcane, and > > might point you in the right direction to figure this out. > > > Judson > > > On Dec 2, 2007 3:10 AM, Jan Koprowski wrote: > > > > Hi ! > > > > I try to run command system and get streams handlers to 0 (stdin), > > > 1(stdout), 2(stderr), 3(myOwnStdIn1), 4(myOwnStdIn2). I do something > > > like that in PHP by proc_open and table of pipes, but here I don't > > > know how I can get handlers to process streams. I know that this code > > > is bad but I think something like this: > > > > process =popen('command', 'w+'); > > > stdin = process.new(0, "w"); > > > stdout = process.new(1, "r"); > > > > etc... > > > > But new is a static method. What i should to do ? > > Also take a look at open4 and systemu. You can find both at the > codeforpeople project on RubyForge. They, too, will offer some good > insight on what you want to do, though neither does precisely what you > need. > > > > Blessings, > TwP U try to write something like this: # # To change this template, choose Tools | Templates # and open the template in the editor. require 'fcntl' require 'timeout' require 'thread' class Broker_process3 READ = 0 # Consts to explicite mark read WRITE = 1 # and write pipes @stdin @stdout @stderr def initialize end def self.run (command, params) pw, pr, pe, pl, pp = IO.pipe, IO.pipe, IO.pipe, IO.pipe, IO.pipe pl.last.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) pp.last.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) pid = fork { pw.last.close STDIN.reopen pw.first pw.first.close pr.first.close STDOUT.reopen pr.last pr.last.close pe.first.close STDERR.reopen pe.last pe.last.close pl.last.close pp.last.close STDOUT.sync = STDERR.sync = true exec(*command) } [pw.first, pr.last, pe.last, pl.first, pp.first].each{|fd| fd.close} pl.last.write("login"); // ERROR HERE pl.last.close pp.last.write("hasło"); pp.last.close pw.last.close out = pr.first.readlines pr.first.close pe.first.close puts out; end end but in // ERROR HERE I get: ./broker_process3.rb:48:in `write': Broken pipe (Errno::EPIPE) from ./broker_process3.rb:48:in `run' from /home/johny/NetBeansProjects/zhradmin/lib/main.rb:12