[OptTable] Fix typo VALUE => VALUES (NFCI) (#121523)
[llvm-project.git] / libc / test / src / unistd / syscall_test.cpp
blobf6cc3eab9aabe876657dd9efd7fd42d3f3806500
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-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "src/errno/libc_errno.h"
10 #include "src/unistd/syscall.h"
11 #include "test/UnitTest/ErrnoSetterMatcher.h"
12 #include "test/UnitTest/Test.h"
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>
19 using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
21 // We only do a smoke test here. Actual functionality tests are
22 // done by the unit tests of the syscall wrappers like mmap.
23 // The goal is to test syscalls with a wide number of args.
25 // There is no function named "syscall" in llvm-libc, we instead use a macro to
26 // set up the arguments properly. We still need to specify the namespace though
27 // because the macro generates a call to the actual internal function
28 // (__llvm_libc_syscall) which is inside the namespace.
29 TEST(LlvmLibcSyscallTest, TrivialCall) {
30 LIBC_NAMESPACE::libc_errno = 0;
32 ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_gettid), 0l);
33 ASSERT_ERRNO_SUCCESS();
36 TEST(LlvmLibcSyscallTest, SymlinkCreateDestroy) {
37 constexpr const char LINK_VAL[] = "syscall_readlink_test_value";
38 constexpr const char LINK[] = "testdata/syscall_readlink.test.link";
40 #ifdef SYS_symlink
41 ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_symlink, LINK_VAL, LINK), 0l);
42 #elif defined(SYS_symlinkat)
43 ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_symlinkat, LINK_VAL, AT_FDCWD, LINK),
44 0l);
45 #else
46 #error "symlink and symlinkat syscalls not available."
47 #endif
48 ASSERT_ERRNO_SUCCESS();
50 char buf[sizeof(LINK_VAL)];
52 #ifdef SYS_readlink
53 ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_readlink, LINK, buf, sizeof(buf)), 0l);
54 #elif defined(SYS_readlinkat)
55 ASSERT_GE(
56 LIBC_NAMESPACE::syscall(SYS_readlinkat, AT_FDCWD, LINK, buf, sizeof(buf)),
57 0l);
58 #endif
59 ASSERT_ERRNO_SUCCESS();
61 #ifdef SYS_unlink
62 ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_unlink, LINK), 0l);
63 #elif defined(SYS_unlinkat)
64 ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_unlinkat, AT_FDCWD, LINK, 0), 0l);
65 #else
66 #error "unlink and unlinkat syscalls not available."
67 #endif
68 ASSERT_ERRNO_SUCCESS();
71 TEST(LlvmLibcSyscallTest, FileReadWrite) {
72 constexpr const char HELLO[] = "hello";
73 constexpr int HELLO_SIZE = sizeof(HELLO);
75 constexpr const char *TEST_FILE = "testdata/syscall_pread_pwrite.test";
77 #ifdef SYS_open
78 int fd =
79 LIBC_NAMESPACE::syscall(SYS_open, TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
80 #elif defined(SYS_openat)
81 int fd = LIBC_NAMESPACE::syscall(SYS_openat, AT_FDCWD, TEST_FILE,
82 O_WRONLY | O_CREAT, S_IRWXU);
83 #else
84 #error "open and openat syscalls not available."
85 #endif
86 ASSERT_GT(fd, 0);
87 ASSERT_ERRNO_SUCCESS();
89 ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_pwrite64, fd, HELLO, HELLO_SIZE, 0),
90 0l);
91 ASSERT_ERRNO_SUCCESS();
93 ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_fsync, fd), 0l);
94 ASSERT_ERRNO_SUCCESS();
96 ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_close, fd), 0l);
97 ASSERT_ERRNO_SUCCESS();
100 TEST(LlvmLibcSyscallTest, FileLinkCreateDestroy) {
101 constexpr const char *TEST_DIR = "testdata";
102 constexpr const char *TEST_FILE = "syscall_linkat.test";
103 constexpr const char *TEST_FILE_PATH = "testdata/syscall_linkat.test";
104 constexpr const char *TEST_FILE_LINK = "syscall_linkat.test.link";
105 constexpr const char *TEST_FILE_LINK_PATH =
106 "testdata/syscall_linkat.test.link";
108 // The test strategy is as follows:
109 // 1. Create a normal file
110 // 2. Create a link to that file.
111 // 3. Open the link to check that the link was created.
112 // 4. Cleanup the file and its link.
114 #ifdef SYS_open
115 int write_fd = LIBC_NAMESPACE::syscall(SYS_open, TEST_FILE_PATH,
116 O_WRONLY | O_CREAT, S_IRWXU);
117 #elif defined(SYS_openat)
118 int write_fd = LIBC_NAMESPACE::syscall(SYS_openat, AT_FDCWD, TEST_FILE_PATH,
119 O_WRONLY | O_CREAT, S_IRWXU);
120 #else
121 #error "open and openat syscalls not available."
122 #endif
123 ASSERT_GT(write_fd, 0);
124 ASSERT_ERRNO_SUCCESS();
126 ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_close, write_fd), 0l);
127 ASSERT_ERRNO_SUCCESS();
129 #ifdef SYS_open
130 int dir_fd = LIBC_NAMESPACE::syscall(SYS_open, TEST_DIR, O_DIRECTORY, 0);
131 #elif defined(SYS_openat)
132 int dir_fd =
133 LIBC_NAMESPACE::syscall(SYS_openat, AT_FDCWD, TEST_DIR, O_DIRECTORY, 0);
134 #else
135 #error "open and openat syscalls not available."
136 #endif
137 ASSERT_GT(dir_fd, 0);
138 ASSERT_ERRNO_SUCCESS();
140 ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_linkat, dir_fd, TEST_FILE, dir_fd,
141 TEST_FILE_LINK, 0),
142 0l);
143 ASSERT_ERRNO_SUCCESS();
144 #ifdef SYS_open
145 int link_fd =
146 LIBC_NAMESPACE::syscall(SYS_open, TEST_FILE_LINK_PATH, O_PATH, 0);
147 #elif defined(SYS_openat)
148 int link_fd = LIBC_NAMESPACE::syscall(SYS_openat, AT_FDCWD,
149 TEST_FILE_LINK_PATH, O_PATH, 0);
150 #else
151 #error "open and openat syscalls not available."
152 #endif
153 ASSERT_GT(link_fd, 0);
154 ASSERT_ERRNO_SUCCESS();
156 #ifdef SYS_unlink
157 ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_unlink, TEST_FILE_PATH), 0l);
158 #elif defined(SYS_unlinkat)
159 ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_unlinkat, AT_FDCWD, TEST_FILE_PATH, 0),
160 0l);
161 #else
162 #error "unlink and unlinkat syscalls not available."
163 #endif
164 ASSERT_ERRNO_SUCCESS();
166 #ifdef SYS_unlink
167 ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_unlink, TEST_FILE_LINK_PATH), 0l);
168 #elif defined(SYS_unlinkat)
169 ASSERT_GE(
170 LIBC_NAMESPACE::syscall(SYS_unlinkat, AT_FDCWD, TEST_FILE_LINK_PATH, 0),
171 0l);
172 #else
173 #error "unlink and unlinkat syscalls not available."
174 #endif
175 ASSERT_ERRNO_SUCCESS();
177 ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_close, dir_fd), 0l);
178 ASSERT_ERRNO_SUCCESS();