summaryrefslogtreecommitdiff
path: root/Utilities/cmlibuv/src/unix/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'Utilities/cmlibuv/src/unix/process.c')
-rw-r--r--Utilities/cmlibuv/src/unix/process.c42
1 files changed, 39 insertions, 3 deletions
diff --git a/Utilities/cmlibuv/src/unix/process.c b/Utilities/cmlibuv/src/unix/process.c
index f2fe30521..9842710d0 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;