summaryrefslogtreecommitdiff
path: root/Debian/Dgit.pm
diff options
context:
space:
mode:
authorIan Jackson <ijackson@chiark.greenend.org.uk>2016-07-16 23:10:27 +0100
committerIan Jackson <ijackson@chiark.greenend.org.uk>2016-07-17 13:46:14 +0100
commit0658281163715a24c940509ebb8b0a7493e33787 (patch)
tree083e71018282942a6968dfab55af98e96467449f /Debian/Dgit.pm
parent6bce7517ee43b52e0a23c74dec8f5d0bcb7d0668 (diff)
Subprocess error handling: Initialise $? to -1
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.
Diffstat (limited to 'Debian/Dgit.pm')
-rw-r--r--Debian/Dgit.pm13
1 files changed, 12 insertions, 1 deletions
diff --git a/Debian/Dgit.pm b/Debian/Dgit.pm
index 2555812..aa0c5a3 100644
--- a/Debian/Dgit.pm
+++ b/Debian/Dgit.pm
@@ -186,8 +186,19 @@ sub waitstatusmsg () {
}
sub failedcmd {
+ # 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 $!; };
- if ($!) {
+ if ($? < 0) {
fail "failed to fork/exec: $!";
} elsif ($?) {
fail "subprocess ".waitstatusmsg();