Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Perl Misc (http://www.velocityreviews.com/forums/f67-perl-misc.html)
-   -   Inconsistent returns from piped open (http://www.velocityreviews.com/forums/t896644-inconsistent-returns-from-piped-open.html)

fishfry 02-17-2006 04:10 AM

Inconsistent returns from piped open
 
#!/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?

xhoster@gmail.com 02-17-2006 04:30 AM

Re: Inconsistent returns from piped open
 
fishfry <fishfry@your-mailbox.com> 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

fishfry 02-17-2006 05:08 AM

Re: Inconsistent returns from piped open
 
In article <20060216233124.621$mN@newsreader.com>, xhoster@gmail.com
wrote:

> fishfry <fishfry@your-mailbox.com> 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.

Charles DeRykus 02-17-2006 10:40 PM

Re: Inconsistent returns from piped open
 
fishfry wrote:
> In article <20060216233124.621$mN@newsreader.com>, xhoster@gmail.com
> wrote:
>
>> fishfry <fishfry@your-mailbox.com> 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

Csaba 02-18-2006 02:01 AM

Re: Inconsistent returns from piped open
 
xhoster@gmail.com wrote in news:20060216233124.621$mN@newsreader.com:

> fishfry <fishfry@your-mailbox.com> 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.


All times are GMT. The time now is 08:31 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.