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_H |
23 | #define UV_UNIX_H |
24 | |
25 | #include <sys/types.h> |
26 | #include <sys/stat.h> |
27 | #include <fcntl.h> |
28 | #include <dirent.h> |
29 | |
30 | #include <sys/socket.h> |
31 | #include <netinet/in.h> |
32 | #include <netinet/tcp.h> |
33 | #include <arpa/inet.h> |
34 | #include <netdb.h> /* MAXHOSTNAMELEN on Solaris */ |
35 | |
36 | #include <termios.h> |
37 | #include <pwd.h> |
38 | |
39 | #if !defined(__MVS__) |
40 | #include <semaphore.h> |
41 | #include <sys/param.h> /* MAXHOSTNAMELEN on Linux and the BSDs */ |
42 | #endif |
43 | #include <pthread.h> |
44 | #include <signal.h> |
45 | |
46 | #include "uv/threadpool.h" |
47 | |
48 | #if defined(__linux__) |
49 | # include "uv/linux.h" |
50 | #elif defined (__MVS__) |
51 | # include "uv/os390.h" |
52 | #elif defined(__PASE__) /* __PASE__ and _AIX are both defined on IBM i */ |
53 | # include "uv/posix.h" /* IBM i needs uv/posix.h, not uv/aix.h */ |
54 | #elif defined(_AIX) |
55 | # include "uv/aix.h" |
56 | #elif defined(__sun) |
57 | # include "uv/sunos.h" |
58 | #elif defined(__APPLE__) |
59 | # include "uv/darwin.h" |
60 | #elif defined(__DragonFly__) || \ |
61 | defined(__FreeBSD__) || \ |
62 | defined(__FreeBSD_kernel__) || \ |
63 | defined(__OpenBSD__) || \ |
64 | defined(__NetBSD__) |
65 | # include "uv/bsd.h" |
66 | #elif defined(__CYGWIN__) || \ |
67 | defined(__MSYS__) || \ |
68 | defined(__GNU__) |
69 | # include "uv/posix.h" |
70 | #elif defined(__HAIKU__) |
71 | # include "uv/posix.h" |
72 | #elif defined(__QNX__) |
73 | # include "uv/posix.h" |
74 | #endif |
75 | |
76 | #ifndef NI_MAXHOST |
77 | # define NI_MAXHOST 1025 |
78 | #endif |
79 | |
80 | #ifndef NI_MAXSERV |
81 | # define NI_MAXSERV 32 |
82 | #endif |
83 | |
84 | #ifndef UV_IO_PRIVATE_PLATFORM_FIELDS |
85 | # define UV_IO_PRIVATE_PLATFORM_FIELDS /* empty */ |
86 | #endif |
87 | |
88 | struct uv__io_s; |
89 | struct uv_loop_s; |
90 | |
91 | typedef void (*uv__io_cb)(struct uv_loop_s* loop, |
92 | struct uv__io_s* w, |
93 | unsigned int events); |
94 | typedef struct uv__io_s uv__io_t; |
95 | |
96 | struct uv__io_s { |
97 | uv__io_cb cb; |
98 | void* pending_queue[2]; |
99 | void* watcher_queue[2]; |
100 | unsigned int pevents; /* Pending event mask i.e. mask at next tick. */ |
101 | unsigned int events; /* Current event mask. */ |
102 | int fd; |
103 | UV_IO_PRIVATE_PLATFORM_FIELDS |
104 | }; |
105 | |
106 | #ifndef UV_PLATFORM_SEM_T |
107 | # define UV_PLATFORM_SEM_T sem_t |
108 | #endif |
109 | |
110 | #ifndef UV_PLATFORM_LOOP_FIELDS |
111 | # define UV_PLATFORM_LOOP_FIELDS /* empty */ |
112 | #endif |
113 | |
114 | #ifndef UV_PLATFORM_FS_EVENT_FIELDS |
115 | # define UV_PLATFORM_FS_EVENT_FIELDS /* empty */ |
116 | #endif |
117 | |
118 | #ifndef UV_STREAM_PRIVATE_PLATFORM_FIELDS |
119 | # define UV_STREAM_PRIVATE_PLATFORM_FIELDS /* empty */ |
120 | #endif |
121 | |
122 | /* Note: May be cast to struct iovec. See writev(2). */ |
123 | typedef struct uv_buf_t { |
124 | char* base; |
125 | size_t len; |
126 | } uv_buf_t; |
127 | |
128 | typedef int uv_file; |
129 | typedef int uv_os_sock_t; |
130 | typedef int uv_os_fd_t; |
131 | typedef pid_t uv_pid_t; |
132 | |
133 | #define UV_ONCE_INIT PTHREAD_ONCE_INIT |
134 | |
135 | typedef pthread_once_t uv_once_t; |
136 | typedef pthread_t uv_thread_t; |
137 | typedef pthread_mutex_t uv_mutex_t; |
138 | typedef pthread_rwlock_t uv_rwlock_t; |
139 | typedef UV_PLATFORM_SEM_T uv_sem_t; |
140 | typedef pthread_cond_t uv_cond_t; |
141 | typedef pthread_key_t uv_key_t; |
142 | |
143 | /* Note: guard clauses should match uv_barrier_init's in src/unix/thread.c. */ |
144 | #if defined(_AIX) || \ |
145 | defined(__OpenBSD__) || \ |
146 | !defined(PTHREAD_BARRIER_SERIAL_THREAD) |
147 | /* TODO(bnoordhuis) Merge into uv_barrier_t in v2. */ |
148 | struct _uv_barrier { |
149 | uv_mutex_t mutex; |
150 | uv_cond_t cond; |
151 | unsigned threshold; |
152 | unsigned in; |
153 | unsigned out; |
154 | }; |
155 | |
156 | typedef struct { |
157 | struct _uv_barrier* b; |
158 | # if defined(PTHREAD_BARRIER_SERIAL_THREAD) |
159 | /* TODO(bnoordhuis) Remove padding in v2. */ |
160 | char pad[sizeof(pthread_barrier_t) - sizeof(struct _uv_barrier*)]; |
161 | # endif |
162 | } uv_barrier_t; |
163 | #else |
164 | typedef pthread_barrier_t uv_barrier_t; |
165 | #endif |
166 | |
167 | /* Platform-specific definitions for uv_spawn support. */ |
168 | typedef gid_t uv_gid_t; |
169 | typedef uid_t uv_uid_t; |
170 | |
171 | typedef struct dirent uv__dirent_t; |
172 | |
173 | #define UV_DIR_PRIVATE_FIELDS \ |
174 | DIR* dir; |
175 | |
176 | #if defined(DT_UNKNOWN) |
177 | # define HAVE_DIRENT_TYPES |
178 | # if defined(DT_REG) |
179 | # define UV__DT_FILE DT_REG |
180 | # else |
181 | # define UV__DT_FILE -1 |
182 | # endif |
183 | # if defined(DT_DIR) |
184 | # define UV__DT_DIR DT_DIR |
185 | # else |
186 | # define UV__DT_DIR -2 |
187 | # endif |
188 | # if defined(DT_LNK) |
189 | # define UV__DT_LINK DT_LNK |
190 | # else |
191 | # define UV__DT_LINK -3 |
192 | # endif |
193 | # if defined(DT_FIFO) |
194 | # define UV__DT_FIFO DT_FIFO |
195 | # else |
196 | # define UV__DT_FIFO -4 |
197 | # endif |
198 | # if defined(DT_SOCK) |
199 | # define UV__DT_SOCKET DT_SOCK |
200 | # else |
201 | # define UV__DT_SOCKET -5 |
202 | # endif |
203 | # if defined(DT_CHR) |
204 | # define UV__DT_CHAR DT_CHR |
205 | # else |
206 | # define UV__DT_CHAR -6 |
207 | # endif |
208 | # if defined(DT_BLK) |
209 | # define UV__DT_BLOCK DT_BLK |
210 | # else |
211 | # define UV__DT_BLOCK -7 |
212 | # endif |
213 | #endif |
214 | |
215 | /* Platform-specific definitions for uv_dlopen support. */ |
216 | #define UV_DYNAMIC /* empty */ |
217 | |
218 | typedef struct { |
219 | void* handle; |
220 | char* errmsg; |
221 | } uv_lib_t; |
222 | |
223 | #define UV_LOOP_PRIVATE_FIELDS \ |
224 | unsigned long flags; \ |
225 | int backend_fd; \ |
226 | void* pending_queue[2]; \ |
227 | void* watcher_queue[2]; \ |
228 | uv__io_t** watchers; \ |
229 | unsigned int nwatchers; \ |
230 | unsigned int nfds; \ |
231 | void* wq[2]; \ |
232 | uv_mutex_t wq_mutex; \ |
233 | uv_async_t wq_async; \ |
234 | uv_rwlock_t cloexec_lock; \ |
235 | uv_handle_t* closing_handles; \ |
236 | void* process_handles[2]; \ |
237 | void* prepare_handles[2]; \ |
238 | void* check_handles[2]; \ |
239 | void* idle_handles[2]; \ |
240 | void* async_handles[2]; \ |
241 | void (*async_unused)(void); /* TODO(bnoordhuis) Remove in libuv v2. */ \ |
242 | uv__io_t async_io_watcher; \ |
243 | int async_wfd; \ |
244 | struct { \ |
245 | void* min; \ |
246 | unsigned int nelts; \ |
247 | } timer_heap; \ |
248 | uint64_t timer_counter; \ |
249 | uint64_t time; \ |
250 | int signal_pipefd[2]; \ |
251 | uv__io_t signal_io_watcher; \ |
252 | uv_signal_t child_watcher; \ |
253 | int emfile_fd; \ |
254 | UV_PLATFORM_LOOP_FIELDS \ |
255 | |
256 | #define UV_REQ_TYPE_PRIVATE /* empty */ |
257 | |
258 | #define UV_REQ_PRIVATE_FIELDS /* empty */ |
259 | |
260 | #define UV_PRIVATE_REQ_TYPES /* empty */ |
261 | |
262 | #define UV_WRITE_PRIVATE_FIELDS \ |
263 | void* queue[2]; \ |
264 | unsigned int write_index; \ |
265 | uv_buf_t* bufs; \ |
266 | unsigned int nbufs; \ |
267 | int error; \ |
268 | uv_buf_t bufsml[4]; \ |
269 | |
270 | #define UV_CONNECT_PRIVATE_FIELDS \ |
271 | void* queue[2]; \ |
272 | |
273 | #define UV_SHUTDOWN_PRIVATE_FIELDS /* empty */ |
274 | |
275 | #define UV_UDP_SEND_PRIVATE_FIELDS \ |
276 | void* queue[2]; \ |
277 | struct sockaddr_storage addr; \ |
278 | unsigned int nbufs; \ |
279 | uv_buf_t* bufs; \ |
280 | ssize_t status; \ |
281 | uv_udp_send_cb send_cb; \ |
282 | uv_buf_t bufsml[4]; \ |
283 | |
284 | #define UV_HANDLE_PRIVATE_FIELDS \ |
285 | uv_handle_t* next_closing; \ |
286 | unsigned int flags; \ |
287 | |
288 | #define UV_STREAM_PRIVATE_FIELDS \ |
289 | uv_connect_t *connect_req; \ |
290 | uv_shutdown_t *shutdown_req; \ |
291 | uv__io_t io_watcher; \ |
292 | void* write_queue[2]; \ |
293 | void* write_completed_queue[2]; \ |
294 | uv_connection_cb connection_cb; \ |
295 | int delayed_error; \ |
296 | int accepted_fd; \ |
297 | void* queued_fds; \ |
298 | UV_STREAM_PRIVATE_PLATFORM_FIELDS \ |
299 | |
300 | #define UV_TCP_PRIVATE_FIELDS /* empty */ |
301 | |
302 | #define UV_UDP_PRIVATE_FIELDS \ |
303 | uv_alloc_cb alloc_cb; \ |
304 | uv_udp_recv_cb recv_cb; \ |
305 | uv__io_t io_watcher; \ |
306 | void* write_queue[2]; \ |
307 | void* write_completed_queue[2]; \ |
308 | |
309 | #define UV_PIPE_PRIVATE_FIELDS \ |
310 | const char* pipe_fname; /* strdup'ed */ |
311 | |
312 | #define UV_POLL_PRIVATE_FIELDS \ |
313 | uv__io_t io_watcher; |
314 | |
315 | #define UV_PREPARE_PRIVATE_FIELDS \ |
316 | uv_prepare_cb prepare_cb; \ |
317 | void* queue[2]; \ |
318 | |
319 | #define UV_CHECK_PRIVATE_FIELDS \ |
320 | uv_check_cb check_cb; \ |
321 | void* queue[2]; \ |
322 | |
323 | #define UV_IDLE_PRIVATE_FIELDS \ |
324 | uv_idle_cb idle_cb; \ |
325 | void* queue[2]; \ |
326 | |
327 | #define UV_ASYNC_PRIVATE_FIELDS \ |
328 | uv_async_cb async_cb; \ |
329 | void* queue[2]; \ |
330 | int pending; \ |
331 | |
332 | #define UV_TIMER_PRIVATE_FIELDS \ |
333 | uv_timer_cb timer_cb; \ |
334 | void* heap_node[3]; \ |
335 | uint64_t timeout; \ |
336 | uint64_t repeat; \ |
337 | uint64_t start_id; |
338 | |
339 | #define UV_GETADDRINFO_PRIVATE_FIELDS \ |
340 | struct uv__work work_req; \ |
341 | uv_getaddrinfo_cb cb; \ |
342 | struct addrinfo* hints; \ |
343 | char* hostname; \ |
344 | char* service; \ |
345 | struct addrinfo* addrinfo; \ |
346 | int retcode; |
347 | |
348 | #define UV_GETNAMEINFO_PRIVATE_FIELDS \ |
349 | struct uv__work work_req; \ |
350 | uv_getnameinfo_cb getnameinfo_cb; \ |
351 | struct sockaddr_storage storage; \ |
352 | int flags; \ |
353 | char host[NI_MAXHOST]; \ |
354 | char service[NI_MAXSERV]; \ |
355 | int retcode; |
356 | |
357 | #define UV_PROCESS_PRIVATE_FIELDS \ |
358 | void* queue[2]; \ |
359 | int status; \ |
360 | |
361 | #define UV_FS_PRIVATE_FIELDS \ |
362 | const char *new_path; \ |
363 | uv_file file; \ |
364 | int flags; \ |
365 | mode_t mode; \ |
366 | unsigned int nbufs; \ |
367 | uv_buf_t* bufs; \ |
368 | off_t off; \ |
369 | uv_uid_t uid; \ |
370 | uv_gid_t gid; \ |
371 | double atime; \ |
372 | double mtime; \ |
373 | struct uv__work work_req; \ |
374 | uv_buf_t bufsml[4]; \ |
375 | |
376 | #define UV_WORK_PRIVATE_FIELDS \ |
377 | struct uv__work work_req; |
378 | |
379 | #define UV_TTY_PRIVATE_FIELDS \ |
380 | struct termios orig_termios; \ |
381 | int mode; |
382 | |
383 | #define UV_SIGNAL_PRIVATE_FIELDS \ |
384 | /* RB_ENTRY(uv_signal_s) tree_entry; */ \ |
385 | struct { \ |
386 | struct uv_signal_s* rbe_left; \ |
387 | struct uv_signal_s* rbe_right; \ |
388 | struct uv_signal_s* rbe_parent; \ |
389 | int rbe_color; \ |
390 | } tree_entry; \ |
391 | /* Use two counters here so we don have to fiddle with atomics. */ \ |
392 | unsigned int caught_signals; \ |
393 | unsigned int dispatched_signals; |
394 | |
395 | #define UV_FS_EVENT_PRIVATE_FIELDS \ |
396 | uv_fs_event_cb cb; \ |
397 | UV_PLATFORM_FS_EVENT_FIELDS \ |
398 | |
399 | /* fs open() flags supported on this platform: */ |
400 | #if defined(O_APPEND) |
401 | # define UV_FS_O_APPEND O_APPEND |
402 | #else |
403 | # define UV_FS_O_APPEND 0 |
404 | #endif |
405 | #if defined(O_CREAT) |
406 | # define UV_FS_O_CREAT O_CREAT |
407 | #else |
408 | # define UV_FS_O_CREAT 0 |
409 | #endif |
410 | |
411 | #if defined(__linux__) && defined(__arm__) |
412 | # define UV_FS_O_DIRECT 0x10000 |
413 | #elif defined(__linux__) && defined(__m68k__) |
414 | # define UV_FS_O_DIRECT 0x10000 |
415 | #elif defined(__linux__) && defined(__mips__) |
416 | # define UV_FS_O_DIRECT 0x08000 |
417 | #elif defined(__linux__) && defined(__powerpc__) |
418 | # define UV_FS_O_DIRECT 0x20000 |
419 | #elif defined(__linux__) && defined(__s390x__) |
420 | # define UV_FS_O_DIRECT 0x04000 |
421 | #elif defined(__linux__) && defined(__x86_64__) |
422 | # define UV_FS_O_DIRECT 0x04000 |
423 | #elif defined(O_DIRECT) |
424 | # define UV_FS_O_DIRECT O_DIRECT |
425 | #else |
426 | # define UV_FS_O_DIRECT 0 |
427 | #endif |
428 | |
429 | #if defined(O_DIRECTORY) |
430 | # define UV_FS_O_DIRECTORY O_DIRECTORY |
431 | #else |
432 | # define UV_FS_O_DIRECTORY 0 |
433 | #endif |
434 | #if defined(O_DSYNC) |
435 | # define UV_FS_O_DSYNC O_DSYNC |
436 | #else |
437 | # define UV_FS_O_DSYNC 0 |
438 | #endif |
439 | #if defined(O_EXCL) |
440 | # define UV_FS_O_EXCL O_EXCL |
441 | #else |
442 | # define UV_FS_O_EXCL 0 |
443 | #endif |
444 | #if defined(O_EXLOCK) |
445 | # define UV_FS_O_EXLOCK O_EXLOCK |
446 | #else |
447 | # define UV_FS_O_EXLOCK 0 |
448 | #endif |
449 | #if defined(O_NOATIME) |
450 | # define UV_FS_O_NOATIME O_NOATIME |
451 | #else |
452 | # define UV_FS_O_NOATIME 0 |
453 | #endif |
454 | #if defined(O_NOCTTY) |
455 | # define UV_FS_O_NOCTTY O_NOCTTY |
456 | #else |
457 | # define UV_FS_O_NOCTTY 0 |
458 | #endif |
459 | #if defined(O_NOFOLLOW) |
460 | # define UV_FS_O_NOFOLLOW O_NOFOLLOW |
461 | #else |
462 | # define UV_FS_O_NOFOLLOW 0 |
463 | #endif |
464 | #if defined(O_NONBLOCK) |
465 | # define UV_FS_O_NONBLOCK O_NONBLOCK |
466 | #else |
467 | # define UV_FS_O_NONBLOCK 0 |
468 | #endif |
469 | #if defined(O_RDONLY) |
470 | # define UV_FS_O_RDONLY O_RDONLY |
471 | #else |
472 | # define UV_FS_O_RDONLY 0 |
473 | #endif |
474 | #if defined(O_RDWR) |
475 | # define UV_FS_O_RDWR O_RDWR |
476 | #else |
477 | # define UV_FS_O_RDWR 0 |
478 | #endif |
479 | #if defined(O_SYMLINK) |
480 | # define UV_FS_O_SYMLINK O_SYMLINK |
481 | #else |
482 | # define UV_FS_O_SYMLINK 0 |
483 | #endif |
484 | #if defined(O_SYNC) |
485 | # define UV_FS_O_SYNC O_SYNC |
486 | #else |
487 | # define UV_FS_O_SYNC 0 |
488 | #endif |
489 | #if defined(O_TRUNC) |
490 | # define UV_FS_O_TRUNC O_TRUNC |
491 | #else |
492 | # define UV_FS_O_TRUNC 0 |
493 | #endif |
494 | #if defined(O_WRONLY) |
495 | # define UV_FS_O_WRONLY O_WRONLY |
496 | #else |
497 | # define UV_FS_O_WRONLY 0 |
498 | #endif |
499 | |
500 | /* fs open() flags supported on other platforms: */ |
501 | #define UV_FS_O_FILEMAP 0 |
502 | #define UV_FS_O_RANDOM 0 |
503 | #define UV_FS_O_SHORT_LIVED 0 |
504 | #define UV_FS_O_SEQUENTIAL 0 |
505 | #define UV_FS_O_TEMPORARY 0 |
506 | |
507 | #endif /* UV_UNIX_H */ |
508 | |