41
static void uv__chld(EV_P_ ev_child* watcher, int revents) {
42
int status = watcher->rstatus;
45
uv_process_t *process = watcher->data;
47
assert(&process->child_watcher == watcher);
48
assert(revents & EV_CHILD);
50
ev_child_stop(EV_A_ &process->child_watcher);
52
if (WIFEXITED(status)) {
53
exit_status = WEXITSTATUS(status);
56
if (WIFSIGNALED(status)) {
57
term_signal = WTERMSIG(status);
60
if (process->exit_cb) {
44
static ngx_queue_t* uv__process_queue(uv_loop_t* loop, int pid) {
46
return loop->process_handles + pid % ARRAY_SIZE(loop->process_handles);
50
static uv_process_t* uv__process_find(uv_loop_t* loop, int pid) {
55
h = uv__process_queue(loop, pid);
57
ngx_queue_foreach(q, h) {
58
handle = ngx_queue_data(q, uv_process_t, queue);
59
if (handle->pid == pid) return handle;
66
static void uv__chld(uv_signal_t* handle, int signum) {
67
uv_process_t* process;
73
assert(signum == SIGCHLD);
76
pid = waitpid(-1, &status, WNOHANG);
83
return; /* XXX stop signal watcher? */
88
process = uv__process_find(handle->loop, pid);
90
continue; /* XXX bug? abort? */
92
uv__handle_stop(process);
94
if (process->exit_cb == NULL)
100
if (WIFEXITED(status))
101
exit_status = WEXITSTATUS(status);
103
if (WIFSIGNALED(status))
104
term_signal = WTERMSIG(status);
106
if (process->errorno) {
107
uv__set_sys_error(process->loop, process->errorno);
108
exit_status = -1; /* execve() failed */
61
111
process->exit_cb(process, exit_status, term_signal);
66
#define UV__F_IPC (1 << 0)
67
#define UV__F_NONBLOCK (1 << 1)
69
static int uv__make_socketpair(int fds[2], int flags) {
75
if (flags & UV__F_NONBLOCK)
78
if (socketpair(AF_UNIX, SOCK_STREAM|fl, 0, fds) == 0)
116
int uv__make_socketpair(int fds[2], int flags) {
117
#if defined(__linux__)
118
static int no_cloexec;
123
if (socketpair(AF_UNIX, SOCK_STREAM | UV__SOCK_CLOEXEC | flags, 0, fds) == 0)
126
/* Retry on EINVAL, it means SOCK_CLOEXEC is not supported.
127
* Anything else is a genuine error.
81
129
if (errno != EINVAL)
84
/* errno == EINVAL so maybe the kernel headers lied about
85
* the availability of SOCK_NONBLOCK. This can happen if people
86
* build libuv against newer kernel headers than the kernel
87
* they actually run the software on.
91
137
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds))
144
186
* Used for initializing stdio streams like options.stdin_stream. Returns
145
187
* zero on success.
147
static int uv__process_init_pipe(uv_pipe_t* handle, int fds[2], int flags) {
148
if (handle->type != UV_NAMED_PIPE) {
189
static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2]) {
193
mask = UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD | UV_INHERIT_STREAM;
195
switch (container->flags & mask) {
200
assert(container->data.stream != NULL);
201
if (container->data.stream->type != UV_NAMED_PIPE) {
205
return uv__make_socketpair(fds, 0);
208
case UV_INHERIT_STREAM:
209
if (container->flags & UV_INHERIT_FD)
210
fd = container->data.fd;
212
fd = uv__stream_fd(container->data.stream);
223
assert(0 && "Unexpected flags");
154
return uv__make_socketpair(fds, flags);
229
static int uv__process_open_stream(uv_stdio_container_t* container,
234
if (!(container->flags & UV_CREATE_PIPE) || pipefds[0] < 0)
237
if (close(pipefds[1]))
238
if (errno != EINTR && errno != EINPROGRESS)
242
uv__nonblock(pipefds[0], 1);
244
if (container->data.stream->type == UV_NAMED_PIPE &&
245
((uv_pipe_t*)container->data.stream)->ipc)
246
flags = UV_STREAM_READABLE | UV_STREAM_WRITABLE;
248
flags = UV_STREAM_WRITABLE;
156
return uv__make_pipe(fds, flags);
160
#ifndef SPAWN_WAIT_EXEC
161
# define SPAWN_WAIT_EXEC 1
164
int uv_spawn2(uv_loop_t* loop, uv_process_t* process,
165
uv_process_options2_t options) {
167
* Save environ in the case that we get it clobbered
168
* by the child process.
170
char** save_our_env = environ;
171
int stdin_pipe[2] = { -1, -1 };
172
int stdout_pipe[2] = { -1, -1 };
173
int stderr_pipe[2] = { -1, -1 };
250
flags = UV_STREAM_READABLE;
252
return uv__stream_open(container->data.stream, pipefds[0], flags);
256
static void uv__process_close_stream(uv_stdio_container_t* container) {
257
if (!(container->flags & UV_CREATE_PIPE)) return;
258
uv__stream_close((uv_stream_t*)container->data.stream);
262
static void uv__write_int(int fd, int val) {
266
n = write(fd, &val, sizeof(val));
267
while (n == -1 && errno == EINTR);
269
if (n == -1 && errno == EPIPE)
270
return; /* parent process has quit */
272
assert(n == sizeof(val));
276
static void uv__process_child_init(uv_process_options_t options,
284
if (options.flags & UV_PROCESS_DETACHED)
287
for (fd = 0; fd < stdio_count; fd++) {
288
close_fd = pipes[fd][0];
289
use_fd = pipes[fd][1];
296
/* redirect stdin, stdout and stderr to /dev/null even if UV_IGNORE is
299
use_fd = open("/dev/null", fd == 0 ? O_RDONLY : O_RDWR);
302
uv__write_int(error_fd, errno);
303
perror("failed to open stdio");
309
uv__cloexec(use_fd, 0);
319
if (options.cwd && chdir(options.cwd)) {
320
uv__write_int(error_fd, errno);
325
if ((options.flags & UV_PROCESS_SETGID) && setgid(options.gid)) {
326
uv__write_int(error_fd, errno);
331
if ((options.flags & UV_PROCESS_SETUID) && setuid(options.uid)) {
332
uv__write_int(error_fd, errno);
338
environ = options.env;
341
execvp(options.file, options.args);
342
uv__write_int(error_fd, errno);
348
int uv_spawn(uv_loop_t* loop,
349
uv_process_t* process,
350
const uv_process_options_t options) {
175
351
int signal_pipe[2] = { -1, -1 };
182
359
assert(options.file != NULL);
183
assert(!(options.flags & ~(UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS |
360
assert(!(options.flags & ~(UV_PROCESS_DETACHED |
184
361
UV_PROCESS_SETGID |
185
UV_PROCESS_SETUID)));
363
UV_PROCESS_WINDOWS_HIDE |
364
UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS)));
188
366
uv__handle_init(loop, (uv_handle_t*)process, UV_PROCESS);
189
loop->counters.process_init++;
191
process->exit_cb = options.exit_cb;
193
if (options.stdin_stream &&
194
uv__process_init_pipe(options.stdin_stream, stdin_pipe, 0)) {
198
if (options.stdout_stream &&
199
uv__process_init_pipe(options.stdout_stream, stdout_pipe, 0)) {
203
if (options.stderr_stream &&
204
uv__process_init_pipe(options.stderr_stream, stderr_pipe, 0)) {
367
ngx_queue_init(&process->queue);
369
stdio_count = options.stdio_count;
373
pipes = malloc(stdio_count * sizeof(*pipes));
379
for (i = 0; i < stdio_count; i++) {
384
for (i = 0; i < options.stdio_count; i++)
385
if (uv__process_init_stdio(options.stdio + i, pipes[i]))
208
388
/* This pipe is used by the parent to wait until
209
389
* the child has called `execve()`. We need this
224
404
* To avoid ambiguity, we create a pipe with both ends
225
405
* marked close-on-exec. Then, after the call to `fork()`,
226
* the parent polls the read end until it sees POLLHUP.
406
* the parent polls the read end until it EOFs or errors with EPIPE.
229
if (uv__make_pipe(signal_pipe, UV__F_NONBLOCK))
408
if (uv__make_pipe(signal_pipe, 0))
411
uv_signal_start(&loop->child_watcher, uv__chld, SIGCHLD);
237
uv__close(signal_pipe[0]);
238
uv__close(signal_pipe[1]);
240
environ = save_our_env;
416
close(signal_pipe[0]);
417
close(signal_pipe[1]);
245
if (stdin_pipe[0] >= 0) {
246
uv__close(stdin_pipe[1]);
247
dup2(stdin_pipe[0], STDIN_FILENO);
249
/* Reset flags that might be set by Node */
250
uv__cloexec(STDIN_FILENO, 0);
251
uv__nonblock(STDIN_FILENO, 0);
254
if (stdout_pipe[1] >= 0) {
255
uv__close(stdout_pipe[0]);
256
dup2(stdout_pipe[1], STDOUT_FILENO);
258
/* Reset flags that might be set by Node */
259
uv__cloexec(STDOUT_FILENO, 0);
260
uv__nonblock(STDOUT_FILENO, 0);
263
if (stderr_pipe[1] >= 0) {
264
uv__close(stderr_pipe[0]);
265
dup2(stderr_pipe[1], STDERR_FILENO);
267
/* Reset flags that might be set by Node */
268
uv__cloexec(STDERR_FILENO, 0);
269
uv__nonblock(STDERR_FILENO, 0);
272
if (options.cwd && chdir(options.cwd)) {
277
if ((options.flags & UV_PROCESS_SETGID) && setgid(options.gid)) {
282
if ((options.flags & UV_PROCESS_SETUID) && setuid(options.uid)) {
287
environ = options.env;
289
execvp(options.file, options.args);
292
/* Execution never reaches here. */
297
/* Restore environment. */
298
environ = save_our_env;
301
/* POLLHUP signals child has exited or execve()'d. */
302
uv__close(signal_pipe[1]);
304
pfd.fd = signal_pipe[0];
305
pfd.events = POLLIN|POLLHUP;
307
errno = 0, status = poll(&pfd, 1, -1);
309
while (status == -1 && (errno == EINTR || errno == ENOMEM));
311
assert((status == 1) && "poll() on pipe read end failed");
312
uv__close(signal_pipe[0]);
422
uv__process_child_init(options, stdio_count, pipes, signal_pipe[1]);
426
close(signal_pipe[1]);
428
process->errorno = 0;
430
r = read(signal_pipe[0], &process->errorno, sizeof(process->errorno));
431
while (r == -1 && errno == EINTR);
435
else if (r == sizeof(process->errorno))
436
; /* okay, read errorno */
437
else if (r == -1 && errno == EPIPE)
438
; /* okay, got EPIPE */
442
close(signal_pipe[0]);
444
for (i = 0; i < options.stdio_count; i++) {
445
if (uv__process_open_stream(options.stdio + i, pipes[i], i == 0)) {
446
while (i--) uv__process_close_stream(options.stdio + i);
451
q = uv__process_queue(loop, pid);
452
ngx_queue_insert_tail(q, &process->queue);
315
454
process->pid = pid;
317
ev_child_init(&process->child_watcher, uv__chld, pid, 0);
318
ev_child_start(process->loop->ev, &process->child_watcher);
319
process->child_watcher.data = process;
321
if (stdin_pipe[1] >= 0) {
322
assert(options.stdin_stream);
323
assert(stdin_pipe[0] >= 0);
324
uv__close(stdin_pipe[0]);
325
uv__nonblock(stdin_pipe[1], 1);
326
flags = UV_WRITABLE | (options.stdin_stream->ipc ? UV_READABLE : 0);
327
uv__stream_open((uv_stream_t*)options.stdin_stream, stdin_pipe[1],
331
if (stdout_pipe[0] >= 0) {
332
assert(options.stdout_stream);
333
assert(stdout_pipe[1] >= 0);
334
uv__close(stdout_pipe[1]);
335
uv__nonblock(stdout_pipe[0], 1);
336
flags = UV_READABLE | (options.stdout_stream->ipc ? UV_WRITABLE : 0);
337
uv__stream_open((uv_stream_t*)options.stdout_stream, stdout_pipe[0],
341
if (stderr_pipe[0] >= 0) {
342
assert(options.stderr_stream);
343
assert(stderr_pipe[1] >= 0);
344
uv__close(stderr_pipe[1]);
345
uv__nonblock(stderr_pipe[0], 1);
346
flags = UV_READABLE | (options.stderr_stream->ipc ? UV_WRITABLE : 0);
347
uv__stream_open((uv_stream_t*)options.stderr_stream, stderr_pipe[0],
455
process->exit_cb = options.exit_cb;
456
uv__handle_start(process);
354
462
uv__set_sys_error(process->loop, errno);
355
uv__close(stdin_pipe[0]);
356
uv__close(stdin_pipe[1]);
357
uv__close(stdout_pipe[0]);
358
uv__close(stdout_pipe[1]);
359
uv__close(stderr_pipe[0]);
360
uv__close(stderr_pipe[1]);
464
for (i = 0; i < stdio_count; i++) {