2008-09-29  Dmitry V. Levin <ldv@altlinux.org>

	* strace.c (startup_child): Save child pid for future use.
	(main): Exit/kill ourself with straced child's exitcode/signal.
	(trace): If signalled process pid matches the saved child pid,
	save the signal number.  If terminated process pid matches the
	saved child pid, save its exit status.
	Patch from Denys Vlasenko <dvlasenk@redhat.com>
diff --git a/strace.c b/strace.c
index cab3489..9f3c724 100644
--- a/strace.c
+++ b/strace.c
@@ -85,6 +85,9 @@
 /* Sometimes we want to print only succeeding syscalls. */
 int not_failing_only = 0;
 
+static int exit_code = 0;
+static int strace_child = 0;
+
 static char *username = NULL;
 uid_t run_uid;
 gid_t run_gid;
@@ -523,7 +526,8 @@
 			progname, filename);
 		exit(1);
 	}
-	switch (pid = fork()) {
+	strace_child = pid = fork();
+	switch (pid) {
 	case -1:
 		perror("strace: fork");
 		cleanup();
@@ -879,7 +883,17 @@
 	if (trace() < 0)
 		exit(1);
 	cleanup();
-	exit(0);
+	fflush(NULL);
+	if (exit_code > 0xff) {
+		/* Child was killed by a signal, mimic that.  */
+		exit_code &= 0xff;
+		signal(exit_code, SIG_DFL);
+		raise(exit_code);
+		/* Paranoia - what if this signal is not fatal?
+		   Exit with 128 + signo then.  */
+		exit_code += 128;
+	}
+	exit(exit_code);
 }
 
 int
@@ -1783,7 +1797,7 @@
 	switch (fork()) {
 	case -1:
 		perror("fork");
-		_exit(0);
+		_exit(1);
 	case 0:
 		break;
 	default:
@@ -1807,7 +1821,7 @@
 
 	if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
 		perror("getrlimit(RLIMIT_NOFILE, ...)");
-		_exit(0);
+		_exit(1);
 	}
 	n = rl.rlim_cur;
 	for (i = 0; i < n; i++) {
@@ -2322,6 +2336,8 @@
 			continue;
 		}
 		if (WIFSIGNALED(status)) {
+			if (pid == strace_child)
+				exit_code = 0x100 | WTERMSIG(status);
 			if (!cflag
 			    && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) {
 				printleader(tcp);
@@ -2341,6 +2357,8 @@
 			continue;
 		}
 		if (WIFEXITED(status)) {
+			if (pid == strace_child)
+				exit_code = WEXITSTATUS(status);
 			if (debug)
 				fprintf(stderr, "pid %u exited\n", pid);
 			if ((tcp->flags & TCB_ATTACHED)