diff --git a/test/gtest-extra-test.cc b/test/gtest-extra-test.cc index d4d38e4b..6d13a4e5 100644 --- a/test/gtest-extra-test.cc +++ b/test/gtest-extra-test.cc @@ -145,15 +145,15 @@ TEST(ErrorCodeTest, Ctor) { EXPECT_EQ(42, ErrorCode(42).get()); } -TEST(FileDescriptorTest, DefaultCtor) { - FileDescriptor fd; - EXPECT_EQ(-1, fd.get()); +TEST(FileTest, DefaultCtor) { + File f; + EXPECT_EQ(-1, f.get()); } -TEST(FileDescriptorTest, OpenFileInCtor) { +TEST(FileTest, OpenFileInCtor) { FILE *f = 0; { - FileDescriptor fd(".travis.yml", FileDescriptor::RDONLY); + File fd(".travis.yml", File::RDONLY); f = fdopen(fd.get(), "r"); ASSERT_TRUE(f != 0); } @@ -163,29 +163,28 @@ TEST(FileDescriptorTest, OpenFileInCtor) { fclose(f); } -TEST(FileDescriptorTest, OpenFileError) { - EXPECT_SYSTEM_ERROR( - FileDescriptor("nonexistent", FileDescriptor::RDONLY), ENOENT, - "cannot open file nonexistent"); +TEST(FileTest, OpenFileError) { + EXPECT_SYSTEM_ERROR(File("nonexistent", File::RDONLY), + ENOENT, "cannot open file nonexistent"); } -TEST(FileDescriptorTest, MoveCtor) { - FileDescriptor fd(".travis.yml", FileDescriptor::RDONLY); - int fd_value = fd.get(); - EXPECT_NE(-1, fd_value); - FileDescriptor fd2(std::move(fd)); - EXPECT_EQ(fd_value, fd2.get()); - EXPECT_EQ(-1, fd.get()); +TEST(FileTest, MoveCtor) { + File f(".travis.yml", File::RDONLY); + int fd = f.get(); + EXPECT_NE(-1, fd); + File f2(std::move(f)); + EXPECT_EQ(fd, f2.get()); + EXPECT_EQ(-1, f.get()); } -TEST(FileDescriptorTest, MoveAssignment) { - FileDescriptor fd(".travis.yml", FileDescriptor::RDONLY); - int fd_value = fd.get(); - EXPECT_NE(-1, fd_value); - FileDescriptor fd2; - fd2 = std::move(fd); - EXPECT_EQ(fd_value, fd2.get()); - EXPECT_EQ(-1, fd.get()); +TEST(FileTest, MoveAssignment) { + File f(".travis.yml", File::RDONLY); + int fd = f.get(); + EXPECT_NE(-1, fd); + File f2; + f2 = std::move(f); + EXPECT_EQ(fd, f2.get()); + EXPECT_EQ(-1, f.get()); } bool IsClosed(int fd) { @@ -194,48 +193,48 @@ bool IsClosed(int fd) { return result == -1 && errno == EBADF; } -TEST(FileDescriptorTest, MoveAssignmentClosesFile) { - FileDescriptor fd(".travis.yml", FileDescriptor::RDONLY); - FileDescriptor fd2("CMakeLists.txt", FileDescriptor::RDONLY); - int old_fd = fd2.get(); - fd2 = std::move(fd); +TEST(FileTest, MoveAssignmentClosesFile) { + File f(".travis.yml", File::RDONLY); + File f2("CMakeLists.txt", File::RDONLY); + int old_fd = f2.get(); + f2 = std::move(f); EXPECT_TRUE(IsClosed(old_fd)); } -FileDescriptor OpenFile(int &fd_value) { - FileDescriptor fd(".travis.yml", FileDescriptor::RDONLY); - fd_value = fd.get(); - return std::move(fd); +File OpenFile(int &fd) { + File f(".travis.yml", File::RDONLY); + fd = f.get(); + return std::move(f); } -TEST(FileDescriptorTest, MoveFromTemporaryInCtor) { - int fd_value = 0xdeadbeef; - FileDescriptor fd(OpenFile(fd_value)); - EXPECT_EQ(fd_value, fd.get()); +TEST(FileTest, MoveFromTemporaryInCtor) { + int fd = 0xdeadbeef; + File f(OpenFile(fd)); + EXPECT_EQ(fd, f.get()); } -TEST(FileDescriptorTest, MoveFromTemporaryInAssignment) { - int fd_value = 0xdeadbeef; - FileDescriptor fd; - fd = OpenFile(fd_value); - EXPECT_EQ(fd_value, fd.get()); +TEST(FileTest, MoveFromTemporaryInAssignment) { + int fd = 0xdeadbeef; + File f; + f = OpenFile(fd); + EXPECT_EQ(fd, f.get()); } -TEST(FileDescriptorTest, MoveFromTemporaryInAssignmentClosesFile) { - int fd_value = 0xdeadbeef; - FileDescriptor fd(".travis.yml", FileDescriptor::RDONLY); - int old_fd = fd.get(); - fd = OpenFile(fd_value); +TEST(FileTest, MoveFromTemporaryInAssignmentClosesFile) { + int fd = 0xdeadbeef; + File f(".travis.yml", File::RDONLY); + int old_fd = f.get(); + f = OpenFile(fd); EXPECT_TRUE(IsClosed(old_fd)); } -TEST(FileDescriptorTest, CloseFileInDtor) { - int fd_value = 0; +TEST(FileTest, CloseFileInDtor) { + int fd = 0; { - FileDescriptor fd(".travis.yml", FileDescriptor::RDONLY); - fd_value = fd.get(); + File f(".travis.yml", File::RDONLY); + fd = f.get(); } - FILE *f = fdopen(fd_value, "r"); + FILE *f = fdopen(fd, "r"); int error_code = errno; if (f) fclose(f); @@ -243,89 +242,88 @@ TEST(FileDescriptorTest, CloseFileInDtor) { EXPECT_EQ(EBADF, error_code); } -TEST(FileDescriptorTest, CloseError) { - FileDescriptor *fd = - new FileDescriptor(".travis.yml", FileDescriptor::RDONLY); +TEST(FileTest, CloseError) { + File *fd = new File(".travis.yml", File::RDONLY); EXPECT_STDERR(close(fd->get()); delete fd, FormatSystemErrorMessage(EBADF, "cannot close file") + "\n"); } -std::string ReadLine(FileDescriptor &fd) { +std::string ReadLine(File &f) { enum { BUFFER_SIZE = 100 }; char buffer[BUFFER_SIZE]; - std::streamsize result = fd.read(buffer, BUFFER_SIZE); + std::streamsize result = f.read(buffer, BUFFER_SIZE); buffer[std::min(BUFFER_SIZE - 1, result)] = '\0'; if (char *end = strchr(buffer, '\n')) *end = '\0'; return buffer; } -TEST(FileDescriptorTest, Read) { - FileDescriptor fd(".travis.yml", FileDescriptor::RDONLY); - EXPECT_EQ("language: cpp", ReadLine(fd)); +TEST(FileTest, Read) { + File f(".travis.yml", File::RDONLY); + EXPECT_EQ("language: cpp", ReadLine(f)); } -TEST(FileDescriptorTest, ReadError) { - FileDescriptor fd; +TEST(FileTest, ReadError) { + File f; char buf; - EXPECT_SYSTEM_ERROR(fd.read(&buf, 1), EBADF, "cannot read from file"); + EXPECT_SYSTEM_ERROR(f.read(&buf, 1), EBADF, "cannot read from file"); } -TEST(FileDescriptorTest, Dup) { - FileDescriptor fd(".travis.yml", FileDescriptor::RDONLY); - FileDescriptor dup = FileDescriptor::dup(fd.get()); - EXPECT_NE(fd.get(), dup.get()); +TEST(FileTest, Dup) { + File f(".travis.yml", File::RDONLY); + File dup = File::dup(f.get()); + EXPECT_NE(f.get(), dup.get()); EXPECT_EQ("language: cpp", ReadLine(dup)); } -TEST(FileDescriptorTest, DupError) { - EXPECT_SYSTEM_ERROR(FileDescriptor::dup(-1), +TEST(FileTest, DupError) { + EXPECT_SYSTEM_ERROR(File::dup(-1), EBADF, "cannot duplicate file descriptor -1"); } -TEST(FileDescriptorTest, Dup2) { - FileDescriptor fd(".travis.yml", FileDescriptor::RDONLY); - FileDescriptor dup("CMakeLists.txt", FileDescriptor::RDONLY); - fd.dup2(dup.get()); - EXPECT_NE(fd.get(), dup.get()); +TEST(FileTest, Dup2) { + File f(".travis.yml", File::RDONLY); + File dup("CMakeLists.txt", File::RDONLY); + f.dup2(dup.get()); + EXPECT_NE(f.get(), dup.get()); EXPECT_EQ("language: cpp", ReadLine(dup)); } -TEST(FileDescriptorTest, Dup2Error) { - FileDescriptor fd(".travis.yml", FileDescriptor::RDONLY); - EXPECT_SYSTEM_ERROR(fd.dup2(-1), EBADF, - fmt::Format("cannot duplicate file descriptor {} to -1") << fd.get()); +TEST(FileTest, Dup2Error) { + File f(".travis.yml", File::RDONLY); + EXPECT_SYSTEM_ERROR(f.dup2(-1), EBADF, + fmt::Format("cannot duplicate file descriptor {} to -1") << f.get()); } -TEST(FileDescriptorTest, Dup2NoExcept) { - FileDescriptor fd(".travis.yml", FileDescriptor::RDONLY); - FileDescriptor dup("CMakeLists.txt", FileDescriptor::RDONLY); +TEST(FileTest, Dup2NoExcept) { + File f(".travis.yml", File::RDONLY); + File dup("CMakeLists.txt", File::RDONLY); ErrorCode ec; - fd.dup2(dup.get(), ec); + f.dup2(dup.get(), ec); EXPECT_EQ(0, ec.get()); - EXPECT_NE(fd.get(), dup.get()); + EXPECT_NE(f.get(), dup.get()); EXPECT_EQ("language: cpp", ReadLine(dup)); } -TEST(FileDescriptorTest, Dup2NoExceptError) { - FileDescriptor fd(".travis.yml", FileDescriptor::RDONLY); +TEST(FileTest, Dup2NoExceptError) { + File f(".travis.yml", File::RDONLY); ErrorCode ec; - fd.dup2(-1, ec); + f.dup2(-1, ec); EXPECT_EQ(EBADF, ec.get()); } -TEST(FileDescriptorTest, Pipe) { - FileDescriptor read_fd, write_fd; - FileDescriptor::pipe(read_fd, write_fd); - EXPECT_NE(-1, read_fd.get()); - EXPECT_NE(-1, write_fd.get()); +TEST(FileTest, Pipe) { + File read_end, write_end; + File::pipe(read_end, write_end); + EXPECT_NE(-1, read_end.get()); + EXPECT_NE(-1, write_end.get()); // TODO: try writing to write_fd and reading from read_fd } // TODO: test pipe -// TODO: test FileDescriptor::read +// TODO: test File::read // TODO: compile both with C++11 & C++98 mode diff --git a/test/gtest-extra.cc b/test/gtest-extra.cc index df024560..5b18121e 100644 --- a/test/gtest-extra.cc +++ b/test/gtest-extra.cc @@ -51,7 +51,7 @@ result = (expression); \ } while (result == -1 && errno == EINTR) -FileDescriptor::FileDescriptor(const char *path, int oflag) { +File::File(const char *path, int oflag) { int mode = S_IRUSR | S_IWUSR; #ifdef _WIN32 fd_ = -1; @@ -63,7 +63,7 @@ FileDescriptor::FileDescriptor(const char *path, int oflag) { fmt::ThrowSystemError(errno, "cannot open file {}") << path; } -void FileDescriptor::close() { +void File::close() { if (fd_ == -1) return; // Don't need to retry close in case of EINTR. @@ -72,7 +72,7 @@ void FileDescriptor::close() { fmt::ReportSystemError(errno, "cannot close file"); } -std::streamsize FileDescriptor::read(void *buffer, std::size_t count) { +std::streamsize File::read(void *buffer, std::size_t count) { std::streamsize result = 0; FMT_RETRY(result, ::read(fd_, buffer, count)); if (result == -1) @@ -80,7 +80,7 @@ std::streamsize FileDescriptor::read(void *buffer, std::size_t count) { return result; } -std::streamsize FileDescriptor::write(const void *buffer, std::size_t count) { +std::streamsize File::write(const void *buffer, std::size_t count) { std::streamsize result = 0; FMT_RETRY(result, ::write(fd_, buffer, count)); if (result == -1) @@ -88,15 +88,15 @@ std::streamsize FileDescriptor::write(const void *buffer, std::size_t count) { return result; } -FileDescriptor FileDescriptor::dup(int fd) { +File File::dup(int fd) { int new_fd = 0; FMT_RETRY(new_fd, ::FMT_POSIX(dup(fd))); if (new_fd == -1) fmt::ThrowSystemError(errno, "cannot duplicate file descriptor {}") << fd; - return FileDescriptor(new_fd); + return File(new_fd); } -void FileDescriptor::dup2(int fd) { +void File::dup2(int fd) { int result = 0; FMT_RETRY(result, ::FMT_POSIX(dup2(fd_, fd))); if (result == -1) { @@ -105,18 +105,18 @@ void FileDescriptor::dup2(int fd) { } } -void FileDescriptor::dup2(int fd, ErrorCode &ec) FMT_NOEXCEPT(true) { +void File::dup2(int fd, ErrorCode &ec) FMT_NOEXCEPT(true) { int result = 0; FMT_RETRY(result, ::FMT_POSIX(dup2(fd_, fd))); if (result == -1) ec = ErrorCode(errno); } -void FileDescriptor::pipe(FileDescriptor &read_fd, FileDescriptor &write_fd) { +void File::pipe(File &read_end, File &write_end) { // Close the descriptors first to make sure that assignments don't throw // and there are no leaks. - read_fd.close(); - write_fd.close(); + read_end.close(); + write_end.close(); int fds[2] = {}; #ifdef _WIN32 // Make the default pipe capacity same as on Linux 2.6.11+. @@ -130,25 +130,25 @@ void FileDescriptor::pipe(FileDescriptor &read_fd, FileDescriptor &write_fd) { fmt::ThrowSystemError(errno, "cannot create pipe"); // The following assignments don't throw because read_fd and write_fd // are closed. - read_fd = FileDescriptor(fds[0]); - write_fd = FileDescriptor(fds[1]); + read_end = File(fds[0]); + write_end = File(fds[1]); } OutputRedirector::OutputRedirector(FILE *file) : file_(file) { if (std::fflush(file) != 0) fmt::ThrowSystemError(errno, "cannot flush stream"); int fd = fileno(file); - saved_fd_ = FileDescriptor::dup(fd); - FileDescriptor write_fd; - FileDescriptor::pipe(read_fd_, write_fd); - write_fd.dup2(fd); + saved_ = File::dup(fd); + File write_end; + File::pipe(read_end_, write_end); + write_end.dup2(fd); } OutputRedirector::~OutputRedirector() { if (std::fflush(file_) != 0) fmt::ReportSystemError(errno, "cannot flush stream"); ErrorCode ec; - saved_fd_.dup2(fileno(file_), ec); + saved_.dup2(fileno(file_), ec); if (ec.get()) fmt::ReportSystemError(errno, "cannot restore output"); } @@ -157,7 +157,7 @@ std::string OutputRedirector::Read() { // Restore output. if (std::fflush(file_) != 0) fmt::ThrowSystemError(errno, "cannot flush stream"); - saved_fd_.dup2(fileno(file_)); + saved_.dup2(fileno(file_)); // Read everything from the pipe. std::string content; @@ -165,7 +165,7 @@ std::string OutputRedirector::Read() { char buffer[BUFFER_SIZE]; std::streamsize count = 0; do { - count = read_fd_.read(buffer, BUFFER_SIZE); + count = read_end_.read(buffer, BUFFER_SIZE); content.append(buffer, count); } while (count != 0); return content; diff --git a/test/gtest-extra.h b/test/gtest-extra.h index c7bd6168..1f2a05a8 100644 --- a/test/gtest-extra.h +++ b/test/gtest-extra.h @@ -103,16 +103,16 @@ class ErrorCode { int get() const FMT_NOEXCEPT(true) { return value_; } }; -// A RAII class for file descriptors. -class FileDescriptor { +// A file. +class File { private: - int fd_; + int fd_; // File descriptor. // Closes the file if its descriptor is not -1. void close(); - // Constructs a FileDescriptor object with a given descriptor. - explicit FileDescriptor(int fd) : fd_(fd) {} + // Constructs a File object with a given descriptor. + explicit File(int fd) : fd_(fd) {} public: // Possible values for the oflag argument to the constructor. @@ -122,13 +122,12 @@ class FileDescriptor { RDWR = FMT_POSIX(O_RDWR) // Open for reading and writing. }; - // Constructs a FileDescriptor object with a descriptor of -1 which - // is ignored by the destructor. - FileDescriptor() FMT_NOEXCEPT(true) : fd_(-1) {} + // Constructs a File object which doesn't represent any file. + File() FMT_NOEXCEPT(true) : fd_(-1) {} - // Opens a file and constructs a FileDescriptor object with the descriptor - // of the opened file. Throws fmt::SystemError on error. - FileDescriptor(const char *path, int oflag); + // Opens a file and constructs a File object representing this file. + // Throws fmt::SystemError on error. + File(const char *path, int oflag); #if !FMT_USE_RVALUE_REFERENCES // Emulate a move constructor and a move assignment operator if rvalue @@ -143,22 +142,22 @@ class FileDescriptor { public: // A "move" constructor for moving from a temporary. - FileDescriptor(Proxy p) FMT_NOEXCEPT(true) : fd_(p.fd) {} + File(Proxy p) FMT_NOEXCEPT(true) : fd_(p.fd) {} // A "move" constructor for for moving from an lvalue. - FileDescriptor(FileDescriptor &other) FMT_NOEXCEPT(true) : fd_(other.fd_) { + File(File &other) FMT_NOEXCEPT(true) : fd_(other.fd_) { other.fd_ = -1; } // A "move" assignment operator for moving from a temporary. - FileDescriptor &operator=(Proxy p) { + File &operator=(Proxy p) { close(); fd_ = p.fd; return *this; } // A "move" assignment operator for moving from an lvalue. - FileDescriptor &operator=(FileDescriptor &other) { + File &operator=(File &other) { close(); fd_ = other.fd_; other.fd_ = -1; @@ -166,7 +165,7 @@ class FileDescriptor { } // Returns a proxy object for moving from a temporary: - // FileDescriptor fd = FileDescriptor(...); + // File file = File(...); operator Proxy() FMT_NOEXCEPT(true) { Proxy p = {fd_}; fd_ = -1; @@ -174,37 +173,36 @@ class FileDescriptor { } #else private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(FileDescriptor); + GTEST_DISALLOW_COPY_AND_ASSIGN_(File); public: - FileDescriptor(FileDescriptor &&other) FMT_NOEXCEPT(true) : fd_(other.fd_) { + File(File &&other) FMT_NOEXCEPT(true) : fd_(other.fd_) { other.fd_ = -1; } - FileDescriptor& operator=(FileDescriptor &&other) FMT_NOEXCEPT(true) { + File& operator=(File &&other) FMT_NOEXCEPT(true) { fd_ = other.fd_; other.fd_ = -1; return *this; } #endif - // Closes the file if its descriptor is not -1 and destroys the object. - ~FileDescriptor() { close(); } + // Destroys the object closing the file it represents if any. + ~File() { close(); } // Returns the file descriptor. + // TODO: rename int get() const FMT_NOEXCEPT(true) { return fd_; } - // Attempts to read count bytes from the file associated with this file - // descriptor into the specified buffer. + // Attempts to read count bytes from the file into the specified buffer. std::streamsize read(void *buffer, std::size_t count); - // Attempts to write count bytes from the specified buffer to the file - // associated with this file descriptor. + // Attempts to write count bytes from the specified buffer to the file. std::streamsize write(const 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); + // the duplicate as a file object. Throws fmt::SystemError on error. + static File dup(int fd); // Makes fd be the copy of this file descriptor, closing fd first if // necessary. Throws fmt::SystemError on error. @@ -214,15 +212,15 @@ class FileDescriptor { // necessary. void dup2(int fd, ErrorCode &ec) FMT_NOEXCEPT(true); - // Creates a pipe setting up read and write file descriptors for reading - // and writing respecively. Throws fmt::SystemError on error. - static void pipe(FileDescriptor &read_fd, FileDescriptor &write_fd); + // Creates a pipe setting up read_end and write_end file objects for reading + // and writing respectively. Throws fmt::SystemError on error. + static void pipe(File &read_end, File &write_end); }; #if !FMT_USE_RVALUE_REFERENCES namespace std { // For compatibility with C++98. -inline FileDescriptor &move(FileDescriptor &fd) { return fd; } +inline File &move(File &f) { return f; } } #endif @@ -230,9 +228,8 @@ inline FileDescriptor &move(FileDescriptor &fd) { return fd; } class OutputRedirector { private: FILE *file_; - FileDescriptor saved_fd_; // Saved file descriptor created with dup. - FileDescriptor read_fd_; // Read end of the pipe where the output is - // redirected. + File saved_; // Saved file created with dup. + File read_end_; // Read end of the pipe where the output is redirected. GTEST_DISALLOW_COPY_AND_ASSIGN_(OutputRedirector);