diff options
Diffstat (limited to 'Utilities/cmlibuv/src/unix/process.c')
-rw-r--r-- | Utilities/cmlibuv/src/unix/process.c | 42 |
1 files changed, 39 insertions, 3 deletions
diff --git a/Utilities/cmlibuv/src/unix/process.c b/Utilities/cmlibuv/src/unix/process.c index f2fe305..9842710 100644 --- a/Utilities/cmlibuv/src/unix/process.c +++ b/Utilities/cmlibuv/src/unix/process.c @@ -279,9 +279,12 @@ static void uv__process_child_init(const uv_process_options_t* options, int stdio_count, int (*pipes)[2], int error_fd) { + sigset_t set; int close_fd; int use_fd; + int err; int fd; + int n; if (options->flags & UV_PROCESS_DETACHED) setsid(); @@ -376,6 +379,31 @@ static void uv__process_child_init(const uv_process_options_t* options, environ = options->env; } + /* Reset signal disposition. Use a hard-coded limit because NSIG + * is not fixed on Linux: it's either 32, 34 or 64, depending on + * whether RT signals are enabled. We are not allowed to touch + * RT signal handlers, glibc uses them internally. + */ + for (n = 1; n < 32; n += 1) { + if (n == SIGKILL || n == SIGSTOP) + continue; /* Can't be changed. */ + + if (SIG_ERR != signal(n, SIG_DFL)) + continue; + + uv__write_int(error_fd, -errno); + _exit(127); + } + + /* Reset signal mask. */ + sigemptyset(&set); + err = pthread_sigmask(SIG_SETMASK, &set, NULL); + + if (err != 0) { + uv__write_int(error_fd, -err); + _exit(127); + } + execvp(options->file, options->args); uv__write_int(error_fd, -errno); _exit(127); @@ -391,6 +419,7 @@ int uv_spawn(uv_loop_t* loop, return -ENOSYS; #else int signal_pipe[2] = { -1, -1 }; + int pipes_storage[8][2]; int (*pipes)[2]; int stdio_count; ssize_t r; @@ -415,7 +444,10 @@ int uv_spawn(uv_loop_t* loop, stdio_count = 3; err = -ENOMEM; - pipes = uv__malloc(stdio_count * sizeof(*pipes)); + pipes = pipes_storage; + if (stdio_count > (int) ARRAY_SIZE(pipes_storage)) + pipes = uv__malloc(stdio_count * sizeof(*pipes)); + if (pipes == NULL) goto error; @@ -520,7 +552,9 @@ int uv_spawn(uv_loop_t* loop, process->pid = pid; process->exit_cb = options->exit_cb; - uv__free(pipes); + if (pipes != pipes_storage) + uv__free(pipes); + return exec_errorno; error: @@ -534,7 +568,9 @@ error: if (pipes[i][1] != -1) uv__close_nocheckstdio(pipes[i][1]); } - uv__free(pipes); + + if (pipes != pipes_storage) + uv__free(pipes); } return err; |