Fix \watch's interaction with libedit on ^C.
authorThomas Munro <[email protected]>
Sun, 10 Jul 2022 04:30:03 +0000 (16:30 +1200)
committerThomas Munro <[email protected]>
Sun, 10 Jul 2022 04:52:38 +0000 (16:52 +1200)
When you hit ^C, the terminal driver in Unix-like systems echoes "^C" as
well as sending an interrupt signal (depending on stty settings).  At
least libedit (but maybe also libreadline) is then confused about the
current cursor location, and corrupts the display if you try to scroll
back.  Fix, by moving to a new line before the next prompt is displayed.

Back-patch to all supported released.

Author: Pavel Stehule <[email protected]>
Reported-by: Tom Lane <[email protected]>
Discussion: https://postgr.es/m/3278793.1626198638%40sss.pgh.pa.us

src/bin/psql/command.c

index c562c04afee5e9812ca84d71ea5559e1a70ab3ce..0955142215a6b25c39380d666e2e09f336ca9b87 100644 (file)
@@ -5145,6 +5145,18 @@ do_watch(PQExpBuffer query_buf, double sleep)
        pclose(pagerpipe);
        restore_sigpipe_trap();
    }
+   else
+   {
+       /*
+        * If the terminal driver echoed "^C", libedit/libreadline might be
+        * confused about the cursor position.  Therefore, inject a newline
+        * before the next prompt is displayed.  We only do this when not
+        * using a pager, because pagers are expected to restore the screen to
+        * a sane state on exit.
+        */
+       fprintf(stdout, "\n");
+       fflush(stdout);
+   }
 
 #ifdef HAVE_POSIX_DECL_SIGWAIT
    /* Disable the interval timer. */