From fa86b4030ae67b7a8445c831493bba551c6613e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaroslav=20=C5=A0karvada?= Date: Fri, 4 May 2018 14:56:13 +0200 Subject: [PATCH] RHEL-7 PowerTOP 2.3 compatibility patch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jaroslav Škarvada --- doc/powertop.8 | 22 ++++-- src/Makefile.am | 2 + src/Makefile.in | 20 +++++ src/main.cpp | 17 +++-- src/report/report-formatter-plain.cpp | 133 ++++++++++++++++++++++++++++++++++ src/report/report-formatter-plain.h | 54 ++++++++++++++ src/report/report-maker.cpp | 3 + src/report/report-maker.h | 5 +- src/report/report.cpp | 53 ++++++++------ 9 files changed, 275 insertions(+), 34 deletions(-) create mode 100644 src/report/report-formatter-plain.cpp create mode 100644 src/report/report-formatter-plain.h diff --git a/doc/powertop.8 b/doc/powertop.8 index 60e3c73..c18344d 100644 --- a/doc/powertop.8 +++ b/doc/powertop.8 @@ -23,12 +23,20 @@ can get more accurate estimates by using this option to enable a calibration cycle. This will cycle through various display levels and USB device activities and workloads. .TP -\fB\-C\fR, \fB\-\-csv\fR[=\fIfilename\fR] +\fB\-C\fR[\fIfilename\fR], \fB\-\-csv\fR[=\fIfilename\fR] Generate a CSV report. If a .I filename is not specified then the default name .B powertop.csv -is used. The CSV report can be used for reporting and data analysis. +is used. If a +.I filename +is "\fB\-\fR" then STDOUT is used. The CSV report can +be used for reporting and data analysis. +.TP +\fB\-d\fR[\fIfilename\fR], \fB\-\-dump\fR[=\fIfilename\fR] +Generate a plain text report. If a +.I filename +is not specified or it is "\fB\-\fR" then STDOUT is used. .TP .B \-\-debug Run in debug mode. @@ -39,13 +47,15 @@ specify the serial device node of the serial to USB adaptor connecting to the Extech Power Analyzer, for example .IR /dev/ttyUSB0 . .TP -\fB\-r\fR, \fB\-\-html\fR[=\fIfilename\fR] +\fB\-r\fR[\fIfilename\fR], \fB\-h\fR[\fIfilename\fR], \fB\-\-html\fR[=\fIfilename\fR] Generate an HTML report. If a .I filename is not specified then the default name .B powertop.html -is used. The HTML report can be sent to others to help diagnose power -issues. +is used. If a +.I filename +is "\fB\-\fR" then STDOUT is used. The HTML report can be sent to others to help +diagnose power issues. .TP \fB\-i\fR, \fB\-\-iteration\fR[=\fIiterations\fR] Number of times to run each test. @@ -65,7 +75,7 @@ file as a part of calibration before making a report. .BR \-V ", " \-\-version Print version information and exit. .TP -.BR \-h ", " \-\-help +.BR \-u ", " \-\-help Show the help message and exit. .SH COMMANDS In interactive mode, the following key bindings are available: diff --git a/src/Makefile.am b/src/Makefile.am index 8357bae..5882468 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -99,6 +99,8 @@ powertop_SOURCES = \ report/report-formatter-csv.h \ report/report-formatter-html.cpp \ report/report-formatter-html.h \ + report/report-formatter-plain.cpp \ + eport/report-formatter-plain.h \ report/report-formatter.h \ report/report-maker.cpp \ report/report-maker.h \ diff --git a/src/Makefile.in b/src/Makefile.in index 643b7ce..90ebdff 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -159,6 +159,7 @@ am_powertop_OBJECTS = powertop-devlist.$(OBJEXT) \ report/powertop-report-formatter-base.$(OBJEXT) \ report/powertop-report-formatter-csv.$(OBJEXT) \ report/powertop-report-formatter-html.$(OBJEXT) \ + report/powertop-report-formatter-plain.$(OBJEXT) \ report/powertop-report-maker.$(OBJEXT) \ report/powertop-report.$(OBJEXT) \ tuning/powertop-bluetooth.$(OBJEXT) \ @@ -512,6 +513,8 @@ powertop_SOURCES = \ report/report-formatter-csv.h \ report/report-formatter-html.cpp \ report/report-formatter-html.h \ + report/report-formatter-plain.cpp \ + report/report-formatter-plain.h \ report/report-formatter.h \ report/report-maker.cpp \ report/report-maker.h \ @@ -806,6 +809,8 @@ report/powertop-report-formatter-csv.$(OBJEXT): \ report/$(am__dirstamp) report/$(DEPDIR)/$(am__dirstamp) report/powertop-report-formatter-html.$(OBJEXT): \ report/$(am__dirstamp) report/$(DEPDIR)/$(am__dirstamp) +report/powertop-report-formatter-plain.$(OBJEXT): \ + report/$(am__dirstamp) report/$(DEPDIR)/$(am__dirstamp) report/powertop-report-maker.$(OBJEXT): report/$(am__dirstamp) \ report/$(DEPDIR)/$(am__dirstamp) report/powertop-report.$(OBJEXT): report/$(am__dirstamp) \ @@ -907,6 +912,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@report/$(DEPDIR)/powertop-report-formatter-base.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@report/$(DEPDIR)/powertop-report-formatter-csv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@report/$(DEPDIR)/powertop-report-formatter-html.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@report/$(DEPDIR)/powertop-report-formatter-plain.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@report/$(DEPDIR)/powertop-report-maker.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@report/$(DEPDIR)/powertop-report.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@tuning/$(DEPDIR)/powertop-bluetooth.Po@am__quote@ @@ -1675,6 +1681,20 @@ report/powertop-report-formatter-html.o: report/report-formatter-html.cpp @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(powertop_CPPFLAGS) $(CPPFLAGS) $(powertop_CXXFLAGS) $(CXXFLAGS) -c -o report/powertop-report-formatter-html.o `test -f 'report/report-formatter-html.cpp' || echo '$(srcdir)/'`report/report-formatter-html.cpp +report/powertop-report-formatter-plain.o: report/report-formatter-plain.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(powertop_CPPFLAGS) $(CPPFLAGS) $(powertop_CXXFLAGS) $(CXXFLAGS) -MT report/powertop-report-formatter-plain.o -MD -MP -MF report/$(DEPDIR)/powertop-report-formatter-plain.Tpo -c -o report/powertop-report-formatter-plain.o `test -f 'report/report-formatter-plain.cpp' || echo '$(srcdir)/'`report/report-formatter-plain.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) report/$(DEPDIR)/powertop-report-formatter-plain.Tpo report/$(DEPDIR)/powertop-report-formatter-plain.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='report/report-formatter-plain.cpp' object='report/powertop-report-formatter-plain.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(powertop_CPPFLAGS) $(CPPFLAGS) $(powertop_CXXFLAGS) $(CXXFLAGS) -c -o report/powertop-report-formatter-plain.o `test -f 'report/report-formatter-plain.cpp' || echo '$(srcdir)/'`report/report-formatter-plain.cpp + +report/powertop-report-formatter-plain.obj: report/report-formatter-plain.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(powertop_CPPFLAGS) $(CPPFLAGS) $(powertop_CXXFLAGS) $(CXXFLAGS) -MT report/powertop-report-formatter-plain.obj -MD -MP -MF report/$(DEPDIR)/powertop-report-formatter-plain.Tpo -c -o report/powertop-report-formatter-plain.obj `if test -f 'report/report-formatter-plain.cpp'; then $(CYGPATH_W) 'report/report-formatter-plain.cpp'; else $(CYGPATH_W) '$(srcdir)/report/report-formatter-plain.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) report/$(DEPDIR)/powertop-report-formatter-plain.Tpo report/$(DEPDIR)/powertop-report-formatter-plain.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='report/report-formatter-palin.cpp' object='report/powertop-report-formatter-plain.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(powertop_CPPFLAGS) $(CPPFLAGS) $(powertop_CXXFLAGS) $(CXXFLAGS) -c -o report/powertop-report-formatter-plain.obj `if test -f 'report/report-formatter-plain.cpp'; then $(CYGPATH_W) 'report/report-formatter-plain.cpp'; else $(CYGPATH_W) '$(srcdir)/report/report-formatter-plain.cpp'; fi` + report/powertop-report-formatter-html.obj: report/report-formatter-html.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(powertop_CPPFLAGS) $(CPPFLAGS) $(powertop_CXXFLAGS) $(CXXFLAGS) -MT report/powertop-report-formatter-html.obj -MD -MP -MF report/$(DEPDIR)/powertop-report-formatter-html.Tpo -c -o report/powertop-report-formatter-html.obj `if test -f 'report/report-formatter-html.cpp'; then $(CYGPATH_W) 'report/report-formatter-html.cpp'; else $(CYGPATH_W) '$(srcdir)/report/report-formatter-html.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) report/$(DEPDIR)/powertop-report-formatter-html.Tpo report/$(DEPDIR)/powertop-report-formatter-html.Po diff --git a/src/main.cpp b/src/main.cpp index 7467f0f..769d593 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -84,6 +84,7 @@ static const struct option long_options[] = {"auto-tune", no_argument, NULL, OPT_AUTO_TUNE}, {"calibrate", no_argument, NULL, 'c'}, {"csv", optional_argument, NULL, 'C'}, + {"dump", optional_argument, NULL, 'd'}, {"debug", no_argument, &debug_learning, OPT_DEBUG}, {"extech", optional_argument, NULL, OPT_EXTECH}, {"html", optional_argument, NULL, 'r'}, @@ -93,7 +94,7 @@ static const struct option long_options[] = {"time", optional_argument, NULL, 't'}, {"workload", optional_argument, NULL, 'w'}, {"version", no_argument, NULL, 'V'}, - {"help", no_argument, NULL, 'h'}, + {"help", no_argument, NULL, 'u'}, {NULL, 0, NULL, 0} }; @@ -122,16 +123,17 @@ static void print_usage() printf(" --auto-tune\t %s\n", _("sets all tunable options to their GOOD setting")); printf(" -c, --calibrate\t %s\n", _("runs powertop in calibration mode")); printf(" -C, --csv%s\t %s\n", _("[=filename]"), _("generate a csv report")); + printf(" -d, --dump%s\t %s\n", _("[=filename]"), _("generate plain text report")); printf(" --debug\t\t %s\n", _("run in \"debug\" mode")); printf(" --extech%s\t %s\n", _("[=devnode]"), _("uses an Extech Power Analyzer for measurements")); - printf(" -r, --html%s\t %s\n", _("[=filename]"), _("generate a html report")); + printf(" -r, -h, --html%s\t %s\n", _("[=filename]"), _("generate a html report")); printf(" -i, --iteration%s\n", _("[=iterations] number of times to run each test")); printf(" -q, --quiet\t\t %s\n", _("suppress stderr output")); printf(" -s, --sample%s\t %s\n", _("[=seconds]"), _("interval for power consumption measurement")); printf(" -t, --time%s\t %s\n", _("[=seconds]"), _("generate a report for 'x' seconds")); printf(" -w, --workload%s %s\n", _("[=workload]"), _("file to execute for workload")); printf(" -V, --version\t\t %s\n", _("print version information")); - printf(" -h, --help\t\t %s\n", _("print this help menu")); + printf(" -u, --help\t\t %s\n", _("print this help menu")); printf("\n"); printf("%s\n\n", _("For more help please refer to the 'man 8 powertop'")); } @@ -441,7 +443,7 @@ int main(int argc, char **argv) #endif ui_notify_user = ui_notify_user_ncurses; while (1) { /* parse commandline options */ - c = getopt_long(argc, argv, "cC:r:i:qt:w:Vh", long_options, &option_index); + c = getopt_long(argc, argv, "cC::d::r::i:qt:w:uVh::", long_options, &option_index); /* Detect the end of the options. */ if (c == -1) break; @@ -471,6 +473,7 @@ int main(int argc, char **argv) checkroot(); extech_power_meter(optarg ? optarg : "/dev/ttyUSB0"); break; + case 'h': case 'r': /* html report */ reporttype = REPORT_HTML; snprintf(filename, sizeof(filename), "%s", optarg ? optarg : "powertop.html"); @@ -480,6 +483,10 @@ int main(int argc, char **argv) exit(1); } break; + case 'd': /* plain text report (dump) */ + reporttype = REPORT_PLAIN; + snprintf(filename, sizeof(filename), "%s", optarg ? optarg : "-"); + break; case 'i': iterations = (optarg ? atoi(optarg) : 1); break; @@ -500,7 +507,7 @@ int main(int argc, char **argv) print_version(); exit(0); break; - case 'h': + case 'u': print_usage(); exit(0); break; diff --git a/src/report/report-formatter-plain.cpp b/src/report/report-formatter-plain.cpp new file mode 100644 index 0000000..9a0d636 --- /dev/null +++ b/src/report/report-formatter-plain.cpp @@ -0,0 +1,133 @@ +/* Copyright (c) 2016-2018 Jaroslav Škarvada + * Based on CSV formatter code by Igor Zhbanov + * + * This file is part of PowerTOP + * + * This program file is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + */ + +#define _BSD_SOURCE + +/* Uncomment to disable asserts */ +/*#define NDEBUG*/ + +#include +#include +#include + +#include "report-formatter-plain.h" +#include "report-data-html.h" + +/* ************************************************************************ */ +report_formatter_plain::report_formatter_plain() +{ + /* Do nothing special */ +} + +/* ************************************************************************ */ +void report_formatter_plain::finish_report() +{ + /* Do nothing special */ +} + +string report_formatter_plain::escape_string(const char *str) +{ + assert(str); + return string(str); +} + +/* Report Style */ +void report_formatter_plain::add_header() +{ +} + +void +report_formatter_plain::end_header() +{ + /* Do nothing */ +} + +void +report_formatter_plain::add_logo() +{ + add_exact("===PowerTOP Report===\n"); +} + + +void +report_formatter_plain::add_div(struct tag_attr * div_attr) +{ + add_exact("\n"); +} + +void +report_formatter_plain::end_div() +{ + /*Do nothing*/ +} + +void +report_formatter_plain::add_title(struct tag_attr *title_att, const char *title) +{ + addf_exact("==%s==\n", title); +} + +void +report_formatter_plain::add_navigation() +{ + /* No nav in plain - thinking on table of contents */ +} + +void +report_formatter_plain::add_summary_list(string *list, int size) +{ + int i; + add_exact("\n"); + for (i=0; i < size; i+=2){ + addf_exact("%s %s", list[i].c_str(), list[i+1].c_str()); + if(i < (size - 1)) + add_exact(" "); + } + add_exact("\n"); +} + +void +report_formatter_plain::add_table(string *system_data, struct table_attributes* tb_attr) +{ + int i, j; + int offset=0; + string tmp_str=""; + int empty_row=0; + add_exact("\n"); + for (i=0; i < tb_attr->rows; i++){ + for (j=0; j < tb_attr->cols; j++){ + offset = i * (tb_attr->cols) + j; + tmp_str=system_data[offset]; + + if(tmp_str == " ") + empty_row+=1; + else{ + addf_exact("%s", system_data[offset].c_str()); + if(j < (tb_attr->cols - 1)) + add_exact(" "); + } + } + if(empty_row < tb_attr->cols) + add_exact("\n"); + empty_row=0; + } +} diff --git a/src/report/report-formatter-plain.h b/src/report/report-formatter-plain.h new file mode 100644 index 0000000..276b5ac --- /dev/null +++ b/src/report/report-formatter-plain.h @@ -0,0 +1,54 @@ +/* Copyright (c) 2016-2018 Jaroslav Škarvada + * Based on CSV formatter code by Igor Zhbanov + * + * This file is part of PowerTOP + * + * This program file is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + */ + +#ifndef _REPORT_FORMATTER_PLAIN_H_ +#define _REPORT_FORMATTER_PLAIN_H_ + +#include + +#include "report-formatter-base.h" + +class report_formatter_plain: public report_formatter_string_base +{ +public: + report_formatter_plain(); + void finish_report(); + + /* Report Style */ + void add_logo(); + void add_header(); + void end_header(); + void add_div(struct tag_attr *div_attr); + void end_div(); + void add_title(struct tag_attr *title_att, const char *title); + void add_navigation(); + void add_summary_list(string *list, int size); + void add_table(string *system_data, struct table_attributes *tb_attr); + +private: + void add_quotes(); + string escape_string(const char *str); + bool csv_need_quotes; + size_t text_start; +}; + +#endif /* _REPORT_FORMATTER_PLAIN_H_ */ diff --git a/src/report/report-maker.cpp b/src/report/report-maker.cpp index 4049a54..4d0932a 100644 --- a/src/report/report-maker.cpp +++ b/src/report/report-maker.cpp @@ -32,6 +32,7 @@ #include "report-maker.h" #include "report-formatter-csv.h" #include "report-formatter-html.h" +#include "report-formatter-plain.h" /* ************************************************************************ */ @@ -103,6 +104,8 @@ report_maker::setup_report_formatter() formatter = new report_formatter_html(); else if (type == REPORT_CSV) formatter = new report_formatter_csv(); + else if (type == REPORT_PLAIN) + formatter = new report_formatter_plain(); else if (type == REPORT_OFF) formatter = new report_formatter(); else diff --git a/src/report/report-maker.h b/src/report/report-maker.h index bda4cef..08d2a6d 100644 --- a/src/report/report-maker.h +++ b/src/report/report-maker.h @@ -65,7 +65,7 @@ using namespace std; /* Conditional gettext. We need original strings for CSV. */ #ifdef ENABLE_NLS #define __(STRING) \ - ((report.get_type() == REPORT_CSV) ? (STRING) : gettext(STRING)) + ((report.get_type() == REPORT_CSV || report.get_type() == REPORT_PLAIN) ? (STRING) : gettext(STRING)) #else #define __(STRING) (STRING) #endif @@ -79,7 +79,8 @@ using namespace std; enum report_type { REPORT_OFF, REPORT_HTML, - REPORT_CSV + REPORT_CSV, + REPORT_PLAIN }; /* ************************************************************************ */ diff --git a/src/report/report.cpp b/src/report/report.cpp index f0f31ee..5fa9051 100644 --- a/src/report/report.cpp +++ b/src/report/report.cpp @@ -172,30 +172,37 @@ void init_report_output(char *filename_str, int iterations) string filename; time_t stamp; char datestr[200]; + int len; - if (iterations == 1) - snprintf(reportout.filename, sizeof(reportout.filename), "%s", filename_str); + len = strlen(filename_str); + if (!len || (len == 1 && filename_str[0] == '-')) + reportout.report_file = stdout; else { - filename = string(filename_str); - period = filename.find_last_of("."); - if (period > filename.length()) - period = filename.length(); - memset(&datestr, 0, 200); - memset(&stamp, 0, sizeof(time_t)); - stamp = time(NULL); - strftime(datestr, sizeof(datestr), "%Y%m%d-%H%M%S", localtime(&stamp)); - snprintf(reportout.filename, sizeof(reportout.filename), "%s-%s%s", - filename.substr(0, period).c_str(), datestr, - filename.substr(period).c_str()); - } + if (iterations == 1) + snprintf(reportout.filename, sizeof(reportout.filename), "%s", filename_str); + else + { + filename = string(filename_str); + period = filename.find_last_of("."); + if (period > filename.length()) + period = filename.length(); + memset(&datestr, 0, 200); + memset(&stamp, 0, sizeof(time_t)); + stamp = time(NULL); + strftime(datestr, sizeof(datestr), "%Y%m%d-%H%M%S", localtime(&stamp)); + snprintf(reportout.filename, sizeof(reportout.filename), "%s-%s%s", + filename.substr(0, period).c_str(), datestr, + filename.substr(period).c_str()); + } - reportout.report_file = fopen(reportout.filename, "wm"); - if (!reportout.report_file) { - fprintf(stderr, _("Cannot open output file %s (%s)\n"), - reportout.filename, strerror(errno)); + reportout.report_file = fopen(reportout.filename, "wm"); + if (!reportout.report_file) { + fprintf(stderr, _("Cannot open output file %s (%s)\n"), + reportout.filename, strerror(errno)); + } } - + report.set_type(reporttype); system_info(); } @@ -208,10 +215,14 @@ void finish_report_output(void) report.finish_report(); if (reportout.report_file) { - fprintf(stderr, _("PowerTOP outputing using base filename %s\n"), reportout.filename); + if (reportout.report_file == stdout) + fprintf(stderr, _("PowerTOP outputing using standard output\n")); + else + fprintf(stderr, _("PowerTOP outputing using base filename %s\n"), reportout.filename); fputs(report.get_result(), reportout.report_file); fdatasync(fileno(reportout.report_file)); - fclose(reportout.report_file); + if (reportout.report_file != stdout) + fclose(reportout.report_file); } report.clear_result(); } -- 2.14.3