Implement -C option to combine regular and -c output

* defs.h (cflag_t): New enum.
* strace.1: Document -C option.
* strace.c (cflag): Update type.
(main): Handle -C option.
(trace): Update use of cflag.
* count.c (count_syscall): Move clearing of TCB_INSYSCALL to ...
* syscall.c (trace_syscall): ... here.  Update use of cflag.
Based on patch by Adrien Kunysz.
diff --git a/count.c b/count.c
index 4e272a3..d0ea016 100644
--- a/count.c
+++ b/count.c
@@ -50,7 +50,6 @@
 int
 count_syscall(struct tcb *tcp, struct timeval *tv)
 {
-	tcp->flags &= ~TCB_INSYSCALL;
 	if (tcp->scno < 0 || tcp->scno >= nsyscalls)
 		return 0;
 
diff --git a/defs.h b/defs.h
index 4797e96..62b3719 100644
--- a/defs.h
+++ b/defs.h
@@ -456,10 +456,17 @@
 #define TRACE_SIGNAL	020	/* Trace signal-related syscalls. */
 #define TRACE_DESC	040	/* Trace file descriptor-related syscalls. */
 
+typedef enum {
+	CFLAG_NONE = 0,
+	CFLAG_ONLY_STATS,
+	CFLAG_BOTH
+} cflag_t;
+
 extern struct tcb **tcbtab;
 extern int *qual_flags;
 extern int debug, followfork;
-extern int dtime, cflag, xflag, qflag;
+extern int dtime, xflag, qflag;
+extern cflag_t cflag;
 extern int acolumn;
 extern unsigned int nprocs, tcbtabsize;
 extern int max_strlen;
diff --git a/strace.1 b/strace.1
index d35a74e..aff8f41 100644
--- a/strace.1
+++ b/strace.1
@@ -43,7 +43,7 @@
 .SH SYNOPSIS
 .B strace
 [
-.B \-dffhiqrtttTvxx
+.B \-CdffhiqrtttTvxx
 ]
 [
 .BI \-a column
@@ -243,6 +243,11 @@
 running in the kernel) independent of wall clock time.  If -c is used with
 -f or -F (below), only aggregate totals for all traced processes are kept.
 .TP
+.B \-C
+Like
+.B \-c
+but also print regular output while processes are running.
+.TP
 .B \-d
 Show some debugging output of
 .B strace
diff --git a/strace.c b/strace.c
index 2fb75c9..40f8907 100644
--- a/strace.c
+++ b/strace.c
@@ -83,7 +83,8 @@
 
 
 int debug = 0, followfork = 0;
-int dtime = 0, cflag = 0, xflag = 0, qflag = 0;
+int dtime = 0, xflag = 0, qflag = 0;
+cflag_t cflag = CFLAG_NONE;
 static int iflag = 0, interactive = 0, pflag_seen = 0, rflag = 0, tflag = 0;
 /*
  * daemonized_tracer supports -D option.
@@ -719,15 +720,27 @@
 	qualify("verbose=all");
 	qualify("signal=all");
 	while ((c = getopt(argc, argv,
-		"+cdfFhiqrtTvVxz"
+		"+cCdfFhiqrtTvVxz"
 #ifndef USE_PROCFS
 		"D"
 #endif
 		"a:e:o:O:p:s:S:u:E:")) != EOF) {
 		switch (c) {
 		case 'c':
-			cflag++;
-			dtime++;
+			if (cflag == CFLAG_BOTH) {
+				fprintf(stderr, "%s: -c and -C are mutually exclusive options\n",
+					progname);
+				exit(1);
+			}
+			cflag = CFLAG_ONLY_STATS;
+			break;
+		case 'C':
+			if (cflag == CFLAG_ONLY_STATS) {
+				fprintf(stderr, "%s: -c and -C are mutually exclusive options\n",
+					progname);
+				exit(1);
+			}
+			cflag = CFLAG_BOTH;
 			break;
 		case 'd':
 			debug++;
@@ -838,7 +851,7 @@
 
 	if (followfork > 1 && cflag) {
 		fprintf(stderr,
-			"%s: -c and -ff are mutually exclusive options\n",
+			"%s: (-c or -C) and -ff are mutually exclusive options\n",
 			progname);
 		exit(1);
 	}
@@ -2144,7 +2157,8 @@
 			}
 			break;
 		case PR_SIGNALLED:
-			if (!cflag && (qual_flags[what] & QUAL_SIGNAL)) {
+			if (cflag != CFLAG_ONLY_STATS
+			    && (qual_flags[what] & QUAL_SIGNAL)) {
 				printleader(tcp);
 				tprintf("--- %s (%s) ---",
 					signame(what), strsignal(what));
@@ -2160,7 +2174,8 @@
 			}
 			break;
 		case PR_FAULTED:
-			if (!cflag && (qual_flags[what] & QUAL_FAULT)) {
+			if (cflag != CFLAGS_ONLY_STATS
+			    && (qual_flags[what] & QUAL_FAULT)) {
 				printleader(tcp);
 				tprintf("=== FAULT %d ===", what);
 				printtrailer();
@@ -2383,7 +2398,7 @@
 		if (WIFSIGNALED(status)) {
 			if (pid == strace_child)
 				exit_code = 0x100 | WTERMSIG(status);
-			if (!cflag
+			if (cflag != CFLAG_ONLY_STATS
 			    && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) {
 				printleader(tcp);
 				tprintf("+++ killed by %s %s+++",
@@ -2482,7 +2497,7 @@
 				}
 				continue;
 			}
-			if (!cflag
+			if (cflag != CFLAG_ONLY_STATS
 			    && (qual_flags[WSTOPSIG(status)] & QUAL_SIGNAL)) {
 				unsigned long addr = 0;
 				long pc = 0;
diff --git a/syscall.c b/syscall.c
index a56d7df..6a6fad8 100644
--- a/syscall.c
+++ b/syscall.c
@@ -2369,7 +2369,7 @@
 		long u_error;
 
 		/* Measure the exit time as early as possible to avoid errors. */
-		if (dtime)
+		if (dtime || cflag)
 			gettimeofday(&tv, NULL);
 
 		/* BTW, why we don't just memorize syscall no. on entry
@@ -2407,8 +2407,15 @@
 			tprintf(" resumed> ");
 		}
 
-		if (cflag)
-			return count_syscall(tcp, &tv);
+		if (cflag) {
+			struct timeval t = tv;
+			int rc = count_syscall(tcp, &t);
+			if (cflag == CFLAG_ONLY_STATS)
+			{
+				tcp->flags &= ~TCB_INSYSCALL;
+				return rc;
+			}
+		}
 
 		if (res != 1) {
 			tprintf(") ");
@@ -2647,9 +2654,9 @@
 		return 0;
 	}
 
-	if (cflag) {
-		gettimeofday(&tcp->etime, NULL);
+	if (cflag == CFLAG_ONLY_STATS) {
 		tcp->flags |= TCB_INSYSCALL;
+		gettimeofday(&tcp->etime, NULL);
 		return 0;
 	}
 
@@ -2669,7 +2676,7 @@
 		return -1;
 	tcp->flags |= TCB_INSYSCALL;
 	/* Measure the entrance time as late as possible to avoid errors. */
-	if (dtime)
+	if (dtime || cflag)
 		gettimeofday(&tcp->etime, NULL);
 	return sys_res;
 }