1 //===-- Unittests for fgets -----------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "src/stdio/fclose.h"
10 #include "src/stdio/feof.h"
11 #include "src/stdio/ferror.h"
12 #include "src/stdio/fgets.h"
13 #include "src/stdio/fopen.h"
14 #include "src/stdio/fwrite.h"
15 #include "test/UnitTest/Test.h"
17 #include "src/errno/libc_errno.h"
19 TEST(LlvmLibcFgetsTest
, WriteAndReadCharacters
) {
20 constexpr char FILENAME
[] = "testdata/fgets.test";
21 ::FILE *file
= LIBC_NAMESPACE::fopen(FILENAME
, "w");
22 ASSERT_FALSE(file
== nullptr);
23 constexpr char CONTENT
[] = "123456789\n"
27 constexpr size_t WRITE_SIZE
= sizeof(CONTENT
) - 1;
32 ASSERT_EQ(WRITE_SIZE
, LIBC_NAMESPACE::fwrite(CONTENT
, 1, WRITE_SIZE
, file
));
33 // This is a write-only file so reads should fail.
34 ASSERT_TRUE(LIBC_NAMESPACE::fgets(buff
, 8, file
) == nullptr);
35 // This is an error and not a real EOF.
36 ASSERT_EQ(LIBC_NAMESPACE::feof(file
), 0);
37 ASSERT_NE(LIBC_NAMESPACE::ferror(file
), 0);
38 LIBC_NAMESPACE::libc_errno
= 0;
40 ASSERT_EQ(0, LIBC_NAMESPACE::fclose(file
));
42 file
= LIBC_NAMESPACE::fopen(FILENAME
, "r");
43 ASSERT_FALSE(file
== nullptr);
45 // The GPU build relies on the host C library, so this check may be different.
46 #ifndef LIBC_TARGET_ARCH_IS_GPU
47 // If we request just 1 byte, it should return just a null byte and not
48 // advance the read head. This is implementation defined.
49 output
= LIBC_NAMESPACE::fgets(buff
, 1, file
);
50 ASSERT_TRUE(output
== buff
);
51 ASSERT_EQ(buff
[0], '\0');
52 ASSERT_ERRNO_SUCCESS();
54 // If we request less than 1 byte, it should do nothing and return nullptr.
55 // This is also implementation defined.
56 output
= LIBC_NAMESPACE::fgets(buff
, 0, file
);
57 ASSERT_TRUE(output
== nullptr);
60 const char *output_arr
[] = {
61 "1234567", "89\n", "1234567", "\n", "123456\n", "1",
64 constexpr size_t ARR_SIZE
= sizeof(output_arr
) / sizeof(char *);
66 for (size_t i
= 0; i
< ARR_SIZE
; ++i
) {
67 output
= LIBC_NAMESPACE::fgets(buff
, 8, file
);
69 // This pointer comparison is intentional, fgets should return a pointer to
70 // buff when it succeeds.
71 ASSERT_TRUE(output
== buff
);
72 ASSERT_EQ(LIBC_NAMESPACE::ferror(file
), 0);
74 EXPECT_STREQ(buff
, output_arr
[i
]);
77 // This should have hit the end of the file, but that isn't an error unless it
78 // fails to read anything.
79 ASSERT_NE(LIBC_NAMESPACE::feof(file
), 0);
80 ASSERT_EQ(LIBC_NAMESPACE::ferror(file
), 0);
81 ASSERT_ERRNO_SUCCESS();
83 // Reading more should be an EOF, but not an error.
84 output
= LIBC_NAMESPACE::fgets(buff
, 8, file
);
85 ASSERT_TRUE(output
== nullptr);
86 ASSERT_NE(LIBC_NAMESPACE::feof(file
), 0);
87 ASSERT_ERRNO_SUCCESS();
89 ASSERT_EQ(0, LIBC_NAMESPACE::fclose(file
));