91 lines · cpp
1//===-- Unittest for fdopen -----------------------------------------------===//2//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "src/stdio/fdopen.h"10 11#include "hdr/fcntl_macros.h"12#include "src/fcntl/open.h"13#include "src/stdio/fclose.h"14#include "src/stdio/fgets.h"15#include "src/stdio/fputs.h"16#include "src/unistd/close.h"17#include "test/UnitTest/ErrnoCheckingTest.h"18#include "test/UnitTest/ErrnoSetterMatcher.h"19#include "test/UnitTest/Test.h"20 21#include <sys/stat.h> // For S_IRWXU22 23using LlvmLibcStdioFdopenTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;24 25TEST_F(LlvmLibcStdioFdopenTest, WriteAppendRead) {26 using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;27 constexpr const char *TEST_FILE_NAME =28 APPEND_LIBC_TEST("testdata/write_read_append.test");29 auto TEST_FILE = libc_make_test_file_path(TEST_FILE_NAME);30 int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU);31 auto *fp = LIBC_NAMESPACE::fdopen(fd, "w");32 ASSERT_ERRNO_SUCCESS();33 ASSERT_TRUE(nullptr != fp);34 constexpr const char HELLO[] = "Hello";35 LIBC_NAMESPACE::fputs(HELLO, fp);36 LIBC_NAMESPACE::fclose(fp);37 ASSERT_ERRNO_SUCCESS();38 39 constexpr const char LLVM[] = "LLVM";40 int fd2 = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_RDWR);41 auto *fp2 = LIBC_NAMESPACE::fdopen(fd2, "a");42 ASSERT_ERRNO_SUCCESS();43 ASSERT_TRUE(nullptr != fp2);44 LIBC_NAMESPACE::fputs(LLVM, fp2);45 LIBC_NAMESPACE::fclose(fp2);46 ASSERT_ERRNO_SUCCESS();47 48 int fd3 = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_RDWR);49 auto *fp3 = LIBC_NAMESPACE::fdopen(fd3, "r");50 char buffer[10];51 LIBC_NAMESPACE::fgets(buffer, sizeof(buffer), fp3);52 ASSERT_STREQ("HelloLLVM", buffer);53 LIBC_NAMESPACE::fclose(fp3);54 ASSERT_ERRNO_SUCCESS();55}56 57TEST_F(LlvmLibcStdioFdopenTest, InvalidFd) {58 constexpr const char *TEST_FILE_NAME =59 APPEND_LIBC_TEST("testdata/invalid_fd.test");60 auto TEST_FILE = libc_make_test_file_path(TEST_FILE_NAME);61 int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_TRUNC);62 LIBC_NAMESPACE::close(fd);63 // With `fd` already closed, `fdopen` should fail and set the `errno` to EBADF64 auto *fp = LIBC_NAMESPACE::fdopen(fd, "r");65 ASSERT_ERRNO_EQ(EBADF);66 ASSERT_TRUE(nullptr == fp);67}68 69TEST_F(LlvmLibcStdioFdopenTest, InvalidMode) {70 constexpr const char *TEST_FILE_NAME =71 APPEND_LIBC_TEST("testdata/invalid_mode.test");72 auto TEST_FILE = libc_make_test_file_path(TEST_FILE_NAME);73 int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_RDONLY, S_IRWXU);74 ASSERT_ERRNO_SUCCESS();75 ASSERT_GT(fd, 0);76 77 // `Mode` must be one of "r", "w" or "a"78 auto *fp = LIBC_NAMESPACE::fdopen(fd, "m+");79 ASSERT_ERRNO_EQ(EINVAL);80 ASSERT_TRUE(nullptr == fp);81 82 // If the mode argument is invalid, then `fdopen` returns a nullptr and sets83 // the `errno` to EINVAL. In this case the `mode` param can only be "r" or84 // "r+"85 auto *fp2 = LIBC_NAMESPACE::fdopen(fd, "w");86 ASSERT_ERRNO_EQ(EINVAL);87 ASSERT_TRUE(nullptr == fp2);88 LIBC_NAMESPACE::close(fd);89 ASSERT_ERRNO_SUCCESS();90}91