summaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-stat.c
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2009-06-10 15:55:59 +0200
committerIngo Molnar <mingo@elte.hu>2009-06-10 16:55:27 +0200
commitf7b7c26e01e51fe46097e11f179dc71ce7950084 (patch)
tree4a542e0c386ceebc306886604337dbe6db50c413 /tools/perf/builtin-stat.c
parent4502d77c1d8f15f20c04b92cb96c12d4e465de29 (diff)
downloadlinux-f7b7c26e01e51fe46097e11f179dc71ce7950084.tar.gz
linux-f7b7c26e01e51fe46097e11f179dc71ce7950084.tar.bz2
linux-f7b7c26e01e51fe46097e11f179dc71ce7950084.zip
perf_counter tools: Propagate signals properly
Currently report and stat catch SIGINT (and others) without altering their exit state. This means that things like: while :; do perf stat ./foo ; done Loops become hard-to-interrupt, because bash never sees perf terminate due to interruption. Fix this. Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> LKML-Reference: <new-submission> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/builtin-stat.c')
-rw-r--r--tools/perf/builtin-stat.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 80855090fd9f..6404906924fa 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -296,8 +296,20 @@ static int do_perf_stat(int argc, const char **argv)
return 0;
}
+static volatile int signr = -1;
+
static void skip_signal(int signo)
{
+ signr = signo;
+}
+
+static void sig_atexit(void)
+{
+ if (signr == -1)
+ return;
+
+ signal(signr, SIG_DFL);
+ kill(getpid(), signr);
}
static const char * const stat_usage[] = {
@@ -345,6 +357,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix)
* What we want is for Ctrl-C to work in the exec()-ed
* task, but being ignored by perf stat itself:
*/
+ atexit(sig_atexit);
signal(SIGINT, skip_signal);
signal(SIGALRM, skip_signal);
signal(SIGABRT, skip_signal);