00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef OUTPUTCAPTURER_H
00014 #define OUTPUTCAPTURER_H
00015
00016 #include <sys/types.h>
00017 #include <sys/stat.h>
00018 #include <fcntl.h>
00019 #include <stdio.h>
00020 #include <stdlib.h>
00021 #include <unistd.h>
00022
00023 #include <string>
00024 #include <sstream>
00025
00026 #include "rlog/rlog.h"
00027 #include "rlog/RLogChannel.h"
00028
00030 class OutputCapturer {
00031 public:
00032 OutputCapturer() :
00033 start_sig("---start marker---\n\n\n"),
00034 end_sig("--- end marker ---\n\n\n"),
00035 stream_redir_(stdout),
00036 fd_save_(-1)
00037 {
00038 }
00039
00040 void begin_capture() {
00041 rAssert(fd_save_ == -1);
00042 int fd_redir = fileno(stream_redir_);
00043
00044
00045 ::fflush(stream_redir_);
00046 ::fsync(fd_redir);
00047 fd_save_ = ::dup(fd_redir);
00048 rAssert(fd_save_ != -1);
00049 ::strcpy(capture_file_name_, "captXXXXXX");
00050 int fd_file = ::mkstemp(capture_file_name_);
00051 rAssert(fd_file != -1);
00052 ::close(fd_redir);
00053 int fd = ::dup(fd_file);
00054 rAssert(fd == fd_redir);
00055 ::close(fd_file);
00056
00057
00058 int ret = ::write(fd_redir, start_sig, ::strlen(start_sig));
00059 rAssert(ret == static_cast<int>(::strlen(start_sig)));
00060 }
00061
00062 void end_capture() {
00063 rAssert(fd_save_ != -1);
00064 int fd_redir = fileno(stream_redir_);
00065
00066
00067 ::fflush(stream_redir_);
00068
00069
00070 int ret = ::write(fd_redir, end_sig, ::strlen(start_sig));
00071 rAssert(ret == static_cast<int>(::strlen(end_sig)));
00072 ::fsync(fd_redir);
00073
00074
00075 ::close(fd_redir);
00076 int fd = ::dup(fd_save_);
00077 rAssert(fd == fd_redir);
00078 ::close(fd_save_);
00079 fd_save_ = -1;
00080
00081
00082 std::ifstream infile(capture_file_name_);
00083 stdout_buf_.str("");
00084 int ch;
00085 while ((ch = infile.get()) != EOF)
00086 stdout_buf_.put(ch);
00087 infile.close();
00088
00089
00090
00091
00092
00093 ::unlink(capture_file_name_);
00094 }
00095
00096 std::string get_stdout() const {
00097 rAssert(fd_save_ == -1);
00098 std::string str = stdout_buf_.str();
00099 rAssert(str.substr(0, ::strlen(start_sig)) == start_sig);
00100 rAssert(str.substr(str.size() - ::strlen(end_sig), ::strlen(end_sig)) == end_sig);
00101 std::string payload(str,
00102 ::strlen(start_sig),
00103 str.size() - ::strlen(start_sig) - ::strlen(end_sig));
00104 return payload;
00105 }
00106
00107 std::string get_stderr() const {
00108 rAssert(false);
00109 return "";
00110 }
00111
00112 void log(std::string prefix, rlog::RLogChannel* channel) {
00113 std::string msg(prefix + std::string(":\n") + get_stdout());
00114 rLog(channel, "%s", msg.c_str());
00115 }
00116
00117 protected:
00118 std::string get_temp_file_name() {
00119 return "zoltan.out";
00120 }
00121
00122 private:
00123 const char* start_sig;
00124 const char* end_sig;
00125 FILE* stream_redir_;
00126 char capture_file_name_[10];
00128 int fd_save_;
00130 std::ostringstream stdout_buf_;
00131 };
00132
00133 #endif