Various coverage improvements.
Mostly from extra test cases, but also:
* Move the fgets size < 0 assertion into fgets.
* Use ELF aliases for strtoq/strtouq rather than duplicating code.
* Don't check uname() succeeded, since it can't fail.
Test: treehugger
Change-Id: I2e6b3b88b0a3eb16bd68be68b9bc9f40d8043291
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index f6eca05..c21c3b8 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -371,6 +371,11 @@
#endif
}
+TEST(STDIO_TEST, snprintf_measure) {
+ char buf[16];
+ ASSERT_EQ(11, snprintf(buf, 0, "Hello %s", "world"));
+}
+
TEST(STDIO_TEST, snprintf_smoke) {
char buf[BUFSIZ];
@@ -1155,7 +1160,6 @@
free(p1);
}
-
TEST(STDIO_TEST, sscanf_mlc) {
// This is so useless that clang doesn't even believe it exists...
#pragma clang diagnostic push
@@ -1189,7 +1193,6 @@
#pragma clang diagnostic pop
}
-
TEST(STDIO_TEST, sscanf_ms) {
CheckScanfM(sscanf, "hello", "%ms", 1, "hello");
CheckScanfM(sscanf, "hello", "%4ms", 1, "hell");
@@ -2533,6 +2536,16 @@
eth.Run([&]() { exit(puts("a b c")); }, 0, "a b c\n");
}
+TEST(STDIO_TEST, putchar) {
+ ExecTestHelper eth;
+ eth.Run([&]() { exit(putchar('A')); }, 65, "A");
+}
+
+TEST(STDIO_TEST, putchar_unlocked) {
+ ExecTestHelper eth;
+ eth.Run([&]() { exit(putchar('B')); }, 66, "B");
+}
+
TEST(STDIO_TEST, unlocked) {
TemporaryFile tf;
@@ -2733,3 +2746,73 @@
ASSERT_NE(0, RENAME_WHITEOUT);
#endif
}
+
+TEST(STDIO_TEST, fdopen_failures) {
+ FILE* fp;
+ int fd = open("/proc/version", O_RDONLY);
+ ASSERT_TRUE(fd != -1);
+
+ // Nonsense mode.
+ errno = 0;
+ fp = fdopen(fd, "nonsense");
+ ASSERT_TRUE(fp == nullptr);
+ ASSERT_EQ(EINVAL, errno);
+
+ // Mode that isn't a subset of the fd's actual mode.
+ errno = 0;
+ fp = fdopen(fd, "w");
+ ASSERT_TRUE(fp == nullptr);
+ ASSERT_EQ(EINVAL, errno);
+
+ // Can't set append on the underlying fd.
+ errno = 0;
+ fp = fdopen(fd, "a");
+ ASSERT_TRUE(fp == nullptr);
+ ASSERT_EQ(EINVAL, errno);
+
+ // Bad fd.
+ errno = 0;
+ fp = fdopen(-1, "re");
+ ASSERT_TRUE(fp == nullptr);
+ ASSERT_EQ(EBADF, errno);
+
+ close(fd);
+}
+
+TEST(STDIO_TEST, fmemopen_invalid_mode) {
+ errno = 0;
+ FILE* fp = fmemopen(nullptr, 16, "nonsense");
+ ASSERT_TRUE(fp == nullptr);
+ ASSERT_EQ(EINVAL, errno);
+}
+
+TEST(STDIO_TEST, fopen_invalid_mode) {
+ errno = 0;
+ FILE* fp = fopen("/proc/version", "nonsense");
+ ASSERT_TRUE(fp == nullptr);
+ ASSERT_EQ(EINVAL, errno);
+}
+
+TEST(STDIO_TEST, freopen_invalid_mode) {
+ FILE* fp = fopen("/proc/version", "re");
+ ASSERT_TRUE(fp != nullptr);
+
+ errno = 0;
+ fp = freopen("/proc/version", "nonsense", fp);
+ ASSERT_TRUE(fp == nullptr);
+ ASSERT_EQ(EINVAL, errno);
+}
+
+TEST(STDIO_TEST, asprintf_smoke) {
+ char* p = nullptr;
+ ASSERT_EQ(11, asprintf(&p, "hello %s", "world"));
+ ASSERT_STREQ("hello world", p);
+ free(p);
+}
+
+TEST(STDIO_TEST, fopen_ENOENT) {
+ errno = 0;
+ FILE* fp = fopen("/proc/does-not-exist", "re");
+ ASSERT_TRUE(fp == nullptr);
+ ASSERT_EQ(ENOENT, errno);
+}