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