From: Donatas Abraitis Date: Wed, 10 Aug 2022 10:43:11 +0000 (+0300) Subject: vtysh: Handle SIGTSTP (C-z) without exiting the vty shell X-Git-Tag: docker/8.3.1~7^2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=94377ec0f1e7de6657d8daa24600bead8412bbf9;p=matthieu%2Ffrr.git vtysh: Handle SIGTSTP (C-z) without exiting the vty shell After 4c92dd90d3d15cff640de063ff14eec950402d25 switching to poll-based I/O, vtysh prompt exits on C-z signal. Signed-off-by: Donatas Abraitis (cherry picked from commit 149a3fffe0d713e4c78edd908f4ebf3fd99cb397) --- diff --git a/vtysh/vtysh_main.c b/vtysh/vtysh_main.c index 04eb47feeb..ca119eb900 100644 --- a/vtysh/vtysh_main.c +++ b/vtysh/vtysh_main.c @@ -78,36 +78,56 @@ int execute_flag = 0; /* Flag to indicate if in user/unprivileged mode. */ int user_mode; -/* For sigsetjmp() & siglongjmp(). */ -static sigjmp_buf jmpbuf; - -/* Flag for avoid recursive siglongjmp() call. */ -static int jmpflag = 0; - /* Master of threads. */ struct thread_master *master; /* Command logging */ FILE *logfile; +static void vtysh_rl_callback(char *line_read) +{ + HIST_ENTRY *last; + + rl_callback_handler_remove(); + + if (!line_read) { + vtysh_loop_exited = true; + return; + } + + /* If the line has any text in it, save it on the history. But only if + * last command in history isn't the same one. + */ + if (*line_read) { + using_history(); + last = previous_history(); + if (!last || strcmp(last->line, line_read) != 0) { + add_history(line_read); + append_history(1, history_file); + } + } + + vtysh_execute(line_read); + + if (!vtysh_loop_exited) + rl_callback_handler_install(vtysh_prompt(), vtysh_rl_callback); +} + /* SIGTSTP handler. This function care user's ^Z input. */ static void sigtstp(int sig) { + rl_callback_handler_remove(); + /* Execute "end" command. */ vtysh_execute("end"); + if (!vtysh_loop_exited) + rl_callback_handler_install(vtysh_prompt(), vtysh_rl_callback); + /* Initialize readline. */ rl_initialize(); printf("\n"); - - /* Check jmpflag for duplicate siglongjmp(). */ - if (!jmpflag) - return; - - jmpflag = 0; - - /* Back to main command loop. */ - siglongjmp(jmpbuf, 1); + rl_forced_update_display(); } /* SIGINT handler. This function care user's ^Z input. */ @@ -207,34 +227,6 @@ struct option longopts[] = { bool vtysh_loop_exited; -static void vtysh_rl_callback(char *line_read) -{ - HIST_ENTRY *last; - - rl_callback_handler_remove(); - - if (!line_read) { - vtysh_loop_exited = true; - return; - } - - /* If the line has any text in it, save it on the history. But only if - * last command in history isn't the same one. */ - if (*line_read) { - using_history(); - last = previous_history(); - if (!last || strcmp(last->line, line_read) != 0) { - add_history(line_read); - append_history(1, history_file); - } - } - - vtysh_execute(line_read); - - if (!vtysh_loop_exited) - rl_callback_handler_install(vtysh_prompt(), vtysh_rl_callback); -} - static struct thread *vtysh_rl_read_thread; static void vtysh_rl_read(struct thread *thread) @@ -752,10 +744,6 @@ int main(int argc, char **argv, char **env) vtysh_add_timestamp = ts_flag; - /* Preparation for longjmp() in sigtstp(). */ - sigsetjmp(jmpbuf, 1); - jmpflag = 1; - /* Main command loop. */ vtysh_rl_run();