Inconsistent returns from piped open

Discussion in 'Perl Misc' started by fishfry, Feb 17, 2006.

  1. fishfry

    fishfry Guest

    #!/usr/bin/perl
    use strict;

    # 1. The open() call returns false.
    my $x = open(XX, "| junk");
    print "x = $x\n";

    # 2. The open() call returns true.
    my $y = open(YY, "| junk > foozle");
    print "y = $y\n";


    When the above code is run (on a Unix system), $x has a value of 0, and
    $y has a nonzero value.

    junk is a non-existent executable. It's correct for the open() to fail,
    since the process creation failed.

    However, adding an output redirect causes open() to return a nonzero
    value.

    This is causing me a problem, since I need to know if the process
    creation failed.

    Any explanation for why the second example returns true? And perhaps an
    alternate way to do the same thing so I can find out if the process
    creation fails?
     
    fishfry, Feb 17, 2006
    #1
    1. Advertising

  2. fishfry

    Guest

    fishfry <> wrote:
    > #!/usr/bin/perl
    > use strict;
    >
    > # 1. The open() call returns false.
    > my $x = open(XX, "| junk");
    > print "x = $x\n";


    Perl tries to execute junk. It fails.

    > # 2. The open() call returns true.
    > my $y = open(YY, "| junk > foozle");
    > print "y = $y\n";


    This contains shell metacharacters, so perl tries to start
    up a shell. It succeeds, and returns the pid of the shell it
    started. The shell turns around and tries to execute junk, and of
    course it fails. But the shell's failure is not perl's failure.

    >
    > When the above code is run (on a Unix system), $x has a value of 0, and
    > $y has a nonzero value.
    >
    > junk is a non-existent executable. It's correct for the open() to fail,
    > since the process creation failed.
    >
    > However, adding an output redirect causes open() to return a nonzero
    > value.
    >
    > This is causing me a problem, since I need to know if the process
    > creation failed.


    You do know that. It is just that that is not what you really want
    to know.

    >
    > Any explanation for why the second example returns true? And perhaps an
    > alternate way to do the same thing so I can find out if the process
    > creation fails?


    You will be notified of this problem via a SIGPIPE or by the close of
    the piped filehandle failing (plus by the shell's whining on STDERR).
    If that isn't sufficient, then I don't know--maybe perldoc perlipc has
    something useful to say on the matter.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
     
    , Feb 17, 2006
    #2
    1. Advertising

  3. fishfry

    fishfry Guest

    In article <20060216233124.621$>,
    wrote:

    > fishfry <> wrote:
    > > #!/usr/bin/perl
    > > use strict;
    > >
    > > # 1. The open() call returns false.
    > > my $x = open(XX, "| junk");
    > > print "x = $x\n";

    >
    > Perl tries to execute junk. It fails.
    >
    > > # 2. The open() call returns true.
    > > my $y = open(YY, "| junk > foozle");
    > > print "y = $y\n";

    >
    > This contains shell metacharacters, so perl tries to start
    > up a shell. It succeeds, and returns the pid of the shell it
    > started. The shell turns around and tries to execute junk, and of
    > course it fails. But the shell's failure is not perl's failure.
    >
    > >


    Very sensible explanation, thanks. Didn't realize that the output
    redirect caused an intervening shell to be created, whereas the first
    case didn't. I think I'm going to have to explicitly fork/exec to get
    control of the process creation.
     
    fishfry, Feb 17, 2006
    #3
  4. fishfry wrote:
    > In article <20060216233124.621$>,
    > wrote:
    >
    >> fishfry <> wrote:
    >>> #!/usr/bin/perl
    >>> use strict;
    >>>
    >>> # 1. The open() call returns false.
    >>> my $x = open(XX, "| junk");
    >>> print "x = $x\n";

    >> Perl tries to execute junk. It fails.
    >>
    >>> # 2. The open() call returns true.
    >>> my $y = open(YY, "| junk > foozle");
    >>> print "y = $y\n";

    >> This contains shell metacharacters, so perl tries to start
    >> up a shell. It succeeds, and returns the pid of the shell it
    >> started. The shell turns around and tries to execute junk, and of
    >> course it fails. But the shell's failure is not perl's failure.
    >>

    >
    > Very sensible explanation, thanks. Didn't realize that the output
    > redirect caused an intervening shell to be created, whereas the first
    > case didn't. I think I'm going to have to explicitly fork/exec to get
    > control of the process creation.


    There are some caveats - perldoc IPC::Open3 - but alternatively you may
    be able to use something simpler:

    use IPC::Open3;

    my $pid = open3( \*W, \*R, \*E ,'./junk > froozle');
    die "open fork failed: $!" unless $pid;
    die "open error: ",<E> unless eof E;


    --
    Charles DeRykus
     
    Charles DeRykus, Feb 17, 2006
    #4
  5. fishfry

    Csaba Guest

    wrote in news:20060216233124.621$:

    > fishfry <> wrote:
    >> #!/usr/bin/perl
    >> use strict;
    >>
    >> # 1. The open() call returns false.
    >> my $x = open(XX, "| junk");
    >> print "x = $x\n";

    >
    > Perl tries to execute junk. It fails.
    >
    >> # 2. The open() call returns true.
    >> my $y = open(YY, "| junk > foozle");
    >> print "y = $y\n";

    >
    > This contains shell metacharacters, so perl tries to start
    > up a shell. It succeeds, and returns the pid of the shell it
    > started. The shell turns around and tries to execute junk, and of
    > course it fails. But the shell's failure is not perl's failure.
    >

    [snip]
    >>
    >> Any explanation for why the second example returns true? And perhaps an
    >> alternate way to do the same thing so I can find out if the process
    >> creation fails?

    >
    > You will be notified of this problem via a SIGPIPE or by the close of
    > the piped filehandle failing (plus by the shell's whining on STDERR).
    > If that isn't sufficient, then I don't know--maybe perldoc perlipc has
    > something useful to say on the matter.
    >


    Maybe that you absolutely, positively have to check the return value of
    close() when using open() for IPC.


    --
    Life is complex, with real and imaginary parts.
     
    Csaba, Feb 18, 2006
    #5
    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. Andrew Tucker

    Piped stream help.

    Andrew Tucker, Oct 5, 2003, in forum: Java
    Replies:
    3
    Views:
    559
    Harald Hein
    Oct 6, 2003
  2. Todd
    Replies:
    18
    Views:
    1,448
    Arne Vajhøj
    Apr 14, 2010
  3. Rohit

    Taint mode piped open problem

    Rohit, Jan 26, 2008, in forum: Perl Misc
    Replies:
    4
    Views:
    150
    Rohit
    Jan 27, 2008
  4. John Kelly

    piped open and shell metacharacters

    John Kelly, Jul 30, 2010, in forum: Perl Misc
    Replies:
    22
    Views:
    400
    Ilya Zakharevich
    Aug 3, 2010
  5. Glenn
    Replies:
    5
    Views:
    277
    C.DeRykus
    Jan 3, 2011
Loading...

Share This Page