summaryrefslogtreecommitdiff
path: root/tests/stdio_test.cpp
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2017-07-25 18:06:46 -0700
committerElliott Hughes <enh@google.com>2017-07-25 18:11:23 -0700
commit33a8cb1d1a32b40406ec643f4a781c4a592a6f44 (patch)
tree06be4fc0f936ba60093cb4e4c1133500a6c2bda4 /tests/stdio_test.cpp
parent33f9043f482769c35f82df9d25b4ccc8f1193229 (diff)
Use O_APPEND for stdio append mode.
"Although not explicitly required by this volume of POSIX.1-2008, a good implementation of append (a) mode would cause the O_APPEND flag to be set." Yeah, about that... Bug: N/A Test: ran tests Change-Id: I23c4bc5c1ebc92e0cb44025d2d313f321f9ffa68
Diffstat (limited to 'tests/stdio_test.cpp')
-rw-r--r--tests/stdio_test.cpp72
1 files changed, 72 insertions, 0 deletions
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index 1f27c832a..dac7056e2 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -47,6 +47,24 @@ using namespace std::string_literals;
class stdio_DeathTest : public BionicDeathTest {};
class stdio_nofortify_DeathTest : public BionicDeathTest {};
+static void SetFileTo(const char* path, const char* content) {
+ FILE* fp;
+ ASSERT_NE(nullptr, fp = fopen(path, "w"));
+ ASSERT_NE(EOF, fputs(content, fp));
+ ASSERT_EQ(0, fclose(fp));
+}
+
+static void AssertFileIs(const char* path, const char* expected) {
+ FILE* fp;
+ ASSERT_NE(nullptr, fp = fopen(path, "r"));
+ char* line = nullptr;
+ size_t length;
+ ASSERT_NE(EOF, getline(&line, &length, fp));
+ ASSERT_EQ(0, fclose(fp));
+ ASSERT_STREQ(expected, line);
+ free(line);
+}
+
static void AssertFileIs(FILE* fp, const char* expected, bool is_fmemopen = false) {
rewind(fp);
@@ -1846,3 +1864,57 @@ TEST(STDIO_TEST, sprintf_30445072) {
sprintf(&buf[0], "hello");
ASSERT_EQ(buf, "hello");
}
+
+TEST(STDIO_TEST, fopen_append_mode_and_ftell) {
+ TemporaryFile tf;
+ SetFileTo(tf.filename, "0123456789");
+ FILE* fp = fopen(tf.filename, "a");
+ EXPECT_EQ(10, ftell(fp));
+ ASSERT_EQ(0, fseek(fp, 2, SEEK_SET));
+ EXPECT_EQ(2, ftell(fp));
+ ASSERT_NE(EOF, fputs("xxx", fp));
+ ASSERT_EQ(0, fflush(fp));
+ EXPECT_EQ(13, ftell(fp));
+ ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
+ EXPECT_EQ(13, ftell(fp));
+ ASSERT_EQ(0, fclose(fp));
+ AssertFileIs(tf.filename, "0123456789xxx");
+}
+
+TEST(STDIO_TEST, fdopen_append_mode_and_ftell) {
+ TemporaryFile tf;
+ SetFileTo(tf.filename, "0123456789");
+ int fd = open(tf.filename, O_RDWR);
+ ASSERT_NE(-1, fd);
+ // POSIX: "The file position indicator associated with the new stream is set to the position
+ // indicated by the file offset associated with the file descriptor."
+ ASSERT_EQ(4, lseek(fd, 4, SEEK_SET));
+ FILE* fp = fdopen(fd, "a");
+ EXPECT_EQ(4, ftell(fp));
+ ASSERT_EQ(0, fseek(fp, 2, SEEK_SET));
+ EXPECT_EQ(2, ftell(fp));
+ ASSERT_NE(EOF, fputs("xxx", fp));
+ ASSERT_EQ(0, fflush(fp));
+ EXPECT_EQ(13, ftell(fp));
+ ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
+ EXPECT_EQ(13, ftell(fp));
+ ASSERT_EQ(0, fclose(fp));
+ AssertFileIs(tf.filename, "0123456789xxx");
+}
+
+TEST(STDIO_TEST, freopen_append_mode_and_ftell) {
+ TemporaryFile tf;
+ SetFileTo(tf.filename, "0123456789");
+ FILE* other_fp = fopen("/proc/version", "r");
+ FILE* fp = freopen(tf.filename, "a", other_fp);
+ EXPECT_EQ(10, ftell(fp));
+ ASSERT_EQ(0, fseek(fp, 2, SEEK_SET));
+ EXPECT_EQ(2, ftell(fp));
+ ASSERT_NE(EOF, fputs("xxx", fp));
+ ASSERT_EQ(0, fflush(fp));
+ EXPECT_EQ(13, ftell(fp));
+ ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
+ EXPECT_EQ(13, ftell(fp));
+ ASSERT_EQ(0, fclose(fp));
+ AssertFileIs(tf.filename, "0123456789xxx");
+}