| //===----------------------------------------------------------------------===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| /// | |
| /// \file | |
| /// This file contains the tests for the fallocate POSIX functions | |
| /// | |
| //===----------------------------------------------------------------------===// | |
| #include "hdr/fcntl_macros.h" | |
| #include "src/__support/CPP/scope.h" | |
| #include "src/__support/libc_errno.h" | |
| #include "src/fcntl/fallocate.h" | |
| #include "src/fcntl/open.h" | |
| #include "src/sys/stat/fstat.h" | |
| #include "src/sys/stat/stat.h" | |
| #include "src/unistd/close.h" | |
| #include "src/unistd/unlink.h" | |
| #include "test/UnitTest/ErrnoCheckingTest.h" | |
| #include "test/UnitTest/ErrnoSetterMatcher.h" | |
| #include "test/UnitTest/Test.h" | |
| #include <linux/falloc.h> | |
| using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails; | |
| using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds; | |
| TEST(LlvmLibcFallocateTest, BasicAllocate) { | |
| constexpr char TEST_FILE[] = "fallocate_basic.test"; | |
| int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_WRONLY | O_TRUNC, 0600); | |
| ASSERT_ERRNO_SUCCESS(); | |
| ASSERT_GT(fd, 0); | |
| LIBC_NAMESPACE::cpp::scope_exit cleanup_fd([&] { | |
| EXPECT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE), Succeeds(0)); | |
| EXPECT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0)); | |
| }); | |
| // Mode 0: expand file size to offset + len (4096 bytes) | |
| ASSERT_THAT(LIBC_NAMESPACE::fallocate(fd, 0, 1024, 3072), Succeeds(0)); | |
| struct stat st; | |
| ASSERT_EQ(LIBC_NAMESPACE::fstat(fd, &st), 0); | |
| ASSERT_EQ(static_cast<off_t>(st.st_size), static_cast<off_t>(4096)); | |
| } | |
| TEST(LlvmLibcFallocateTest, KeepSize) { | |
| constexpr char TEST_FILE[] = "fallocate_keep_size.test"; | |
| int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_WRONLY | O_TRUNC, 0600); | |
| ASSERT_ERRNO_SUCCESS(); | |
| ASSERT_GT(fd, 0); | |
| LIBC_NAMESPACE::cpp::scope_exit cleanup_fd([&] { | |
| EXPECT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE), Succeeds(0)); | |
| EXPECT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0)); | |
| }); | |
| // Pre-allocate space at offset 8192, length 4096, but keep file size at 0 | |
| ASSERT_THAT(LIBC_NAMESPACE::fallocate(fd, FALLOC_FL_KEEP_SIZE, 8192, 4096), | |
| Succeeds(0)); | |
| struct stat st; | |
| ASSERT_EQ(LIBC_NAMESPACE::fstat(fd, &st), 0); | |
| ASSERT_EQ(static_cast<off_t>(st.st_size), static_cast<off_t>(0)); | |
| } | |
| TEST(LlvmLibcFallocateTest, InvalidFd) { | |
| // Passing an invalid file descriptor should fail with EBADF | |
| ASSERT_THAT(LIBC_NAMESPACE::fallocate(-1, 0, 0, 4096), Fails(EBADF)); | |
| } | |
| TEST(LlvmLibcFallocateTest, InvalidMode) { | |
| constexpr char TEST_FILE[] = "fallocate_invalid_mode.test"; | |
| int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_WRONLY | O_TRUNC, 0600); | |
| ASSERT_ERRNO_SUCCESS(); | |
| ASSERT_GT(fd, 0); | |
| LIBC_NAMESPACE::cpp::scope_exit cleanup_fd([&] { | |
| EXPECT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE), Succeeds(0)); | |
| EXPECT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0)); | |
| }); | |
| ASSERT_EQ(LIBC_NAMESPACE::fallocate(fd, -1, 0, 4096), -1); | |
| // Could be any one of those and potentially more depending on the file system | |
| ASSERT_TRUE(libc_errno == EINVAL || libc_errno == ENOTSUP || | |
| libc_errno == EOPNOTSUPP); | |
| // for the cleanup to work | |
| libc_errno = 0; | |
| } |