summaryrefslogtreecommitdiffstats
path: root/gtest/src/gtest-port.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gtest/src/gtest-port.cc')
-rw-r--r--gtest/src/gtest-port.cc151
1 files changed, 60 insertions, 91 deletions
diff --git a/gtest/src/gtest-port.cc b/gtest/src/gtest-port.cc
index b9504f5..de169e2 100644
--- a/gtest/src/gtest-port.cc
+++ b/gtest/src/gtest-port.cc
@@ -68,10 +68,8 @@ namespace internal {
#if defined(_MSC_VER) || defined(__BORLANDC__)
// MSVC and C++Builder do not provide a definition of STDERR_FILENO.
-const int kStdOutFileno = 1;
const int kStdErrFileno = 2;
#else
-const int kStdOutFileno = STDOUT_FILENO;
const int kStdErrFileno = STDERR_FILENO;
#endif // _MSC_VER
@@ -111,14 +109,8 @@ size_t GetThreadCount() {
// Implements RE. Currently only needed for death tests.
RE::~RE() {
- if (is_valid_) {
- // regfree'ing an invalid regex might crash because the content
- // of the regex is undefined. Since the regex's are essentially
- // the same, one cannot be valid (or invalid) without the other
- // being so too.
- regfree(&partial_regex_);
- regfree(&full_regex_);
- }
+ regfree(&partial_regex_);
+ regfree(&full_regex_);
free(const_cast<char*>(pattern_));
}
@@ -158,10 +150,9 @@ void RE::Init(const char* regex) {
// Some implementation of POSIX regex (e.g. on at least some
// versions of Cygwin) doesn't accept the empty string as a valid
// regex. We change it to an equivalent form "()" to be safe.
- if (is_valid_) {
- const char* const partial_regex = (*regex == '\0') ? "()" : regex;
- is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0;
- }
+ const char* const partial_regex = (*regex == '\0') ? "()" : regex;
+ is_valid_ = (regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0)
+ && is_valid_;
EXPECT_TRUE(is_valid_)
<< "Regular expression \"" << regex
<< "\" is not a valid POSIX Extended regular expression.";
@@ -448,83 +439,81 @@ GTestLog::~GTestLog() {
#pragma warning(disable: 4996)
#endif // _MSC_VER
-#if GTEST_HAS_STREAM_REDIRECTION_
+// Defines the stderr capturer.
-// Object that captures an output stream (stdout/stderr).
-class CapturedStream {
+class CapturedStderr {
public:
- // The ctor redirects the stream to a temporary file.
- CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) {
+ // The ctor redirects stderr to a temporary file.
+ CapturedStderr() {
+#if GTEST_OS_WINDOWS_MOBILE
+ // Not supported on Windows CE.
+ posix::Abort();
+#else
+ uncaptured_fd_ = dup(kStdErrFileno);
+
#if GTEST_OS_WINDOWS
char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT
char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT
::GetTempPathA(sizeof(temp_dir_path), temp_dir_path);
- const UINT success = ::GetTempFileNameA(temp_dir_path,
- "gtest_redir",
- 0, // Generate unique file name.
- temp_file_path);
- GTEST_CHECK_(success != 0)
- << "Unable to create a temporary file in " << temp_dir_path;
+ ::GetTempFileNameA(temp_dir_path, "gtest_redir", 0, temp_file_path);
const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE);
- GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file "
- << temp_file_path;
filename_ = temp_file_path;
#else
// There's no guarantee that a test has write access to the
// current directory, so we create the temporary file in the /tmp
// directory instead.
- char name_template[] = "/tmp/captured_stream.XXXXXX";
+ char name_template[] = "/tmp/captured_stderr.XXXXXX";
const int captured_fd = mkstemp(name_template);
filename_ = name_template;
#endif // GTEST_OS_WINDOWS
fflush(NULL);
- dup2(captured_fd, fd_);
+ dup2(captured_fd, kStdErrFileno);
close(captured_fd);
+#endif // GTEST_OS_WINDOWS_MOBILE
}
- ~CapturedStream() {
+ ~CapturedStderr() {
+#if !GTEST_OS_WINDOWS_MOBILE
remove(filename_.c_str());
+#endif // !GTEST_OS_WINDOWS_MOBILE
}
- String GetCapturedString() {
- if (uncaptured_fd_ != -1) {
- // Restores the original stream.
- fflush(NULL);
- dup2(uncaptured_fd_, fd_);
- close(uncaptured_fd_);
- uncaptured_fd_ = -1;
- }
-
- FILE* const file = posix::FOpen(filename_.c_str(), "r");
- const String content = ReadEntireFile(file);
- posix::FClose(file);
- return content;
+ // Stops redirecting stderr.
+ void StopCapture() {
+#if !GTEST_OS_WINDOWS_MOBILE
+ // Restores the original stream.
+ fflush(NULL);
+ dup2(uncaptured_fd_, kStdErrFileno);
+ close(uncaptured_fd_);
+ uncaptured_fd_ = -1;
+#endif // !GTEST_OS_WINDOWS_MOBILE
}
- private:
- // Reads the entire content of a file as a String.
- static String ReadEntireFile(FILE* file);
-
- // Returns the size (in bytes) of a file.
- static size_t GetFileSize(FILE* file);
+ // Returns the name of the temporary file holding the stderr output.
+ // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we
+ // can use it here.
+ ::std::string filename() const { return filename_; }
- const int fd_; // A stream to capture.
+ private:
int uncaptured_fd_;
- // Name of the temporary file holding the stderr output.
::std::string filename_;
-
- GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream);
};
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif // _MSC_VER
+
+static CapturedStderr* g_captured_stderr = NULL;
+
// Returns the size (in bytes) of a file.
-size_t CapturedStream::GetFileSize(FILE* file) {
+static size_t GetFileSize(FILE * file) {
fseek(file, 0, SEEK_END);
return static_cast<size_t>(ftell(file));
}
// Reads the entire content of a file as a string.
-String CapturedStream::ReadEntireFile(FILE* file) {
+static String ReadEntireFile(FILE * file) {
const size_t file_size = GetFileSize(file);
char* const buffer = new char[file_size];
@@ -546,50 +535,30 @@ String CapturedStream::ReadEntireFile(FILE* file) {
return content;
}
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif // _MSC_VER
-
-static CapturedStream* g_captured_stderr = NULL;
-static CapturedStream* g_captured_stdout = NULL;
-
-// Starts capturing an output stream (stdout/stderr).
-void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) {
- if (*stream != NULL) {
- GTEST_LOG_(FATAL) << "Only one " << stream_name
- << " capturer can exist at a time.";
+// Starts capturing stderr.
+void CaptureStderr() {
+ if (g_captured_stderr != NULL) {
+ GTEST_LOG_(FATAL) << "Only one stderr capturer can exist at one time.";
}
- *stream = new CapturedStream(fd);
+ g_captured_stderr = new CapturedStderr;
}
-// Stops capturing the output stream and returns the captured string.
-String GetCapturedStream(CapturedStream** captured_stream) {
- const String content = (*captured_stream)->GetCapturedString();
+// Stops capturing stderr and returns the captured string.
+// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can
+// use it here.
+String GetCapturedStderr() {
+ g_captured_stderr->StopCapture();
- delete *captured_stream;
- *captured_stream = NULL;
+ FILE* const file = posix::FOpen(g_captured_stderr->filename().c_str(), "r");
+ const String content = ReadEntireFile(file);
+ posix::FClose(file);
- return content;
-}
+ delete g_captured_stderr;
+ g_captured_stderr = NULL;
-// Starts capturing stdout.
-void CaptureStdout() {
- CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout);
-}
-
-// Starts capturing stderr.
-void CaptureStderr() {
- CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr);
+ return content;
}
-// Stops capturing stdout and returns the captured string.
-String GetCapturedStdout() { return GetCapturedStream(&g_captured_stdout); }
-
-// Stops capturing stderr and returns the captured string.
-String GetCapturedStderr() { return GetCapturedStream(&g_captured_stderr); }
-
-#endif // GTEST_HAS_STREAM_REDIRECTION_
-
#if GTEST_HAS_DEATH_TEST
// A copy of all command line arguments. Set by InitGoogleTest().