Using popen with 0,1,2,3,4 streams

Discussion in 'Ruby' started by Jan Koprowski, Dec 2, 2007.

  1. 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 ?
     
    Jan Koprowski, Dec 2, 2007
    #1
    1. Advertising

  2. Note: parts of this message were removed by the gateway to make it a legal Usenet post.

    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 ?
    >
    >



    --
    Your subnet is currently 169.254.0.0/16. You are likely to be eaten by a
    grue.
     
    Judson Lester, Dec 4, 2007
    #2
    1. Advertising

  3. Jan Koprowski

    Tim Pease Guest

    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.

    <http://rubyforge.org/projects/codeforpeople>

    Blessings,
    TwP
     
    Tim Pease, Dec 4, 2007
    #3
  4. 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.
    >
    > <http://rubyforge.org/projects/codeforpeople>
    >
    > Blessings,
    > TwP


    Thank You for respond. I know that I can use only 3 pipes. But I think
    I can look for open4 and try to write something similar. Thanks !
     
    Jan Koprowski, Dec 6, 2007
    #4
  5. 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.
    >
    > <http://rubyforge.org/projects/codeforpeople>
    >
    > 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
     
    Jan Koprowski, Dec 6, 2007
    #5
  6. 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.
    >
    > <http://rubyforge.org/projects/codeforpeople>
    >
    > 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
     
    Jan Koprowski, Dec 6, 2007
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    0
    Views:
    387
  2. Saulius

    Using file streams in DLL

    Saulius, Aug 16, 2003, in forum: C++
    Replies:
    3
    Views:
    483
    Gianni Mariani
    Aug 17, 2003
  3. Till Crueger

    Using Polymortphism with streams

    Till Crueger, May 10, 2004, in forum: C++
    Replies:
    3
    Views:
    319
    Jerry Coffin
    May 11, 2004
  4. ferran
    Replies:
    5
    Views:
    516
    John Harrison
    Sep 3, 2004
  5. File.popen/IO.popen

    , May 20, 2006, in forum: Ruby
    Replies:
    1
    Views:
    249
    Robert Klemme
    May 20, 2006
Loading...

Share This Page