[PATCH v2] common: cli_hush: terminate all commands when Ctrl-C is pressed
Simon Glass
sjg at chromium.org
Tue Jan 6 00:30:25 CET 2026
Hi Shiji,
On Sun, 28 Dec 2025 at 04:04, Shiji Yang <yangshiji66 at outlook.com> wrote:
>
> Check Ctrl-C status before executing each command in the pipeline so
> that the Ctrl-C can skip all subsequent commands. in the meantime, we
> need to clear the ctrlc status at the end of a pipeline. This should
> be the default behavior of most shell parsers.
>
> Before the change:
> ```
> => echo start; while true; do echo loop; sleep 1; done; echo int; if true; then echo if; fi; echo stop
> start
> loop
> loop <-- Input Ctrl-C
> int
> if
> stop
> =>
> ```
> After the change:
> ```
> => echo start; while true; do echo loop; sleep 1; done; echo int; if true; then echo if; fi; echo stop
> start
> loop
> loop <-- Input Ctrl-C
> ^C
> =>
> ```
>
> Signed-off-by: Shiji Yang <yangshiji66 at outlook.com>
> ---
> v1 --> v2:
> - use puts() instead of printf()
> - only clear Ctrl-C status when one pipe reaches the end
>
> common/cli_hush.c | 20 ++++++++++++--------
> 1 file changed, 12 insertions(+), 8 deletions(-)
>
> diff --git a/common/cli_hush.c b/common/cli_hush.c
> index 7bd6943d3ed..3f6adc01934 100644
> --- a/common/cli_hush.c
> +++ b/common/cli_hush.c
> @@ -1792,16 +1792,15 @@ static int run_list_real(struct pipe *pi)
> }
> }
> for (; pi; pi = (flag_restore != 0) ? rpipe : pi->next) {
> - if (pi->r_mode == RES_WHILE || pi->r_mode == RES_UNTIL ||
> - pi->r_mode == RES_FOR) {
> #ifdef __U_BOOT__
> - /* check Ctrl-C */
> - ctrlc();
> - if ((had_ctrlc())) {
> - return 1;
> - }
> + /* check Ctrl-C */
> + ctrlc();
> + if (had_ctrlc())
> + return 1;
> #endif
> - flag_restore = 0;
> + if (pi->r_mode == RES_WHILE || pi->r_mode == RES_UNTIL ||
> + pi->r_mode == RES_FOR) {
> + flag_restore = 0;
> if (!rpipe) {
> flag_rep = 0;
> rpipe = pi;
> @@ -3207,6 +3206,11 @@ static int parse_stream_outer(struct in_str *inp, int flag)
> run_list(ctx.list_head);
> #else
> code = run_list(ctx.list_head);
> + /* clear Ctrl-C status when one pipe reaches the end */
> + if (had_ctrlc() && !(flag & FLAG_REPARSING)) {
> + puts("^C\n");
> + clear_ctrlc();
> + }
> if (code == -2) { /* exit */
> b_free(&temp);
> code = 0;
> --
> 2.51.0
>
I'm not an expert on this but it seems reasonable. Is there a way we
can test this behaviour?
Regards,
Simon
More information about the U-Boot
mailing list