aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpi-cheng.chen <pi-cheng.chen@linaro.org>2014-08-22 16:28:17 +0800
committerAmit Kucheria <amit.kucheria@linaro.org>2014-08-29 10:45:54 +0530
commit7fcb68773e2af712b047172db300757d2d1badf9 (patch)
treef111fca25273522ce15e98341f8d73c6bec498ba
parent9ecbc807bef4c27fa74765a54e95bd8cfdcf4261 (diff)
idlestat: Add -o option to save output report to a file
Currently the serial terminal connected to the boards running idlestat are restricted to be at least 80 characters wide to output the report. Otherwise idlestat quits with message "The terminal must be at least 80 columns wide". Changes v1 to v2: * Duplicate opened report file to stdout instead of replacing all printf() Fix it by adding a "-o" option to save report output to a file. Signed-off-by: Pi-Cheng Chen <pi-cheng.chen@linaro.org> [amit.kucheria@linaro.org: Removed extra examples and check for bad filenames] Signed-off-by: Amit Kucheria <amit.kucheria@linaro.org>
-rw-r--r--idlestat.c53
-rw-r--r--idlestat.h1
2 files changed, 47 insertions, 7 deletions
diff --git a/idlestat.c b/idlestat.c
index c60f39a..2b199ef 100644
--- a/idlestat.c
+++ b/idlestat.c
@@ -34,6 +34,7 @@
#include <sched.h>
#include <string.h>
#include <float.h>
+#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/types.h>
@@ -95,6 +96,33 @@ static void charrep(char c, int count)
printf("%c", c);
}
+static int open_report_file(const char *path)
+{
+ int fd;
+ int ret = 0;
+
+ if (path) {
+ fd = open(path, O_RDWR | O_CREAT | O_TRUNC,
+ S_IRUSR | S_IWUSR | S_IRGRP |S_IROTH);
+ if (fd < 0) {
+ fprintf(stderr, "%s: failed to open '%s'\n", __func__, path);
+ return -1;
+ }
+
+ close(STDOUT_FILENO);
+
+ ret = dup2(fd, STDOUT_FILENO);
+ close(fd);
+
+ if (ret < 0) {
+ fprintf(stderr, "%s: failed to duplicate '%s'\n", __func__, path);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
static void display_cpu_header(char *cpu, int length)
{
charrep('-', length);
@@ -1135,11 +1163,11 @@ static void help(const char *cmd)
{
fprintf(stderr,
"\nUsage:\nTrace mode:\n\t%s --trace -f|--trace-file <filename>"
- " -t|--duration <seconds> -c|--idle -p|--frequency -w|--wakeup",
- basename(cmd));
+ " -o|--output-file <filename> -t|--duration <seconds>"
+ " -c|--idle -p|--frequency -w|--wakeup", basename(cmd));
fprintf(stderr,
- "\nReporting mode:\n\t%s --import -f|--trace-file <filename>",
- basename(cmd));
+ "\nReporting mode:\n\t%s --import -f|--trace-file <filename>"
+ " -o|--output-file <filename>", basename(cmd));
fprintf(stderr,
"\n\nExamples:\n1. Run a trace, post-process the results"
" (default is to show only C-state statistics):\n\tsudo "
@@ -1155,6 +1183,10 @@ static void help(const char *cmd)
fprintf(stderr,
"\n4. Post-process a trace captured earlier:\n\tsudo ./%s"
" --import -f /tmp/mytrace\n", basename(cmd));
+ fprintf(stderr,
+ "\n5. Run a trace, post-process the results and print all"
+ " statistics into a file:\n\tsudo ./%s --trace -f /tmp/mytrace -t 10 -p -c -w"
+ " -o /tmp/myreport\n", basename(cmd));
}
static void version(const char *cmd)
@@ -1168,6 +1200,7 @@ int getoptions(int argc, char *argv[], struct program_options *options)
{ "trace", no_argument, &options->mode, TRACE },
{ "import", no_argument, &options->mode, IMPORT },
{ "trace-file", required_argument, NULL, 'f' },
+ { "output-file", required_argument, NULL, 'o' },
{ "help", no_argument, NULL, 'h' },
{ "duration", required_argument, NULL, 't' },
{ "version", no_argument, NULL, 'V' },
@@ -1181,13 +1214,14 @@ int getoptions(int argc, char *argv[], struct program_options *options)
memset(options, 0, sizeof(*options));
options->filename = NULL;
+ options->outfilename = NULL;
options->mode = -1;
options->format = -1;
while (1) {
int optindex = 0;
- c = getopt_long(argc, argv, ":df:ht:cpwVv",
+ c = getopt_long(argc, argv, ":df:o:ht:cpwVv",
long_options, &optindex);
if (c == -1)
break;
@@ -1196,6 +1230,9 @@ int getoptions(int argc, char *argv[], struct program_options *options)
case 'f':
options->filename = optarg;
break;
+ case 'o':
+ options->outfilename = optarg;
+ break;
case 'h':
help(argv[0]);
exit(0);
@@ -1244,7 +1281,7 @@ int getoptions(int argc, char *argv[], struct program_options *options)
return -1;
}
- if (bad_filename(options->filename)) {
+ if (bad_filename(options->filename) || bad_filename(options->outfilename)) {
return -1;
}
@@ -1455,7 +1492,7 @@ int main(int argc, char *argv[], char *const envp[])
return -1;
}
- if (check_window_size()) {
+ if (check_window_size() && !options.outfilename) {
fprintf(stderr, "The terminal must be at least "
"80 columns wide\n");
return -1;
@@ -1529,6 +1566,8 @@ int main(int argc, char *argv[], char *const envp[])
* the same cluster
*/
if (0 == establish_idledata_to_topo(datas)) {
+ if (open_report_file(options.outfilename))
+ return -1;
if (options.display & IDLE_DISPLAY) {
display_cstates_header();
diff --git a/idlestat.h b/idlestat.h
index 1d5f961..735f0fe 100644
--- a/idlestat.h
+++ b/idlestat.h
@@ -132,6 +132,7 @@ struct program_options {
int display;
unsigned int duration;
char *filename;
+ char *outfilename;
int verbose;
};