uv: Upgrade to v0.10.18
[platform/upstream/nodejs.git] / deps / uv / src / unix / process.c
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 "uv.h"
23 #include "internal.h"
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <assert.h>
28 #include <errno.h>
29
30 #include <sys/types.h>
31 #include <sys/wait.h>
32 #include <unistd.h>
33 #include <fcntl.h>
34 #include <poll.h>
35
36 #if defined(__APPLE__) && !TARGET_OS_IPHONE
37 # include <crt_externs.h>
38 # define environ (*_NSGetEnviron())
39 #else
40 extern char **environ;
41 #endif
42
43
44 static ngx_queue_t* uv__process_queue(uv_loop_t* loop, int pid) {
45   assert(pid > 0);
46   return loop->process_handles + pid % ARRAY_SIZE(loop->process_handles);
47 }
48
49
50 static uv_process_t* uv__process_find(uv_loop_t* loop, int pid) {
51   uv_process_t* handle;
52   ngx_queue_t* h;
53   ngx_queue_t* q;
54
55   h = uv__process_queue(loop, pid);
56
57   ngx_queue_foreach(q, h) {
58     handle = ngx_queue_data(q, uv_process_t, queue);
59     if (handle->pid == pid) return handle;
60   }
61
62   return NULL;
63 }
64
65
66 static void uv__chld(uv_signal_t* handle, int signum) {
67   uv_process_t* process;
68   int exit_status;
69   int term_signal;
70   int status;
71   pid_t pid;
72
73   assert(signum == SIGCHLD);
74
75   for (;;) {
76     do
77       pid = waitpid(-1, &status, WNOHANG);
78     while (pid == -1 && errno == EINTR);
79
80     if (pid == 0)
81       return;
82
83     if (pid == -1) {
84       if (errno == ECHILD)
85         return; /* XXX stop signal watcher? */
86       else
87         abort();
88     }
89
90     process = uv__process_find(handle->loop, pid);
91     if (process == NULL)
92       continue; /* XXX bug? abort? */
93
94     uv__handle_stop(process);
95
96     if (process->exit_cb == NULL)
97       continue;
98
99     exit_status = 0;
100     term_signal = 0;
101
102     if (WIFEXITED(status))
103       exit_status = WEXITSTATUS(status);
104
105     if (WIFSIGNALED(status))
106       term_signal = WTERMSIG(status);
107
108     if (process->errorno) {
109       uv__set_sys_error(process->loop, process->errorno);
110       exit_status = -1; /* execve() failed */
111     }
112
113     process->exit_cb(process, exit_status, term_signal);
114   }
115 }
116
117
118 int uv__make_socketpair(int fds[2], int flags) {
119 #if defined(__linux__)
120   static int no_cloexec;
121
122   if (no_cloexec)
123     goto skip;
124
125   if (socketpair(AF_UNIX, SOCK_STREAM | UV__SOCK_CLOEXEC | flags, 0, fds) == 0)
126     return 0;
127
128   /* Retry on EINVAL, it means SOCK_CLOEXEC is not supported.
129    * Anything else is a genuine error.
130    */
131   if (errno != EINVAL)
132     return -1;
133
134   no_cloexec = 1;
135
136 skip:
137 #endif
138
139   if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds))
140     return -1;
141
142   uv__cloexec(fds[0], 1);
143   uv__cloexec(fds[1], 1);
144
145   if (flags & UV__F_NONBLOCK) {
146     uv__nonblock(fds[0], 1);
147     uv__nonblock(fds[1], 1);
148   }
149
150   return 0;
151 }
152
153
154 int uv__make_pipe(int fds[2], int flags) {
155 #if defined(__linux__)
156   static int no_pipe2;
157
158   if (no_pipe2)
159     goto skip;
160
161   if (uv__pipe2(fds, flags | UV__O_CLOEXEC) == 0)
162     return 0;
163
164   if (errno != ENOSYS)
165     return -1;
166
167   no_pipe2 = 1;
168
169 skip:
170 #endif
171
172   if (pipe(fds))
173     return -1;
174
175   uv__cloexec(fds[0], 1);
176   uv__cloexec(fds[1], 1);
177
178   if (flags & UV__F_NONBLOCK) {
179     uv__nonblock(fds[0], 1);
180     uv__nonblock(fds[1], 1);
181   }
182
183   return 0;
184 }
185
186
187 /*
188  * Used for initializing stdio streams like options.stdin_stream. Returns
189  * zero on success. See also the cleanup section in uv_spawn().
190  */
191 static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2]) {
192   int mask;
193   int fd;
194
195   mask = UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD | UV_INHERIT_STREAM;
196
197   switch (container->flags & mask) {
198   case UV_IGNORE:
199     return 0;
200
201   case UV_CREATE_PIPE:
202     assert(container->data.stream != NULL);
203     if (container->data.stream->type != UV_NAMED_PIPE) {
204       errno = EINVAL;
205       return -1;
206     }
207     return uv__make_socketpair(fds, 0);
208
209   case UV_INHERIT_FD:
210   case UV_INHERIT_STREAM:
211     if (container->flags & UV_INHERIT_FD)
212       fd = container->data.fd;
213     else
214       fd = uv__stream_fd(container->data.stream);
215
216     if (fd == -1) {
217       errno = EINVAL;
218       return -1;
219     }
220
221     fds[1] = fd;
222     return 0;
223
224   default:
225     assert(0 && "Unexpected flags");
226     return -1;
227   }
228 }
229
230
231 static int uv__process_open_stream(uv_stdio_container_t* container,
232                                    int pipefds[2],
233                                    int writable) {
234   int flags;
235
236   if (!(container->flags & UV_CREATE_PIPE) || pipefds[0] < 0)
237     return 0;
238
239   if (close(pipefds[1]))
240     if (errno != EINTR && errno != EINPROGRESS)
241       abort();
242
243   pipefds[1] = -1;
244   uv__nonblock(pipefds[0], 1);
245
246   if (container->data.stream->type == UV_NAMED_PIPE &&
247       ((uv_pipe_t*)container->data.stream)->ipc)
248     flags = UV_STREAM_READABLE | UV_STREAM_WRITABLE;
249   else if (writable)
250     flags = UV_STREAM_WRITABLE;
251   else
252     flags = UV_STREAM_READABLE;
253
254   return uv__stream_open(container->data.stream, pipefds[0], flags);
255 }
256
257
258 static void uv__process_close_stream(uv_stdio_container_t* container) {
259   if (!(container->flags & UV_CREATE_PIPE)) return;
260   uv__stream_close((uv_stream_t*)container->data.stream);
261 }
262
263
264 static void uv__write_int(int fd, int val) {
265   ssize_t n;
266
267   do
268     n = write(fd, &val, sizeof(val));
269   while (n == -1 && errno == EINTR);
270
271   if (n == -1 && errno == EPIPE)
272     return; /* parent process has quit */
273
274   assert(n == sizeof(val));
275 }
276
277
278 static void uv__process_child_init(uv_process_options_t options,
279                                    int stdio_count,
280                                    int (*pipes)[2],
281                                    int error_fd) {
282   int close_fd;
283   int use_fd;
284   int fd;
285
286   if (options.flags & UV_PROCESS_DETACHED)
287     setsid();
288
289   for (fd = 0; fd < stdio_count; fd++) {
290     close_fd = pipes[fd][0];
291     use_fd = pipes[fd][1];
292
293     if (use_fd >= 0)
294       close(close_fd);
295     else if (fd >= 3)
296       continue;
297     else {
298       /* redirect stdin, stdout and stderr to /dev/null even if UV_IGNORE is
299        * set
300        */
301       use_fd = open("/dev/null", fd == 0 ? O_RDONLY : O_RDWR);
302
303       if (use_fd == -1) {
304         uv__write_int(error_fd, errno);
305         perror("failed to open stdio");
306         _exit(127);
307       }
308     }
309
310     if (fd == use_fd)
311       uv__cloexec(use_fd, 0);
312     else {
313       dup2(use_fd, fd);
314       close(use_fd);
315     }
316
317     if (fd <= 2)
318       uv__nonblock(fd, 0);
319   }
320
321   if (options.cwd && chdir(options.cwd)) {
322     uv__write_int(error_fd, errno);
323     perror("chdir()");
324     _exit(127);
325   }
326
327   if ((options.flags & UV_PROCESS_SETGID) && setgid(options.gid)) {
328     uv__write_int(error_fd, errno);
329     perror("setgid()");
330     _exit(127);
331   }
332
333   if ((options.flags & UV_PROCESS_SETUID) && setuid(options.uid)) {
334     uv__write_int(error_fd, errno);
335     perror("setuid()");
336     _exit(127);
337   }
338
339   if (options.env) {
340     environ = options.env;
341   }
342
343   execvp(options.file, options.args);
344   uv__write_int(error_fd, errno);
345   perror("execvp()");
346   _exit(127);
347 }
348
349
350 int uv_spawn(uv_loop_t* loop,
351              uv_process_t* process,
352              const uv_process_options_t options) {
353   int signal_pipe[2] = { -1, -1 };
354   int (*pipes)[2];
355   int stdio_count;
356   ngx_queue_t* q;
357   ssize_t r;
358   pid_t pid;
359   int i;
360
361   assert(options.file != NULL);
362   assert(!(options.flags & ~(UV_PROCESS_DETACHED |
363                              UV_PROCESS_SETGID |
364                              UV_PROCESS_SETUID |
365                              UV_PROCESS_WINDOWS_HIDE |
366                              UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS)));
367
368   uv__handle_init(loop, (uv_handle_t*)process, UV_PROCESS);
369   ngx_queue_init(&process->queue);
370
371   stdio_count = options.stdio_count;
372   if (stdio_count < 3)
373     stdio_count = 3;
374
375   pipes = malloc(stdio_count * sizeof(*pipes));
376   if (pipes == NULL) {
377     errno = ENOMEM;
378     goto error;
379   }
380
381   for (i = 0; i < stdio_count; i++) {
382     pipes[i][0] = -1;
383     pipes[i][1] = -1;
384   }
385
386   for (i = 0; i < options.stdio_count; i++)
387     if (uv__process_init_stdio(options.stdio + i, pipes[i]))
388       goto error;
389
390   /* This pipe is used by the parent to wait until
391    * the child has called `execve()`. We need this
392    * to avoid the following race condition:
393    *
394    *    if ((pid = fork()) > 0) {
395    *      kill(pid, SIGTERM);
396    *    }
397    *    else if (pid == 0) {
398    *      execve("/bin/cat", argp, envp);
399    *    }
400    *
401    * The parent sends a signal immediately after forking.
402    * Since the child may not have called `execve()` yet,
403    * there is no telling what process receives the signal,
404    * our fork or /bin/cat.
405    *
406    * To avoid ambiguity, we create a pipe with both ends
407    * marked close-on-exec. Then, after the call to `fork()`,
408    * the parent polls the read end until it EOFs or errors with EPIPE.
409    */
410   if (uv__make_pipe(signal_pipe, 0))
411     goto error;
412
413   uv_signal_start(&loop->child_watcher, uv__chld, SIGCHLD);
414
415   pid = fork();
416
417   if (pid == -1) {
418     close(signal_pipe[0]);
419     close(signal_pipe[1]);
420     goto error;
421   }
422
423   if (pid == 0) {
424     uv__process_child_init(options, stdio_count, pipes, signal_pipe[1]);
425     abort();
426   }
427
428   close(signal_pipe[1]);
429
430   process->errorno = 0;
431   do
432     r = read(signal_pipe[0], &process->errorno, sizeof(process->errorno));
433   while (r == -1 && errno == EINTR);
434
435   if (r == 0)
436     ; /* okay, EOF */
437   else if (r == sizeof(process->errorno))
438     ; /* okay, read errorno */
439   else if (r == -1 && errno == EPIPE)
440     ; /* okay, got EPIPE */
441   else
442     abort();
443
444   close(signal_pipe[0]);
445
446   for (i = 0; i < options.stdio_count; i++) {
447     if (uv__process_open_stream(options.stdio + i, pipes[i], i == 0)) {
448       while (i--) uv__process_close_stream(options.stdio + i);
449       goto error;
450     }
451   }
452
453   q = uv__process_queue(loop, pid);
454   ngx_queue_insert_tail(q, &process->queue);
455
456   process->pid = pid;
457   process->exit_cb = options.exit_cb;
458   uv__handle_start(process);
459
460   free(pipes);
461   return 0;
462
463 error:
464   uv__set_sys_error(process->loop, errno);
465
466   if (pipes != NULL) {
467     for (i = 0; i < stdio_count; i++) {
468       if (i < options.stdio_count)
469         if (options.stdio[i].flags & (UV_INHERIT_FD | UV_INHERIT_STREAM))
470           continue;
471       if (pipes[i][0] != -1)
472         close(pipes[i][0]);
473       if (pipes[i][1] != -1)
474         close(pipes[i][1]);
475     }
476     free(pipes);
477   }
478
479   return -1;
480 }
481
482
483 int uv_process_kill(uv_process_t* process, int signum) {
484   int r = kill(process->pid, signum);
485
486   if (r) {
487     uv__set_sys_error(process->loop, errno);
488     return -1;
489   } else {
490     return 0;
491   }
492 }
493
494
495 uv_err_t uv_kill(int pid, int signum) {
496   int r = kill(pid, signum);
497
498   if (r) {
499     return uv__new_sys_error(errno);
500   } else {
501     return uv_ok_;
502   }
503 }
504
505
506 void uv__process_close(uv_process_t* handle) {
507   /* TODO stop signal watcher when this is the last handle */
508   ngx_queue_remove(&handle->queue);
509   uv__handle_stop(handle);
510 }