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 <sys/syscall.h>
25 #include <sys/types.h>
26 #include <errno.h>
27
28 #if defined(__i386__)
29 # ifndef __NR_socketcall
30 # define __NR_socketcall 102
31 # endif
32 #endif
33
34 #if defined(__arm__)
35 # if defined(__thumb__) || defined(__ARM_EABI__)
36 # define UV_SYSCALL_BASE 0
37 # else
38 # define UV_SYSCALL_BASE 0x900000
39 # endif
40 #endif /* __arm__ */
41
42 #ifndef __NR_accept4
43 # if defined(__x86_64__)
44 # define __NR_accept4 288
45 # elif defined(__i386__)
46 /* Nothing. Handled through socketcall(). */
47 # elif defined(__arm__)
48 # define __NR_accept4 (UV_SYSCALL_BASE + 366)
49 # endif
50 #endif /* __NR_accept4 */
51
52 #ifndef __NR_eventfd
53 # if defined(__x86_64__)
54 # define __NR_eventfd 284
55 # elif defined(__i386__)
56 # define __NR_eventfd 323
57 # elif defined(__arm__)
58 # define __NR_eventfd (UV_SYSCALL_BASE + 351)
59 # endif
60 #endif /* __NR_eventfd */
61
62 #ifndef __NR_eventfd2
63 # if defined(__x86_64__)
64 # define __NR_eventfd2 290
65 # elif defined(__i386__)
66 # define __NR_eventfd2 328
67 # elif defined(__arm__)
68 # define __NR_eventfd2 (UV_SYSCALL_BASE + 356)
69 # endif
70 #endif /* __NR_eventfd2 */
71
72 #ifndef __NR_epoll_create
73 # if defined(__x86_64__)
74 # define __NR_epoll_create 213
75 # elif defined(__i386__)
76 # define __NR_epoll_create 254
77 # elif defined(__arm__)
78 # define __NR_epoll_create (UV_SYSCALL_BASE + 250)
79 # endif
80 #endif /* __NR_epoll_create */
81
82 #ifndef __NR_epoll_create1
83 # if defined(__x86_64__)
84 # define __NR_epoll_create1 291
85 # elif defined(__i386__)
86 # define __NR_epoll_create1 329
87 # elif defined(__arm__)
88 # define __NR_epoll_create1 (UV_SYSCALL_BASE + 357)
89 # endif
90 #endif /* __NR_epoll_create1 */
91
92 #ifndef __NR_epoll_ctl
93 # if defined(__x86_64__)
94 # define __NR_epoll_ctl 233 /* used to be 214 */
95 # elif defined(__i386__)
96 # define __NR_epoll_ctl 255
97 # elif defined(__arm__)
98 # define __NR_epoll_ctl (UV_SYSCALL_BASE + 251)
99 # endif
100 #endif /* __NR_epoll_ctl */
101
102 #ifndef __NR_epoll_wait
103 # if defined(__x86_64__)
104 # define __NR_epoll_wait 232 /* used to be 215 */
105 # elif defined(__i386__)
106 # define __NR_epoll_wait 256
107 # elif defined(__arm__)
108 # define __NR_epoll_wait (UV_SYSCALL_BASE + 252)
109 # endif
110 #endif /* __NR_epoll_wait */
111
112 #ifndef __NR_epoll_pwait
113 # if defined(__x86_64__)
114 # define __NR_epoll_pwait 281
115 # elif defined(__i386__)
116 # define __NR_epoll_pwait 319
117 # elif defined(__arm__)
118 # define __NR_epoll_pwait (UV_SYSCALL_BASE + 346)
119 # endif
120 #endif /* __NR_epoll_pwait */
121
122 #ifndef __NR_inotify_init
123 # if defined(__x86_64__)
124 # define __NR_inotify_init 253
125 # elif defined(__i386__)
126 # define __NR_inotify_init 291
127 # elif defined(__arm__)
128 # define __NR_inotify_init (UV_SYSCALL_BASE + 316)
129 # endif
130 #endif /* __NR_inotify_init */
131
132 #ifndef __NR_inotify_init1
133 # if defined(__x86_64__)
134 # define __NR_inotify_init1 294
135 # elif defined(__i386__)
136 # define __NR_inotify_init1 332
137 # elif defined(__arm__)
138 # define __NR_inotify_init1 (UV_SYSCALL_BASE + 360)
139 # endif
140 #endif /* __NR_inotify_init1 */
141
142 #ifndef __NR_inotify_add_watch
143 # if defined(__x86_64__)
144 # define __NR_inotify_add_watch 254
145 # elif defined(__i386__)
146 # define __NR_inotify_add_watch 292
147 # elif defined(__arm__)
148 # define __NR_inotify_add_watch (UV_SYSCALL_BASE + 317)
149 # endif
150 #endif /* __NR_inotify_add_watch */
151
152 #ifndef __NR_inotify_rm_watch
153 # if defined(__x86_64__)
154 # define __NR_inotify_rm_watch 255
155 # elif defined(__i386__)
156 # define __NR_inotify_rm_watch 293
157 # elif defined(__arm__)
158 # define __NR_inotify_rm_watch (UV_SYSCALL_BASE + 318)
159 # endif
160 #endif /* __NR_inotify_rm_watch */
161
162 #ifndef __NR_pipe2
163 # if defined(__x86_64__)
164 # define __NR_pipe2 293
165 # elif defined(__i386__)
166 # define __NR_pipe2 331
167 # elif defined(__arm__)
168 # define __NR_pipe2 (UV_SYSCALL_BASE + 359)
169 # endif
170 #endif /* __NR_pipe2 */
171
172 #ifndef __NR_recvmmsg
173 # if defined(__x86_64__)
174 # define __NR_recvmmsg 299
175 # elif defined(__i386__)
176 # define __NR_recvmmsg 337
177 # elif defined(__arm__)
178 # define __NR_recvmmsg (UV_SYSCALL_BASE + 365)
179 # endif
180 #endif /* __NR_recvmsg */
181
182 #ifndef __NR_sendmmsg
183 # if defined(__x86_64__)
184 # define __NR_sendmmsg 307
185 # elif defined(__i386__)
186 # define __NR_sendmmsg 345
187 # elif defined(__arm__)
188 # define __NR_sendmmsg (UV_SYSCALL_BASE + 374)
189 # endif
190 #endif /* __NR_sendmmsg */
191
192 #ifndef __NR_utimensat
193 # if defined(__x86_64__)
194 # define __NR_utimensat 280
195 # elif defined(__i386__)
196 # define __NR_utimensat 320
197 # elif defined(__arm__)
198 # define __NR_utimensat (UV_SYSCALL_BASE + 348)
199 # endif
200 #endif /* __NR_utimensat */
201
202
uv__accept4(int fd,struct sockaddr * addr,socklen_t * addrlen,int flags)203 int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags) {
204 #if defined(__i386__)
205 unsigned long args[4];
206 int r;
207
208 args[0] = (unsigned long) fd;
209 args[1] = (unsigned long) addr;
210 args[2] = (unsigned long) addrlen;
211 args[3] = (unsigned long) flags;
212
213 r = syscall(__NR_socketcall, 18 /* SYS_ACCEPT4 */, args);
214
215 /* socketcall() raises EINVAL when SYS_ACCEPT4 is not supported but so does
216 * a bad flags argument. Try to distinguish between the two cases.
217 */
218 if (r == -1)
219 if (errno == EINVAL)
220 if ((flags & ~(UV__SOCK_CLOEXEC|UV__SOCK_NONBLOCK)) == 0)
221 errno = ENOSYS;
222
223 return r;
224 #elif defined(__NR_accept4)
225 return syscall(__NR_accept4, fd, addr, addrlen, flags);
226 #else
227 return errno = ENOSYS, -1;
228 #endif
229 }
230
231
uv__eventfd(unsigned int count)232 int uv__eventfd(unsigned int count) {
233 #if defined(__NR_eventfd)
234 return syscall(__NR_eventfd, count);
235 #else
236 return errno = ENOSYS, -1;
237 #endif
238 }
239
240
uv__eventfd2(unsigned int count,int flags)241 int uv__eventfd2(unsigned int count, int flags) {
242 #if defined(__NR_eventfd2)
243 return syscall(__NR_eventfd2, count, flags);
244 #else
245 return errno = ENOSYS, -1;
246 #endif
247 }
248
249
uv__epoll_create(int size)250 int uv__epoll_create(int size) {
251 #if defined(__NR_epoll_create)
252 return syscall(__NR_epoll_create, size);
253 #else
254 return errno = ENOSYS, -1;
255 #endif
256 }
257
258
uv__epoll_create1(int flags)259 int uv__epoll_create1(int flags) {
260 #if defined(__NR_epoll_create1)
261 return syscall(__NR_epoll_create1, flags);
262 #else
263 return errno = ENOSYS, -1;
264 #endif
265 }
266
267
uv__epoll_ctl(int epfd,int op,int fd,struct uv__epoll_event * events)268 int uv__epoll_ctl(int epfd, int op, int fd, struct uv__epoll_event* events) {
269 #if defined(__NR_epoll_ctl)
270 return syscall(__NR_epoll_ctl, epfd, op, fd, events);
271 #else
272 return errno = ENOSYS, -1;
273 #endif
274 }
275
276
uv__epoll_wait(int epfd,struct uv__epoll_event * events,int nevents,int timeout)277 int uv__epoll_wait(int epfd,
278 struct uv__epoll_event* events,
279 int nevents,
280 int timeout) {
281 #if defined(__NR_epoll_wait)
282 return syscall(__NR_epoll_wait, epfd, events, nevents, timeout);
283 #else
284 return errno = ENOSYS, -1;
285 #endif
286 }
287
288
uv__epoll_pwait(int epfd,struct uv__epoll_event * events,int nevents,int timeout,const sigset_t * sigmask)289 int uv__epoll_pwait(int epfd,
290 struct uv__epoll_event* events,
291 int nevents,
292 int timeout,
293 const sigset_t* sigmask) {
294 #if defined(__NR_epoll_pwait)
295 return syscall(__NR_epoll_pwait,
296 epfd,
297 events,
298 nevents,
299 timeout,
300 sigmask,
301 sizeof(*sigmask));
302 #else
303 return errno = ENOSYS, -1;
304 #endif
305 }
306
307
uv__inotify_init(void)308 int uv__inotify_init(void) {
309 #if defined(__NR_inotify_init)
310 return syscall(__NR_inotify_init);
311 #else
312 return errno = ENOSYS, -1;
313 #endif
314 }
315
316
uv__inotify_init1(int flags)317 int uv__inotify_init1(int flags) {
318 #if defined(__NR_inotify_init1)
319 return syscall(__NR_inotify_init1, flags);
320 #else
321 return errno = ENOSYS, -1;
322 #endif
323 }
324
325
uv__inotify_add_watch(int fd,const char * path,uint32_t mask)326 int uv__inotify_add_watch(int fd, const char* path, uint32_t mask) {
327 #if defined(__NR_inotify_add_watch)
328 return syscall(__NR_inotify_add_watch, fd, path, mask);
329 #else
330 return errno = ENOSYS, -1;
331 #endif
332 }
333
334
uv__inotify_rm_watch(int fd,int32_t wd)335 int uv__inotify_rm_watch(int fd, int32_t wd) {
336 #if defined(__NR_inotify_rm_watch)
337 return syscall(__NR_inotify_rm_watch, fd, wd);
338 #else
339 return errno = ENOSYS, -1;
340 #endif
341 }
342
343
uv__pipe2(int pipefd[2],int flags)344 int uv__pipe2(int pipefd[2], int flags) {
345 #if defined(__NR_pipe2)
346 return syscall(__NR_pipe2, pipefd, flags);
347 #else
348 return errno = ENOSYS, -1;
349 #endif
350 }
351
352
uv__sendmmsg(int fd,struct uv__mmsghdr * mmsg,unsigned int vlen,unsigned int flags)353 int uv__sendmmsg(int fd,
354 struct uv__mmsghdr* mmsg,
355 unsigned int vlen,
356 unsigned int flags) {
357 #if defined(__NR_sendmmsg)
358 return syscall(__NR_sendmmsg, fd, mmsg, vlen, flags);
359 #else
360 return errno = ENOSYS, -1;
361 #endif
362 }
363
364
uv__recvmmsg(int fd,struct uv__mmsghdr * mmsg,unsigned int vlen,unsigned int flags,struct timespec * timeout)365 int uv__recvmmsg(int fd,
366 struct uv__mmsghdr* mmsg,
367 unsigned int vlen,
368 unsigned int flags,
369 struct timespec* timeout) {
370 #if defined(__NR_recvmmsg)
371 return syscall(__NR_recvmmsg, fd, mmsg, vlen, flags, timeout);
372 #else
373 return errno = ENOSYS, -1;
374 #endif
375 }
376
377
uv__utimesat(int dirfd,const char * path,const struct timespec times[2],int flags)378 int uv__utimesat(int dirfd,
379 const char* path,
380 const struct timespec times[2],
381 int flags)
382 {
383 #if defined(__NR_utimensat)
384 return syscall(__NR_utimensat, dirfd, path, times, flags);
385 #else
386 return errno = ENOSYS, -1;
387 #endif
388 }
389