Commit 564da259 authored by Victor Zverovich's avatar Victor Zverovich

Add ctor & print method to BufferedFile.

parent 108cd1d1
...@@ -70,6 +70,16 @@ fmt::BufferedFile::~BufferedFile() FMT_NOEXCEPT(true) { ...@@ -70,6 +70,16 @@ fmt::BufferedFile::~BufferedFile() FMT_NOEXCEPT(true) {
fmt::report_system_error(errno, "cannot close file"); fmt::report_system_error(errno, "cannot close file");
} }
fmt::BufferedFile::BufferedFile(fmt::StringRef filename, fmt::StringRef mode) {
for (;;) {
file_ = FMT_SYSTEM(fopen(filename.c_str(), mode.c_str()));
if (file_)
return;
if (errno != EINTR)
throw SystemError(errno, "cannot open file");
}
}
void fmt::BufferedFile::close() { void fmt::BufferedFile::close() {
if (!file_) if (!file_)
return; return;
......
...@@ -162,6 +162,9 @@ public: ...@@ -162,6 +162,9 @@ public:
} }
#endif #endif
// Opens a file.
BufferedFile(fmt::StringRef filename, fmt::StringRef mode);
// Closes the file. // Closes the file.
void close(); void close();
...@@ -169,6 +172,11 @@ public: ...@@ -169,6 +172,11 @@ public:
FILE *get() const { return file_; } FILE *get() const { return file_; }
int fileno() const; int fileno() const;
void print(fmt::StringRef format_str, const ArgList &args) {
fmt::print(file_, format_str, args);
}
FMT_VARIADIC(void, print, fmt::StringRef)
}; };
// A file. Closed file is represented by a File object with descriptor -1. // A file. Closed file is represented by a File object with descriptor -1.
......
...@@ -50,6 +50,7 @@ int fdopen_count; ...@@ -50,6 +50,7 @@ int fdopen_count;
int read_count; int read_count;
int write_count; int write_count;
int pipe_count; int pipe_count;
int fopen_count;
int fclose_count; int fclose_count;
int fileno_count; int fileno_count;
std::size_t read_nbyte; std::size_t read_nbyte;
...@@ -123,6 +124,11 @@ int test::pipe(int *pfds, unsigned psize, int textmode) { ...@@ -123,6 +124,11 @@ int test::pipe(int *pfds, unsigned psize, int textmode) {
} }
#endif #endif
FILE *test::fopen(const char *filename, const char *mode) {
EMULATE_EINTR(fopen, 0);
return ::fopen(filename, mode);
}
int test::fclose(FILE *stream) { int test::fclose(FILE *stream) {
EMULATE_EINTR(fclose, EOF); EMULATE_EINTR(fclose, EOF);
return ::fclose(stream); return ::fclose(stream);
...@@ -148,10 +154,16 @@ int test::fileno(FILE *stream) { ...@@ -148,10 +154,16 @@ int test::fileno(FILE *stream) {
# define EXPECT_EQ_POSIX(expected, actual) # define EXPECT_EQ_POSIX(expected, actual)
#endif #endif
void write_file(fmt::StringRef filename, fmt::StringRef content) {
fmt::BufferedFile f(filename, "w");
fmt::print(f.get(), "{}", content);
}
TEST(FileTest, OpenRetry) { TEST(FileTest, OpenRetry) {
write_file("test", "there must be something here");
File *f = 0; File *f = 0;
EXPECT_RETRY(f = new File("CMakeLists.txt", File::RDONLY), EXPECT_RETRY(f = new File("test", File::RDONLY),
open, "cannot open file CMakeLists.txt"); open, "cannot open file test");
#ifndef _WIN32 #ifndef _WIN32
char c = 0; char c = 0;
f->read(&c, 1); f->read(&c, 1);
...@@ -289,6 +301,18 @@ TEST(FileTest, FdopenNoRetry) { ...@@ -289,6 +301,18 @@ TEST(FileTest, FdopenNoRetry) {
fdopen_count = 0; fdopen_count = 0;
} }
TEST(BufferedFileTest, OpenRetry) {
write_file("test", "there must be something here");
BufferedFile *f = 0;
EXPECT_RETRY(f = new BufferedFile("test", "r"),
fopen, "cannot open file test");
#ifndef _WIN32
char c = 0;
fread(&c, 1, 1, f->get());
#endif
delete f;
}
TEST(BufferedFileTest, CloseNoRetryInDtor) { TEST(BufferedFileTest, CloseNoRetryInDtor) {
File read_end, write_end; File read_end, write_end;
File::pipe(read_end, write_end); File::pipe(read_end, write_end);
......
...@@ -61,6 +61,7 @@ int pipe(int fildes[2]); ...@@ -61,6 +61,7 @@ int pipe(int fildes[2]);
int pipe(int *pfds, unsigned psize, int textmode); int pipe(int *pfds, unsigned psize, int textmode);
#endif #endif
FILE *fopen(const char *filename, const char *mode);
int fclose(FILE *stream); int fclose(FILE *stream);
int fileno(FILE *stream); int fileno(FILE *stream);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment