xref: /aosp_15_r20/external/llvm-libc/test/src/stdio/setvbuf_test.cpp (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
1*71db0c75SAndroid Build Coastguard Worker //===-- Unittests for setvbuf ---------------------------------------------===//
2*71db0c75SAndroid Build Coastguard Worker //
3*71db0c75SAndroid Build Coastguard Worker // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*71db0c75SAndroid Build Coastguard Worker // See https://llvm.org/LICENSE.txt for license information.
5*71db0c75SAndroid Build Coastguard Worker // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*71db0c75SAndroid Build Coastguard Worker //
7*71db0c75SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
8*71db0c75SAndroid Build Coastguard Worker 
9*71db0c75SAndroid Build Coastguard Worker #include "src/stdio/fclose.h"
10*71db0c75SAndroid Build Coastguard Worker #include "src/stdio/fopen.h"
11*71db0c75SAndroid Build Coastguard Worker #include "src/stdio/fread.h"
12*71db0c75SAndroid Build Coastguard Worker #include "src/stdio/fwrite.h"
13*71db0c75SAndroid Build Coastguard Worker #include "src/stdio/setvbuf.h"
14*71db0c75SAndroid Build Coastguard Worker #include "test/UnitTest/Test.h"
15*71db0c75SAndroid Build Coastguard Worker 
16*71db0c75SAndroid Build Coastguard Worker #include "hdr/stdio_macros.h"
17*71db0c75SAndroid Build Coastguard Worker #include "src/errno/libc_errno.h"
18*71db0c75SAndroid Build Coastguard Worker 
TEST(LlvmLibcSetvbufTest,SetNBFBuffer)19*71db0c75SAndroid Build Coastguard Worker TEST(LlvmLibcSetvbufTest, SetNBFBuffer) {
20*71db0c75SAndroid Build Coastguard Worker   // The idea in this test is that we open a file for writing and reading, and
21*71db0c75SAndroid Build Coastguard Worker   // then set a NBF buffer to the write handle. Since it is NBF, the data
22*71db0c75SAndroid Build Coastguard Worker   // written using the write handle should be immediately readable by the read
23*71db0c75SAndroid Build Coastguard Worker   // handle.
24*71db0c75SAndroid Build Coastguard Worker   constexpr char FILENAME[] = "testdata/setvbuf_nbf.test";
25*71db0c75SAndroid Build Coastguard Worker 
26*71db0c75SAndroid Build Coastguard Worker   ::FILE *fw = LIBC_NAMESPACE::fopen(FILENAME, "w");
27*71db0c75SAndroid Build Coastguard Worker   ASSERT_FALSE(fw == nullptr);
28*71db0c75SAndroid Build Coastguard Worker   char buffer[BUFSIZ];
29*71db0c75SAndroid Build Coastguard Worker   ASSERT_EQ(LIBC_NAMESPACE::setvbuf(fw, buffer, _IONBF, BUFSIZ), 0);
30*71db0c75SAndroid Build Coastguard Worker 
31*71db0c75SAndroid Build Coastguard Worker   ::FILE *fr = LIBC_NAMESPACE::fopen(FILENAME, "r");
32*71db0c75SAndroid Build Coastguard Worker   ASSERT_FALSE(fr == nullptr);
33*71db0c75SAndroid Build Coastguard Worker 
34*71db0c75SAndroid Build Coastguard Worker   constexpr char CONTENT[] = "abcdef";
35*71db0c75SAndroid Build Coastguard Worker   constexpr size_t CONTENT_SIZE = sizeof(CONTENT);
36*71db0c75SAndroid Build Coastguard Worker   for (size_t i = 0; i < CONTENT_SIZE; ++i) {
37*71db0c75SAndroid Build Coastguard Worker     ASSERT_EQ(size_t(1), LIBC_NAMESPACE::fwrite(CONTENT + i, 1, 1, fw));
38*71db0c75SAndroid Build Coastguard Worker     char c;
39*71db0c75SAndroid Build Coastguard Worker     ASSERT_EQ(size_t(1), LIBC_NAMESPACE::fread(&c, 1, 1, fr));
40*71db0c75SAndroid Build Coastguard Worker     ASSERT_EQ(c, CONTENT[i]);
41*71db0c75SAndroid Build Coastguard Worker   }
42*71db0c75SAndroid Build Coastguard Worker 
43*71db0c75SAndroid Build Coastguard Worker   ASSERT_EQ(0, LIBC_NAMESPACE::fclose(fw));
44*71db0c75SAndroid Build Coastguard Worker   ASSERT_EQ(0, LIBC_NAMESPACE::fclose(fr));
45*71db0c75SAndroid Build Coastguard Worker 
46*71db0c75SAndroid Build Coastguard Worker   // Make sure NBF buffer has no effect for reading.
47*71db0c75SAndroid Build Coastguard Worker   fr = LIBC_NAMESPACE::fopen(FILENAME, "r");
48*71db0c75SAndroid Build Coastguard Worker   char data[CONTENT_SIZE];
49*71db0c75SAndroid Build Coastguard Worker   ASSERT_EQ(LIBC_NAMESPACE::setvbuf(fr, buffer, _IONBF, BUFSIZ), 0);
50*71db0c75SAndroid Build Coastguard Worker   ASSERT_EQ(CONTENT_SIZE, LIBC_NAMESPACE::fread(data, 1, CONTENT_SIZE, fr));
51*71db0c75SAndroid Build Coastguard Worker   ASSERT_STREQ(CONTENT, data);
52*71db0c75SAndroid Build Coastguard Worker   ASSERT_EQ(0, LIBC_NAMESPACE::fclose(fr));
53*71db0c75SAndroid Build Coastguard Worker }
54*71db0c75SAndroid Build Coastguard Worker 
TEST(LlvmLibcSetvbufTest,SetLBFBuffer)55*71db0c75SAndroid Build Coastguard Worker TEST(LlvmLibcSetvbufTest, SetLBFBuffer) {
56*71db0c75SAndroid Build Coastguard Worker   // The idea in this test is that we open a file for writing and reading, and
57*71db0c75SAndroid Build Coastguard Worker   // then set a LBF buffer to the write handle. Since it is LBF, the data
58*71db0c75SAndroid Build Coastguard Worker   // written using the write handle should be available right after a '\n' is
59*71db0c75SAndroid Build Coastguard Worker   // written.
60*71db0c75SAndroid Build Coastguard Worker   constexpr char FILENAME[] = "testdata/setvbuf_lbf.test";
61*71db0c75SAndroid Build Coastguard Worker 
62*71db0c75SAndroid Build Coastguard Worker   ::FILE *fw = LIBC_NAMESPACE::fopen(FILENAME, "w");
63*71db0c75SAndroid Build Coastguard Worker   ASSERT_FALSE(fw == nullptr);
64*71db0c75SAndroid Build Coastguard Worker   char buffer[BUFSIZ];
65*71db0c75SAndroid Build Coastguard Worker   ASSERT_EQ(LIBC_NAMESPACE::setvbuf(fw, buffer, _IOLBF, BUFSIZ), 0);
66*71db0c75SAndroid Build Coastguard Worker 
67*71db0c75SAndroid Build Coastguard Worker   ::FILE *fr = LIBC_NAMESPACE::fopen(FILENAME, "r");
68*71db0c75SAndroid Build Coastguard Worker   ASSERT_FALSE(fr == nullptr);
69*71db0c75SAndroid Build Coastguard Worker 
70*71db0c75SAndroid Build Coastguard Worker   constexpr char CONTENT[] = "abcdef\n";
71*71db0c75SAndroid Build Coastguard Worker   constexpr size_t CONTENT_SIZE = sizeof(CONTENT);
72*71db0c75SAndroid Build Coastguard Worker   ASSERT_EQ(CONTENT_SIZE, LIBC_NAMESPACE::fwrite(CONTENT, 1, CONTENT_SIZE, fw));
73*71db0c75SAndroid Build Coastguard Worker 
74*71db0c75SAndroid Build Coastguard Worker   // Note that CONTENT_SIZE worth of data written also includes the
75*71db0c75SAndroid Build Coastguard Worker   // null-terminator '\0'. But, since it is after the new line character,
76*71db0c75SAndroid Build Coastguard Worker   // it should not be availabe for reading.
77*71db0c75SAndroid Build Coastguard Worker   char data[CONTENT_SIZE];
78*71db0c75SAndroid Build Coastguard Worker   ASSERT_EQ(CONTENT_SIZE - 1, LIBC_NAMESPACE::fread(data, 1, CONTENT_SIZE, fr));
79*71db0c75SAndroid Build Coastguard Worker   char c;
80*71db0c75SAndroid Build Coastguard Worker   ASSERT_EQ(size_t(0), LIBC_NAMESPACE::fread(&c, 1, 1, fr));
81*71db0c75SAndroid Build Coastguard Worker 
82*71db0c75SAndroid Build Coastguard Worker   data[CONTENT_SIZE - 1] = '\0';
83*71db0c75SAndroid Build Coastguard Worker   ASSERT_STREQ(CONTENT, data);
84*71db0c75SAndroid Build Coastguard Worker 
85*71db0c75SAndroid Build Coastguard Worker   ASSERT_EQ(0, LIBC_NAMESPACE::fclose(fw));
86*71db0c75SAndroid Build Coastguard Worker   ASSERT_EQ(0, LIBC_NAMESPACE::fclose(fr));
87*71db0c75SAndroid Build Coastguard Worker 
88*71db0c75SAndroid Build Coastguard Worker   // Make sure LBF buffer has no effect for reading.
89*71db0c75SAndroid Build Coastguard Worker   fr = LIBC_NAMESPACE::fopen(FILENAME, "r");
90*71db0c75SAndroid Build Coastguard Worker   ASSERT_EQ(LIBC_NAMESPACE::setvbuf(fr, buffer, _IOLBF, BUFSIZ), 0);
91*71db0c75SAndroid Build Coastguard Worker   ASSERT_EQ(CONTENT_SIZE, LIBC_NAMESPACE::fread(data, 1, CONTENT_SIZE, fr));
92*71db0c75SAndroid Build Coastguard Worker   ASSERT_STREQ(CONTENT, data);
93*71db0c75SAndroid Build Coastguard Worker   ASSERT_EQ(0, LIBC_NAMESPACE::fclose(fr));
94*71db0c75SAndroid Build Coastguard Worker }
95*71db0c75SAndroid Build Coastguard Worker 
TEST(LlvmLibcSetbufTest,InvalidBufferMode)96*71db0c75SAndroid Build Coastguard Worker TEST(LlvmLibcSetbufTest, InvalidBufferMode) {
97*71db0c75SAndroid Build Coastguard Worker   constexpr char FILENAME[] = "testdata/setvbuf_invalid_bufmode.test";
98*71db0c75SAndroid Build Coastguard Worker   ::FILE *f = LIBC_NAMESPACE::fopen(FILENAME, "w");
99*71db0c75SAndroid Build Coastguard Worker   ASSERT_FALSE(f == nullptr);
100*71db0c75SAndroid Build Coastguard Worker   char buf[BUFSIZ];
101*71db0c75SAndroid Build Coastguard Worker   ASSERT_NE(LIBC_NAMESPACE::setvbuf(f, buf, _IOFBF + _IOLBF + _IONBF, BUFSIZ),
102*71db0c75SAndroid Build Coastguard Worker             0);
103*71db0c75SAndroid Build Coastguard Worker   ASSERT_ERRNO_EQ(EINVAL);
104*71db0c75SAndroid Build Coastguard Worker 
105*71db0c75SAndroid Build Coastguard Worker   LIBC_NAMESPACE::libc_errno = 0;
106*71db0c75SAndroid Build Coastguard Worker   ASSERT_EQ(0, LIBC_NAMESPACE::fclose(f));
107*71db0c75SAndroid Build Coastguard Worker }
108