From patchwork Tue Nov 1 19:20:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Francis Laniel X-Patchwork-Id: 1697887 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=amarulasolutions.com header.i=@amarulasolutions.com header.a=rsa-sha256 header.s=google header.b=T0CeshmF; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4N20LS1pdnz23l6 for ; Wed, 2 Nov 2022 06:23:44 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 50CBF85047; Tue, 1 Nov 2022 20:22:36 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=amarulasolutions.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=amarulasolutions.com header.i=@amarulasolutions.com header.b="T0CeshmF"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id EF9E384F49; Tue, 1 Nov 2022 20:22:02 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-wr1-x42b.google.com (mail-wr1-x42b.google.com [IPv6:2a00:1450:4864:20::42b]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 66CDF850A1 for ; Tue, 1 Nov 2022 20:21:37 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=amarulasolutions.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=francis.laniel@amarulasolutions.com Received: by mail-wr1-x42b.google.com with SMTP id j15so21503236wrq.3 for ; Tue, 01 Nov 2022 12:21:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amarulasolutions.com; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=rCsBXf9FcmPcM3ordF5cW+NAUmmDz3xG1BHI8oTHyM0=; b=T0CeshmFpCUqh/VRm3JaHYftPy5ox989pEIh7lVwm5bC02JTcWPgchXu1gXpwThO5/ rCjJ5g82nhxpCOaXtr40ixMSCSCNLK4MyMyXbgRHGs+p4671ekZRSX/W9kZ5R1xkjyYO Ke5uHai656pQeCbu7y9/LBM4CHLf7M7pOGNEc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=rCsBXf9FcmPcM3ordF5cW+NAUmmDz3xG1BHI8oTHyM0=; b=Wg9Br/NNP/kjJQgnyVQEtjRkUyMprKnUve5e3CD2jUJI5W/GNq/mP5rQYpTMFEWCeU QFdf5dIyxffY9G7ITfvtEmiqNcnwKSR/rqLIwZ2i1epF5hoE2K4DdRQcxhIiFtHDFjca DkKkvlr8/Dh+F4ERQDJ9N8yzwip6kEcB0VszdEmTyStDcJHjqIC2YiEFWUhwQitIMQDM +SMBmg6bPumSYiGm0hMxDIoYtlyorEoJv/3yjWiZGc1JdJC663tZb6VkhxsYESvJew63 QZCemii7r0ulaqEXn3iiw1E2+m2Y3i4AI7OSiskOAoTIstkM/4xPO+rM7BWO3d+prQDj dEmA== X-Gm-Message-State: ACrzQf1NMk1QJEk3rkBwRXmwHEq00wKPrlvhA82VQWiA4eFqqcZzMrzj mPy3E+UPCLDEWshbWV1OcVTz7oxUYEMJKA== X-Google-Smtp-Source: AMsMyM7/5+NIpeZGOhW8sqDPTlgp37YbcdtZG88U65Whvcis/NOAGbTaHTwayqjnTAVQpsuSusAPoA== X-Received: by 2002:a5d:6a90:0:b0:236:4835:ca94 with SMTP id s16-20020a5d6a90000000b002364835ca94mr12488888wru.187.1667330497049; Tue, 01 Nov 2022 12:21:37 -0700 (PDT) Received: from pwmachine.numericable.fr (85-170-25-210.rev.numericable.fr. [85.170.25.210]) by smtp.gmail.com with ESMTPSA id h17-20020a5d6e11000000b002356c051b9csm10755732wrz.66.2022.11.01.12.21.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Nov 2022 12:21:36 -0700 (PDT) From: Francis Laniel To: u-boot@lists.denx.de Cc: Michael Nazzareno Trimarchi , Tom Rini , Aleksandar Gerasimovski , Holger Brunck , Francis Laniel , Simon Glass , Harald Seiler Subject: [RFC PATCH v5 23/24] cli: hush_2021: Add upstream commits up to 24th March 2022. Date: Tue, 1 Nov 2022 20:20:28 +0100 Message-Id: <20221101192029.10231-24-francis.laniel@amarulasolutions.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221101192029.10231-1-francis.laniel@amarulasolutions.com> References: <20221101192029.10231-1-francis.laniel@amarulasolutions.com> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.6 at phobos.denx.de X-Virus-Status: Clean This commit adds the following hush busybox upstream commits: 7d1c7d833785 ("ash,hush: use HOME for tab completion and prompts") 21afddefd258 ("hush: fix "error: invalid preprocessing directive ##"") e53c7dbafc78 ("hush: fix set -n to act immediately, not just after run_list() ") 574b9c446da1 ("hush: fix var_LINENO3.tests failure") 49bcf9f40cff ("hush: speed up ${x//\*/|} too") 53b2fdcdba4c ("*: add NOINLINEs where code noticeably shrinks") 7c3e96d4b3d4 ("shell: use more compact SHELL_ASH / HUSH config defines. no code changes") 62f1eed1e191 ("hush: in a comment, document what -i might be doing") aaf3d5ba74c5 ("shell: tweak --help") db5546ca1018 ("libbb: code shrink: introduce and use [_]exit_SUCCESS()") 931c55f9e2b4 ("libbb: invert the meaning of SETUP_ENV_NO_CHDIR -> SETUP_ENV_CHDIR") 12566e7f9b5e ("ash,hush: fix handling of SIGINT while waiting for interactive input") 987be932ed3c ("*: slap on a few ALIGN_PTR where appropriate") Signed-off-by: Francis Laniel --- common/cli_hush_2021.c | 2 +- common/cli_hush_upstream.c | 162 +++++++++++++++++++++++++++---------- 2 files changed, 120 insertions(+), 44 deletions(-) diff --git a/common/cli_hush_2021.c b/common/cli_hush_2021.c index 4fc712d5b2..8afa7272fc 100644 --- a/common/cli_hush_2021.c +++ b/common/cli_hush_2021.c @@ -26,7 +26,7 @@ /* * BusyBox Version: UPDATE THIS WHEN PULLING NEW UPSTREAM REVISION! */ -#define BB_VER "1.34.0.git37460f5daff9" +#define BB_VER "1.35.0.git7d1c7d833785" /* * Define hush features by the names used upstream. diff --git a/common/cli_hush_upstream.c b/common/cli_hush_upstream.c index f75cc877ce..de037e28bd 100644 --- a/common/cli_hush_upstream.c +++ b/common/cli_hush_upstream.c @@ -339,7 +339,7 @@ * therefore we don't show them either. */ //usage:#define hush_trivial_usage -//usage: "[-enxl] [-c 'SCRIPT' [ARG0 ARGS] | FILE [ARGS] | -s [ARGS]]" +//usage: "[-enxl] [-c 'SCRIPT' [ARG0 ARGS] | FILE ARGS | -s ARGS]" //usage:#define hush_full_usage "\n\n" //usage: "Unix shell interpreter" @@ -374,7 +374,7 @@ # define F_DUPFD_CLOEXEC F_DUPFD #endif -#if ENABLE_FEATURE_SH_EMBEDDED_SCRIPTS && !(ENABLE_ASH || ENABLE_SH_IS_ASH || ENABLE_BASH_IS_ASH) +#if ENABLE_FEATURE_SH_EMBEDDED_SCRIPTS && !ENABLE_SHELL_ASH # include "embedded_scripts.h" #else # define NUM_SCRIPTS 0 @@ -574,7 +574,7 @@ enum { #define NULL_O_STRING { NULL } #ifndef debug_printf_parse -static const char *const assignment_flag[] = { +static const char *const assignment_flag[] ALIGN_PTR = { "MAYBE_ASSIGNMENT", "DEFINITELY_ASSIGNMENT", "NOT_ASSIGNMENT", @@ -958,6 +958,7 @@ struct globals { #if ENABLE_HUSH_INTERACTIVE smallint promptmode; /* 0: PS1, 1: PS2 */ #endif + /* set by signal handler if SIGINT is received _and_ its trap is not set */ smallint flag_SIGINT; #ifndef __U_BOOT__ #if ENABLE_HUSH_LOOPS @@ -2034,6 +2035,9 @@ enum { static void record_pending_signo(int sig) { sigaddset(&G.pending_set, sig); +#if ENABLE_FEATURE_EDITING + bb_got_signal = sig; /* for read_line_input: "we got a signal" */ +#endif #if ENABLE_HUSH_FAST if (sig == SIGCHLD) { G.count_SIGCHLD++; @@ -2795,30 +2799,53 @@ static void get_user_input(struct in_str *i) for (;;) { reinit_unicode_for_hush(); G.flag_SIGINT = 0; - /* buglet: SIGINT will not make new prompt to appear _at once_, - * only after . (^C works immediately) */ - r = read_line_input(G.line_input_state, prompt_str, + + bb_got_signal = 0; + if (!sigisemptyset(&G.pending_set)) { + /* Whoops, already got a signal, do not call read_line_input */ + bb_got_signal = r = -1; + } else { + /* For shell, LI_INTERRUPTIBLE is set: + * read_line_input will abort on either + * getting EINTR in poll(), or if it sees bb_got_signal != 0 + * (IOW: if signal arrives before poll() is reached). + * Interactive testcases: + * (while kill -INT $$; do sleep 1; done) & + * #^^^ prints ^C, prints prompt, repeats + * trap 'echo I' int; (while kill -INT $$; do sleep 1; done) & + * #^^^ prints ^C, prints "I", prints prompt, repeats + * trap 'echo T' term; (while kill $$; do sleep 1; done) & + * #^^^ prints "T", prints prompt, repeats + * #(bash 5.0.17 exits after first "T", looks like a bug) + */ + r = read_line_input(G.line_input_state, prompt_str, G.user_input_buf, CONFIG_FEATURE_EDITING_MAX_LEN-1 - ); - /* read_line_input intercepts ^C, "convert" it to SIGINT */ - if (r == 0) { - raise(SIGINT); + ); + /* read_line_input intercepts ^C, "convert" it to SIGINT */ + if (r == 0) + raise(SIGINT); + } + /* bash prints ^C (before running a trap, if any) + * both on keyboard ^C and on real SIGINT (non-kbd generated). + */ + if (sigismember(&G.pending_set, SIGINT)) { + write(STDOUT_FILENO, "^C\n", 3); + G.last_exitcode = 128 | SIGINT; } check_and_run_traps(); - if (r != 0 && !G.flag_SIGINT) + if (r == 0) /* keyboard ^C? */ + continue; /* go back, read another input line */ + if (r > 0) /* normal input? (no ^C, no ^D, no signals) */ break; - /* ^C or SIGINT: repeat */ - /* bash prints ^C even on real SIGINT (non-kbd generated) */ - write(STDOUT_FILENO, "^C\n", 3); - G.last_exitcode = 128 | SIGINT; - } - if (r < 0) { - /* EOF/error detected */ - /* ^D on interactive input goes to next line before exiting: */ - write(STDOUT_FILENO, "\n", 1); - i->p = NULL; - i->peek_buf[0] = r = EOF; - return r; + if (!bb_got_signal) { + /* r < 0: ^D/EOF/error detected (but not signal) */ + /* ^D on interactive input goes to next line before exiting: */ + write(STDOUT_FILENO, "\n", 1); + i->p = NULL; + i->peek_buf[0] = r = EOF; + return r; + } + /* it was a signal: go back, read another input line */ } i->p = G.user_input_buf; return (unsigned char)*i->p++; @@ -2998,6 +3025,12 @@ static int i_getch(struct in_str *i) if (ch != '\0') { i->p++; i->last_char = ch; +#if ENABLE_HUSH_LINENO_VAR + if (ch == '\n') { + G.parse_lineno++; + debug_printf_parse("G.parse_lineno++ = %u\n", G.parse_lineno); + } +#endif return ch; } return EOF; @@ -3645,7 +3678,7 @@ static int glob_brace(char *pattern, o_string *o, int n) * NEXT points past the terminator of the first element, and REST * points past the final }. We will accumulate result names from * recursive runs for each brace alternative in the buffer using - * GLOB_APPEND. */ + * GLOB_APPEND. */ p = begin + 1; while (1) { @@ -3961,7 +3994,7 @@ static void free_pipe_list(struct pipe *pi) #ifndef debug_print_tree static void debug_print_tree(struct pipe *pi, int lvl) { - static const char *const PIPE[] = { + static const char *const PIPE[] ALIGN_PTR = { [PIPE_SEQ] = "SEQ", [PIPE_AND] = "AND", [PIPE_OR ] = "OR" , @@ -3996,7 +4029,7 @@ static void debug_print_tree(struct pipe *pi, int lvl) [RES_XXXX ] = "XXXX" , [RES_SNTX ] = "SNTX" , }; - static const char *const CMDTYPE[] = { + static const char *const CMDTYPE[] ALIGN_PTR = { "{}", "()", "[noglob]", @@ -5361,7 +5394,7 @@ static int parse_dollar_squote(o_string *as_string, o_string *dest, struct in_st # undef as_string } #else -# #define parse_dollar_squote(as_string, dest, input) 0 +# define parse_dollar_squote(as_string, dest, input) 0 #endif /* BASH_DOLLAR_SQUOTE */ #endif /* !__U_BOOT__ */ @@ -6733,7 +6766,7 @@ static char *encode_then_expand_vararg(const char *str, int handle_squotes, int /* Expanding ARG in ${var+ARG}, ${var-ARG} */ -static int encode_then_append_var_plusminus(o_string *output, int n, +static NOINLINE int encode_then_append_var_plusminus(o_string *output, int n, char *str, int dquoted) { struct in_str input; @@ -6898,16 +6931,21 @@ static arith_t expand_and_evaluate_arith(const char *arg, const char **errmsg_p) /* ${var/[/]pattern[/repl]} helpers */ static char *strstr_pattern(char *val, const char *pattern, int *size) { - int sz = strcspn(pattern, "*?[\\"); - if (pattern[sz] == '\0') { + int first_escaped = (pattern[0] == '\\' && pattern[1]); + /* "first_escaped" trick allows to treat e.g. "\*no_glob_chars" + * as literal too (as it is semi-common, and easy to accomodate + * by just using str + 1). + */ + int sz = strcspn(pattern + first_escaped * 2, "*?[\\"); + if ((pattern + first_escaped * 2)[sz] == '\0') { /* Optimization for trivial patterns. * Testcase for very slow replace (performs about 22k replaces): * x=:::::::::::::::::::::: * x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;echo ${#x} * echo "${x//:/|}" */ - *size = sz; - return strstr(val, pattern); + *size = sz + first_escaped; + return strstr(val, pattern + first_escaped); } while (1) { @@ -8028,7 +8066,11 @@ static int parse_and_run_string(const char *s) #endif /* __U_BOOT__ */ { struct in_str input; +#ifndef __U_BOOT__ + IF_HUSH_LINENO_VAR(unsigned sv = G.parse_lineno;) +#else /* __U_BOOT__ */ //IF_HUSH_LINENO_VAR(unsigned sv = G.parse_lineno;) +#endif /* __U_BOOT__ */ setup_string_in_str(&input, s); #ifndef __U_BOOT__ @@ -8036,7 +8078,11 @@ static int parse_and_run_string(const char *s) #else /* __U_BOOT__ */ return parse_and_run_stream(&input, '\0'); #endif /* __U_BOOT__ */ - //IF_HUSH_LINENO_VAR(G.parse_lineno = sv;) +#ifndef __U_BOOT__ + IF_HUSH_LINENO_VAR(unsigned sv = G.parse_lineno;) +#else /* __U_BOOT__ */ + //IF_HUSH_LINENO_VAR(unsigned sv = G.parse_lineno;) +#endif /* __U_BOOT__ */ } #ifdef __U_BOOT__ @@ -8144,7 +8190,7 @@ static int generate_stream_from_string(const char *s, pid_t *pid_p) if (is_prefixed_with(s, "trap") && skip_whitespace(s + 4)[0] == '\0' ) { - static const char *const argv[] = { NULL, NULL }; + static const char *const argv[] ALIGN_PTR = { NULL, NULL }; builtin_trap((char**)argv); fflush_all(); /* important */ _exit(0); @@ -8673,7 +8719,7 @@ static const struct built_in_command *find_builtin(const char *name) return find_builtin_helper(name, bltins2, &bltins2[ARRAY_SIZE(bltins2)]); } -#if ENABLE_HUSH_JOB && EDITING_HAS_get_exe_name +#if ENABLE_HUSH_JOB && ENABLE_FEATURE_EDITING static const char * FAST_FUNC get_builtin_name(int i) { if (/*i >= 0 && */ i < ARRAY_SIZE(bltins1)) { @@ -9109,7 +9155,7 @@ static NOINLINE void pseudo_exec_argv(nommu_save_t *nommu_save, * expand_assignments(): think about ... | var=`sleep 1` | ... */ free_strings(new_env); - _exit(EXIT_SUCCESS); + _exit_SUCCESS(); } sv_shadowed = G.shadowed_vars_pp; @@ -9290,7 +9336,7 @@ static void pseudo_exec(nommu_save_t *nommu_save, /* Case when we are here: ... | >file */ debug_printf_exec("pseudo_exec'ed null command\n"); - _exit(EXIT_SUCCESS); + _exit_SUCCESS(); } #if ENABLE_HUSH_JOB @@ -10423,7 +10469,7 @@ static int run_list(struct pipe *pi) static const char encoded_dollar_at[] ALIGN1 = { SPECIAL_VAR_SYMBOL, '@' | 0x80, SPECIAL_VAR_SYMBOL, '\0' }; /* encoded representation of "$@" */ - static const char *const encoded_dollar_at_argv[] = { + static const char *const encoded_dollar_at_argv[] ALIGN_PTR = { encoded_dollar_at, NULL }; /* argv list with one element: "$@" */ char **vals; @@ -10550,7 +10596,12 @@ static int run_list(struct pipe *pi) G.flag_break_continue = 0; #endif #endif /* !__U_BOOT__ */ +#ifndef __U_BOOT__ + rcode = r = G.o_opt[OPT_O_NOEXEC] ? 0 : run_pipe(pi); + /* NB: rcode is a smalluint, r is int */ +#else /* __U_BOOT__ */ rcode = r = run_pipe(pi); /* NB: rcode is a smalluint, r is int */ +#endif /* __U_BOOT__ */ if (r != -1) { /* We ran a builtin, function, or group. * rcode is already known @@ -10807,7 +10858,10 @@ static int set_mode(int state, char mode, const char *o_opt) int idx; switch (mode) { case 'n': - G.o_opt[OPT_O_NOEXEC] = state; + /* set -n has no effect in interactive shell */ + /* Try: while set -n; do echo $-; done */ + if (!G_interactive_fd) + G.o_opt[OPT_O_NOEXEC] = state; break; case 'x': IF_HUSH_MODE_X(G_x_mode = state;) @@ -10880,7 +10934,7 @@ int hush_main(int argc, char **argv) cached_getpid = getpid(); /* for tcsetpgrp() during init */ G.root_pid = cached_getpid; /* for $PID (NOMMU can override via -$HEXPID:HEXPPID:...) */ - G.root_ppid = getppid(); /* for $PPID (NOMMU can override) */ + G.root_ppid = getppid(); /* for $PPID (NOMMU can override) */ /* Deal with HUSH_VERSION */ debug_printf_env("unsetenv '%s'\n", "HUSH_VERSION"); @@ -11011,6 +11065,29 @@ int hush_main(int argc, char **argv) /* Well, we cannot just declare interactiveness, * we have to have some stuff (ctty, etc) */ /* G_interactive_fd++; */ +//There are a few cases where bash -i -c 'SCRIPT' +//has visible effect (differs from bash -c 'SCRIPT'): +//it ignores TERM: +// bash -i -c 'kill $$; echo ALIVE' +// ALIVE +//it resets SIG_IGNed HUP to SIG_DFL: +// trap '' hup; bash -i -c 'kill -hup $$; echo ALIVE' +// Hangup [the message is not printed by bash, it's the shell which started it] +//is talkative about jobs and exiting: +// bash -i -c 'sleep 1 & exit' +// [1] 16170 +// exit +//includes $ENV file (only if run as "sh"): +// echo last >/tmp/ENV; ENV=/tmp/ENV sh -i -c 'echo HERE' +// last: cannot open /var/log/wtmp: No such file or directory +// HERE +//(under "bash", it's the opposite: it runs $BASH_ENV file only *without* -i). +// +//ash -i -c 'sleep 3; sleep 3', on ^C, drops into a prompt instead of exiting +//(this may be a bug, bash does not do this). +//(ash -i -c 'sleep 3' won't show this, the last command gets auto-"exec"ed) +// +//None of the above feel like useful features people would rely on. break; case 's': G.opt_s = 1; @@ -11275,9 +11352,8 @@ int hush_main(int argc, char **argv) # if ENABLE_FEATURE_EDITING G.line_input_state = new_line_input_t(FOR_SHELL); -# if EDITING_HAS_get_exe_name G.line_input_state->get_exe_name = get_builtin_name; -# endif + G.line_input_state->sh_get_var = get_local_var_value; # endif # if ENABLE_HUSH_SAVEHISTORY && MAX_HISTORY > 0 { @@ -12390,7 +12466,7 @@ static int FAST_FUNC builtin_fg_bg(char **argv) /* TODO: bash prints a string representation * of job being foregrounded (like "sleep 1 | cat") */ if (argv[0][0] == 'f' && G_saved_tty_pgrp) { - /* Put the job into the foreground. */ + /* Put the job into the foreground. */ tcsetpgrp(G_interactive_fd, pi->pgrp); }