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

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,

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 <Jan.Koprowski@gmail.com> 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.

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&gt;

Blessings,
TwP

···

On Dec 3, 2007 5:32 PM, Judson Lester <nyarly@gmail.com> 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 <Jan.Koprowski@gmail.com> 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 ?
>

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 !

···

On 4 Gru, 17:58, Tim Pease <tim.pe...@gmail.com> wrote:

On Dec 3, 2007 5:32 PM, Judson Lester <nya...@gmail.com> 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 <Jan.Koprow...@gmail.com> 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&gt;

Blessings,
TwP

U try to write something like this:

···

On 4 Gru, 17:58, Tim Pease <tim.pe...@gmail.com> wrote:

On Dec 3, 2007 5:32 PM, Judson Lester <nya...@gmail.com> 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 <Jan.Koprow...@gmail.com> 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&gt;

Blessings,
TwP

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

U try to write something like this:

···

On 4 Gru, 17:58, Tim Pease <tim.pe...@gmail.com> wrote:

On Dec 3, 2007 5:32 PM, Judson Lester <nya...@gmail.com> 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 <Jan.Koprow...@gmail.com> 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&gt;

Blessings,
TwP

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