Add FileDescriptor::read.

This commit is contained in:
Victor Zverovich 2014-05-03 11:26:46 -07:00
parent 90a3f0a620
commit a297e272d1
2 changed files with 26 additions and 10 deletions

View File

@ -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<ssize_t>(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

View File

@ -28,6 +28,10 @@
#ifndef FMT_GTEST_EXTRA_H
#define FMT_GTEST_EXTRA_H
#include <cstddef>
#include <ios>
#include <string>
#if FMT_USE_FILE_DESCRIPTORS
# include <fcntl.h>
#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);