tst_run_cmd: Make the tst_run_cmd survive SIGCHLD

The tst_sig() installs poisoned signal handlers for all signals the test
is not expected to get, this causes abort in tst_run_cmd right after the
child exits and parent starts running.

This commit makes the tst_run_cmd temporarily disable the handler for
SIGCHLD (the handler is set to SIG_DFL at the start of the tst_run_cmd
function and restored at the end of it) so that we don't have to disable
the poisoned handler in each test using tst_run_cmd.

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
diff --git a/lib/tst_run_cmd.c b/lib/tst_run_cmd.c
index 804103c..4eb32e6 100644
--- a/lib/tst_run_cmd.c
+++ b/lib/tst_run_cmd.c
@@ -25,6 +25,7 @@
 #include <sys/wait.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <signal.h>
 #include "test.h"
 
 #define OPEN_MODE	(S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
@@ -40,6 +41,16 @@
 			"argument list is empty at %s:%d", __FILE__, __LINE__);
 	}
 
+	/*
+	 * The tst_sig() install poisoned signal handlers for all signals the
+	 * test is not expected to get.
+	 *
+	 * So we temporarily disable the handler for sigchild we get after our
+	 * child exits so that we don't have to disable it in each test that
+	 * uses this interface.
+	 */
+	void *old_handler = signal(SIGCHLD, SIG_DFL);
+
 	pid_t pid = vfork();
 	if (pid == -1) {
 		tst_brkm(TBROK | TERRNO, cleanup_fn, "vfork failed at %s:%d",
@@ -62,10 +73,12 @@
 
 	int ret = -1;
 	if (waitpid(pid, &ret, 0) != pid) {
-		tst_brkm(TBROK, cleanup_fn, "waitpid failed at %s:%d",
+		tst_brkm(TBROK | TERRNO, cleanup_fn, "waitpid failed at %s:%d",
 			__FILE__, __LINE__);
 	}
 
+	signal(SIGCHLD, old_handler);
+
 	if (!WIFEXITED(ret) || WEXITSTATUS(ret) != 0) {
 		tst_brkm(TBROK, cleanup_fn, "failed to exec cmd '%s' at %s:%d",
 			argv[0], __FILE__, __LINE__);