Tree @HEAD (Download .tar.gz)
- ..
- widecharwidth
- ast.cpp
- ast.h
- ast_node_types.inc
- autoload.cpp
- autoload.h
- builtin.cpp
- builtin.h
- builtin_argparse.cpp
- builtin_argparse.h
- builtin_bg.cpp
- builtin_bg.h
- builtin_bind.cpp
- builtin_bind.h
- builtin_block.cpp
- builtin_block.h
- builtin_builtin.cpp
- builtin_builtin.h
- builtin_cd.cpp
- builtin_cd.h
- builtin_command.cpp
- builtin_command.h
- builtin_commandline.cpp
- builtin_commandline.h
- builtin_complete.cpp
- builtin_complete.h
- builtin_contains.cpp
- builtin_contains.h
- builtin_disown.cpp
- builtin_disown.h
- builtin_echo.cpp
- builtin_echo.h
- builtin_emit.cpp
- builtin_emit.h
- builtin_eval.cpp
- builtin_eval.h
- builtin_exit.cpp
- builtin_exit.h
- builtin_fg.cpp
- builtin_fg.h
- builtin_function.cpp
- builtin_function.h
- builtin_functions.cpp
- builtin_functions.h
- builtin_history.cpp
- builtin_history.h
- builtin_jobs.cpp
- builtin_jobs.h
- builtin_math.cpp
- builtin_math.h
- builtin_printf.cpp
- builtin_printf.h
- builtin_pwd.cpp
- builtin_pwd.h
- builtin_random.cpp
- builtin_random.h
- builtin_read.cpp
- builtin_read.h
- builtin_realpath.cpp
- builtin_realpath.h
- builtin_return.cpp
- builtin_return.h
- builtin_set.cpp
- builtin_set.h
- builtin_set_color.cpp
- builtin_set_color.h
- builtin_source.cpp
- builtin_source.h
- builtin_status.cpp
- builtin_status.h
- builtin_string.cpp
- builtin_string.h
- builtin_test.cpp
- builtin_test.h
- builtin_type.cpp
- builtin_type.h
- builtin_ulimit.cpp
- builtin_ulimit.h
- builtin_wait.cpp
- builtin_wait.h
- color.cpp
- color.h
- common.cpp
- common.h
- complete.cpp
- complete.h
- enum_set.h
- env.cpp
- env.h
- env_dispatch.cpp
- env_dispatch.h
- env_universal_common.cpp
- env_universal_common.h
- event.cpp
- event.h
- exec.cpp
- exec.h
- expand.cpp
- expand.h
- fallback.cpp
- fallback.h
- fd_monitor.cpp
- fd_monitor.h
- fds.cpp
- fds.h
- fish.cpp
- fish_indent.cpp
- fish_key_reader.cpp
- fish_test_helper.cpp
- fish_tests.cpp
- fish_version.cpp
- fish_version.h
- flog.cpp
- flog.h
- function.cpp
- function.h
- future_feature_flags.cpp
- future_feature_flags.h
- global_safety.h
- highlight.cpp
- highlight.h
- history.cpp
- history.h
- history_file.cpp
- history_file.h
- input.cpp
- input.h
- input_common.cpp
- input_common.h
- intern.cpp
- intern.h
- io.cpp
- io.h
- iothread.cpp
- iothread.h
- job_group.cpp
- job_group.h
- kill.cpp
- kill.h
- lru.h
- maybe.h
- null_terminated_array.cpp
- null_terminated_array.h
- operation_context.cpp
- operation_context.h
- output.cpp
- output.h
- pager.cpp
- pager.h
- parse_constants.h
- parse_execution.cpp
- parse_execution.h
- parse_tree.cpp
- parse_tree.h
- parse_util.cpp
- parse_util.h
- parser.cpp
- parser.h
- parser_keywords.cpp
- parser_keywords.h
- path.cpp
- path.h
- postfork.cpp
- postfork.h
- print_help.cpp
- print_help.h
- proc.cpp
- proc.h
- reader.cpp
- reader.h
- redirection.cpp
- redirection.h
- sanity.cpp
- sanity.h
- screen.cpp
- screen.h
- signal.cpp
- signal.h
- termsize.cpp
- termsize.h
- timer.cpp
- timer.h
- tinyexpr.cpp
- tinyexpr.h
- tokenizer.cpp
- tokenizer.h
- topic_monitor.cpp
- topic_monitor.h
- trace.cpp
- trace.h
- utf8.cpp
- utf8.h
- util.cpp
- util.h
- wcstringutil.cpp
- wcstringutil.h
- wgetopt.cpp
- wgetopt.h
- wildcard.cpp
- wildcard.h
- wutil.cpp
- wutil.h
builtin_fg.cpp @HEAD — raw · history · blame
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | // Implementation of the fg builtin. #include "config.h" // IWYU pragma: keep #include "builtin_fg.h" #include <cerrno> #include <cstdio> #include <cstdlib> #include <cwchar> #include "builtin.h" #include "common.h" #include "env.h" #include "fallback.h" // IWYU pragma: keep #include "io.h" #include "job_group.h" #include "parser.h" #include "proc.h" #include "reader.h" #include "tokenizer.h" #include "wutil.h" // IWYU pragma: keep /// Builtin for putting a job in the foreground. maybe_t<int> builtin_fg(parser_t &parser, io_streams_t &streams, wchar_t **argv) { const wchar_t *cmd = argv[0]; int argc = builtin_count_args(argv); help_only_cmd_opts_t opts; int optind; int retval = parse_help_only_cmd_opts(opts, &optind, argc, argv, parser, streams); if (retval != STATUS_CMD_OK) return retval; if (opts.print_help) { builtin_print_help(parser, streams, cmd); return STATUS_CMD_OK; } job_t *job = nullptr; if (optind == argc) { // Select last constructed job (i.e. first job in the job queue) that can be brought // to the foreground. for (const auto &j : parser.jobs()) { if (j->is_constructed() && (!j->is_completed()) && ((j->is_stopped() || (!j->is_foreground())) && j->wants_job_control())) { job = j.get(); break; } } if (!job) { streams.err.append_format(_(L"%ls: There are no suitable jobs\n"), cmd); } } else if (optind + 1 < argc) { // Specifying more than one job to put to the foreground is a syntax error, we still // try to locate the job $argv[1], since we need to determine which error message to // emit (ambigous job specification vs malformed job id). bool found_job = false; int pid = fish_wcstoi(argv[optind]); if (errno == 0 && pid > 0) { found_job = (parser.job_get_from_pid(pid) != nullptr); } if (found_job) { streams.err.append_format(_(L"%ls: Ambiguous job\n"), cmd); } else { streams.err.append_format(_(L"%ls: '%ls' is not a job\n"), cmd, argv[optind]); } job = nullptr; builtin_print_error_trailer(parser, streams.err, cmd); } else { int pid = abs(fish_wcstoi(argv[optind])); if (errno) { streams.err.append_format(BUILTIN_ERR_NOT_NUMBER, cmd, argv[optind]); builtin_print_error_trailer(parser, streams.err, cmd); } else { job = parser.job_get_from_pid(pid); if (!job || !job->is_constructed() || job->is_completed()) { streams.err.append_format(_(L"%ls: No suitable job: %d\n"), cmd, pid); job = nullptr; } else if (!job->wants_job_control()) { streams.err.append_format(_(L"%ls: Can't put job %d, '%ls' to foreground because " L"it is not under job control\n"), cmd, pid, job->command_wcstr()); job = nullptr; } } } if (!job) { return STATUS_INVALID_ARGS; } if (streams.err_is_redirected) { streams.err.append_format(FG_MSG, job->job_id(), job->command_wcstr()); } else { // If we aren't redirecting, send output to real stderr, since stuff in sb_err won't get // printed until the command finishes. std::fwprintf(stderr, FG_MSG, job->job_id(), job->command_wcstr()); } wcstring ft = tok_command(job->command()); // For compatibility with fish 2.0's $_, now replaced with `status current-command` if (!ft.empty()) parser.set_var_and_fire(L"_", ENV_EXPORT, std::move(ft)); reader_write_title(job->command(), parser); parser.job_promote(job); job->group->set_is_foreground(true); job->continue_job(parser); return STATUS_CMD_OK; } |