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 143 struct uv__mmsghdr; 144 145 int 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 170 int 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 196 ssize_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 205 ssize_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 214 int 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 223 ssize_t 224 uv__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 245 int 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 258 ssize_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