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 --- idlestat.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++------ idlestat.h | 1 + 2 files changed, 51 insertions(+), 6 deletions(-)
diff --git a/idlestat.c b/idlestat.c index bba8951..7aa9d74 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> @@ -71,6 +72,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); @@ -1111,11 +1139,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 " @@ -1131,6 +1159,15 @@ 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)); + fprintf(stderr, + "\n6. Post-process a trace captured earlier and print all" + " statistics into a file:\n\tsudo ./%s --import -f /tmp/mytrace -p -c -w" + " -o /tmp/myreport\n", + basename(cmd)); }
static void version(const char *cmd) @@ -1144,6 +1181,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' }, @@ -1157,13 +1195,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; @@ -1172,6 +1211,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); @@ -1427,7 +1469,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; @@ -1501,6 +1543,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; };
Applied with a fix to check for bad filenames. See earlier commit in the tree.
On Fri, Aug 22, 2014 at 1:58 PM, pi-cheng.chen pi-cheng.chen@linaro.org wrote:
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
idlestat.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++------ idlestat.h | 1 + 2 files changed, 51 insertions(+), 6 deletions(-)
diff --git a/idlestat.c b/idlestat.c index bba8951..7aa9d74 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> @@ -71,6 +72,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); @@ -1111,11 +1139,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 "
@@ -1131,6 +1159,15 @@ 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));
fprintf(stderr,
"\n6. Post-process a trace captured earlier and print all"
" statistics into a file:\n\tsudo ./%s --import -f /tmp/mytrace -p -c -w"
" -o /tmp/myreport\n",
basename(cmd));
}
static void version(const char *cmd) @@ -1144,6 +1181,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' },
@@ -1157,13 +1195,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;
@@ -1172,6 +1211,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);
@@ -1427,7 +1469,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;
@@ -1501,6 +1543,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;
};
-- 1.9.1