src/OutputCapturer.h

Go to the documentation of this file.
00001 //
00002 // C++ Interface: OutputCapturer
00003 //
00004 // Description: 
00005 //
00006 //
00007 // Author: Roman Geus <geus@maxwell>, (C) 2004
00008 //
00009 // Copyright: See COPYING file that comes with this distribution
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         // redirect stdout to file
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         // write start signature
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         // flush file stream buffer to disk
00067         ::fflush(stream_redir_);
00068 
00069         // write end signature
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         // revert redirection
00075         ::close(fd_redir);            /* close file */
00076         int fd = ::dup(fd_save_);          /* reinstall old stdout */
00077         rAssert(fd == fd_redir);
00078         ::close(fd_save_);             /* free duplicate fd */
00079         fd_save_ = -1;
00080 
00081         // read capture file into string buffer
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         // verify captured data
00090 
00091 
00092         // delete capture file
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

Generated on Fri Oct 26 13:35:12 2007 for FEMAXX (Finite Element Maxwell Eigensolver) by  doxygen 1.4.7