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(__arm__) 30# if defined(__thumb__) || defined(__ARM_EABI__) 31# define UV_SYSCALL_BASE 0 32# else 33# define UV_SYSCALL_BASE 0x900000 34# endif 35#endif /* __arm__ */ 36 37#ifndef __NR_recvmmsg 38# if defined(__x86_64__) 39# define __NR_recvmmsg 299 40# elif defined(__arm__) 41# define __NR_recvmmsg (UV_SYSCALL_BASE + 365) 42# endif 43#endif /* __NR_recvmsg */ 44 45#ifndef __NR_sendmmsg 46# if defined(__x86_64__) 47# define __NR_sendmmsg 307 48# elif defined(__arm__) 49# define __NR_sendmmsg (UV_SYSCALL_BASE + 374) 50# endif 51#endif /* __NR_sendmmsg */ 52 53#ifndef __NR_utimensat 54# if defined(__x86_64__) 55# define __NR_utimensat 280 56# elif defined(__i386__) 57# define __NR_utimensat 320 58# elif defined(__arm__) 59# define __NR_utimensat (UV_SYSCALL_BASE + 348) 60# endif 61#endif /* __NR_utimensat */ 62 63#ifndef __NR_preadv 64# if defined(__x86_64__) 65# define __NR_preadv 295 66# elif defined(__i386__) 67# define __NR_preadv 333 68# elif defined(__arm__) 69# define __NR_preadv (UV_SYSCALL_BASE + 361) 70# endif 71#endif /* __NR_preadv */ 72 73#ifndef __NR_pwritev 74# if defined(__x86_64__) 75# define __NR_pwritev 296 76# elif defined(__i386__) 77# define __NR_pwritev 334 78# elif defined(__arm__) 79# define __NR_pwritev (UV_SYSCALL_BASE + 362) 80# endif 81#endif /* __NR_pwritev */ 82 83#ifndef __NR_dup3 84# if defined(__x86_64__) 85# define __NR_dup3 292 86# elif defined(__i386__) 87# define __NR_dup3 330 88# elif defined(__arm__) 89# define __NR_dup3 (UV_SYSCALL_BASE + 358) 90# endif 91#endif /* __NR_pwritev */ 92 93#ifndef __NR_copy_file_range 94# if defined(__x86_64__) 95# define __NR_copy_file_range 326 96# elif defined(__i386__) 97# define __NR_copy_file_range 377 98# elif defined(__s390__) 99# define __NR_copy_file_range 375 100# elif defined(__arm__) 101# define __NR_copy_file_range (UV_SYSCALL_BASE + 391) 102# elif defined(__aarch64__) 103# define __NR_copy_file_range 285 104# elif defined(__powerpc__) 105# define __NR_copy_file_range 379 106# elif defined(__arc__) 107# define __NR_copy_file_range 285 108# endif 109#endif /* __NR_copy_file_range */ 110 111#ifndef __NR_statx 112# if defined(__x86_64__) 113# define __NR_statx 332 114# elif defined(__i386__) 115# define __NR_statx 383 116# elif defined(__aarch64__) 117# define __NR_statx 397 118# elif defined(__arm__) 119# define __NR_statx (UV_SYSCALL_BASE + 397) 120# elif defined(__ppc__) 121# define __NR_statx 383 122# elif defined(__s390__) 123# define __NR_statx 379 124# endif 125#endif /* __NR_statx */ 126 127#ifndef __NR_getrandom 128# if defined(__x86_64__) 129# define __NR_getrandom 318 130# elif defined(__i386__) 131# define __NR_getrandom 355 132# elif defined(__aarch64__) 133# define __NR_getrandom 384 134# elif defined(__arm__) 135# define __NR_getrandom (UV_SYSCALL_BASE + 384) 136# elif defined(__ppc__) 137# define __NR_getrandom 359 138# elif defined(__s390__) 139# define __NR_getrandom 349 140# endif 141#endif /* __NR_getrandom */ 142 143struct uv__mmsghdr; 144 145int uv__sendmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) { 146#if defined(__i386__) 147 unsigned long args[4]; 148 int rc; 149 150 args[0] = (unsigned long) fd; 151 args[1] = (unsigned long) mmsg; 152 args[2] = (unsigned long) vlen; 153 args[3] = /* flags */ 0; 154 155 /* socketcall() raises EINVAL when SYS_SENDMMSG is not supported. */ 156 rc = syscall(/* __NR_socketcall */ 102, 20 /* SYS_SENDMMSG */, args); 157 if (rc == -1) 158 if (errno == EINVAL) 159 errno = ENOSYS; 160 161 return rc; 162#elif defined(__NR_sendmmsg) 163 return syscall(__NR_sendmmsg, fd, mmsg, vlen, /* flags */ 0); 164#else 165 return errno = ENOSYS, -1; 166#endif 167} 168 169 170int uv__recvmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) { 171#if defined(__i386__) 172 unsigned long args[5]; 173 int rc; 174 175 args[0] = (unsigned long) fd; 176 args[1] = (unsigned long) mmsg; 177 args[2] = (unsigned long) vlen; 178 args[3] = /* flags */ 0; 179 args[4] = /* timeout */ 0; 180 181 /* socketcall() raises EINVAL when SYS_RECVMMSG is not supported. */ 182 rc = syscall(/* __NR_socketcall */ 102, 19 /* SYS_RECVMMSG */, args); 183 if (rc == -1) 184 if (errno == EINVAL) 185 errno = ENOSYS; 186 187 return rc; 188#elif defined(__NR_recvmmsg) 189 return syscall(__NR_recvmmsg, fd, mmsg, vlen, /* flags */ 0, /* timeout */ 0); 190#else 191 return errno = ENOSYS, -1; 192#endif 193} 194 195 196ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, int64_t offset) { 197#if !defined(__NR_preadv) || defined(__ANDROID_API__) && __ANDROID_API__ < 24 198 return errno = ENOSYS, -1; 199#else 200 return syscall(__NR_preadv, fd, iov, iovcnt, (long)offset, (long)(offset >> 32)); 201#endif 202} 203 204 205ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, int64_t offset) { 206#if !defined(__NR_pwritev) || defined(__ANDROID_API__) && __ANDROID_API__ < 24 207 return errno = ENOSYS, -1; 208#else 209 return syscall(__NR_pwritev, fd, iov, iovcnt, (long)offset, (long)(offset >> 32)); 210#endif 211} 212 213 214int uv__dup3(int oldfd, int newfd, int flags) { 215#if !defined(__NR_dup3) || defined(__ANDROID_API__) && __ANDROID_API__ < 21 216 return errno = ENOSYS, -1; 217#else 218 return syscall(__NR_dup3, oldfd, newfd, flags); 219#endif 220} 221 222 223ssize_t 224uv__fs_copy_file_range(int fd_in, 225 off_t* off_in, 226 int fd_out, 227 off_t* off_out, 228 size_t len, 229 unsigned int flags) 230{ 231#ifdef __NR_copy_file_range 232 return syscall(__NR_copy_file_range, 233 fd_in, 234 off_in, 235 fd_out, 236 off_out, 237 len, 238 flags); 239#else 240 return errno = ENOSYS, -1; 241#endif 242} 243 244 245int uv__statx(int dirfd, 246 const char* path, 247 int flags, 248 unsigned int mask, 249 struct uv__statx* statxbuf) { 250#if !defined(__NR_statx) || defined(__ANDROID_API__) && __ANDROID_API__ < 30 251 return errno = ENOSYS, -1; 252#else 253 return syscall(__NR_statx, dirfd, path, flags, mask, statxbuf); 254#endif 255} 256 257 258ssize_t uv__getrandom(void* buf, size_t buflen, unsigned flags) { 259#if !defined(__NR_getrandom) || defined(__ANDROID_API__) && __ANDROID_API__ < 28 260 return errno = ENOSYS, -1; 261#else 262 return syscall(__NR_getrandom, buf, buflen, flags); 263#endif 264} 265