2003-12-15 Dmitry V. Levin Introduce -k option. * strace.c (main, trace): Handle -k option. When specified, strace attempts to keep exit status of the first traced process, and return it to the caller. * strace.1: Document it. diff -upk.orig strace-4.5.12.orig/strace.1 strace-4.5.12/strace.1 --- strace-4.5.12.orig/strace.1 2005-06-10 11:43:05 +0000 +++ strace-4.5.12/strace.1 2005-06-10 11:55:00 +0000 @@ -43,7 +43,7 @@ strace \- trace system calls and signals .SH SYNOPSIS .B strace [ -.B \-dffhiqrtttTvxx +.B \-dffhikqrtttTvxx ] [ .BI \-a column @@ -278,6 +278,11 @@ Suppress messages about attaching, detac automatically when output is redirected to a file and the command is run directly instead of attaching. .TP +.B \-k +Attempt to keep exit status of the first traced process, and return +it to the caller. Main purpose of this option is to exit with nonzero +code in case of unsucessful exit of the first traced process. +.TP .B \-r Print a relative timestamp upon entry to each system call. This records the time difference between the beginning of successive diff -upk.orig strace-4.5.12.orig/strace.c strace-4.5.12/strace.c --- strace-4.5.12.orig/strace.c 2005-06-08 18:02:40 +0000 +++ strace-4.5.12/strace.c 2005-06-10 13:03:47 +0000 @@ -71,6 +71,9 @@ int pflag_seen = 0; /* Sometimes we want to print only succeeding syscalls. */ int not_failing_only = 0; +static int keep_status = 0; +static int return_code = 0; + char *username = NULL; uid_t run_uid; gid_t run_gid; @@ -135,7 +138,7 @@ FILE *ofp; int exitval; { fprintf(ofp, "\ -usage: strace [-dffhiqrtttTvVxx] [-a column] [-e expr] ... [-o file]\n\ +usage: strace [-dffhikqrtttTvVxx] [-a column] [-e expr] ... [-o file]\n\ [-p pid] ... [-s strsize] [-u username] [-E var=val] ...\n\ [command [arg ...]]\n\ or: strace -c [-e expr] ... [-O overhead] [-S sortby] [-E var=val] ...\n\ @@ -144,6 +147,7 @@ usage: strace [-dffhiqrtttTvVxx] [-a col -f -- follow forks, -ff -- with output into separate files\n\ -F -- attempt to follow vforks, -h -- print help message\n\ -i -- print instruction pointer at time of syscall\n\ +-k -- attempt to keep exit status of the first traced process\n\ -q -- suppress messages about attaching, detaching, etc.\n\ -r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\ -T -- print time spent in each syscall, -V -- print version\n\ @@ -206,7 +210,7 @@ char *argv[]; set_sortby(DEFAULT_SORTBY); set_personality(DEFAULT_PERSONALITY); while ((c = getopt(argc, argv, - "+cdfFhiqrtTvVxza:e:o:O:p:s:S:u:E:")) != EOF) { + "+cdfFhikqrtTvVxza:e:o:O:p:s:S:u:E:")) != EOF) { switch (c) { case 'c': cflag++; @@ -227,6 +231,9 @@ char *argv[]; case 'i': iflag++; break; + case 'k': + keep_status++; + break; case 'q': qflag++; break; @@ -674,7 +681,7 @@ Process %u attached - interrupt to quit\ if (trace() < 0) exit(1); cleanup(); - exit(0); + exit(return_code); } void @@ -2125,6 +2132,8 @@ Process %d attached (waiting for parent) continue; } if (WIFSIGNALED(status)) { + if (keep_status) + return_code = 128 + WTERMSIG(status); if (!cflag && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) { printleader(tcp); @@ -2144,6 +2153,8 @@ Process %d attached (waiting for parent) continue; } if (WIFEXITED(status)) { + if (keep_status) + return_code = WEXITSTATUS(status); if (debug) fprintf(stderr, "pid %u exited\n", pid); if ((tcp->flags & TCB_ATTACHED)