]> git.puffer.fish Git - matthieu/frr.git/commitdiff
vtysh: Handle SIGTSTP (C-z) without exiting the vty shell
authorDonatas Abraitis <donatas@opensourcerouting.org>
Wed, 10 Aug 2022 10:43:11 +0000 (13:43 +0300)
committerMergify <37929162+mergify[bot]@users.noreply.github.com>
Wed, 10 Aug 2022 16:12:14 +0000 (16:12 +0000)
After 4c92dd90d3d15cff640de063ff14eec950402d25 switching to poll-based I/O,
vtysh prompt exits on C-z signal.

Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
(cherry picked from commit 149a3fffe0d713e4c78edd908f4ebf3fd99cb397)

vtysh/vtysh_main.c

index 04eb47feeb8a5529ed658a3d65c8bb3080f4fd9c..ca119eb9004155fdc4dc45c0d984b7ddcafcc749 100644 (file)
@@ -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();