From 0658281163715a24c940509ebb8b0a7493e33787 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sat, 16 Jul 2016 23:10:27 +0100 Subject: 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. --- Debian/Dgit.pm | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'Debian/Dgit.pm') 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(); -- cgit v1.2.3