2016-05-03 12:28:06 +08:00
|
|
|
// Functions that we may safely call after fork(), of which there are very few. In particular we
|
|
|
|
// cannot allocate memory, since we're insane enough to call fork from a multithreaded process.
|
2012-02-28 11:20:27 +08:00
|
|
|
#ifndef FISH_POSTFORK_H
|
|
|
|
#define FISH_POSTFORK_H
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
2021-07-01 10:23:57 +08:00
|
|
|
#ifdef HAVE_SPAWN_H
|
2012-08-15 15:57:56 +08:00
|
|
|
#include <spawn.h>
|
|
|
|
#endif
|
|
|
|
#ifndef FISH_USE_POSIX_SPAWN
|
2012-11-19 08:30:30 +08:00
|
|
|
#define FISH_USE_POSIX_SPAWN HAVE_SPAWN_H
|
2012-08-15 15:57:56 +08:00
|
|
|
#endif
|
|
|
|
|
2022-08-21 14:14:48 +08:00
|
|
|
#include "common.h"
|
|
|
|
#include "maybe.h"
|
|
|
|
|
2019-01-29 06:35:56 +08:00
|
|
|
class dup2_list_t;
|
2016-04-21 14:00:54 +08:00
|
|
|
class job_t;
|
|
|
|
class process_t;
|
2012-08-15 15:57:56 +08:00
|
|
|
|
2020-07-01 06:29:06 +08:00
|
|
|
/// Tell the proc \p pid to join process group \p pgroup.
|
2020-05-30 05:51:48 +08:00
|
|
|
/// If \p is_child is true, we are the child process; otherwise we are fish.
|
|
|
|
/// Called by both parent and child; this is an unavoidable race inherent to Unix.
|
|
|
|
/// If is_parent is set, then we are the parent process and should swallow EACCESS.
|
|
|
|
/// \return 0 on success, an errno error code on failure.
|
2020-07-01 06:29:06 +08:00
|
|
|
int execute_setpgid(pid_t pid, pid_t pgroup, bool is_parent);
|
2020-05-30 05:51:48 +08:00
|
|
|
|
|
|
|
/// Report the error code \p err for a failed setpgid call.
|
|
|
|
/// Note not all errors should be reported; in particular EACCESS is expected and benign in the
|
|
|
|
/// parent only.
|
2020-11-21 04:22:42 +08:00
|
|
|
void report_setpgid_error(int err, bool is_parent, pid_t desired_pgid, const job_t *j,
|
|
|
|
const process_t *p);
|
2012-03-01 03:27:14 +08:00
|
|
|
|
2016-05-03 12:28:06 +08:00
|
|
|
/// Initialize a new child process. This should be called right away after forking in the child
|
2022-02-14 05:12:18 +08:00
|
|
|
/// process. This resets signal handlers and applies IO redirections.
|
2016-05-03 12:28:06 +08:00
|
|
|
///
|
2022-02-14 05:12:18 +08:00
|
|
|
/// If \p claim_tty_from is >= 0 and owns the tty, use tcsetpgrp() to claim it.
|
2019-07-02 01:57:09 +08:00
|
|
|
///
|
2022-02-14 05:12:18 +08:00
|
|
|
/// \return 0 on success, -1 on failure, in which case an error will be printed.
|
|
|
|
int child_setup_process(pid_t claim_tty_from, const job_t &job, bool is_forked,
|
2020-04-22 01:24:33 +08:00
|
|
|
const dup2_list_t &dup2s);
|
2012-02-28 11:20:27 +08:00
|
|
|
|
2019-11-24 04:36:44 +08:00
|
|
|
/// Call fork(), retrying on failure a few times.
|
|
|
|
pid_t execute_fork();
|
2012-02-29 07:11:46 +08:00
|
|
|
|
2016-05-03 12:28:06 +08:00
|
|
|
/// Report an error from failing to exec or posix_spawn a command.
|
|
|
|
void safe_report_exec_error(int err, const char *actual_cmd, const char *const *argv,
|
|
|
|
const char *const *envv);
|
2012-08-15 15:57:56 +08:00
|
|
|
|
2021-07-01 10:23:57 +08:00
|
|
|
#if FISH_USE_POSIX_SPAWN
|
2020-06-10 05:56:03 +08:00
|
|
|
/// A RAII type which wraps up posix_spawn's data structures.
|
2021-09-22 09:26:44 +08:00
|
|
|
class posix_spawner_t : noncopyable_t, nonmovable_t {
|
2020-06-10 05:56:03 +08:00
|
|
|
public:
|
|
|
|
/// Attempt to construct from a job and dup2 list.
|
|
|
|
/// The caller must check the error function, as this may fail.
|
|
|
|
posix_spawner_t(const job_t *j, const dup2_list_t &dup2s);
|
|
|
|
|
|
|
|
/// \return the last error code, or 0 if there is no error.
|
|
|
|
int get_error() const { return error_; }
|
|
|
|
|
|
|
|
/// If this spawner does not have an error, invoke posix_spawn. Parameters are the same as
|
|
|
|
/// posix_spawn.
|
|
|
|
/// \return the pid, or none() on failure, in which case our error will be set.
|
|
|
|
maybe_t<pid_t> spawn(const char *cmd, char *const argv[], char *const envp[]);
|
|
|
|
|
|
|
|
~posix_spawner_t();
|
|
|
|
|
|
|
|
private:
|
|
|
|
bool check_fail(int err);
|
|
|
|
posix_spawnattr_t *attr() { return &*attr_; }
|
|
|
|
posix_spawn_file_actions_t *actions() { return &*actions_; }
|
|
|
|
|
|
|
|
posix_spawner_t();
|
|
|
|
int error_{0};
|
|
|
|
maybe_t<posix_spawnattr_t> attr_{};
|
|
|
|
maybe_t<posix_spawn_file_actions_t> actions_{};
|
|
|
|
};
|
|
|
|
|
2012-08-15 15:57:56 +08:00
|
|
|
#endif
|
|
|
|
|
2012-02-28 11:20:27 +08:00
|
|
|
#endif
|