1 // Prototypes for utilities for keeping track of jobs, processes and subshells, as well as signal 2 // handling functions for tracking children. These functions do not themselves launch new processes, 3 // the exec library will call proc to create representations of the running jobs as needed. 4 #ifndef FISH_PROC_H 5 #define FISH_PROC_H 6 #include "config.h" // IWYU pragma: keep 7 8 #include <signal.h> 9 #include <stddef.h> 10 #include <sys/time.h> // IWYU pragma: keep 11 #include <sys/wait.h> // IWYU pragma: keep 12 #include <unistd.h> 13 14 #include <deque> 15 #include <memory> 16 #include <vector> 17 18 #include "common.h" 19 #include "event.h" 20 #include "global_safety.h" 21 #include "io.h" 22 #include "parse_tree.h" 23 #include "topic_monitor.h" 24 #include "wait_handle.h" 25 26 /// Types of processes. 27 enum class process_type_t { 28 /// A regular external command. 29 external, 30 /// A builtin command. 31 builtin, 32 /// A shellscript function. 33 function, 34 /// A block of commands, represented as a node. 35 block_node, 36 /// The exec builtin. 37 exec, 38 }; 39 40 enum class job_control_t { 41 all, 42 interactive, 43 none, 44 }; 45 46 namespace ast { 47 struct statement_t; 48 } 49 50 class job_group_t; 51 using job_group_ref_t = std::shared_ptr<job_group_t>; 52 53 /// A proc_status_t is a value type that encapsulates logic around exited vs stopped vs signaled, 54 /// etc. 55 class proc_status_t { 56 int status_{}; 57 58 /// If set, there is no actual status to report, e.g. background or variable assignment. 59 bool empty_{}; 60 proc_status_t(int status)61 explicit proc_status_t(int status) : status_(status), empty_(false) {} 62 proc_status_t(int status,bool empty)63 proc_status_t(int status, bool empty) : status_(status), empty_(empty) {} 64 65 /// Encode a return value \p ret and signal \p sig into a status value like waitpid() does. w_exitcode(int ret,int sig)66 static constexpr int w_exitcode(int ret, int sig) { 67 #ifdef W_EXITCODE 68 return W_EXITCODE(ret, sig); 69 #else 70 return ((ret) << 8 | (sig)); 71 #endif 72 } 73 74 public: 75 proc_status_t() = default; 76 77 /// Construct from a status returned from a waitpid call. from_waitpid(int status)78 static proc_status_t from_waitpid(int status) { return proc_status_t(status); } 79 80 /// Construct directly from an exit code. from_exit_code(int ret)81 static proc_status_t from_exit_code(int ret) { 82 // Some paranoia. 83 constexpr int zerocode = w_exitcode(0, 0); 84 static_assert(WIFEXITED(zerocode), "Synthetic exit status not reported as exited"); 85 86 assert(ret < 256); 87 return proc_status_t(w_exitcode(ret, 0 /* sig */)); 88 } 89 90 /// Construct directly from a signal. from_signal(int sig)91 static proc_status_t from_signal(int sig) { 92 return proc_status_t(w_exitcode(0 /* ret */, sig)); 93 } 94 95 /// Construct an empty status_t (e.g. `set foo bar`). empty()96 static proc_status_t empty() { 97 bool empty = true; 98 return proc_status_t(0, empty); 99 } 100 101 /// \return if we are stopped (as in SIGSTOP). stopped()102 bool stopped() const { return WIFSTOPPED(status_); } 103 104 /// \return if we are continued (as in SIGCONT). continued()105 bool continued() const { return WIFCONTINUED(status_); } 106 107 /// \return if we exited normally (not a signal). normal_exited()108 bool normal_exited() const { return WIFEXITED(status_); } 109 110 /// \return if we exited because of a signal. signal_exited()111 bool signal_exited() const { return WIFSIGNALED(status_); } 112 113 /// \return the signal code, given that we signal exited. signal_code()114 int signal_code() const { 115 assert(signal_exited() && "Process is not signal exited"); 116 return WTERMSIG(status_); 117 } 118 119 /// \return the exit code, given that we normal exited. exit_code()120 int exit_code() const { 121 assert(normal_exited() && "Process is not normal exited"); 122 return WEXITSTATUS(status_); 123 } 124 125 /// \return if this status represents success. is_success()126 bool is_success() const { return normal_exited() && exit_code() == EXIT_SUCCESS; } 127 128 /// \return if this status is empty. is_empty()129 bool is_empty() const { return empty_; } 130 131 /// \return the value appropriate to populate $status. status_value()132 int status_value() const { 133 if (signal_exited()) { 134 return 128 + signal_code(); 135 } else if (normal_exited()) { 136 return exit_code(); 137 } else { 138 DIE("Process is not exited"); 139 } 140 } 141 }; 142 143 /// A structure representing a "process" internal to fish. This is backed by a pthread instead of a 144 /// separate process. 145 class internal_proc_t { 146 /// An identifier for internal processes. 147 /// This is used for logging purposes only. 148 const uint64_t internal_proc_id_; 149 150 /// Whether the process has exited. 151 std::atomic<bool> exited_{}; 152 153 /// If the process has exited, its status code. 154 std::atomic<proc_status_t> status_{}; 155 156 public: 157 /// \return if this process has exited. exited()158 bool exited() const { return exited_.load(std::memory_order_acquire); } 159 160 /// Mark this process as exited, with the given status. 161 void mark_exited(proc_status_t status); 162 get_status()163 proc_status_t get_status() const { 164 assert(exited() && "Process is not exited"); 165 return status_.load(std::memory_order_relaxed); 166 } 167 get_id()168 uint64_t get_id() const { return internal_proc_id_; } 169 170 internal_proc_t(); 171 }; 172 173 /// 0 should not be used; although it is not a valid PGID in userspace, 174 /// the Linux kernel will use it for kernel processes. 175 /// -1 should not be used; it is a possible return value of the getpgid() 176 /// function 177 enum { INVALID_PID = -2 }; 178 179 /// A structure representing a single fish process. Contains variables for tracking process state 180 /// and the process argument list. Actually, a fish process can be either a regular external 181 /// process, an internal builtin which may or may not spawn a fake IO process during execution, a 182 /// shellscript function or a block of commands to be evaluated by calling eval. Lastly, this 183 /// process can be the result of an exec command. The role of this process_t is determined by the 184 /// type field, which can be one of process_type_t::external, process_type_t::builtin, 185 /// process_type_t::function, process_type_t::exec. 186 /// 187 /// The process_t contains information on how the process should be started, such as command name 188 /// and arguments, as well as runtime information on the status of the actual physical process which 189 /// represents it. Shellscript functions, builtins and blocks of code may all need to spawn an 190 /// external process that handles the piping and redirecting of IO for them. 191 /// 192 /// If the process is of type process_type_t::external or process_type_t::exec, argv is the argument 193 /// array and actual_cmd is the absolute path of the command to execute. 194 /// 195 /// If the process is of type process_type_t::builtin, argv is the argument vector, and argv[0] is 196 /// the name of the builtin command. 197 /// 198 /// If the process is of type process_type_t::function, argv is the argument vector, and argv[0] is 199 /// the name of the shellscript function. 200 class parser_t; 201 class process_t { 202 public: 203 process_t(); 204 205 /// Note whether we are the first and/or last in the job 206 bool is_first_in_job{false}; 207 bool is_last_in_job{false}; 208 209 /// Type of process. 210 process_type_t type{process_type_t::external}; 211 212 /// For internal block processes only, the node of the statement. 213 /// This is always either block, ifs, or switchs, never boolean or decorated. 214 parsed_source_ref_t block_node_source{}; 215 const ast::statement_t *internal_block_node{}; 216 217 struct concrete_assignment { 218 wcstring variable_name; 219 wcstring_list_t values; 220 }; 221 /// The expanded variable assignments for this process, as specified by the `a=b cmd` syntax. 222 std::vector<concrete_assignment> variable_assignments; 223 224 /// Sets argv. set_argv(wcstring_list_t argv)225 void set_argv(wcstring_list_t argv) { argv_ = std::move(argv); } 226 227 /// Returns argv. argv()228 const wcstring_list_t &argv() { return argv_; } 229 230 /// Returns argv[0], or nullptr. argv0()231 const wchar_t *argv0() const { return argv_.empty() ? nullptr : argv_.front().c_str(); } 232 233 /// Redirection list getter and setter. redirection_specs()234 const redirection_spec_list_t &redirection_specs() const { return proc_redirection_specs_; } 235 set_redirection_specs(redirection_spec_list_t specs)236 void set_redirection_specs(redirection_spec_list_t specs) { 237 this->proc_redirection_specs_ = std::move(specs); 238 } 239 240 /// Store the current topic generations. That is, right before the process is launched, record 241 /// the generations of all topics; then we can tell which generation values have changed after 242 /// launch. This helps us avoid spurious waitpid calls. 243 void check_generations_before_launch(); 244 245 /// Mark that this process was part of a pipeline which was aborted. 246 /// The process was never successfully launched; give it a status of EXIT_FAILURE. 247 void mark_aborted_before_launch(); 248 249 /// \return whether this process type is internal (block, function, or builtin). 250 bool is_internal() const; 251 252 /// \return the wait handle for the process, creating it if \p create is set. 253 /// This will return nullptr if the process does not have a pid (i.e. is not external). 254 wait_handle_ref_t get_wait_handle(bool create = true); 255 256 /// Actual command to pass to exec in case of process_type_t::external or process_type_t::exec. 257 wcstring actual_cmd; 258 259 /// Generation counts for reaping. 260 generation_list_t gens_{}; 261 262 /// Process ID 263 pid_t pid{0}; 264 265 /// If we are an "internal process," that process. 266 std::shared_ptr<internal_proc_t> internal_proc_{}; 267 268 /// File descriptor that pipe output should bind to. 269 int pipe_write_fd{0}; 270 271 /// True if process has completed. 272 bool completed{false}; 273 274 /// True if process has stopped. 275 bool stopped{false}; 276 277 /// Reported status value. 278 proc_status_t status{}; 279 280 /// Last time of cpu time check. 281 struct timeval last_time {}; 282 283 /// Number of jiffies spent in process at last cpu time check. 284 unsigned long last_jiffies{0}; 285 286 // No copying. 287 process_t(const process_t &rhs) = delete; 288 void operator=(const process_t &rhs) = delete; 289 290 private: 291 wcstring_list_t argv_; 292 redirection_spec_list_t proc_redirection_specs_; 293 294 // The wait handle. This is constructed lazily, and cached. 295 wait_handle_ref_t wait_handle_{}; 296 }; 297 298 using process_ptr_t = std::unique_ptr<process_t>; 299 using process_list_t = std::vector<process_ptr_t>; 300 301 /// A struct representing a job. A job is a pipeline of one or more processes. 302 class job_t { 303 public: 304 /// A set of jobs properties. These are immutable: they do not change for the lifetime of the 305 /// job. 306 struct properties_t { 307 /// Whether the specified job is a part of a subshell, event handler or some other form of 308 /// special job that should not be reported. 309 bool skip_notification{}; 310 311 /// Whether the job had the background ampersand when constructed, e.g. /bin/echo foo & 312 /// Note that a job may move between foreground and background; this just describes what the 313 /// initial state should be. 314 bool initial_background{}; 315 316 /// Whether the job has the 'time' prefix and so we should print timing for this job. 317 bool wants_timing{}; 318 319 /// Whether this job was created as part of an event handler. 320 bool from_event_handler{}; 321 322 /// Whether the job is under job control, i.e. has its own pgrp. 323 bool job_control{}; 324 }; 325 326 private: 327 /// Set of immutable job properties. 328 const properties_t properties; 329 330 /// The original command which led to the creation of this job. It is used for displaying 331 /// messages about job status on the terminal. 332 const wcstring command_str; 333 334 // No copying. 335 job_t(const job_t &rhs) = delete; 336 void operator=(const job_t &) = delete; 337 338 public: 339 job_t(const properties_t &props, wcstring command_str); 340 ~job_t(); 341 342 /// Returns the command as a wchar_t *. */ command_wcstr()343 const wchar_t *command_wcstr() const { return command_str.c_str(); } 344 345 /// Returns the command. command()346 const wcstring &command() const { return command_str; } 347 348 /// \return whether it is OK to reap a given process. Sometimes we want to defer reaping a 349 /// process if it is the group leader and the job is not yet constructed, because then we might 350 /// also reap the process group and then we cannot add new processes to the group. can_reap(const process_ptr_t & p)351 bool can_reap(const process_ptr_t &p) const { 352 if (p->completed) { 353 // Can't reap twice. 354 return false; 355 } else if (p->pid && !is_constructed() && this->get_pgid() == maybe_t<pid_t>{p->pid}) { 356 // p is the the group leader in an under-construction job. 357 return false; 358 } else { 359 return true; 360 } 361 } 362 363 /// Returns a truncated version of the job string. Used when a message has already been emitted 364 /// containing the full job string and job id, but using the job id alone would be confusing 365 /// due to reuse of freed job ids. Prevents overloading the debug comments with the full, 366 /// untruncated job string when we don't care what the job is, only which of the currently 367 /// running jobs it is. preview()368 wcstring preview() const { 369 if (processes.empty()) return L""; 370 // Note argv0 may be empty in e.g. a block process. 371 const wchar_t *argv0 = processes.front()->argv0(); 372 wcstring result = argv0 ? argv0 : L"null"; 373 return result + L" ..."; 374 } 375 376 /// All the processes in this job. 377 process_list_t processes; 378 379 // The group containing this job. 380 // This is never null and not changed after construction. 381 job_group_ref_t group{}; 382 383 /// \return the pgid for the job, based on the job group. 384 /// This may be none if the job consists of just internal fish functions or builtins. 385 /// This may also be fish itself. 386 maybe_t<pid_t> get_pgid() const; 387 388 /// \return the pid of the last external process in the job. 389 /// This may be none if the job consists of just internal fish functions or builtins. 390 /// This will never be fish's own pid. 391 maybe_t<pid_t> get_last_pid() const; 392 393 /// The id of this job. 394 /// This is user-visible, is recycled, and may be -1. 395 job_id_t job_id() const; 396 397 /// A non-user-visible, never-recycled job ID. 398 const internal_job_id_t internal_job_id; 399 400 /// Flags associated with the job. 401 struct flags_t { 402 /// Whether the specified job is completely constructed: every process in the job has been 403 /// forked, etc. 404 bool constructed{false}; 405 406 /// Whether the user has been told about stopped job. 407 bool notified{false}; 408 409 /// Whether the exit status should be negated. This flag can only be set by the not builtin. 410 bool negate{false}; 411 412 /// This job is disowned, and should be removed from the active jobs list. 413 bool disown_requested{false}; 414 415 // Indicates that we are the "group root." Any other jobs using this tree are nested. 416 bool is_group_root{false}; 417 418 } job_flags{}; 419 420 /// Access the job flags. flags()421 const flags_t &flags() const { return job_flags; } 422 423 /// Access mutable job flags. mut_flags()424 flags_t &mut_flags() { return job_flags; } 425 426 // \return whether we should print timing information. wants_timing()427 bool wants_timing() const { return properties.wants_timing; } 428 429 /// \return if we want job control. wants_job_control()430 bool wants_job_control() const { return properties.job_control; } 431 432 /// \return whether this job is initially going to run in the background, because & was 433 /// specified. is_initially_background()434 bool is_initially_background() const { return properties.initial_background; } 435 436 /// Mark this job as constructed. The job must not have previously been marked as constructed. 437 void mark_constructed(); 438 439 /// \return whether we have internal or external procs, respectively. 440 /// Internal procs are builtins, blocks, and functions. 441 /// External procs include exec and external. 442 bool has_internal_proc() const; 443 bool has_external_proc() const; 444 445 // Helper functions to check presence of flags on instances of jobs 446 /// The job has been fully constructed, i.e. all its member processes have been launched is_constructed()447 bool is_constructed() const { return flags().constructed; } 448 /// The job is complete, i.e. all its member processes have been reaped 449 bool is_completed() const; 450 /// The job is in a stopped state 451 bool is_stopped() const; 452 /// The job is OK to be externally visible, e.g. to the user via `jobs` is_visible()453 bool is_visible() const { 454 return !is_completed() && is_constructed() && !flags().disown_requested; 455 } skip_notification()456 bool skip_notification() const { return properties.skip_notification; } from_event_handler()457 bool from_event_handler() const { return properties.from_event_handler; } 458 459 /// \return whether this job's group is in the foreground. 460 bool is_foreground() const; 461 462 /// \return whether we should report process exit events. 463 /// This implements some historical behavior which has not been justified. 464 bool should_report_process_exits() const; 465 466 /// \return whether this job and its parent chain are fully constructed. 467 bool job_chain_is_fully_constructed() const; 468 469 /// Continues running a job, which may be stopped, or may just have started. 470 /// This will send SIGCONT if the job is stopped. 471 /// If \p in_foreground is set, then wait for the job to stop or complete; 472 /// otherwise do not wait for the job. 473 void continue_job(parser_t &parser, bool in_foreground = true); 474 475 /// Send the specified signal to all processes in this job. 476 /// \return true on success, false on failure. 477 bool signal(int signal); 478 479 /// \returns the statuses for this job. 480 maybe_t<statuses_t> get_statuses() const; 481 }; 482 483 /// Whether this shell is attached to a tty. 484 bool is_interactive_session(); 485 void set_interactive_session(bool flag); 486 487 /// Whether we are a login shell. 488 bool get_login(); 489 void mark_login(); 490 491 /// If this flag is set, fish will never fork or run execve. It is used to put fish into a syntax 492 /// verifier mode where fish tries to validate the syntax of a file but doesn't actually do 493 /// anything. 494 bool no_exec(); 495 void mark_no_exec(); 496 497 // List of jobs. 498 typedef std::deque<shared_ptr<job_t>> job_list_t; 499 500 /// The current job control mode. 501 /// 502 /// Must be one of job_control_t::all, job_control_t::interactive and job_control_t::none. 503 job_control_t get_job_control_mode(); 504 void set_job_control_mode(job_control_t mode); 505 506 /// Notify the user about stopped or terminated jobs, and delete completed jobs from the job list. 507 /// If \p interactive is set, allow removing interactive jobs; otherwise skip them. 508 /// \return whether text was printed to stdout. 509 class parser_t; 510 bool job_reap(parser_t &parser, bool interactive); 511 512 /// \return the list of background jobs which we should warn the user about, if the user attempts to 513 /// exit. An empty result (common) means no such jobs. 514 job_list_t jobs_requiring_warning_on_exit(const parser_t &parser); 515 516 /// Print the exit warning for the given jobs, which should have been obtained via 517 /// jobs_requiring_warning_on_exit(). 518 void print_exit_warning_for_jobs(const job_list_t &jobs); 519 520 /// Use the procfs filesystem to look up how many jiffies of cpu time was used by this process. This 521 /// function is only available on systems with the procfs file entry 'stat', i.e. Linux. 522 unsigned long proc_get_jiffies(process_t *p); 523 524 /// Update process time usage for all processes by calling the proc_get_jiffies function for every 525 /// process of every job. 526 void proc_update_jiffies(parser_t &parser); 527 528 /// Perform a set of simple sanity checks on the job list. This includes making sure that only one 529 /// job is in the foreground, that every process is in a valid state, etc. 530 void proc_sanity_check(const parser_t &parser); 531 532 /// Initializations. 533 void proc_init(); 534 535 /// Wait for any process finishing, or receipt of a signal. 536 void proc_wait_any(parser_t &parser); 537 538 /// Set and get whether we are in initialization. 539 // Hackish. In order to correctly report the origin of code with no associated file, we need to 540 // know whether it's run during initialization or not. 541 void set_is_within_fish_initialization(bool flag); 542 bool is_within_fish_initialization(); 543 544 /// Send SIGHUP to the list \p jobs, excepting those which are in fish's pgroup. 545 void hup_jobs(const job_list_t &jobs); 546 547 /// Give ownership of the terminal to the specified job group, if it wants it. 548 /// 549 /// \param jg The job group to give the terminal to. 550 /// \param continuing_from_stopped If this variable is set, we are giving back control to a job that 551 /// was previously stopped. In that case, we need to set the terminal attributes to those saved in 552 /// the job. 553 /// \return 1 if transferred, 0 if no transfer was necessary, -1 on error. 554 int terminal_maybe_give_to_job_group(const job_group_t *jg, bool continuing_from_stopped); 555 556 /// Add a job to the list of PIDs/PGIDs we wait on even though they are not associated with any 557 /// jobs. Used to avoid zombie processes after disown. 558 void add_disowned_job(const job_t *j); 559 560 bool have_proc_stat(); 561 562 #endif 563