From a297e272d1323e43fe1358f9b27b0f77b57723e3 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sat, 3 May 2014 11:26:46 -0700 Subject: [PATCH] Add FileDescriptor::read. --- test/gtest-extra.cc | 28 ++++++++++++++++++---------- test/gtest-extra.h | 8 ++++++++ 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/test/gtest-extra.cc b/test/gtest-extra.cc index a1973e33..f4018ba2 100644 --- a/test/gtest-extra.cc +++ b/test/gtest-extra.cc @@ -43,9 +43,6 @@ # define S_IRUSR _S_IREAD # define S_IWUSR _S_IWRITE -// The read function is defined as returning int on Windows. -typedef int ssize_t; - #endif // _WIN32 // Retries the expression while it evaluates to -1 and error equals to EINTR. @@ -75,6 +72,14 @@ void FileDescriptor::close() { fmt::ReportSystemError(errno, "cannot close file"); } +std::streamsize FileDescriptor::read(void *buffer, std::size_t count) { + std::streamsize result = 0; + FMT_RETRY(result, ::read(fd_, buffer, count)); + if (result == -1) + fmt::ThrowSystemError(errno, "cannot read from file"); + return result; +} + FileDescriptor FileDescriptor::dup(int fd) { int new_fd = 0; FMT_RETRY(new_fd, ::FMT_POSIX(dup(fd))); @@ -110,6 +115,7 @@ void FileDescriptor::pipe(FileDescriptor &read_fd, FileDescriptor &write_fd) { enum { DEFAULT_CAPACITY = 65536 }; int result = _pipe(fds, DEFAULT_CAPACITY, _O_BINARY); #else + // The pipe function doesn't return EINTR, so no need to retry. int result = ::pipe(fds); #endif if (result != 0) @@ -145,14 +151,16 @@ std::string OutputRedirector::Read() { fmt::ThrowSystemError(errno, "cannot flush stream"); saved_fd_.dup2(fileno(file_)); - // TODO: move to FileDescriptor - enum { BUFFER_SIZE = 100 }; + // Read everything from the pipe. + std::string content; + enum { BUFFER_SIZE = 4096 }; char buffer[BUFFER_SIZE]; - ssize_t result = read(read_fd_.get(), buffer, BUFFER_SIZE); - if (result == -1) - fmt::ThrowSystemError(errno, "cannot read file"); - buffer[std::min(BUFFER_SIZE - 1, result)] = '\0'; - return buffer; + std::streamsize count = 0; + do { + count = read_fd_.read(buffer, BUFFER_SIZE); + content.append(buffer, count); + } while (count != 0); + return content; } // TODO: test EXPECT_STDOUT and EXPECT_STDERR diff --git a/test/gtest-extra.h b/test/gtest-extra.h index bd0eaaa7..888234ef 100644 --- a/test/gtest-extra.h +++ b/test/gtest-extra.h @@ -28,6 +28,10 @@ #ifndef FMT_GTEST_EXTRA_H #define FMT_GTEST_EXTRA_H +#include +#include +#include + #if FMT_USE_FILE_DESCRIPTORS # include #endif @@ -190,6 +194,10 @@ class FileDescriptor { // Returns the file descriptor. int get() const FMT_NOEXCEPT(true) { return fd_; } + // Attempts to read count chars from the file associated with this file + // descriptor into the specified buffer. + std::streamsize read(void *buffer, std::size_t count); + // Duplicates a file descriptor with the dup function and returns // the duplicate. Throws fmt::SystemError on error. static FileDescriptor dup(int fd);