1 //===-- Unittests for shm_open/shm_unlink ---------------------------------===// 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "hdr/fcntl_macros.h" 10 #include "src/__support/OSUtil/syscall.h" 11 #include "src/fcntl/fcntl.h" 12 #include "src/sys/mman/mmap.h" 13 #include "src/sys/mman/munmap.h" 14 #include "src/sys/mman/shm_open.h" 15 #include "src/sys/mman/shm_unlink.h" 16 #include "src/unistd/close.h" 17 #include "src/unistd/ftruncate.h" 18 #include "test/UnitTest/ErrnoSetterMatcher.h" 19 #include "test/UnitTest/Test.h" 20 #include <sys/syscall.h> 21 22 using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher; 23 // since shm_open/shm_unlink are wrappers around open/unlink, we only focus on 24 // testing basic cases and name conversions. 25 26 TEST(LlvmLibcShmTest, Basic) { 27 const char *name = "/test_shm_open"; 28 int fd; 29 ASSERT_THAT(fd = LIBC_NAMESPACE::shm_open(name, O_CREAT | O_RDWR, 0666), 30 returns(GE(0)).with_errno(EQ(0))); 31 32 // check that FD_CLOEXEC is set by default. 33 long flag = LIBC_NAMESPACE::fcntl(fd, F_GETFD); 34 ASSERT_GE(static_cast<int>(flag), 0); 35 EXPECT_NE(static_cast<int>(flag) & FD_CLOEXEC, 0); 36 37 // allocate space using ftruncate 38 ASSERT_THAT(LIBC_NAMESPACE::ftruncate(fd, 4096), Succeeds()); 39 // map the shared memory 40 void *addr = LIBC_NAMESPACE::mmap(nullptr, 4096, PROT_READ | PROT_WRITE, 41 MAP_SHARED, fd, 0); 42 ASSERT_NE(addr, MAP_FAILED); 43 // just write random data to the shared memory 44 char data[] = "Despite its name, LLVM has little to do with traditional " 45 "virtual machines."; 46 for (size_t i = 0; i < sizeof(data); ++i) 47 static_cast<char *>(addr)[i] = data[i]; 48 49 // close fd does not affect the mapping 50 ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds()); 51 for (size_t i = 0; i < sizeof(data); ++i) 52 EXPECT_EQ(static_cast<char *>(addr)[i], data[i]); 53 54 // unmap the shared memory 55 ASSERT_THAT(LIBC_NAMESPACE::munmap(addr, 4096), Succeeds()); 56 // remove the shared memory 57 ASSERT_THAT(LIBC_NAMESPACE::shm_unlink(name), Succeeds()); 58 } 59 60 TEST(LlvmLibcShmTest, NameConversion) { 61 const char *name = "////test_shm_open"; 62 int fd; 63 ASSERT_THAT(fd = LIBC_NAMESPACE::shm_open(name, O_CREAT | O_RDWR, 0666), 64 returns(GE(0)).with_errno(EQ(0))); 65 ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds()); 66 ASSERT_THAT(LIBC_NAMESPACE::shm_unlink(name), Succeeds()); 67 68 ASSERT_THAT(LIBC_NAMESPACE::shm_open("/123/123", O_CREAT | O_RDWR, 0666), 69 Fails(EINVAL)); 70 71 ASSERT_THAT(LIBC_NAMESPACE::shm_open("/.", O_CREAT | O_RDWR, 0666), 72 Fails(EINVAL)); 73 74 ASSERT_THAT(LIBC_NAMESPACE::shm_open("/..", O_CREAT | O_RDWR, 0666), 75 Fails(EINVAL)); 76 } 77