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#ifndef UV_UNIX_INTERNAL_H_
23#define UV_UNIX_INTERNAL_H_
24
25#include "uv-common.h"
26
27#include <assert.h>
28#include <limits.h> /* _POSIX_PATH_MAX, PATH_MAX */
29#include <stdlib.h> /* abort */
30#include <string.h> /* strrchr */
31#include <fcntl.h> /* O_CLOEXEC, may be */
32#include <stdio.h>
33#include <errno.h>
34
35#if defined(__STRICT_ANSI__)
36# define inline __inline
37#endif
38
39#if defined(__linux__)
40# include "linux-syscalls.h"
41#endif /* __linux__ */
42
43#if defined(__MVS__)
44# include "os390-syscalls.h"
45#endif /* __MVS__ */
46
47#if defined(__sun)
48# include <sys/port.h>
49# include <port.h>
50#endif /* __sun */
51
52#if defined(_AIX)
53# define reqevents events
54# define rtnevents revents
55# include <sys/poll.h>
56#else
57# include <poll.h>
58#endif /* _AIX */
59
60#if defined(__APPLE__) && !TARGET_OS_IPHONE
61# include <AvailabilityMacros.h>
62#endif
63
64#if defined(_POSIX_PATH_MAX)
65# define UV__PATH_MAX _POSIX_PATH_MAX
66#elif defined(PATH_MAX)
67# define UV__PATH_MAX PATH_MAX
68#else
69# define UV__PATH_MAX 8192
70#endif
71
72#if defined(__ANDROID__)
73int uv__pthread_sigmask(int how, const sigset_t* set, sigset_t* oset);
74# ifdef pthread_sigmask
75# undef pthread_sigmask
76# endif
77# define pthread_sigmask(how, set, oldset) uv__pthread_sigmask(how, set, oldset)
78#endif
79
80#define ACCESS_ONCE(type, var) \
81 (*(volatile type*) &(var))
82
83#define ROUND_UP(a, b) \
84 ((a) % (b) ? ((a) + (b)) - ((a) % (b)) : (a))
85
86#define UNREACHABLE() \
87 do { \
88 assert(0 && "unreachable code"); \
89 abort(); \
90 } \
91 while (0)
92
93#define SAVE_ERRNO(block) \
94 do { \
95 int _saved_errno = errno; \
96 do { block; } while (0); \
97 errno = _saved_errno; \
98 } \
99 while (0)
100
101/* The __clang__ and __INTEL_COMPILER checks are superfluous because they
102 * define __GNUC__. They are here to convey to you, dear reader, that these
103 * macros are enabled when compiling with clang or icc.
104 */
105#if defined(__clang__) || \
106 defined(__GNUC__) || \
107 defined(__INTEL_COMPILER)
108# define UV_DESTRUCTOR(declaration) __attribute__((destructor)) declaration
109# define UV_UNUSED(declaration) __attribute__((unused)) declaration
110#else
111# define UV_DESTRUCTOR(declaration) declaration
112# define UV_UNUSED(declaration) declaration
113#endif
114
115/* Leans on the fact that, on Linux, POLLRDHUP == EPOLLRDHUP. */
116#ifdef POLLRDHUP
117# define UV__POLLRDHUP POLLRDHUP
118#else
119# define UV__POLLRDHUP 0x2000
120#endif
121
122#ifdef POLLPRI
123# define UV__POLLPRI POLLPRI
124#else
125# define UV__POLLPRI 0
126#endif
127
128#if !defined(O_CLOEXEC) && defined(__FreeBSD__)
129/*
130 * It may be that we are just missing `__POSIX_VISIBLE >= 200809`.
131 * Try using fixed value const and give up, if it doesn't work
132 */
133# define O_CLOEXEC 0x00100000
134#endif
135
136typedef struct uv__stream_queued_fds_s uv__stream_queued_fds_t;
137
138/* loop flags */
139enum {
140 UV_LOOP_BLOCK_SIGPROF = 1
141};
142
143/* flags of excluding ifaddr */
144enum {
145 UV__EXCLUDE_IFPHYS,
146 UV__EXCLUDE_IFADDR
147};
148
149typedef enum {
150 UV_CLOCK_PRECISE = 0, /* Use the highest resolution clock available. */
151 UV_CLOCK_FAST = 1 /* Use the fastest clock with <= 1ms granularity. */
152} uv_clocktype_t;
153
154struct uv__stream_queued_fds_s {
155 unsigned int size;
156 unsigned int offset;
157 int fds[1];
158};
159
160
161#if defined(_AIX) || \
162 defined(__APPLE__) || \
163 defined(__DragonFly__) || \
164 defined(__FreeBSD__) || \
165 defined(__FreeBSD_kernel__) || \
166 defined(__linux__) || \
167 defined(__OpenBSD__) || \
168 defined(__NetBSD__)
169#define uv__cloexec uv__cloexec_ioctl
170#define uv__nonblock uv__nonblock_ioctl
171#else
172#define uv__cloexec uv__cloexec_fcntl
173#define uv__nonblock uv__nonblock_fcntl
174#endif
175
176/* On Linux, uv__nonblock_fcntl() and uv__nonblock_ioctl() do not commute
177 * when O_NDELAY is not equal to O_NONBLOCK. Case in point: linux/sparc32
178 * and linux/sparc64, where O_NDELAY is O_NONBLOCK + another bit.
179 *
180 * Libuv uses uv__nonblock_fcntl() directly sometimes so ensure that it
181 * commutes with uv__nonblock().
182 */
183#if defined(__linux__) && O_NDELAY != O_NONBLOCK
184#undef uv__nonblock
185#define uv__nonblock uv__nonblock_fcntl
186#endif
187
188/* core */
189int uv__cloexec_ioctl(int fd, int set);
190int uv__cloexec_fcntl(int fd, int set);
191int uv__nonblock_ioctl(int fd, int set);
192int uv__nonblock_fcntl(int fd, int set);
193int uv__close(int fd); /* preserves errno */
194int uv__close_nocheckstdio(int fd);
195int uv__close_nocancel(int fd);
196int uv__socket(int domain, int type, int protocol);
197ssize_t uv__recvmsg(int fd, struct msghdr *msg, int flags);
198void uv__make_close_pending(uv_handle_t* handle);
199int uv__getiovmax(void);
200
201void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd);
202void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events);
203void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events);
204void uv__io_close(uv_loop_t* loop, uv__io_t* w);
205void uv__io_feed(uv_loop_t* loop, uv__io_t* w);
206int uv__io_active(const uv__io_t* w, unsigned int events);
207int uv__io_check_fd(uv_loop_t* loop, int fd);
208void uv__io_poll(uv_loop_t* loop, int timeout); /* in milliseconds or -1 */
209int uv__io_fork(uv_loop_t* loop);
210int uv__fd_exists(uv_loop_t* loop, int fd);
211
212/* async */
213void uv__async_stop(uv_loop_t* loop);
214int uv__async_fork(uv_loop_t* loop);
215
216
217/* loop */
218void uv__run_idle(uv_loop_t* loop);
219void uv__run_check(uv_loop_t* loop);
220void uv__run_prepare(uv_loop_t* loop);
221
222/* stream */
223void uv__stream_init(uv_loop_t* loop, uv_stream_t* stream,
224 uv_handle_type type);
225int uv__stream_open(uv_stream_t*, int fd, int flags);
226void uv__stream_destroy(uv_stream_t* stream);
227#if defined(__APPLE__)
228int uv__stream_try_select(uv_stream_t* stream, int* fd);
229#endif /* defined(__APPLE__) */
230void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events);
231int uv__accept(int sockfd);
232int uv__dup2_cloexec(int oldfd, int newfd);
233int uv__open_cloexec(const char* path, int flags);
234
235/* tcp */
236int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb);
237int uv__tcp_nodelay(int fd, int on);
238int uv__tcp_keepalive(int fd, int on, unsigned int delay);
239
240/* pipe */
241int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb);
242
243/* signal */
244void uv__signal_close(uv_signal_t* handle);
245void uv__signal_global_once_init(void);
246void uv__signal_loop_cleanup(uv_loop_t* loop);
247int uv__signal_loop_fork(uv_loop_t* loop);
248
249/* platform specific */
250uint64_t uv__hrtime(uv_clocktype_t type);
251int uv__kqueue_init(uv_loop_t* loop);
252int uv__platform_loop_init(uv_loop_t* loop);
253void uv__platform_loop_delete(uv_loop_t* loop);
254void uv__platform_invalidate_fd(uv_loop_t* loop, int fd);
255
256/* various */
257void uv__async_close(uv_async_t* handle);
258void uv__check_close(uv_check_t* handle);
259void uv__fs_event_close(uv_fs_event_t* handle);
260void uv__idle_close(uv_idle_t* handle);
261void uv__pipe_close(uv_pipe_t* handle);
262void uv__poll_close(uv_poll_t* handle);
263void uv__prepare_close(uv_prepare_t* handle);
264void uv__process_close(uv_process_t* handle);
265void uv__stream_close(uv_stream_t* handle);
266void uv__tcp_close(uv_tcp_t* handle);
267void uv__udp_close(uv_udp_t* handle);
268void uv__udp_finish_close(uv_udp_t* handle);
269uv_handle_type uv__handle_type(int fd);
270FILE* uv__open_file(const char* path);
271int uv__getpwuid_r(uv_passwd_t* pwd);
272
273
274#if defined(__APPLE__)
275int uv___stream_fd(const uv_stream_t* handle);
276#define uv__stream_fd(handle) (uv___stream_fd((const uv_stream_t*) (handle)))
277#else
278#define uv__stream_fd(handle) ((handle)->io_watcher.fd)
279#endif /* defined(__APPLE__) */
280
281#ifdef UV__O_NONBLOCK
282# define UV__F_NONBLOCK UV__O_NONBLOCK
283#else
284# define UV__F_NONBLOCK 1
285#endif
286
287int uv__make_socketpair(int fds[2], int flags);
288int uv__make_pipe(int fds[2], int flags);
289
290#if defined(__APPLE__)
291
292int uv__fsevents_init(uv_fs_event_t* handle);
293int uv__fsevents_close(uv_fs_event_t* handle);
294void uv__fsevents_loop_delete(uv_loop_t* loop);
295
296#endif /* defined(__APPLE__) */
297
298UV_UNUSED(static void uv__update_time(uv_loop_t* loop)) {
299 /* Use a fast time source if available. We only need millisecond precision.
300 */
301 loop->time = uv__hrtime(UV_CLOCK_FAST) / 1000000;
302}
303
304UV_UNUSED(static char* uv__basename_r(const char* path)) {
305 char* s;
306
307 s = strrchr(path, '/');
308 if (s == NULL)
309 return (char*) path;
310
311 return s + 1;
312}
313
314#if defined(__linux__)
315int uv__inotify_fork(uv_loop_t* loop, void* old_watchers);
316#endif
317
318typedef int (*uv__peersockfunc)(int, struct sockaddr*, socklen_t*);
319
320int uv__getsockpeername(const uv_handle_t* handle,
321 uv__peersockfunc func,
322 struct sockaddr* name,
323 int* namelen);
324
325#endif /* UV_UNIX_INTERNAL_H_ */
326