//===-- Unittests for shm_open/shm_unlink ---------------------------------===// // // 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 // //===----------------------------------------------------------------------===// #include "src/__support/OSUtil/syscall.h" #include "src/sys/mman/mmap.h" #include "src/sys/mman/munmap.h" #include "src/sys/mman/shm_open.h" #include "src/sys/mman/shm_unlink.h" #include "src/unistd/close.h" #include "src/unistd/ftruncate.h" #include "test/UnitTest/ErrnoSetterMatcher.h" #include "test/UnitTest/LibcTest.h" #include #include using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher; // since shm_open/shm_unlink are wrappers around open/unlink, we only focus on // testing basic cases and name conversions. TEST(LlvmLibcShmTest, Basic) { const char *name = "/test_shm_open"; int fd; ASSERT_THAT(fd = LIBC_NAMESPACE::shm_open(name, O_CREAT | O_RDWR, 0666), returns(GE(0)).with_errno(EQ(0))); // check that FD_CLOEXEC is set by default. // TODO: use fcntl when implemented. // https://github.com/llvm/llvm-project/issues/84968 long flag = LIBC_NAMESPACE::syscall_impl(SYS_fcntl, fd, F_GETFD); ASSERT_GE(static_cast(flag), 0); EXPECT_NE(static_cast(flag) & FD_CLOEXEC, 0); // allocate space using ftruncate ASSERT_THAT(LIBC_NAMESPACE::ftruncate(fd, 4096), Succeeds()); // map the shared memory void *addr = LIBC_NAMESPACE::mmap(nullptr, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); ASSERT_NE(addr, MAP_FAILED); // just write random data to the shared memory char data[] = "Despite its name, LLVM has little to do with traditional " "virtual machines."; for (size_t i = 0; i < sizeof(data); ++i) static_cast(addr)[i] = data[i]; // close fd does not affect the mapping ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds()); for (size_t i = 0; i < sizeof(data); ++i) EXPECT_EQ(static_cast(addr)[i], data[i]); // unmap the shared memory ASSERT_THAT(LIBC_NAMESPACE::munmap(addr, 4096), Succeeds()); // remove the shared memory ASSERT_THAT(LIBC_NAMESPACE::shm_unlink(name), Succeeds()); } TEST(LlvmLibcShmTest, NameConversion) { const char *name = "////test_shm_open"; int fd; ASSERT_THAT(fd = LIBC_NAMESPACE::shm_open(name, O_CREAT | O_RDWR, 0666), returns(GE(0)).with_errno(EQ(0))); ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds()); ASSERT_THAT(LIBC_NAMESPACE::shm_unlink(name), Succeeds()); ASSERT_THAT(LIBC_NAMESPACE::shm_open("/123/123", O_CREAT | O_RDWR, 0666), Fails(EINVAL)); ASSERT_THAT(LIBC_NAMESPACE::shm_open("/.", O_CREAT | O_RDWR, 0666), Fails(EINVAL)); ASSERT_THAT(LIBC_NAMESPACE::shm_open("/..", O_CREAT | O_RDWR, 0666), Fails(EINVAL)); }