[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