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//===----------------------------------------------------------------------===//
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 are
23// 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 to
27// set up the arguments properly. We still need to specify the namespace though
28// because the macro generates a call to the actual internal function
29// (__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_symlink
40 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#else
45#error "symlink and symlinkat syscalls not available."
46#endif
47 ASSERT_ERRNO_SUCCESS();
48
49 char buf[sizeof(LINK_VAL)];
50
51#ifdef SYS_readlink
52 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#endif
58 ASSERT_ERRNO_SUCCESS();
59
60#ifdef SYS_unlink
61 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#else
65#error "unlink and unlinkat syscalls not available."
66#endif
67 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_open
77 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#else
83#error "open and openat syscalls not available."
84#endif
85 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 file
109 // 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_open
114 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#else
120#error "open and openat syscalls not available."
121#endif
122 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_open
129 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#else
134#error "open and openat syscalls not available."
135#endif
136 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_open
144 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#else
150#error "open and openat syscalls not available."
151#endif
152 ASSERT_GT(link_fd, 0l);
153 ASSERT_ERRNO_SUCCESS();
154
155#ifdef SYS_unlink
156 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#else
161#error "unlink and unlinkat syscalls not available."
162#endif
163 ASSERT_ERRNO_SUCCESS();
164
165#ifdef SYS_unlink
166 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#else
172#error "unlink and unlinkat syscalls not available."
173#endif
174 ASSERT_ERRNO_SUCCESS();
175
176 ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_close, dir_fd), 0l);
177 ASSERT_ERRNO_SUCCESS();
178}
179

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of libc/test/src/unistd/syscall_test.cpp