More posix tests.

This commit is contained in:
Victor Zverovich 2014-05-18 10:05:29 -07:00
parent e654f56210
commit f21fa23186
3 changed files with 58 additions and 10 deletions

View File

@ -136,8 +136,9 @@ std::streamsize File::write(const void *buffer, std::size_t count) {
}
File File::dup(int fd) {
int new_fd = 0;
FMT_RETRY(new_fd, FMT_POSIX_CALL(dup(fd)));
// Don't retry as dup doesn't return EINTR.
// http://pubs.opengroup.org/onlinepubs/009695399/functions/dup.html
int new_fd = FMT_POSIX_CALL(dup(fd));
if (new_fd == -1)
fmt::ThrowSystemError(errno, "cannot duplicate file descriptor {}") << fd;
return File(new_fd);
@ -168,10 +169,11 @@ void File::pipe(File &read_end, File &write_end) {
#ifdef _WIN32
// Make the default pipe capacity same as on Linux 2.6.11+.
enum { DEFAULT_CAPACITY = 65536 };
int result = _pipe(fds, DEFAULT_CAPACITY, _O_BINARY);
int result = FMT_POSIX_CALL(pipe(fds, DEFAULT_CAPACITY, _O_BINARY));
#else
// The pipe function doesn't return EINTR, so no need to retry.
int result = ::pipe(fds);
// Don't retry as the pipe function doesn't return EINTR.
// http://pubs.opengroup.org/onlinepubs/009696799/functions/pipe.html
int result = FMT_POSIX_CALL(pipe(fds));
#endif
if (result != 0)
fmt::ThrowSystemError(errno, "cannot create pipe");
@ -182,9 +184,15 @@ void File::pipe(File &read_end, File &write_end) {
}
BufferedFile File::fdopen(const char *mode) {
BufferedFile f(FMT_POSIX_CALL(fdopen(fd_, mode)));
// Don't retry as fdopen doesn't return EINTR.
FILE *f = FMT_POSIX_CALL(fdopen(fd_, mode));
if (!f) {
fmt::ThrowSystemError(errno,
"cannot associate stream with file descriptor");
}
BufferedFile file(f);
fd_ = -1;
return f;
return file;
}
void OutputRedirect::Flush() {

View File

@ -41,6 +41,7 @@ int fdopen_count;
int fileno_count;
int read_count;
int write_count;
int pipe_count;
}
#define EMULATE_EINTR(func, error_result) \
@ -101,6 +102,11 @@ test::ssize_t test::write(int fildes, const void *buf, test::size_t nbyte) {
return ::write(fildes, buf, nbyte);
}
int test::pipe(int fildes[2]) {
EMULATE_EINTR(pipe, -1);
return ::pipe(fildes);
}
#ifndef _WIN32
# define EXPECT_RETRY(statement, func, message) \
func##_count = 1; \
@ -180,10 +186,12 @@ TEST(FileTest, WriteRetry) {
#endif
}
TEST(FileTest, DupRetry) {
TEST(FileTest, DupNoRetry) {
int stdout_fd = fileno(stdout);
EXPECT_RETRY(File::dup(stdout_fd), dup,
dup_count = 1;
EXPECT_SYSTEM_ERROR(File::dup(stdout_fd), EINTR,
str(fmt::Format("cannot duplicate file descriptor {}") << stdout_fd));
dup_count = 0;
}
TEST(FileTest, Dup2Retry) {
@ -193,5 +201,35 @@ TEST(FileTest, Dup2Retry) {
<< f1.descriptor() << f2.descriptor()));
}
// TODO: test retry on EINTR in dup2, pipe, fdopen
TEST(FileTest, Dup2NoExceptRetry) {
File f1 = File::dup(fileno(stdout)), f2 = File::dup(fileno(stdout));
ErrorCode ec;
dup2_count = 1;
f1.dup2(f2.descriptor(), ec);
#ifndef _WIN32
EXPECT_EQ(4, dup2_count);
#else
EXPECT_EQ(EINTR, ec.get());
#endif
dup2_count = 0;
}
TEST(FileTest, PipeNoRetry) {
File read_end, write_end;
pipe_count = 1;
EXPECT_SYSTEM_ERROR(
File::pipe(read_end, write_end), EINTR, "cannot create pipe");
pipe_count = 0;
}
TEST(FileTest, FdopenNoRetry) {
File read_end, write_end;
File::pipe(read_end, write_end);
fdopen_count = 1;
EXPECT_SYSTEM_ERROR(read_end.fdopen("r"),
EINTR, "cannot associate stream with file descriptor");
fdopen_count = 0;
}
// TODO: test retry on EINTR in fclose & fileno
// TODO: test ConvertRWCount

View File

@ -56,6 +56,8 @@ int fileno(FILE *stream);
ssize_t read(int fildes, void *buf, size_t nbyte);
ssize_t write(int fildes, const void *buf, size_t nbyte);
int pipe(int fildes[2]);
} // namespace test
#define FMT_POSIX_CALL(call) test::call