2016-05-03 04:28:06 +00:00
|
|
|
// Functions that we may safely call after fork().
|
2016-05-18 22:30:21 +00:00
|
|
|
#include "config.h" // IWYU pragma: keep
|
|
|
|
|
2015-07-25 15:14:25 +00:00
|
|
|
#include <errno.h>
|
2016-05-03 04:28:06 +00:00
|
|
|
#include <fcntl.h>
|
2015-07-25 15:14:25 +00:00
|
|
|
#include <signal.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <time.h>
|
2016-04-21 06:00:54 +00:00
|
|
|
#include <memory>
|
|
|
|
#if FISH_USE_POSIX_SPAWN
|
|
|
|
#include <spawn.h>
|
|
|
|
#endif
|
2017-01-03 05:11:53 +00:00
|
|
|
#include <wchar.h>
|
2016-04-21 06:00:54 +00:00
|
|
|
|
2015-07-25 15:14:25 +00:00
|
|
|
#include "common.h"
|
2012-02-28 23:11:46 +00:00
|
|
|
#include "exec.h"
|
2016-04-21 06:00:54 +00:00
|
|
|
#include "io.h"
|
2016-05-03 04:28:06 +00:00
|
|
|
#include "iothread.h"
|
|
|
|
#include "postfork.h"
|
|
|
|
#include "proc.h"
|
|
|
|
#include "signal.h"
|
|
|
|
#include "wutil.h" // IWYU pragma: keep
|
2012-02-28 23:11:46 +00:00
|
|
|
|
2013-01-17 11:46:33 +00:00
|
|
|
#ifndef JOIN_THREADS_BEFORE_FORK
|
2013-01-31 23:57:08 +00:00
|
|
|
#define JOIN_THREADS_BEFORE_FORK 0
|
2013-01-17 11:46:33 +00:00
|
|
|
#endif
|
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
/// The number of times to try to call fork() before giving up.
|
2012-02-28 23:11:46 +00:00
|
|
|
#define FORK_LAPS 5
|
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
/// The number of nanoseconds to sleep between attempts to call fork().
|
2012-02-28 23:11:46 +00:00
|
|
|
#define FORK_SLEEP_TIME 1000000
|
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
/// Base open mode to pass to calls to open.
|
2012-02-28 23:11:46 +00:00
|
|
|
#define OPEN_MASK 0666
|
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
/// Fork error message.
|
2012-03-09 07:21:07 +00:00
|
|
|
#define FORK_ERROR "Could not create child process - exiting"
|
2012-02-28 23:11:46 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
/// File redirection clobbering error message.
|
2012-03-09 07:21:07 +00:00
|
|
|
#define NOCLOB_ERROR "The file '%s' already exists"
|
2012-02-28 23:11:46 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
/// File redirection error message.
|
2012-03-09 07:21:07 +00:00
|
|
|
#define FILE_ERROR "An error occurred while redirecting file '%s'"
|
2012-02-28 23:11:46 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
/// File descriptor redirection error message.
|
|
|
|
#define FD_ERROR "An error occurred while redirecting file descriptor %s"
|
2012-02-28 23:11:46 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
/// Pipe error message.
|
2012-03-09 07:21:07 +00:00
|
|
|
#define LOCAL_PIPE_ERROR "An error occurred while setting up pipe"
|
|
|
|
|
2013-08-18 23:55:01 +00:00
|
|
|
static bool log_redirections = false;
|
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
/// Cover for debug_safe that can take an int. The format string should expect a %s.
|
|
|
|
static void debug_safe_int(int level, const char *format, int val) {
|
2012-03-09 07:21:07 +00:00
|
|
|
char buff[128];
|
|
|
|
format_long_safe(buff, val);
|
|
|
|
debug_safe(level, format, buff);
|
|
|
|
}
|
2012-02-28 03:20:27 +00:00
|
|
|
|
2017-07-27 02:45:22 +00:00
|
|
|
/// Called only by the child to set its own process group (possibly creating a new group in the
|
|
|
|
/// process if it is the first in a JOB_CONTROL job. The parent will wait for this to finish.
|
|
|
|
/// A process that isn't already in control of the terminal can't give itself control of the
|
|
|
|
/// terminal without hanging, but it's not right for the child to try and give itself control
|
|
|
|
/// from the very beginning because the parent may not have gotten around to doing so yet. Let
|
|
|
|
/// the parent figure it out; if the child doesn't have terminal control and it later tries to
|
|
|
|
/// read from the terminal, the kernel will send it SIGTTIN and it'll hang anyway.
|
|
|
|
/// The key here is that the parent should transfer control of the terminal (if appropriate)
|
|
|
|
/// prior to sending the child SIGCONT to wake it up to exec.
|
2016-12-15 03:21:36 +00:00
|
|
|
///
|
|
|
|
/// Returns true on sucess, false on failiure.
|
2017-07-27 02:45:22 +00:00
|
|
|
bool child_set_group(job_t *j, process_t *p) {
|
2016-12-15 03:21:36 +00:00
|
|
|
bool retval = true;
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2017-01-26 23:06:58 +00:00
|
|
|
if (j->get_flag(JOB_CONTROL)) {
|
2017-04-23 14:56:33 +00:00
|
|
|
// New jobs have the pgid set to -2
|
|
|
|
if (j->pgid == -2) {
|
2012-11-19 00:30:30 +00:00
|
|
|
j->pgid = p->pid;
|
|
|
|
}
|
2017-08-06 22:47:01 +00:00
|
|
|
// Retry on EPERM because there's no way that a child cannot join an existing progress group
|
|
|
|
// because we are SIGSTOPing the previous job in the chain. Sometimes we have to try a few
|
|
|
|
// times to get the kernel to see the new group. (Linux 4.4.0)
|
2017-07-27 02:45:22 +00:00
|
|
|
int failure = setpgid(p->pid, j->pgid);
|
2017-07-28 23:08:46 +00:00
|
|
|
while (failure == -1 && (errno == EPERM || errno == EINTR)) {
|
2017-07-30 01:37:49 +00:00
|
|
|
debug_safe(4, "Retrying setpgid in child process");
|
2017-07-28 23:08:46 +00:00
|
|
|
failure = setpgid(p->pid, j->pgid);
|
2017-07-27 22:33:17 +00:00
|
|
|
}
|
2017-07-27 02:45:22 +00:00
|
|
|
// TODO: Figure out why we're testing whether the pgid is correct after attempting to
|
|
|
|
// set it failed. This was added in commit 4e912ef8 from 2012-02-27.
|
|
|
|
failure = failure && getpgid(p->pid) != j->pgid;
|
|
|
|
if (failure) { //!OCLINT(collapsible if statements)
|
|
|
|
char pid_buff[128];
|
|
|
|
char job_id_buff[128];
|
|
|
|
char getpgid_buff[128];
|
|
|
|
char job_pgid_buff[128];
|
|
|
|
char argv0[64];
|
|
|
|
char command[64];
|
|
|
|
|
|
|
|
format_long_safe(pid_buff, p->pid);
|
|
|
|
format_long_safe(job_id_buff, j->job_id);
|
|
|
|
format_long_safe(getpgid_buff, getpgid(p->pid));
|
|
|
|
format_long_safe(job_pgid_buff, j->pgid);
|
|
|
|
narrow_string_safe(argv0, p->argv0());
|
|
|
|
narrow_string_safe(command, j->command_wcstr());
|
|
|
|
|
|
|
|
debug_safe(
|
|
|
|
1, "Could not send own process %s, '%s' in job %s, '%s' from group %s to group %s",
|
|
|
|
pid_buff, argv0, job_id_buff, command, getpgid_buff, job_pgid_buff);
|
|
|
|
|
|
|
|
safe_perror("setpgid");
|
|
|
|
retval = false;
|
|
|
|
}
|
|
|
|
} else {
|
2017-08-06 22:47:01 +00:00
|
|
|
// This is probably stays unused in the child.
|
2017-07-27 02:45:22 +00:00
|
|
|
j->pgid = getpgrp();
|
|
|
|
}
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2017-07-27 02:45:22 +00:00
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2017-08-06 23:05:51 +00:00
|
|
|
/// Called only by the parent only after a child forks and successfully calls child_set_group,
|
|
|
|
/// guaranteeing the job control process group has been created and that the child belongs to the
|
|
|
|
/// correct process group. Here we can update our job_t structure to reflect the correct process
|
|
|
|
/// group in the case of JOB_CONTROL, and we can give the new process group control of the terminal
|
|
|
|
/// if it's to run in the foreground. Note that we can guarantee the child won't try to read from
|
|
|
|
/// the terminal before we've had a chance to run this code, because we haven't woken them up with a
|
|
|
|
/// SIGCONT yet. This musn't be called as a part of setup_child_process because that can hang
|
|
|
|
/// indefinitely until data is available to read/write in the case of IO_FILE, which means we'll
|
|
|
|
/// never reach our SIGSTOP and everything hangs.
|
2017-07-27 02:45:22 +00:00
|
|
|
bool set_child_group(job_t *j, pid_t child_pid) {
|
|
|
|
bool retval = true;
|
|
|
|
|
|
|
|
if (j->get_flag(JOB_CONTROL)) {
|
|
|
|
// New jobs have the pgid set to -2
|
|
|
|
if (j->pgid == -2) {
|
|
|
|
j->pgid = child_pid;
|
2012-11-19 00:30:30 +00:00
|
|
|
}
|
2016-05-03 04:28:06 +00:00
|
|
|
} else {
|
2017-04-23 14:12:13 +00:00
|
|
|
j->pgid = getpgrp();
|
2012-11-18 10:23:22 +00:00
|
|
|
}
|
2012-11-19 00:30:30 +00:00
|
|
|
|
2017-01-26 23:06:58 +00:00
|
|
|
if (j->get_flag(JOB_TERMINAL) && j->get_flag(JOB_FOREGROUND)) { //!OCLINT(early exit)
|
2017-07-26 19:25:21 +00:00
|
|
|
if (tcgetpgrp(STDIN_FILENO) == j->pgid) {
|
2017-08-06 22:47:01 +00:00
|
|
|
// We've already assigned the process group control of the terminal when the first
|
|
|
|
// process in the job was started. There's no need to do so again, and on some platforms
|
|
|
|
// this can cause an EPERM error. In addition, if we've given control of the terminal to
|
|
|
|
// a process group, attempting to call tcsetpgrp from the background will cause SIGTTOU
|
|
|
|
// to be sent to everything in our process group (unless we handle it).
|
2017-07-26 19:25:21 +00:00
|
|
|
debug(4, L"Process group %d already has control of terminal\n", j->pgid);
|
2017-08-06 23:05:51 +00:00
|
|
|
} else {
|
2017-08-06 22:47:01 +00:00
|
|
|
// No need to duplicate the code here, a function already exists that does just this.
|
2017-07-27 02:45:22 +00:00
|
|
|
retval = terminal_give_to_job(j, false /*new job, so not continuing*/);
|
2012-11-19 00:30:30 +00:00
|
|
|
}
|
2012-11-18 10:23:22 +00:00
|
|
|
}
|
2012-02-28 03:20:27 +00:00
|
|
|
|
2016-12-15 03:21:36 +00:00
|
|
|
return retval;
|
2012-02-28 03:20:27 +00:00
|
|
|
}
|
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
/// Set up a childs io redirections. Should only be called by setup_child_process(). Does the
|
|
|
|
/// following: First it closes any open file descriptors not related to the child by calling
|
|
|
|
/// close_unused_internal_pipes() and closing the universal variable server file descriptor. It then
|
|
|
|
/// goes on to perform all the redirections described by \c io.
|
|
|
|
///
|
2016-06-06 01:46:04 +00:00
|
|
|
/// \param io_chain the list of IO redirections for the child
|
2016-05-03 04:28:06 +00:00
|
|
|
///
|
|
|
|
/// \return 0 on sucess, -1 on failure
|
|
|
|
static int handle_child_io(const io_chain_t &io_chain) {
|
|
|
|
for (size_t idx = 0; idx < io_chain.size(); idx++) {
|
2014-04-11 16:50:12 +00:00
|
|
|
const io_data_t *io = io_chain.at(idx).get();
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
if (io->io_mode == IO_FD && io->fd == static_cast<const io_fd_t *>(io)->old_fd) {
|
2012-11-19 00:30:30 +00:00
|
|
|
continue;
|
2012-11-18 10:23:22 +00:00
|
|
|
}
|
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
switch (io->io_mode) {
|
|
|
|
case IO_CLOSE: {
|
2017-01-03 05:11:53 +00:00
|
|
|
if (log_redirections) fwprintf(stderr, L"%d: close %d\n", getpid(), io->fd);
|
2016-05-03 04:28:06 +00:00
|
|
|
if (close(io->fd)) {
|
2012-11-19 08:31:03 +00:00
|
|
|
debug_safe_int(0, "Failed to close file descriptor %s", io->fd);
|
2013-01-10 01:06:20 +00:00
|
|
|
safe_perror("close");
|
2012-11-19 08:31:03 +00:00
|
|
|
}
|
|
|
|
break;
|
2012-11-19 00:30:30 +00:00
|
|
|
}
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
case IO_FILE: {
|
|
|
|
// Here we definitely do not want to set CLO_EXEC because our child needs access.
|
2016-07-30 19:01:37 +00:00
|
|
|
const io_file_t *io_file = static_cast<const io_file_t *>(io);
|
2016-03-04 02:49:12 +00:00
|
|
|
int tmp = open(io_file->filename_cstr, io_file->flags, OPEN_MASK);
|
2016-05-03 04:28:06 +00:00
|
|
|
if (tmp < 0) {
|
|
|
|
if ((io_file->flags & O_EXCL) && (errno == EEXIST)) {
|
2013-01-15 08:18:03 +00:00
|
|
|
debug_safe(1, NOCLOB_ERROR, io_file->filename_cstr);
|
2016-05-03 04:28:06 +00:00
|
|
|
} else {
|
2013-01-15 08:18:03 +00:00
|
|
|
debug_safe(1, FILE_ERROR, io_file->filename_cstr);
|
2013-01-10 01:06:20 +00:00
|
|
|
safe_perror("open");
|
2012-11-19 08:31:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
2016-05-03 04:28:06 +00:00
|
|
|
} else if (tmp != io->fd) {
|
|
|
|
// This call will sometimes fail, but that is ok, this is just a precausion.
|
2012-11-19 08:31:03 +00:00
|
|
|
close(io->fd);
|
2012-11-19 00:30:30 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
if (dup2(tmp, io->fd) == -1) {
|
|
|
|
debug_safe_int(1, FD_ERROR, io->fd);
|
2013-01-10 01:06:20 +00:00
|
|
|
safe_perror("dup2");
|
2015-07-20 09:34:57 +00:00
|
|
|
exec_close(tmp);
|
2012-11-19 08:31:03 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
exec_close(tmp);
|
|
|
|
}
|
|
|
|
break;
|
2012-11-19 00:30:30 +00:00
|
|
|
}
|
2012-11-19 08:31:03 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
case IO_FD: {
|
2013-08-18 23:55:01 +00:00
|
|
|
int old_fd = static_cast<const io_fd_t *>(io)->old_fd;
|
2016-05-03 04:28:06 +00:00
|
|
|
if (log_redirections)
|
2017-01-03 05:11:53 +00:00
|
|
|
fwprintf(stderr, L"%d: fd dup %d to %d\n", getpid(), old_fd, io->fd);
|
2013-08-18 23:55:01 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
// This call will sometimes fail, but that is ok, this is just a precausion.
|
2012-11-19 00:30:30 +00:00
|
|
|
close(io->fd);
|
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
if (dup2(old_fd, io->fd) == -1) {
|
2012-11-19 08:31:03 +00:00
|
|
|
debug_safe_int(1, FD_ERROR, io->fd);
|
2013-01-10 01:06:20 +00:00
|
|
|
safe_perror("dup2");
|
2012-11-19 00:30:30 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2012-11-19 08:31:03 +00:00
|
|
|
break;
|
2012-11-19 00:30:30 +00:00
|
|
|
}
|
|
|
|
|
2012-11-19 08:31:03 +00:00
|
|
|
case IO_BUFFER:
|
2016-05-03 04:28:06 +00:00
|
|
|
case IO_PIPE: {
|
2016-07-30 19:01:37 +00:00
|
|
|
const io_pipe_t *io_pipe = static_cast<const io_pipe_t *>(io);
|
2016-05-03 04:28:06 +00:00
|
|
|
// If write_pipe_idx is 0, it means we're connecting to the read end (first pipe
|
|
|
|
// fd). If it's 1, we're connecting to the write end (second pipe fd).
|
2013-01-16 03:55:57 +00:00
|
|
|
unsigned int write_pipe_idx = (io_pipe->is_input ? 0 : 1);
|
2016-05-03 04:28:06 +00:00
|
|
|
#if 0
|
2017-01-03 05:11:53 +00:00
|
|
|
debug(0, L"%ls %ls on fd %d (%d %d)", write_pipe?L"write":L"read",
|
|
|
|
(io->io_mode == IO_BUFFER)?L"buffer":L"pipe", io->fd, io->pipe_fd[0],
|
|
|
|
io->pipe_fd[1]);
|
2016-05-03 04:28:06 +00:00
|
|
|
#endif
|
|
|
|
if (log_redirections)
|
2017-01-03 05:11:53 +00:00
|
|
|
fwprintf(stderr, L"%d: %s dup %d to %d\n", getpid(),
|
|
|
|
io->io_mode == IO_BUFFER ? "buffer" : "pipe",
|
|
|
|
io_pipe->pipe_fd[write_pipe_idx], io->fd);
|
2016-05-03 04:28:06 +00:00
|
|
|
if (dup2(io_pipe->pipe_fd[write_pipe_idx], io->fd) != io->fd) {
|
2012-11-19 08:31:03 +00:00
|
|
|
debug_safe(1, LOCAL_PIPE_ERROR);
|
2013-01-10 01:06:20 +00:00
|
|
|
safe_perror("dup2");
|
2012-11-19 08:31:03 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
if (io_pipe->pipe_fd[0] >= 0) exec_close(io_pipe->pipe_fd[0]);
|
|
|
|
if (io_pipe->pipe_fd[1] >= 0) exec_close(io_pipe->pipe_fd[1]);
|
2012-11-19 08:31:03 +00:00
|
|
|
break;
|
2012-11-19 00:30:30 +00:00
|
|
|
}
|
|
|
|
}
|
2012-11-18 10:23:22 +00:00
|
|
|
}
|
|
|
|
|
2012-11-19 00:30:30 +00:00
|
|
|
return 0;
|
2012-02-28 23:11:46 +00:00
|
|
|
}
|
|
|
|
|
2017-07-29 21:49:26 +00:00
|
|
|
int setup_child_process(process_t *p, const io_chain_t &io_chain) {
|
2017-07-27 18:48:03 +00:00
|
|
|
bool ok = true;
|
2012-02-28 23:11:46 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
if (ok) {
|
2017-08-06 22:47:01 +00:00
|
|
|
// In the case of IO_FILE, this can hang until data is available to read/write!
|
Big fat refactoring of how redirections work. In fish 1.x and 2.0.0, the redirections for a process were flattened into a big list associated with the job, so there was no way to tell which redirections applied to each process. Each process therefore got all the redirections associated with the job. See https://github.com/fish-shell/fish-shell/issues/877 for how this could manifest.
With this change, jobs only track their block-level redirections. Process level redirections are correctly associated with the process, and at exec time we stitch them together (block, pipe, and process redirects).
This fixes the weird issues where redirects bleed across pipelines (like #877), and also allows us to play with the order in which redirections are applied, since the final list is constructed right before it's needed. This lets us put pipes after block level redirections but before process level redirections, so that a 2>&1-type redirection gets picked up after the pipe, i.e. it should fix https://github.com/fish-shell/fish-shell/issues/110
This is a significant change. The tests all pass. Cross your fingers.
2013-08-19 23:16:41 +00:00
|
|
|
ok = (0 == handle_child_io(io_chain));
|
2016-05-03 04:28:06 +00:00
|
|
|
if (p != 0 && !ok) {
|
2017-07-29 17:40:07 +00:00
|
|
|
debug_safe(4, "handle_child_io failed in setup_child_process");
|
2012-11-19 00:30:30 +00:00
|
|
|
exit_without_destructors(1);
|
|
|
|
}
|
2012-11-18 10:23:22 +00:00
|
|
|
}
|
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
if (ok) {
|
|
|
|
// Set the handling for job control signals back to the default.
|
2012-11-19 00:30:30 +00:00
|
|
|
signal_reset_handlers();
|
|
|
|
}
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2012-11-19 00:30:30 +00:00
|
|
|
return ok ? 0 : -1;
|
2012-02-28 23:11:46 +00:00
|
|
|
}
|
|
|
|
|
2012-03-06 23:12:37 +00:00
|
|
|
int g_fork_count = 0;
|
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
/// This function is a wrapper around fork. If the fork calls fails with EAGAIN, it is retried
|
|
|
|
/// FORK_LAPS times, with a very slight delay between each lap. If fork fails even then, the process
|
|
|
|
/// will exit with an error message.
|
|
|
|
pid_t execute_fork(bool wait_for_threads_to_die) {
|
2012-02-28 23:11:46 +00:00
|
|
|
ASSERT_IS_MAIN_THREAD();
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
if (wait_for_threads_to_die || JOIN_THREADS_BEFORE_FORK) {
|
|
|
|
// Make sure we have no outstanding threads before we fork. This is a pretty sketchy thing
|
|
|
|
// to do here, both because exec.cpp shouldn't have to know about iothreads, and because the
|
|
|
|
// completion handlers may do unexpected things.
|
2017-07-29 17:40:07 +00:00
|
|
|
debug_safe(4, "waiting for threads to drain.");
|
2012-02-28 23:11:46 +00:00
|
|
|
iothread_drain_all();
|
|
|
|
}
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2012-11-19 00:30:30 +00:00
|
|
|
pid_t pid;
|
|
|
|
struct timespec pollint;
|
|
|
|
int i;
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2012-03-06 23:12:37 +00:00
|
|
|
g_fork_count++;
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
for (i = 0; i < FORK_LAPS; i++) {
|
2012-11-19 00:30:30 +00:00
|
|
|
pid = fork();
|
2016-05-03 04:28:06 +00:00
|
|
|
if (pid >= 0) {
|
2012-11-19 00:30:30 +00:00
|
|
|
return pid;
|
|
|
|
}
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
if (errno != EAGAIN) {
|
2012-11-19 00:30:30 +00:00
|
|
|
break;
|
|
|
|
}
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2012-11-19 00:30:30 +00:00
|
|
|
pollint.tv_sec = 0;
|
|
|
|
pollint.tv_nsec = FORK_SLEEP_TIME;
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
// Don't sleep on the final lap - sleeping might change the value of errno, which will break
|
|
|
|
// the error reporting below.
|
|
|
|
if (i != FORK_LAPS - 1) {
|
2012-11-19 00:30:30 +00:00
|
|
|
nanosleep(&pollint, NULL);
|
|
|
|
}
|
2012-11-18 10:23:22 +00:00
|
|
|
}
|
|
|
|
|
2012-11-19 00:30:30 +00:00
|
|
|
debug_safe(0, FORK_ERROR);
|
2013-01-10 01:06:20 +00:00
|
|
|
safe_perror("fork");
|
2012-11-19 00:30:30 +00:00
|
|
|
FATAL_EXIT();
|
2012-03-04 10:35:30 +00:00
|
|
|
return 0;
|
2012-02-28 23:11:46 +00:00
|
|
|
}
|
2012-08-15 07:57:56 +00:00
|
|
|
|
|
|
|
#if FISH_USE_POSIX_SPAWN
|
2016-05-03 04:28:06 +00:00
|
|
|
bool fork_actions_make_spawn_properties(posix_spawnattr_t *attr,
|
|
|
|
posix_spawn_file_actions_t *actions, job_t *j, process_t *p,
|
|
|
|
const io_chain_t &io_chain) {
|
2016-10-09 21:38:26 +00:00
|
|
|
UNUSED(p);
|
2016-05-03 04:28:06 +00:00
|
|
|
// Initialize the output.
|
|
|
|
if (posix_spawnattr_init(attr) != 0) {
|
2012-08-15 07:57:56 +00:00
|
|
|
return false;
|
|
|
|
}
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
if (posix_spawn_file_actions_init(actions) != 0) {
|
2012-08-15 07:57:56 +00:00
|
|
|
posix_spawnattr_destroy(attr);
|
|
|
|
return false;
|
|
|
|
}
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2017-04-23 10:58:01 +00:00
|
|
|
bool should_set_process_group_id = false;
|
|
|
|
int desired_process_group_id = 0;
|
2017-01-26 23:06:58 +00:00
|
|
|
if (j->get_flag(JOB_CONTROL)) {
|
2017-04-23 10:58:01 +00:00
|
|
|
should_set_process_group_id = true;
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2017-04-23 14:56:33 +00:00
|
|
|
// set_child_group puts each job into its own process group
|
|
|
|
// do the same here if there is no PGID yet (i.e. PGID == -2)
|
2017-04-23 10:58:01 +00:00
|
|
|
desired_process_group_id = j->pgid;
|
2017-05-02 04:44:30 +00:00
|
|
|
if (desired_process_group_id == -2) {
|
2017-04-23 14:56:33 +00:00
|
|
|
desired_process_group_id = 0;
|
|
|
|
}
|
2012-08-15 07:57:56 +00:00
|
|
|
}
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
// Set the handling for job control signals back to the default.
|
2012-11-19 00:30:30 +00:00
|
|
|
bool reset_signal_handlers = true;
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
// Remove all signal blocks.
|
2012-11-19 00:30:30 +00:00
|
|
|
bool reset_sigmask = true;
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
// Set our flags.
|
2012-08-15 07:57:56 +00:00
|
|
|
short flags = 0;
|
2016-05-03 04:28:06 +00:00
|
|
|
if (reset_signal_handlers) flags |= POSIX_SPAWN_SETSIGDEF;
|
|
|
|
if (reset_sigmask) flags |= POSIX_SPAWN_SETSIGMASK;
|
2017-04-23 10:58:01 +00:00
|
|
|
if (should_set_process_group_id) flags |= POSIX_SPAWN_SETPGROUP;
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2012-08-15 07:57:56 +00:00
|
|
|
int err = 0;
|
2016-05-03 04:28:06 +00:00
|
|
|
if (!err) err = posix_spawnattr_setflags(attr, flags);
|
2012-08-15 07:57:56 +00:00
|
|
|
|
2017-04-23 10:58:01 +00:00
|
|
|
if (!err && should_set_process_group_id)
|
|
|
|
err = posix_spawnattr_setpgroup(attr, desired_process_group_id);
|
2012-08-16 00:32:57 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
// Everybody gets default handlers.
|
|
|
|
if (!err && reset_signal_handlers) {
|
2012-08-15 07:57:56 +00:00
|
|
|
sigset_t sigdefault;
|
|
|
|
get_signals_with_handlers(&sigdefault);
|
|
|
|
err = posix_spawnattr_setsigdefault(attr, &sigdefault);
|
|
|
|
}
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
// No signals blocked.
|
2012-08-15 07:57:56 +00:00
|
|
|
sigset_t sigmask;
|
|
|
|
sigemptyset(&sigmask);
|
2016-05-03 04:28:06 +00:00
|
|
|
if (!err && reset_sigmask) err = posix_spawnattr_setsigmask(attr, &sigmask);
|
|
|
|
|
|
|
|
for (size_t idx = 0; idx < io_chain.size(); idx++) {
|
Big fat refactoring of how redirections work. In fish 1.x and 2.0.0, the redirections for a process were flattened into a big list associated with the job, so there was no way to tell which redirections applied to each process. Each process therefore got all the redirections associated with the job. See https://github.com/fish-shell/fish-shell/issues/877 for how this could manifest.
With this change, jobs only track their block-level redirections. Process level redirections are correctly associated with the process, and at exec time we stitch them together (block, pipe, and process redirects).
This fixes the weird issues where redirects bleed across pipelines (like #877), and also allows us to play with the order in which redirections are applied, since the final list is constructed right before it's needed. This lets us put pipes after block level redirections but before process level redirections, so that a 2>&1-type redirection gets picked up after the pipe, i.e. it should fix https://github.com/fish-shell/fish-shell/issues/110
This is a significant change. The tests all pass. Cross your fingers.
2013-08-19 23:16:41 +00:00
|
|
|
const shared_ptr<const io_data_t> io = io_chain.at(idx);
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
if (io->io_mode == IO_FD) {
|
2016-07-30 19:01:37 +00:00
|
|
|
const io_fd_t *io_fd = static_cast<const io_fd_t *>(io.get());
|
2016-05-03 04:28:06 +00:00
|
|
|
if (io->fd == io_fd->old_fd) continue;
|
2012-11-19 00:30:30 +00:00
|
|
|
}
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
switch (io->io_mode) {
|
|
|
|
case IO_CLOSE: {
|
|
|
|
if (!err) err = posix_spawn_file_actions_addclose(actions, io->fd);
|
2012-11-19 08:31:03 +00:00
|
|
|
break;
|
|
|
|
}
|
2012-11-19 00:30:30 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
case IO_FILE: {
|
2016-07-30 19:01:37 +00:00
|
|
|
const io_file_t *io_file = static_cast<const io_file_t *>(io.get());
|
2016-05-03 04:28:06 +00:00
|
|
|
if (!err)
|
|
|
|
err = posix_spawn_file_actions_addopen(actions, io->fd, io_file->filename_cstr,
|
|
|
|
io_file->flags /* mode */, OPEN_MASK);
|
2012-11-19 08:31:03 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
case IO_FD: {
|
2016-07-30 19:01:37 +00:00
|
|
|
const io_fd_t *io_fd = static_cast<const io_fd_t *>(io.get());
|
2016-05-03 04:28:06 +00:00
|
|
|
if (!err)
|
|
|
|
err = posix_spawn_file_actions_adddup2(actions, io_fd->old_fd /* from */,
|
|
|
|
io->fd /* to */);
|
2012-11-19 08:31:03 +00:00
|
|
|
break;
|
2012-08-15 07:57:56 +00:00
|
|
|
}
|
2012-11-19 08:31:03 +00:00
|
|
|
|
|
|
|
case IO_BUFFER:
|
2016-05-03 04:28:06 +00:00
|
|
|
case IO_PIPE: {
|
2016-07-30 19:01:37 +00:00
|
|
|
const io_pipe_t *io_pipe = static_cast<const io_pipe_t *>(io.get());
|
2013-01-16 03:55:57 +00:00
|
|
|
unsigned int write_pipe_idx = (io_pipe->is_input ? 0 : 1);
|
2013-01-15 09:31:36 +00:00
|
|
|
int from_fd = io_pipe->pipe_fd[write_pipe_idx];
|
2012-11-19 08:31:03 +00:00
|
|
|
int to_fd = io->fd;
|
2016-05-03 04:28:06 +00:00
|
|
|
if (!err) err = posix_spawn_file_actions_adddup2(actions, from_fd, to_fd);
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
if (write_pipe_idx > 0) {
|
|
|
|
if (!err) err = posix_spawn_file_actions_addclose(actions, io_pipe->pipe_fd[0]);
|
|
|
|
if (!err) err = posix_spawn_file_actions_addclose(actions, io_pipe->pipe_fd[1]);
|
|
|
|
} else {
|
|
|
|
if (!err) err = posix_spawn_file_actions_addclose(actions, io_pipe->pipe_fd[0]);
|
2012-11-19 08:31:03 +00:00
|
|
|
}
|
|
|
|
break;
|
2012-08-15 07:57:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
// Clean up on error.
|
|
|
|
if (err) {
|
2012-08-15 07:57:56 +00:00
|
|
|
posix_spawnattr_destroy(attr);
|
|
|
|
posix_spawn_file_actions_destroy(actions);
|
|
|
|
}
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
return !err;
|
2012-08-15 07:57:56 +00:00
|
|
|
}
|
2016-05-03 04:28:06 +00:00
|
|
|
#endif // FISH_USE_POSIX_SPAWN
|
2012-08-15 07:57:56 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
void safe_report_exec_error(int err, const char *actual_cmd, const char *const *argv,
|
|
|
|
const char *const *envv) {
|
2012-11-19 00:30:30 +00:00
|
|
|
debug_safe(0, "Failed to execute process '%s'. Reason:", actual_cmd);
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
switch (err) {
|
|
|
|
case E2BIG: {
|
2012-11-19 08:31:03 +00:00
|
|
|
char sz1[128], sz2[128];
|
2012-11-19 00:30:30 +00:00
|
|
|
|
2012-11-19 08:31:03 +00:00
|
|
|
long arg_max = -1;
|
2012-11-19 00:30:30 +00:00
|
|
|
|
2012-11-19 08:31:03 +00:00
|
|
|
size_t sz = 0;
|
2016-05-03 04:28:06 +00:00
|
|
|
const char *const *p;
|
|
|
|
for (p = argv; *p; p++) {
|
|
|
|
sz += strlen(*p) + 1;
|
2012-11-19 08:31:03 +00:00
|
|
|
}
|
2012-11-19 00:30:30 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
for (p = envv; *p; p++) {
|
|
|
|
sz += strlen(*p) + 1;
|
2012-11-19 08:31:03 +00:00
|
|
|
}
|
2012-11-19 00:30:30 +00:00
|
|
|
|
2012-11-19 08:31:03 +00:00
|
|
|
format_size_safe(sz1, sz);
|
|
|
|
arg_max = sysconf(_SC_ARG_MAX);
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
if (arg_max > 0) {
|
2015-08-08 17:35:17 +00:00
|
|
|
format_size_safe(sz2, static_cast<unsigned long long>(arg_max));
|
2016-05-03 04:28:06 +00:00
|
|
|
debug_safe(0,
|
|
|
|
"The total size of the argument and environment lists %s exceeds the "
|
|
|
|
"operating system limit of %s.",
|
|
|
|
sz1, sz2);
|
|
|
|
} else {
|
|
|
|
debug_safe(0,
|
|
|
|
"The total size of the argument and environment lists (%s) exceeds the "
|
|
|
|
"operating system limit.",
|
|
|
|
sz1);
|
2012-11-19 08:31:03 +00:00
|
|
|
}
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2012-11-19 08:31:03 +00:00
|
|
|
debug_safe(0, "Try running the command again with fewer arguments.");
|
|
|
|
break;
|
|
|
|
}
|
2012-08-15 07:57:56 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
case ENOEXEC: {
|
2013-01-10 01:06:20 +00:00
|
|
|
const char *err = safe_strerror(errno);
|
2012-11-19 08:31:03 +00:00
|
|
|
debug_safe(0, "exec: %s", err);
|
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
debug_safe(0,
|
|
|
|
"The file '%s' is marked as an executable but could not be run by the "
|
|
|
|
"operating system.",
|
|
|
|
actual_cmd);
|
2012-11-19 08:31:03 +00:00
|
|
|
break;
|
2012-11-19 00:30:30 +00:00
|
|
|
}
|
2012-11-19 08:31:03 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
case ENOENT: {
|
|
|
|
// ENOENT is returned by exec() when the path fails, but also returned by posix_spawn if
|
|
|
|
// an open file action fails. These cases appear to be impossible to distinguish. We
|
|
|
|
// address this by not using posix_spawn for file redirections, so all the ENOENTs we
|
|
|
|
// find must be errors from exec().
|
2012-11-19 08:31:03 +00:00
|
|
|
char interpreter_buff[128] = {}, *interpreter;
|
|
|
|
interpreter = get_interpreter(actual_cmd, interpreter_buff, sizeof interpreter_buff);
|
2016-05-03 04:28:06 +00:00
|
|
|
if (interpreter && 0 != access(interpreter, X_OK)) {
|
|
|
|
debug_safe(0,
|
|
|
|
"The file '%s' specified the interpreter '%s', which is not an "
|
|
|
|
"executable command.",
|
|
|
|
actual_cmd, interpreter);
|
|
|
|
} else {
|
2012-11-19 08:31:03 +00:00
|
|
|
debug_safe(0, "The file '%s' does not exist or could not be executed.", actual_cmd);
|
|
|
|
}
|
|
|
|
break;
|
2012-11-19 00:30:30 +00:00
|
|
|
}
|
2012-08-15 07:57:56 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
case ENOMEM: {
|
2012-11-19 08:31:03 +00:00
|
|
|
debug_safe(0, "Out of memory");
|
|
|
|
break;
|
|
|
|
}
|
2012-08-15 07:57:56 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
default: {
|
2013-01-10 01:06:20 +00:00
|
|
|
const char *err = safe_strerror(errno);
|
2012-11-19 08:31:03 +00:00
|
|
|
debug_safe(0, "exec: %s", err);
|
2012-11-18 10:23:22 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
// debug(0, L"The file '%ls' is marked as an executable but could not be run by the
|
|
|
|
// operating system.", p->actual_cmd);
|
2012-11-19 08:31:03 +00:00
|
|
|
break;
|
|
|
|
}
|
2012-11-18 10:23:22 +00:00
|
|
|
}
|
2012-08-15 07:57:56 +00:00
|
|
|
}
|
2013-01-11 23:09:33 +00:00
|
|
|
|
2016-05-03 04:28:06 +00:00
|
|
|
/// Perform output from builtins. May be called from a forked child, so don't do anything that may
|
|
|
|
/// allocate memory, etc.
|
|
|
|
bool do_builtin_io(const char *out, size_t outlen, const char *err, size_t errlen) {
|
2017-01-07 07:51:49 +00:00
|
|
|
int saved_errno = 0;
|
2013-01-11 23:09:33 +00:00
|
|
|
bool success = true;
|
2016-10-22 18:21:13 +00:00
|
|
|
if (out && outlen && write_loop(STDOUT_FILENO, out, outlen) < 0) {
|
2017-01-07 07:51:49 +00:00
|
|
|
saved_errno = errno;
|
|
|
|
if (errno != EPIPE) {
|
|
|
|
debug_safe(0, "Error while writing to stdout");
|
|
|
|
errno = saved_errno;
|
|
|
|
safe_perror("write_loop");
|
|
|
|
}
|
|
|
|
success = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (err && errlen && write_loop(STDERR_FILENO, err, errlen) < 0) {
|
|
|
|
saved_errno = errno;
|
2016-10-22 18:21:13 +00:00
|
|
|
success = false;
|
2013-01-11 23:09:33 +00:00
|
|
|
}
|
|
|
|
|
2017-01-07 07:51:49 +00:00
|
|
|
errno = saved_errno;
|
2013-01-11 23:09:33 +00:00
|
|
|
return success;
|
|
|
|
}
|