On Thu, Feb 18, 2010 at 10:57:57PM +0100, Rafael Garcia-Suarez wrote:
> On 18 February 2010 17:43, none via RT <perlbug-followup@perl.org> wrote:
> > When the fork of a system() fails, the return value of system() is
> > (correctly) -1, but the value of $? is (arguably incorrectly) still 0.
>
> $? is supposed to return the status from the child process, which in
> that case couldn't be created. So $? can't be trusted, and I'd suggest
> this is a doc bug.
The system() docs since at least 5.000 have been deeply ambiguous about
the relationship between $? and the return value of system(). Since
5.005_03 we've been promising "You can check all the failure possibilities
by inspecting C<$?>", so I suspect there's a fair chunk of code out there
that does
system(...):
various_tests_for_failure($?);
and that all miss the rare but possible case that the fork itself fails.
Note that we already fake up the value of $? under some circumstances:
if the fork succeeds but the exec fails, we pass the errno of the exec in
a pipe back to the parent, then set $? to - 1 and $! to that errno.
I think system should set $? to -1 on fork failure because:
1) it makes things easier; it is no longer the case that $? and system()
always have the same value *except* for a few rare circumstances
2) We make a lot of code already out there that relied on our ambiguous
documentation actual trap some error conditions that they currently
silently miss.
3) I for one was very confused by the perlmonks thread and look me along
while to think of checking for system() return as well as $?
Anyway for info, the history of the system() documentation in perlfunc, ad
regards return value and $?, is roughly as follows:
5.000 has this basic entry:
The return value is the exit status of the program as
returned by the wait() call. To get the actual exit value divide by
256.
5.005_03: added usage examples:
@args = ("command", "arg1", "arg2");
system(@args) == 0
or die "system @args failed: $?"
You can check all the failure possibilities by inspecting
C<$?> like this:
$exit_value = $? >> 8;
$signal_num = $? & 127;
$dumped_core = $? & 128;
5.6.0 added:
Return value of -1 indicates a failure to start the program (inspect $!
for the reason).
5.10.0 amended return value description and updated the $? processing
example:
Return value of -1 indicates a failure to start the program or an
error of the wait(2) system call (inspect $! for the reason).
if ($? == -1) {
print "failed to execute: $!\n";
}
elsif ($? & 127) {
printf "child died with signal %d, %s coredump\n",
($? & 127), ($? & 128) ? 'with' : 'without';
}
else {
printf "child exited with value %d\n", $? >> 8;
}
--
Any [programming] language that doesn't occasionally surprise the
novice will pay for it by continually surprising the expert.
-- Larry Wall