brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.0 KiB · 85caef2 Raw
179 lines · cpp
1//===-- Unittests for syscalls --------------------------------------------===//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/unistd/syscall.h"10#include "test/UnitTest/ErrnoCheckingTest.h"11#include "test/UnitTest/ErrnoSetterMatcher.h"12#include "test/UnitTest/Test.h"13 14#include "hdr/fcntl_macros.h"15#include <sys/stat.h>    // For S_* flags.16#include <sys/syscall.h> // For syscall numbers.17#include <unistd.h>18 19using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;20using LlvmLibcSyscallTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;21 22// We only do a smoke test here. Actual functionality tests are23// done by the unit tests of the syscall wrappers like mmap.24// The goal is to test syscalls with a wide number of args.25 26// There is no function named "syscall" in llvm-libc, we instead use a macro to27// set up the arguments properly. We still need to specify the namespace though28// because the macro generates a call to the actual internal function29// (__llvm_libc_syscall) which is inside the namespace.30TEST_F(LlvmLibcSyscallTest, TrivialCall) {31  ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_gettid), 0l);32  ASSERT_ERRNO_SUCCESS();33}34 35TEST_F(LlvmLibcSyscallTest, SymlinkCreateDestroy) {36  constexpr const char LINK_VAL[] = "syscall_readlink_test_value";37  constexpr const char LINK[] = "testdata/syscall_readlink.test.link";38 39#ifdef SYS_symlink40  ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_symlink, LINK_VAL, LINK), 0l);41#elif defined(SYS_symlinkat)42  ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_symlinkat, LINK_VAL, AT_FDCWD, LINK),43            0l);44#else45#error "symlink and symlinkat syscalls not available."46#endif47  ASSERT_ERRNO_SUCCESS();48 49  char buf[sizeof(LINK_VAL)];50 51#ifdef SYS_readlink52  ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_readlink, LINK, buf, sizeof(buf)), 0l);53#elif defined(SYS_readlinkat)54  ASSERT_GE(55      LIBC_NAMESPACE::syscall(SYS_readlinkat, AT_FDCWD, LINK, buf, sizeof(buf)),56      0l);57#endif58  ASSERT_ERRNO_SUCCESS();59 60#ifdef SYS_unlink61  ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_unlink, LINK), 0l);62#elif defined(SYS_unlinkat)63  ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_unlinkat, AT_FDCWD, LINK, 0), 0l);64#else65#error "unlink and unlinkat syscalls not available."66#endif67  ASSERT_ERRNO_SUCCESS();68}69 70TEST_F(LlvmLibcSyscallTest, FileReadWrite) {71  constexpr const char HELLO[] = "hello";72  constexpr int HELLO_SIZE = sizeof(HELLO);73 74  constexpr const char *TEST_FILE = "testdata/syscall_pread_pwrite.test";75 76#ifdef SYS_open77  long fd =78      LIBC_NAMESPACE::syscall(SYS_open, TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);79#elif defined(SYS_openat)80  long fd = LIBC_NAMESPACE::syscall(SYS_openat, AT_FDCWD, TEST_FILE,81                                    O_WRONLY | O_CREAT, S_IRWXU);82#else83#error "open and openat syscalls not available."84#endif85  ASSERT_GT(fd, 0l);86  ASSERT_ERRNO_SUCCESS();87 88  ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_pwrite64, fd, HELLO, HELLO_SIZE, 0),89            0l);90  ASSERT_ERRNO_SUCCESS();91 92  ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_fsync, fd), 0l);93  ASSERT_ERRNO_SUCCESS();94 95  ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_close, fd), 0l);96  ASSERT_ERRNO_SUCCESS();97}98 99TEST_F(LlvmLibcSyscallTest, FileLinkCreateDestroy) {100  constexpr const char *TEST_DIR = "testdata";101  constexpr const char *TEST_FILE = "syscall_linkat.test";102  constexpr const char *TEST_FILE_PATH = "testdata/syscall_linkat.test";103  constexpr const char *TEST_FILE_LINK = "syscall_linkat.test.link";104  constexpr const char *TEST_FILE_LINK_PATH =105      "testdata/syscall_linkat.test.link";106 107  // The test strategy is as follows:108  //   1. Create a normal file109  //   2. Create a link to that file.110  //   3. Open the link to check that the link was created.111  //   4. Cleanup the file and its link.112 113#ifdef SYS_open114  long write_fd = LIBC_NAMESPACE::syscall(SYS_open, TEST_FILE_PATH,115                                          O_WRONLY | O_CREAT, S_IRWXU);116#elif defined(SYS_openat)117  long write_fd = LIBC_NAMESPACE::syscall(SYS_openat, AT_FDCWD, TEST_FILE_PATH,118                                          O_WRONLY | O_CREAT, S_IRWXU);119#else120#error "open and openat syscalls not available."121#endif122  ASSERT_GT(write_fd, 0l);123  ASSERT_ERRNO_SUCCESS();124 125  ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_close, write_fd), 0l);126  ASSERT_ERRNO_SUCCESS();127 128#ifdef SYS_open129  long dir_fd = LIBC_NAMESPACE::syscall(SYS_open, TEST_DIR, O_DIRECTORY, 0);130#elif defined(SYS_openat)131  long dir_fd =132      LIBC_NAMESPACE::syscall(SYS_openat, AT_FDCWD, TEST_DIR, O_DIRECTORY, 0);133#else134#error "open and openat syscalls not available."135#endif136  ASSERT_GT(dir_fd, 0l);137  ASSERT_ERRNO_SUCCESS();138 139  ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_linkat, dir_fd, TEST_FILE, dir_fd,140                                    TEST_FILE_LINK, 0),141            0l);142  ASSERT_ERRNO_SUCCESS();143#ifdef SYS_open144  long link_fd =145      LIBC_NAMESPACE::syscall(SYS_open, TEST_FILE_LINK_PATH, O_PATH, 0);146#elif defined(SYS_openat)147  long link_fd = LIBC_NAMESPACE::syscall(SYS_openat, AT_FDCWD,148                                         TEST_FILE_LINK_PATH, O_PATH, 0);149#else150#error "open and openat syscalls not available."151#endif152  ASSERT_GT(link_fd, 0l);153  ASSERT_ERRNO_SUCCESS();154 155#ifdef SYS_unlink156  ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_unlink, TEST_FILE_PATH), 0l);157#elif defined(SYS_unlinkat)158  ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_unlinkat, AT_FDCWD, TEST_FILE_PATH, 0),159            0l);160#else161#error "unlink and unlinkat syscalls not available."162#endif163  ASSERT_ERRNO_SUCCESS();164 165#ifdef SYS_unlink166  ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_unlink, TEST_FILE_LINK_PATH), 0l);167#elif defined(SYS_unlinkat)168  ASSERT_GE(169      LIBC_NAMESPACE::syscall(SYS_unlinkat, AT_FDCWD, TEST_FILE_LINK_PATH, 0),170      0l);171#else172#error "unlink and unlinkat syscalls not available."173#endif174  ASSERT_ERRNO_SUCCESS();175 176  ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_close, dir_fd), 0l);177  ASSERT_ERRNO_SUCCESS();178}179