mirror of
https://github.com/fmtlib/fmt.git
synced 2025-04-18 11:42:22 +00:00
Add FileDescriptor::read.
This commit is contained in:
parent
90a3f0a620
commit
a297e272d1
@ -43,9 +43,6 @@
|
|||||||
# define S_IRUSR _S_IREAD
|
# define S_IRUSR _S_IREAD
|
||||||
# define S_IWUSR _S_IWRITE
|
# define S_IWUSR _S_IWRITE
|
||||||
|
|
||||||
// The read function is defined as returning int on Windows.
|
|
||||||
typedef int ssize_t;
|
|
||||||
|
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
// Retries the expression while it evaluates to -1 and error equals to EINTR.
|
// 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");
|
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) {
|
FileDescriptor FileDescriptor::dup(int fd) {
|
||||||
int new_fd = 0;
|
int new_fd = 0;
|
||||||
FMT_RETRY(new_fd, ::FMT_POSIX(dup(fd)));
|
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 };
|
enum { DEFAULT_CAPACITY = 65536 };
|
||||||
int result = _pipe(fds, DEFAULT_CAPACITY, _O_BINARY);
|
int result = _pipe(fds, DEFAULT_CAPACITY, _O_BINARY);
|
||||||
#else
|
#else
|
||||||
|
// The pipe function doesn't return EINTR, so no need to retry.
|
||||||
int result = ::pipe(fds);
|
int result = ::pipe(fds);
|
||||||
#endif
|
#endif
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
@ -145,14 +151,16 @@ std::string OutputRedirector::Read() {
|
|||||||
fmt::ThrowSystemError(errno, "cannot flush stream");
|
fmt::ThrowSystemError(errno, "cannot flush stream");
|
||||||
saved_fd_.dup2(fileno(file_));
|
saved_fd_.dup2(fileno(file_));
|
||||||
|
|
||||||
// TODO: move to FileDescriptor
|
// Read everything from the pipe.
|
||||||
enum { BUFFER_SIZE = 100 };
|
std::string content;
|
||||||
|
enum { BUFFER_SIZE = 4096 };
|
||||||
char buffer[BUFFER_SIZE];
|
char buffer[BUFFER_SIZE];
|
||||||
ssize_t result = read(read_fd_.get(), buffer, BUFFER_SIZE);
|
std::streamsize count = 0;
|
||||||
if (result == -1)
|
do {
|
||||||
fmt::ThrowSystemError(errno, "cannot read file");
|
count = read_fd_.read(buffer, BUFFER_SIZE);
|
||||||
buffer[std::min<ssize_t>(BUFFER_SIZE - 1, result)] = '\0';
|
content.append(buffer, count);
|
||||||
return buffer;
|
} while (count != 0);
|
||||||
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: test EXPECT_STDOUT and EXPECT_STDERR
|
// TODO: test EXPECT_STDOUT and EXPECT_STDERR
|
||||||
|
@ -28,6 +28,10 @@
|
|||||||
#ifndef FMT_GTEST_EXTRA_H
|
#ifndef FMT_GTEST_EXTRA_H
|
||||||
#define FMT_GTEST_EXTRA_H
|
#define FMT_GTEST_EXTRA_H
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <ios>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#if FMT_USE_FILE_DESCRIPTORS
|
#if FMT_USE_FILE_DESCRIPTORS
|
||||||
# include <fcntl.h>
|
# include <fcntl.h>
|
||||||
#endif
|
#endif
|
||||||
@ -190,6 +194,10 @@ class FileDescriptor {
|
|||||||
// Returns the file descriptor.
|
// Returns the file descriptor.
|
||||||
int get() const FMT_NOEXCEPT(true) { return fd_; }
|
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
|
// Duplicates a file descriptor with the dup function and returns
|
||||||
// the duplicate. Throws fmt::SystemError on error.
|
// the duplicate. Throws fmt::SystemError on error.
|
||||||
static FileDescriptor dup(int fd);
|
static FileDescriptor dup(int fd);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user