diff --git a/include/Common/SimpleLog.h b/include/Common/SimpleLog.h index 189065d..2f5215d 100644 --- a/include/Common/SimpleLog.h +++ b/include/Common/SimpleLog.h @@ -26,6 +26,9 @@ class SimpleLog { // \param logFilePath Path to log file. If NULL, using stdout/stderr. int setLogFile(const char* logFilePath=NULL); + // Change file descriptors used for stdout/stderr with provided ones + // They must be valid for the lifetime of this object (or until overwritten), and are not closed. + void setFileDescriptors(int fdStdout, int fdStderr); enum FormatOption : int { ShowTimeStamp = 0x1, diff --git a/src/SimpleLog.cxx b/src/SimpleLog.cxx index 6a02d68..80697ca 100644 --- a/src/SimpleLog.cxx +++ b/src/SimpleLog.cxx @@ -2,6 +2,7 @@ #include #include +#include class SimpleLog::Impl { public: @@ -24,7 +25,9 @@ class SimpleLog::Impl { protected: FILE *fp; // descriptor to be used. If NULL, using stdout/stderr. int formatOptions; - + int fdStdout; + int fdStderr; + friend class SimpleLog; }; @@ -33,6 +36,8 @@ SimpleLog::Impl::Impl() { formatOptions = SimpleLog::FormatOption::ShowTimeStamp | SimpleLog::FormatOption::ShowSeveritySymbol | SimpleLog::FormatOption::ShowMessage; + fdStdout = fileno(stdout); + fdStderr = fileno(stderr); } SimpleLog::Impl::~Impl() { @@ -46,7 +51,7 @@ SimpleLog::Impl::~Impl() { int SimpleLog::Impl::logV(SimpleLog::Impl::Severity s, const char *message, va_list ap) { char buffer[1024] = ""; - size_t len = sizeof(buffer); + size_t len = sizeof(buffer) - 2; size_t ix = 0; if (formatOptions & SimpleLog::FormatOption::ShowTimeStamp) { @@ -95,20 +100,23 @@ int SimpleLog::Impl::logV(SimpleLog::Impl::Severity s, const char *message, va_l ix+=vsnprintf(&buffer[ix], len-ix, message, ap); if (ix>len) { ix=len; } } - + + buffer[ix] = '\n'; + ix++; buffer[ix]=0; - FILE *fpOut=stdout; - - if (fp==NULL) { + int fd; + if (fp != NULL) { + fd = fileno(fp); + } else { if (s==Severity::Error) { - fpOut=stderr; + fd = fdStderr; + } else { + fd = fdStdout; } - } else { - fpOut=fp; } - fprintf(fpOut,"%s\n", buffer); - fflush(fpOut); + write(fd, buffer, ix); + return 0; } @@ -182,4 +190,10 @@ void SimpleLog::setOutputFormat(int opts) { pImpl->formatOptions=opts; } +void SimpleLog::setFileDescriptors(int fdStdout, int fdStderr) +{ + pImpl->fdStdout = fdStdout; + pImpl->fdStderr = fdStderr; +} + /// \todo: thread to flush output every 1 second