summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
6bce751)
When system(3perl) fails due to syscall error, it sets only $!. When
it succeeds it sets only $? and sometimes trashes $!. Conversely,
close of a popened filehandle always sets both in all cases.
Document this in a comment.
So when using system and relying on $?/$! (rather than looking at
system's return value), such as when about to use failedcmd, it's
necessary to initialise $? to -1.
Fix the three call sites where system might be followed by failedcmd
but this wasn't done.
+ # Expects $!,$? as set by close - see below.
+ # To use with system(), set $?=-1 first.
+ #
+ # Actual behaviour of perl operations:
+ # success $!==0 $?==0 close of piped open
+ # program failed $!==0 $? >0 close of piped open
+ # syscall failure $! >0 $?=-1 close of piped open
+ # failure $! >0 unchanged close of something else
+ # success trashed $?==0 system
+ # program failed trashed $? >0 system
+ # syscall failure $! >0 unchanged system
{ local ($!); printcmd \*STDERR, _us().": failed command:", @_ or die $!; };
{ local ($!); printcmd \*STDERR, _us().": failed command:", @_ or die $!; };
fail "failed to fork/exec: $!";
} elsif ($?) {
fail "subprocess ".waitstatusmsg();
fail "failed to fork/exec: $!";
} elsif ($?) {
fail "subprocess ".waitstatusmsg();
sub runcmd {
debugcmd "+",@_;
sub runcmd {
debugcmd "+",@_;
failedcmd @_ if system @_;
}
failedcmd @_ if system @_;
}
my @cmd = (@git, qw(diff --quiet HEAD));
debugcmd "+",@cmd;
my @cmd = (@git, qw(diff --quiet HEAD));
debugcmd "+",@cmd;
- $!=0; $?=0; system @cmd;
- return if !$! && !$?;
- if (!$! && $?==256) {
+ $!=0; $?=-1; system @cmd;
+ return if !$?;
+ if ($?==256) {
fail "working tree is dirty (does not match HEAD)";
} else {
failedcmd @cmd;
fail "working tree is dirty (does not match HEAD)";
} else {
failedcmd @cmd;
my $diffopt = $debuglevel>0 ? '--exit-code' : '--quiet';
my @diffcmd = (@git, qw(diff), $diffopt, $tree);
debugcmd "+",@diffcmd;
my $diffopt = $debuglevel>0 ? '--exit-code' : '--quiet';
my @diffcmd = (@git, qw(diff), $diffopt, $tree);
debugcmd "+",@diffcmd;
my $r = system @diffcmd;
if ($r) {
if ($r==256) {
my $r = system @diffcmd;
if ($r) {
if ($r==256) {