develooper Front page | perl.perl5.porters | Postings from August 2013

Re: runperl() exit oddity

Thread Previous | Thread Next
Nicholas Clark
August 8, 2013 07:51
Re: runperl() exit oddity
Message ID:
On Wed, Aug 07, 2013 at 12:50:55PM -0500, Craig A. Berry wrote:

> > $ sh -c 'pstree -p $$ | cat'
> > sh(13261)-+-cat(13263)
> >           `-pstree(13262)
> > $ ksh -c 'pstree -p $$ | cat'
> > cat(13349)---pstree(13350)

> The root cause of the problem on VMS is that command-line redirection
> is done by Perl and not by the shell.  Tony's addition of the stdin
> parameter to runperl gives us the equivalent of:
> $ perl -e "exit 2;" | perl -e "exit 0;"
> %NONAME-E-NOMSG, Message number 00000002
> $ show symbol $status
>   $STATUS == "%X00000002"
> The Perl process with an exit value of 0 is a child of the one that
> has an exit value of 2 so the final status we see in runperl is the
> exit value of the parent, not of the child.  But the child is actually
> the test program whose exit value we're interested in and we don't get
> it this way.
> I *think* on *nix both perl invocations are subprocesses of the shell,
> or in any case $? is 0 when all is said and done, i.e., the exit
> status from the second Perl invocation.

Well, it turns out to differ between /bin/sh and /bin/ksh (which was the
cause of the AIX bug), but whether it's (ksh) child | parent
or (sh) child | child, either way the exit status of the pipeline is that
of the *last* command.

(This has turned out to be dangerous in the *nix Makefile. There were one
or two rules which were

    some_command ... | sort >output

and if some_command failed, it wasn't noticed, because make picked up the
exit status of the sort, which was 0. I refactored things to avoid the need
for pipelines.)

This sort of means that the VMS pipeline setup is the wrong way round.
At least, it's the wrong way round if it wanted to be consistent with Unix.
Even if it's possible to change, I doubt that it would be a good idea.

> I have a working patch that fixes it by doing a piped open and writing
> to the pipe that provides the stdin of the child, then capturing the
> child's exit and passing it along.  It's ugly and makes the VMS code
> in t/ even more different than it already is.  I've been
> sitting on it for a bit hoping to think of something better, but it
> looks like you've now done that. If /dev/null has portability problems
> on Win32, simply lifting the platform-specific code from
> File::Spec::dev_null should provide the solution in a very small
> amount of additional code.

Well, I sort of worked round it by not using a pipeline. But it achieves
the end goal.

Nicholas Clark

Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About