14eea8849SSiva Chandra Reddy //===-- Unittests for setvbuf ---------------------------------------------===// 24eea8849SSiva Chandra Reddy // 34eea8849SSiva Chandra Reddy // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 44eea8849SSiva Chandra Reddy // See https://llvm.org/LICENSE.txt for license information. 54eea8849SSiva Chandra Reddy // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 64eea8849SSiva Chandra Reddy // 74eea8849SSiva Chandra Reddy //===----------------------------------------------------------------------===// 84eea8849SSiva Chandra Reddy 94eea8849SSiva Chandra Reddy #include "src/stdio/fclose.h" 104eea8849SSiva Chandra Reddy #include "src/stdio/fopen.h" 114eea8849SSiva Chandra Reddy #include "src/stdio/fread.h" 124eea8849SSiva Chandra Reddy #include "src/stdio/fwrite.h" 134eea8849SSiva Chandra Reddy #include "src/stdio/setvbuf.h" 14af1315c2SSiva Chandra Reddy #include "test/UnitTest/Test.h" 154eea8849SSiva Chandra Reddy 16*c63112a9Slntue #include "hdr/stdio_macros.h" 1704a9c625SMichael Jones #include "src/errno/libc_errno.h" 184eea8849SSiva Chandra Reddy 194eea8849SSiva Chandra Reddy TEST(LlvmLibcSetvbufTest, SetNBFBuffer) { 204eea8849SSiva Chandra Reddy // The idea in this test is that we open a file for writing and reading, and 214eea8849SSiva Chandra Reddy // then set a NBF buffer to the write handle. Since it is NBF, the data 224eea8849SSiva Chandra Reddy // written using the write handle should be immediately readable by the read 234eea8849SSiva Chandra Reddy // handle. 244eea8849SSiva Chandra Reddy constexpr char FILENAME[] = "testdata/setvbuf_nbf.test"; 254eea8849SSiva Chandra Reddy 26b6bc9d72SGuillaume Chatelet ::FILE *fw = LIBC_NAMESPACE::fopen(FILENAME, "w"); 274eea8849SSiva Chandra Reddy ASSERT_FALSE(fw == nullptr); 284eea8849SSiva Chandra Reddy char buffer[BUFSIZ]; 29b6bc9d72SGuillaume Chatelet ASSERT_EQ(LIBC_NAMESPACE::setvbuf(fw, buffer, _IONBF, BUFSIZ), 0); 304eea8849SSiva Chandra Reddy 31b6bc9d72SGuillaume Chatelet ::FILE *fr = LIBC_NAMESPACE::fopen(FILENAME, "r"); 324eea8849SSiva Chandra Reddy ASSERT_FALSE(fr == nullptr); 334eea8849SSiva Chandra Reddy 344eea8849SSiva Chandra Reddy constexpr char CONTENT[] = "abcdef"; 354eea8849SSiva Chandra Reddy constexpr size_t CONTENT_SIZE = sizeof(CONTENT); 364eea8849SSiva Chandra Reddy for (size_t i = 0; i < CONTENT_SIZE; ++i) { 37b6bc9d72SGuillaume Chatelet ASSERT_EQ(size_t(1), LIBC_NAMESPACE::fwrite(CONTENT + i, 1, 1, fw)); 384eea8849SSiva Chandra Reddy char c; 39b6bc9d72SGuillaume Chatelet ASSERT_EQ(size_t(1), LIBC_NAMESPACE::fread(&c, 1, 1, fr)); 404eea8849SSiva Chandra Reddy ASSERT_EQ(c, CONTENT[i]); 414eea8849SSiva Chandra Reddy } 424eea8849SSiva Chandra Reddy 43b6bc9d72SGuillaume Chatelet ASSERT_EQ(0, LIBC_NAMESPACE::fclose(fw)); 44b6bc9d72SGuillaume Chatelet ASSERT_EQ(0, LIBC_NAMESPACE::fclose(fr)); 454eea8849SSiva Chandra Reddy 464eea8849SSiva Chandra Reddy // Make sure NBF buffer has no effect for reading. 47b6bc9d72SGuillaume Chatelet fr = LIBC_NAMESPACE::fopen(FILENAME, "r"); 484eea8849SSiva Chandra Reddy char data[CONTENT_SIZE]; 49b6bc9d72SGuillaume Chatelet ASSERT_EQ(LIBC_NAMESPACE::setvbuf(fr, buffer, _IONBF, BUFSIZ), 0); 50b6bc9d72SGuillaume Chatelet ASSERT_EQ(CONTENT_SIZE, LIBC_NAMESPACE::fread(data, 1, CONTENT_SIZE, fr)); 514eea8849SSiva Chandra Reddy ASSERT_STREQ(CONTENT, data); 52b6bc9d72SGuillaume Chatelet ASSERT_EQ(0, LIBC_NAMESPACE::fclose(fr)); 534eea8849SSiva Chandra Reddy } 544eea8849SSiva Chandra Reddy 554eea8849SSiva Chandra Reddy TEST(LlvmLibcSetvbufTest, SetLBFBuffer) { 564eea8849SSiva Chandra Reddy // The idea in this test is that we open a file for writing and reading, and 574eea8849SSiva Chandra Reddy // then set a LBF buffer to the write handle. Since it is LBF, the data 584eea8849SSiva Chandra Reddy // written using the write handle should be available right after a '\n' is 594eea8849SSiva Chandra Reddy // written. 604eea8849SSiva Chandra Reddy constexpr char FILENAME[] = "testdata/setvbuf_lbf.test"; 614eea8849SSiva Chandra Reddy 62b6bc9d72SGuillaume Chatelet ::FILE *fw = LIBC_NAMESPACE::fopen(FILENAME, "w"); 634eea8849SSiva Chandra Reddy ASSERT_FALSE(fw == nullptr); 644eea8849SSiva Chandra Reddy char buffer[BUFSIZ]; 65b6bc9d72SGuillaume Chatelet ASSERT_EQ(LIBC_NAMESPACE::setvbuf(fw, buffer, _IOLBF, BUFSIZ), 0); 664eea8849SSiva Chandra Reddy 67b6bc9d72SGuillaume Chatelet ::FILE *fr = LIBC_NAMESPACE::fopen(FILENAME, "r"); 684eea8849SSiva Chandra Reddy ASSERT_FALSE(fr == nullptr); 694eea8849SSiva Chandra Reddy 704eea8849SSiva Chandra Reddy constexpr char CONTENT[] = "abcdef\n"; 714eea8849SSiva Chandra Reddy constexpr size_t CONTENT_SIZE = sizeof(CONTENT); 72b6bc9d72SGuillaume Chatelet ASSERT_EQ(CONTENT_SIZE, LIBC_NAMESPACE::fwrite(CONTENT, 1, CONTENT_SIZE, fw)); 734eea8849SSiva Chandra Reddy 744eea8849SSiva Chandra Reddy // Note that CONTENT_SIZE worth of data written also includes the 754eea8849SSiva Chandra Reddy // null-terminator '\0'. But, since it is after the new line character, 764eea8849SSiva Chandra Reddy // it should not be availabe for reading. 774eea8849SSiva Chandra Reddy char data[CONTENT_SIZE]; 78b6bc9d72SGuillaume Chatelet ASSERT_EQ(CONTENT_SIZE - 1, LIBC_NAMESPACE::fread(data, 1, CONTENT_SIZE, fr)); 794eea8849SSiva Chandra Reddy char c; 80b6bc9d72SGuillaume Chatelet ASSERT_EQ(size_t(0), LIBC_NAMESPACE::fread(&c, 1, 1, fr)); 814eea8849SSiva Chandra Reddy 824eea8849SSiva Chandra Reddy data[CONTENT_SIZE - 1] = '\0'; 834eea8849SSiva Chandra Reddy ASSERT_STREQ(CONTENT, data); 844eea8849SSiva Chandra Reddy 85b6bc9d72SGuillaume Chatelet ASSERT_EQ(0, LIBC_NAMESPACE::fclose(fw)); 86b6bc9d72SGuillaume Chatelet ASSERT_EQ(0, LIBC_NAMESPACE::fclose(fr)); 874eea8849SSiva Chandra Reddy 884eea8849SSiva Chandra Reddy // Make sure LBF buffer has no effect for reading. 89b6bc9d72SGuillaume Chatelet fr = LIBC_NAMESPACE::fopen(FILENAME, "r"); 90b6bc9d72SGuillaume Chatelet ASSERT_EQ(LIBC_NAMESPACE::setvbuf(fr, buffer, _IOLBF, BUFSIZ), 0); 91b6bc9d72SGuillaume Chatelet ASSERT_EQ(CONTENT_SIZE, LIBC_NAMESPACE::fread(data, 1, CONTENT_SIZE, fr)); 924eea8849SSiva Chandra Reddy ASSERT_STREQ(CONTENT, data); 93b6bc9d72SGuillaume Chatelet ASSERT_EQ(0, LIBC_NAMESPACE::fclose(fr)); 944eea8849SSiva Chandra Reddy } 954eea8849SSiva Chandra Reddy 964eea8849SSiva Chandra Reddy TEST(LlvmLibcSetbufTest, InvalidBufferMode) { 974eea8849SSiva Chandra Reddy constexpr char FILENAME[] = "testdata/setvbuf_invalid_bufmode.test"; 98b6bc9d72SGuillaume Chatelet ::FILE *f = LIBC_NAMESPACE::fopen(FILENAME, "w"); 994eea8849SSiva Chandra Reddy ASSERT_FALSE(f == nullptr); 1004eea8849SSiva Chandra Reddy char buf[BUFSIZ]; 101b6bc9d72SGuillaume Chatelet ASSERT_NE(LIBC_NAMESPACE::setvbuf(f, buf, _IOFBF + _IOLBF + _IONBF, BUFSIZ), 102b6bc9d72SGuillaume Chatelet 0); 10373874f7aSGuillaume Chatelet ASSERT_ERRNO_EQ(EINVAL); 1044eea8849SSiva Chandra Reddy 1053eb1e6d8Smichaelrj-google LIBC_NAMESPACE::libc_errno = 0; 106b6bc9d72SGuillaume Chatelet ASSERT_EQ(0, LIBC_NAMESPACE::fclose(f)); 1074eea8849SSiva Chandra Reddy } 108