7d3267
From 8c8c86d008da636d208ddeb8ac9cf9c06c4164a3 Mon Sep 17 00:00:00 2001
7d3267
From: Willy Tarreau <w@1wt.eu>
7d3267
Date: Thu, 3 Nov 2016 20:31:40 +0100
7d3267
Subject: [PATCH] BUG/MEDIUM: systemd-wrapper: return correct exit codes
7d3267
7d3267
Gabriele Cerami reported the the exit codes of the systemd-wrapper are
7d3267
wrong. In short, it directly returns the output of the wait syscall's
7d3267
status, which is a composite value made of error code an signal numbers.
7d3267
In general it contains the signal number on the lower bits and the error
7d3267
code on the higher bits, but exit() truncates it to the lowest 8 bits,
7d3267
causing config validations to incorrectly report a success. Example :
7d3267
7d3267
  $ ./haproxy-systemd-wrapper -c -f /dev/null
7d3267
  <7>haproxy-systemd-wrapper: executing /tmp/haproxy -c -f /dev/null -Ds
7d3267
  Configuration file has no error but will not start (no listener) => exit(2).
7d3267
  <5>haproxy-systemd-wrapper: exit, haproxy RC=512
7d3267
  $ echo $?
7d3267
  0
7d3267
7d3267
If the process is killed however, the signal number is directly reported
7d3267
in the exit code.
7d3267
7d3267
Let's fix all this to ensure that the exit code matches what the shell does,
7d3267
which means that codes 0..127 are for exit codes, codes 128..254 for signals,
7d3267
and code 255 for unknown exit code. Now the return code is correct :
7d3267
7d3267
  $ ./haproxy-systemd-wrapper -c -f /dev/null
7d3267
  <7>haproxy-systemd-wrapper: executing /tmp/haproxy -c -f /dev/null -Ds
7d3267
  Configuration file has no error but will not start (no listener) => exit(2).
7d3267
  <5>haproxy-systemd-wrapper: exit, haproxy RC=2
7d3267
  $ echo $?
7d3267
  2
7d3267
7d3267
  $ ./haproxy-systemd-wrapper -f /tmp/cfg.conf
7d3267
  <7>haproxy-systemd-wrapper: executing /tmp/haproxy -f /dev/null -Ds
7d3267
  ^C
7d3267
  <5>haproxy-systemd-wrapper: exit, haproxy RC=130
7d3267
  $ echo $?
7d3267
  130
7d3267
7d3267
This fix must be backported to 1.6 and 1.5.
7d3267
---
7d3267
 src/haproxy-systemd-wrapper.c | 10 ++++++++++
7d3267
 1 file changed, 10 insertions(+)
7d3267
7d3267
diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c
7d3267
index 4e4d039..86520ca 100644
7d3267
--- a/src/haproxy-systemd-wrapper.c
7d3267
+++ b/src/haproxy-systemd-wrapper.c
7d3267
@@ -215,6 +215,16 @@ int main(int argc, char **argv)
7d3267
 		}
7d3267
 	}
7d3267
 
7d3267
+	/* return either exit code or signal+128 */
7d3267
+	if (WIFEXITED(status))
7d3267
+		status = WEXITSTATUS(status);
7d3267
+	else if (WIFSIGNALED(status))
7d3267
+		status = 128 + WTERMSIG(status);
7d3267
+	else if (WIFSTOPPED(status))
7d3267
+		status = 128 + WSTOPSIG(status);
7d3267
+	else
7d3267
+		status = 255;
7d3267
+
7d3267
 	fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: exit, haproxy RC=%d\n",
7d3267
 			status);
7d3267
 	return status;
7d3267
-- 
7d3267
2.7.4
7d3267