xref: /aosp_15_r20/external/llvm-libc/test/src/unistd/syscall_test.cpp (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
1*71db0c75SAndroid Build Coastguard Worker //===-- Unittests for syscalls --------------------------------------------===//
2*71db0c75SAndroid Build Coastguard Worker //
3*71db0c75SAndroid Build Coastguard Worker // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*71db0c75SAndroid Build Coastguard Worker // See https://llvm.org/LICENSE.txt for license information.
5*71db0c75SAndroid Build Coastguard Worker // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*71db0c75SAndroid Build Coastguard Worker //
7*71db0c75SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
8*71db0c75SAndroid Build Coastguard Worker 
9*71db0c75SAndroid Build Coastguard Worker #include "src/errno/libc_errno.h"
10*71db0c75SAndroid Build Coastguard Worker #include "src/unistd/syscall.h"
11*71db0c75SAndroid Build Coastguard Worker #include "test/UnitTest/ErrnoSetterMatcher.h"
12*71db0c75SAndroid Build Coastguard Worker #include "test/UnitTest/Test.h"
13*71db0c75SAndroid Build Coastguard Worker 
14*71db0c75SAndroid Build Coastguard Worker #include "hdr/fcntl_macros.h"
15*71db0c75SAndroid Build Coastguard Worker #include <sys/stat.h>    // For S_* flags.
16*71db0c75SAndroid Build Coastguard Worker #include <sys/syscall.h> // For syscall numbers.
17*71db0c75SAndroid Build Coastguard Worker #include <unistd.h>
18*71db0c75SAndroid Build Coastguard Worker 
19*71db0c75SAndroid Build Coastguard Worker using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
20*71db0c75SAndroid Build Coastguard Worker 
21*71db0c75SAndroid Build Coastguard Worker // We only do a smoke test here. Actual functionality tests are
22*71db0c75SAndroid Build Coastguard Worker // done by the unit tests of the syscall wrappers like mmap.
23*71db0c75SAndroid Build Coastguard Worker // The goal is to test syscalls with a wide number of args.
24*71db0c75SAndroid Build Coastguard Worker 
25*71db0c75SAndroid Build Coastguard Worker // There is no function named "syscall" in llvm-libc, we instead use a macro to
26*71db0c75SAndroid Build Coastguard Worker // set up the arguments properly. We still need to specify the namespace though
27*71db0c75SAndroid Build Coastguard Worker // because the macro generates a call to the actual internal function
28*71db0c75SAndroid Build Coastguard Worker // (__llvm_libc_syscall) which is inside the namespace.
TEST(LlvmLibcSyscallTest,TrivialCall)29*71db0c75SAndroid Build Coastguard Worker TEST(LlvmLibcSyscallTest, TrivialCall) {
30*71db0c75SAndroid Build Coastguard Worker   LIBC_NAMESPACE::libc_errno = 0;
31*71db0c75SAndroid Build Coastguard Worker 
32*71db0c75SAndroid Build Coastguard Worker   ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_gettid), 0l);
33*71db0c75SAndroid Build Coastguard Worker   ASSERT_ERRNO_SUCCESS();
34*71db0c75SAndroid Build Coastguard Worker }
35*71db0c75SAndroid Build Coastguard Worker 
TEST(LlvmLibcSyscallTest,SymlinkCreateDestroy)36*71db0c75SAndroid Build Coastguard Worker TEST(LlvmLibcSyscallTest, SymlinkCreateDestroy) {
37*71db0c75SAndroid Build Coastguard Worker   constexpr const char LINK_VAL[] = "syscall_readlink_test_value";
38*71db0c75SAndroid Build Coastguard Worker   constexpr const char LINK[] = "testdata/syscall_readlink.test.link";
39*71db0c75SAndroid Build Coastguard Worker 
40*71db0c75SAndroid Build Coastguard Worker #ifdef SYS_symlink
41*71db0c75SAndroid Build Coastguard Worker   ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_symlink, LINK_VAL, LINK), 0l);
42*71db0c75SAndroid Build Coastguard Worker #elif defined(SYS_symlinkat)
43*71db0c75SAndroid Build Coastguard Worker   ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_symlinkat, LINK_VAL, AT_FDCWD, LINK),
44*71db0c75SAndroid Build Coastguard Worker             0l);
45*71db0c75SAndroid Build Coastguard Worker #else
46*71db0c75SAndroid Build Coastguard Worker #error "symlink and symlinkat syscalls not available."
47*71db0c75SAndroid Build Coastguard Worker #endif
48*71db0c75SAndroid Build Coastguard Worker   ASSERT_ERRNO_SUCCESS();
49*71db0c75SAndroid Build Coastguard Worker 
50*71db0c75SAndroid Build Coastguard Worker   char buf[sizeof(LINK_VAL)];
51*71db0c75SAndroid Build Coastguard Worker 
52*71db0c75SAndroid Build Coastguard Worker #ifdef SYS_readlink
53*71db0c75SAndroid Build Coastguard Worker   ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_readlink, LINK, buf, sizeof(buf)), 0l);
54*71db0c75SAndroid Build Coastguard Worker #elif defined(SYS_readlinkat)
55*71db0c75SAndroid Build Coastguard Worker   ASSERT_GE(
56*71db0c75SAndroid Build Coastguard Worker       LIBC_NAMESPACE::syscall(SYS_readlinkat, AT_FDCWD, LINK, buf, sizeof(buf)),
57*71db0c75SAndroid Build Coastguard Worker       0l);
58*71db0c75SAndroid Build Coastguard Worker #endif
59*71db0c75SAndroid Build Coastguard Worker   ASSERT_ERRNO_SUCCESS();
60*71db0c75SAndroid Build Coastguard Worker 
61*71db0c75SAndroid Build Coastguard Worker #ifdef SYS_unlink
62*71db0c75SAndroid Build Coastguard Worker   ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_unlink, LINK), 0l);
63*71db0c75SAndroid Build Coastguard Worker #elif defined(SYS_unlinkat)
64*71db0c75SAndroid Build Coastguard Worker   ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_unlinkat, AT_FDCWD, LINK, 0), 0l);
65*71db0c75SAndroid Build Coastguard Worker #else
66*71db0c75SAndroid Build Coastguard Worker #error "unlink and unlinkat syscalls not available."
67*71db0c75SAndroid Build Coastguard Worker #endif
68*71db0c75SAndroid Build Coastguard Worker   ASSERT_ERRNO_SUCCESS();
69*71db0c75SAndroid Build Coastguard Worker }
70*71db0c75SAndroid Build Coastguard Worker 
TEST(LlvmLibcSyscallTest,FileReadWrite)71*71db0c75SAndroid Build Coastguard Worker TEST(LlvmLibcSyscallTest, FileReadWrite) {
72*71db0c75SAndroid Build Coastguard Worker   constexpr const char HELLO[] = "hello";
73*71db0c75SAndroid Build Coastguard Worker   constexpr int HELLO_SIZE = sizeof(HELLO);
74*71db0c75SAndroid Build Coastguard Worker 
75*71db0c75SAndroid Build Coastguard Worker   constexpr const char *TEST_FILE = "testdata/syscall_pread_pwrite.test";
76*71db0c75SAndroid Build Coastguard Worker 
77*71db0c75SAndroid Build Coastguard Worker #ifdef SYS_open
78*71db0c75SAndroid Build Coastguard Worker   int fd =
79*71db0c75SAndroid Build Coastguard Worker       LIBC_NAMESPACE::syscall(SYS_open, TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
80*71db0c75SAndroid Build Coastguard Worker #elif defined(SYS_openat)
81*71db0c75SAndroid Build Coastguard Worker   int fd = LIBC_NAMESPACE::syscall(SYS_openat, AT_FDCWD, TEST_FILE,
82*71db0c75SAndroid Build Coastguard Worker                                    O_WRONLY | O_CREAT, S_IRWXU);
83*71db0c75SAndroid Build Coastguard Worker #else
84*71db0c75SAndroid Build Coastguard Worker #error "open and openat syscalls not available."
85*71db0c75SAndroid Build Coastguard Worker #endif
86*71db0c75SAndroid Build Coastguard Worker   ASSERT_GT(fd, 0);
87*71db0c75SAndroid Build Coastguard Worker   ASSERT_ERRNO_SUCCESS();
88*71db0c75SAndroid Build Coastguard Worker 
89*71db0c75SAndroid Build Coastguard Worker   ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_pwrite64, fd, HELLO, HELLO_SIZE, 0),
90*71db0c75SAndroid Build Coastguard Worker             0l);
91*71db0c75SAndroid Build Coastguard Worker   ASSERT_ERRNO_SUCCESS();
92*71db0c75SAndroid Build Coastguard Worker 
93*71db0c75SAndroid Build Coastguard Worker   ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_fsync, fd), 0l);
94*71db0c75SAndroid Build Coastguard Worker   ASSERT_ERRNO_SUCCESS();
95*71db0c75SAndroid Build Coastguard Worker 
96*71db0c75SAndroid Build Coastguard Worker   ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_close, fd), 0l);
97*71db0c75SAndroid Build Coastguard Worker   ASSERT_ERRNO_SUCCESS();
98*71db0c75SAndroid Build Coastguard Worker }
99*71db0c75SAndroid Build Coastguard Worker 
TEST(LlvmLibcSyscallTest,FileLinkCreateDestroy)100*71db0c75SAndroid Build Coastguard Worker TEST(LlvmLibcSyscallTest, FileLinkCreateDestroy) {
101*71db0c75SAndroid Build Coastguard Worker   constexpr const char *TEST_DIR = "testdata";
102*71db0c75SAndroid Build Coastguard Worker   constexpr const char *TEST_FILE = "syscall_linkat.test";
103*71db0c75SAndroid Build Coastguard Worker   constexpr const char *TEST_FILE_PATH = "testdata/syscall_linkat.test";
104*71db0c75SAndroid Build Coastguard Worker   constexpr const char *TEST_FILE_LINK = "syscall_linkat.test.link";
105*71db0c75SAndroid Build Coastguard Worker   constexpr const char *TEST_FILE_LINK_PATH =
106*71db0c75SAndroid Build Coastguard Worker       "testdata/syscall_linkat.test.link";
107*71db0c75SAndroid Build Coastguard Worker 
108*71db0c75SAndroid Build Coastguard Worker   // The test strategy is as follows:
109*71db0c75SAndroid Build Coastguard Worker   //   1. Create a normal file
110*71db0c75SAndroid Build Coastguard Worker   //   2. Create a link to that file.
111*71db0c75SAndroid Build Coastguard Worker   //   3. Open the link to check that the link was created.
112*71db0c75SAndroid Build Coastguard Worker   //   4. Cleanup the file and its link.
113*71db0c75SAndroid Build Coastguard Worker 
114*71db0c75SAndroid Build Coastguard Worker #ifdef SYS_open
115*71db0c75SAndroid Build Coastguard Worker   int write_fd = LIBC_NAMESPACE::syscall(SYS_open, TEST_FILE_PATH,
116*71db0c75SAndroid Build Coastguard Worker                                          O_WRONLY | O_CREAT, S_IRWXU);
117*71db0c75SAndroid Build Coastguard Worker #elif defined(SYS_openat)
118*71db0c75SAndroid Build Coastguard Worker   int write_fd = LIBC_NAMESPACE::syscall(SYS_openat, AT_FDCWD, TEST_FILE_PATH,
119*71db0c75SAndroid Build Coastguard Worker                                          O_WRONLY | O_CREAT, S_IRWXU);
120*71db0c75SAndroid Build Coastguard Worker #else
121*71db0c75SAndroid Build Coastguard Worker #error "open and openat syscalls not available."
122*71db0c75SAndroid Build Coastguard Worker #endif
123*71db0c75SAndroid Build Coastguard Worker   ASSERT_GT(write_fd, 0);
124*71db0c75SAndroid Build Coastguard Worker   ASSERT_ERRNO_SUCCESS();
125*71db0c75SAndroid Build Coastguard Worker 
126*71db0c75SAndroid Build Coastguard Worker   ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_close, write_fd), 0l);
127*71db0c75SAndroid Build Coastguard Worker   ASSERT_ERRNO_SUCCESS();
128*71db0c75SAndroid Build Coastguard Worker 
129*71db0c75SAndroid Build Coastguard Worker #ifdef SYS_open
130*71db0c75SAndroid Build Coastguard Worker   int dir_fd = LIBC_NAMESPACE::syscall(SYS_open, TEST_DIR, O_DIRECTORY, 0);
131*71db0c75SAndroid Build Coastguard Worker #elif defined(SYS_openat)
132*71db0c75SAndroid Build Coastguard Worker   int dir_fd =
133*71db0c75SAndroid Build Coastguard Worker       LIBC_NAMESPACE::syscall(SYS_openat, AT_FDCWD, TEST_DIR, O_DIRECTORY, 0);
134*71db0c75SAndroid Build Coastguard Worker #else
135*71db0c75SAndroid Build Coastguard Worker #error "open and openat syscalls not available."
136*71db0c75SAndroid Build Coastguard Worker #endif
137*71db0c75SAndroid Build Coastguard Worker   ASSERT_GT(dir_fd, 0);
138*71db0c75SAndroid Build Coastguard Worker   ASSERT_ERRNO_SUCCESS();
139*71db0c75SAndroid Build Coastguard Worker 
140*71db0c75SAndroid Build Coastguard Worker   ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_linkat, dir_fd, TEST_FILE, dir_fd,
141*71db0c75SAndroid Build Coastguard Worker                                     TEST_FILE_LINK, 0),
142*71db0c75SAndroid Build Coastguard Worker             0l);
143*71db0c75SAndroid Build Coastguard Worker   ASSERT_ERRNO_SUCCESS();
144*71db0c75SAndroid Build Coastguard Worker #ifdef SYS_open
145*71db0c75SAndroid Build Coastguard Worker   int link_fd =
146*71db0c75SAndroid Build Coastguard Worker       LIBC_NAMESPACE::syscall(SYS_open, TEST_FILE_LINK_PATH, O_PATH, 0);
147*71db0c75SAndroid Build Coastguard Worker #elif defined(SYS_openat)
148*71db0c75SAndroid Build Coastguard Worker   int link_fd = LIBC_NAMESPACE::syscall(SYS_openat, AT_FDCWD,
149*71db0c75SAndroid Build Coastguard Worker                                         TEST_FILE_LINK_PATH, O_PATH, 0);
150*71db0c75SAndroid Build Coastguard Worker #else
151*71db0c75SAndroid Build Coastguard Worker #error "open and openat syscalls not available."
152*71db0c75SAndroid Build Coastguard Worker #endif
153*71db0c75SAndroid Build Coastguard Worker   ASSERT_GT(link_fd, 0);
154*71db0c75SAndroid Build Coastguard Worker   ASSERT_ERRNO_SUCCESS();
155*71db0c75SAndroid Build Coastguard Worker 
156*71db0c75SAndroid Build Coastguard Worker #ifdef SYS_unlink
157*71db0c75SAndroid Build Coastguard Worker   ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_unlink, TEST_FILE_PATH), 0l);
158*71db0c75SAndroid Build Coastguard Worker #elif defined(SYS_unlinkat)
159*71db0c75SAndroid Build Coastguard Worker   ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_unlinkat, AT_FDCWD, TEST_FILE_PATH, 0),
160*71db0c75SAndroid Build Coastguard Worker             0l);
161*71db0c75SAndroid Build Coastguard Worker #else
162*71db0c75SAndroid Build Coastguard Worker #error "unlink and unlinkat syscalls not available."
163*71db0c75SAndroid Build Coastguard Worker #endif
164*71db0c75SAndroid Build Coastguard Worker   ASSERT_ERRNO_SUCCESS();
165*71db0c75SAndroid Build Coastguard Worker 
166*71db0c75SAndroid Build Coastguard Worker #ifdef SYS_unlink
167*71db0c75SAndroid Build Coastguard Worker   ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_unlink, TEST_FILE_LINK_PATH), 0l);
168*71db0c75SAndroid Build Coastguard Worker #elif defined(SYS_unlinkat)
169*71db0c75SAndroid Build Coastguard Worker   ASSERT_GE(
170*71db0c75SAndroid Build Coastguard Worker       LIBC_NAMESPACE::syscall(SYS_unlinkat, AT_FDCWD, TEST_FILE_LINK_PATH, 0),
171*71db0c75SAndroid Build Coastguard Worker       0l);
172*71db0c75SAndroid Build Coastguard Worker #else
173*71db0c75SAndroid Build Coastguard Worker #error "unlink and unlinkat syscalls not available."
174*71db0c75SAndroid Build Coastguard Worker #endif
175*71db0c75SAndroid Build Coastguard Worker   ASSERT_ERRNO_SUCCESS();
176*71db0c75SAndroid Build Coastguard Worker 
177*71db0c75SAndroid Build Coastguard Worker   ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_close, dir_fd), 0l);
178*71db0c75SAndroid Build Coastguard Worker   ASSERT_ERRNO_SUCCESS();
179*71db0c75SAndroid Build Coastguard Worker }
180