Alien-uv
view release on metacpan or search on metacpan
libuv/src/unix/process.c view on Meta::CPAN
close_fd = pipes[fd][0];
use_fd = pipes[fd][1];
if (use_fd < 0) {
if (fd >= 3)
continue;
else {
/* redirect stdin, stdout and stderr to /dev/null even if UV_IGNORE is
* set
*/
use_fd = open("/dev/null", fd == 0 ? O_RDONLY : O_RDWR);
close_fd = use_fd;
if (use_fd == -1) {
uv__write_int(error_fd, UV__ERR(errno));
_exit(127);
}
}
}
if (fd == use_fd)
uv__cloexec_fcntl(use_fd, 0);
else
fd = dup2(use_fd, fd);
if (fd == -1) {
uv__write_int(error_fd, UV__ERR(errno));
_exit(127);
}
if (fd <= 2)
uv__nonblock_fcntl(fd, 0);
if (close_fd >= stdio_count)
uv__close(close_fd);
}
for (fd = 0; fd < stdio_count; fd++) {
use_fd = pipes[fd][1];
if (use_fd >= stdio_count)
uv__close(use_fd);
}
if (options->cwd != NULL && chdir(options->cwd)) {
uv__write_int(error_fd, UV__ERR(errno));
_exit(127);
}
if (options->flags & (UV_PROCESS_SETUID | UV_PROCESS_SETGID)) {
/* When dropping privileges from root, the `setgroups` call will
* remove any extraneous groups. If we don't call this, then
* even though our uid has dropped, we may still have groups
* that enable us to do super-user things. This will fail if we
* aren't root, so don't bother checking the return value, this
* is just done as an optimistic privilege dropping function.
*/
SAVE_ERRNO(setgroups(0, NULL));
}
if ((options->flags & UV_PROCESS_SETGID) && setgid(options->gid)) {
uv__write_int(error_fd, UV__ERR(errno));
_exit(127);
}
if ((options->flags & UV_PROCESS_SETUID) && setuid(options->uid)) {
uv__write_int(error_fd, UV__ERR(errno));
_exit(127);
}
if (options->env != NULL) {
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, UV__ERR(errno));
_exit(127);
}
/* Reset signal mask. */
sigemptyset(&set);
err = pthread_sigmask(SIG_SETMASK, &set, NULL);
if (err != 0) {
uv__write_int(error_fd, UV__ERR(err));
_exit(127);
}
execvp(options->file, options->args);
uv__write_int(error_fd, UV__ERR(errno));
_exit(127);
}
#endif
int uv_spawn(uv_loop_t* loop,
uv_process_t* process,
const uv_process_options_t* options) {
#if defined(__APPLE__) && (TARGET_OS_TV || TARGET_OS_WATCH)
/* fork is marked __WATCHOS_PROHIBITED __TVOS_PROHIBITED. */
return UV_ENOSYS;
#else
int signal_pipe[2] = { -1, -1 };
int pipes_storage[8][2];
int (*pipes)[2];
int stdio_count;
ssize_t r;
pid_t pid;
int err;
int exec_errorno;
( run in 1.347 second using v1.01-cache-2.11-cpan-97f6503c9c8 )