1/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to
5 * deal in the Software without restriction, including without limitation the
6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 * sell copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19 * IN THE SOFTWARE.
20 */
21
22#include "linux-syscalls.h"
23#include <unistd.h>
24#include <signal.h>
25#include <sys/syscall.h>
26#include <sys/types.h>
27#include <errno.h>
28
29#if defined(__has_feature)
30# if __has_feature(memory_sanitizer)
31# define MSAN_ACTIVE 1
32# include <sanitizer/msan_interface.h>
33# endif
34#endif
35
36#if defined(__i386__)
37# ifndef __NR_socketcall
38# define __NR_socketcall 102
39# endif
40#endif
41
42#if defined(__arm__)
43# if defined(__thumb__) || defined(__ARM_EABI__)
44# define UV_SYSCALL_BASE 0
45# else
46# define UV_SYSCALL_BASE 0x900000
47# endif
48#endif /* __arm__ */
49
50#ifndef __NR_accept4
51# if defined(__x86_64__)
52# define __NR_accept4 288
53# elif defined(__i386__)
54 /* Nothing. Handled through socketcall(). */
55# elif defined(__arm__)
56# define __NR_accept4 (UV_SYSCALL_BASE + 366)
57# endif
58#endif /* __NR_accept4 */
59
60#ifndef __NR_eventfd
61# if defined(__x86_64__)
62# define __NR_eventfd 284
63# elif defined(__i386__)
64# define __NR_eventfd 323
65# elif defined(__arm__)
66# define __NR_eventfd (UV_SYSCALL_BASE + 351)
67# endif
68#endif /* __NR_eventfd */
69
70#ifndef __NR_eventfd2
71# if defined(__x86_64__)
72# define __NR_eventfd2 290
73# elif defined(__i386__)
74# define __NR_eventfd2 328
75# elif defined(__arm__)
76# define __NR_eventfd2 (UV_SYSCALL_BASE + 356)
77# endif
78#endif /* __NR_eventfd2 */
79
80#ifndef __NR_inotify_init
81# if defined(__x86_64__)
82# define __NR_inotify_init 253
83# elif defined(__i386__)
84# define __NR_inotify_init 291
85# elif defined(__arm__)
86# define __NR_inotify_init (UV_SYSCALL_BASE + 316)
87# endif
88#endif /* __NR_inotify_init */
89
90#ifndef __NR_inotify_init1
91# if defined(__x86_64__)
92# define __NR_inotify_init1 294
93# elif defined(__i386__)
94# define __NR_inotify_init1 332
95# elif defined(__arm__)
96# define __NR_inotify_init1 (UV_SYSCALL_BASE + 360)
97# endif
98#endif /* __NR_inotify_init1 */
99
100#ifndef __NR_inotify_add_watch
101# if defined(__x86_64__)
102# define __NR_inotify_add_watch 254
103# elif defined(__i386__)
104# define __NR_inotify_add_watch 292
105# elif defined(__arm__)
106# define __NR_inotify_add_watch (UV_SYSCALL_BASE + 317)
107# endif
108#endif /* __NR_inotify_add_watch */
109
110#ifndef __NR_inotify_rm_watch
111# if defined(__x86_64__)
112# define __NR_inotify_rm_watch 255
113# elif defined(__i386__)
114# define __NR_inotify_rm_watch 293
115# elif defined(__arm__)
116# define __NR_inotify_rm_watch (UV_SYSCALL_BASE + 318)
117# endif
118#endif /* __NR_inotify_rm_watch */
119
120#ifndef __NR_pipe2
121# if defined(__x86_64__)
122# define __NR_pipe2 293
123# elif defined(__i386__)
124# define __NR_pipe2 331
125# elif defined(__arm__)
126# define __NR_pipe2 (UV_SYSCALL_BASE + 359)
127# endif
128#endif /* __NR_pipe2 */
129
130#ifndef __NR_recvmmsg
131# if defined(__x86_64__)
132# define __NR_recvmmsg 299
133# elif defined(__i386__)
134# define __NR_recvmmsg 337
135# elif defined(__arm__)
136# define __NR_recvmmsg (UV_SYSCALL_BASE + 365)
137# endif
138#endif /* __NR_recvmsg */
139
140#ifndef __NR_sendmmsg
141# if defined(__x86_64__)
142# define __NR_sendmmsg 307
143# elif defined(__i386__)
144# define __NR_sendmmsg 345
145# elif defined(__arm__)
146# define __NR_sendmmsg (UV_SYSCALL_BASE + 374)
147# endif
148#endif /* __NR_sendmmsg */
149
150#ifndef __NR_utimensat
151# if defined(__x86_64__)
152# define __NR_utimensat 280
153# elif defined(__i386__)
154# define __NR_utimensat 320
155# elif defined(__arm__)
156# define __NR_utimensat (UV_SYSCALL_BASE + 348)
157# endif
158#endif /* __NR_utimensat */
159
160#ifndef __NR_preadv
161# if defined(__x86_64__)
162# define __NR_preadv 295
163# elif defined(__i386__)
164# define __NR_preadv 333
165# elif defined(__arm__)
166# define __NR_preadv (UV_SYSCALL_BASE + 361)
167# endif
168#endif /* __NR_preadv */
169
170#ifndef __NR_pwritev
171# if defined(__x86_64__)
172# define __NR_pwritev 296
173# elif defined(__i386__)
174# define __NR_pwritev 334
175# elif defined(__arm__)
176# define __NR_pwritev (UV_SYSCALL_BASE + 362)
177# endif
178#endif /* __NR_pwritev */
179
180#ifndef __NR_dup3
181# if defined(__x86_64__)
182# define __NR_dup3 292
183# elif defined(__i386__)
184# define __NR_dup3 330
185# elif defined(__arm__)
186# define __NR_dup3 (UV_SYSCALL_BASE + 358)
187# endif
188#endif /* __NR_pwritev */
189
190#ifndef __NR_statx
191# if defined(__x86_64__)
192# define __NR_statx 332
193# elif defined(__i386__)
194# define __NR_statx 383
195# elif defined(__aarch64__)
196# define __NR_statx 397
197# elif defined(__arm__)
198# define __NR_statx (UV_SYSCALL_BASE + 397)
199# elif defined(__ppc__)
200# define __NR_statx 383
201# elif defined(__s390__)
202# define __NR_statx 379
203# endif
204#endif /* __NR_statx */
205
206int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags) {
207#if defined(__i386__)
208 unsigned long args[4];
209 int r;
210
211 args[0] = (unsigned long) fd;
212 args[1] = (unsigned long) addr;
213 args[2] = (unsigned long) addrlen;
214 args[3] = (unsigned long) flags;
215
216 r = syscall(__NR_socketcall, 18 /* SYS_ACCEPT4 */, args);
217
218 /* socketcall() raises EINVAL when SYS_ACCEPT4 is not supported but so does
219 * a bad flags argument. Try to distinguish between the two cases.
220 */
221 if (r == -1)
222 if (errno == EINVAL)
223 if ((flags & ~(UV__SOCK_CLOEXEC|UV__SOCK_NONBLOCK)) == 0)
224 errno = ENOSYS;
225
226 return r;
227#elif defined(__NR_accept4)
228 return syscall(__NR_accept4, fd, addr, addrlen, flags);
229#else
230 return errno = ENOSYS, -1;
231#endif
232}
233
234
235int uv__eventfd(unsigned int count) {
236#if defined(__NR_eventfd)
237 return syscall(__NR_eventfd, count);
238#else
239 return errno = ENOSYS, -1;
240#endif
241}
242
243
244int uv__eventfd2(unsigned int count, int flags) {
245#if defined(__NR_eventfd2)
246 return syscall(__NR_eventfd2, count, flags);
247#else
248 return errno = ENOSYS, -1;
249#endif
250}
251
252
253int uv__inotify_init(void) {
254#if defined(__NR_inotify_init)
255 return syscall(__NR_inotify_init);
256#else
257 return errno = ENOSYS, -1;
258#endif
259}
260
261
262int uv__inotify_init1(int flags) {
263#if defined(__NR_inotify_init1)
264 return syscall(__NR_inotify_init1, flags);
265#else
266 return errno = ENOSYS, -1;
267#endif
268}
269
270
271int uv__inotify_add_watch(int fd, const char* path, uint32_t mask) {
272#if defined(__NR_inotify_add_watch)
273 return syscall(__NR_inotify_add_watch, fd, path, mask);
274#else
275 return errno = ENOSYS, -1;
276#endif
277}
278
279
280int uv__inotify_rm_watch(int fd, int32_t wd) {
281#if defined(__NR_inotify_rm_watch)
282 return syscall(__NR_inotify_rm_watch, fd, wd);
283#else
284 return errno = ENOSYS, -1;
285#endif
286}
287
288
289int uv__pipe2(int pipefd[2], int flags) {
290#if defined(__NR_pipe2)
291 int result;
292 result = syscall(__NR_pipe2, pipefd, flags);
293#if MSAN_ACTIVE
294 if (!result)
295 __msan_unpoison(pipefd, sizeof(int[2]));
296#endif
297 return result;
298#else
299 return errno = ENOSYS, -1;
300#endif
301}
302
303
304int uv__sendmmsg(int fd,
305 struct uv__mmsghdr* mmsg,
306 unsigned int vlen,
307 unsigned int flags) {
308#if defined(__NR_sendmmsg)
309 return syscall(__NR_sendmmsg, fd, mmsg, vlen, flags);
310#else
311 return errno = ENOSYS, -1;
312#endif
313}
314
315
316int uv__recvmmsg(int fd,
317 struct uv__mmsghdr* mmsg,
318 unsigned int vlen,
319 unsigned int flags,
320 struct timespec* timeout) {
321#if defined(__NR_recvmmsg)
322 return syscall(__NR_recvmmsg, fd, mmsg, vlen, flags, timeout);
323#else
324 return errno = ENOSYS, -1;
325#endif
326}
327
328
329ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, int64_t offset) {
330#if defined(__NR_preadv)
331 return syscall(__NR_preadv, fd, iov, iovcnt, (long)offset, (long)(offset >> 32));
332#else
333 return errno = ENOSYS, -1;
334#endif
335}
336
337
338ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, int64_t offset) {
339#if defined(__NR_pwritev)
340 return syscall(__NR_pwritev, fd, iov, iovcnt, (long)offset, (long)(offset >> 32));
341#else
342 return errno = ENOSYS, -1;
343#endif
344}
345
346
347int uv__dup3(int oldfd, int newfd, int flags) {
348#if defined(__NR_dup3)
349 return syscall(__NR_dup3, oldfd, newfd, flags);
350#else
351 return errno = ENOSYS, -1;
352#endif
353}
354
355
356int uv__statx(int dirfd,
357 const char* path,
358 int flags,
359 unsigned int mask,
360 struct uv__statx* statxbuf) {
361 /* __NR_statx make Android box killed by SIGSYS.
362 * That looks like a seccomp2 sandbox filter rejecting the system call.
363 */
364#if defined(__NR_statx) && !defined(__ANDROID__)
365 return syscall(__NR_statx, dirfd, path, flags, mask, statxbuf);
366#else
367 return errno = ENOSYS, -1;
368#endif
369}
370