From c6d4f010633a9961233178666d5a3c056018a758 Mon Sep 17 00:00:00 2001
From: Serge Petrenko <sergepetrenko@tarantool.org>
Date: Tue, 26 Nov 2019 16:59:33 +0300
Subject: [PATCH] clear terminal state on panic

The tarantool_free() call in the end of main() works all the time except
when we exit due to a panic. We need to clear terminal state in this
case also, so return to using atexit() to clear readline state.

Closes #4466
---
 src/main.cc | 47 +++++++++++++++++++++++++++++++++++++----------
 1 file changed, 37 insertions(+), 10 deletions(-)

diff --git a/src/main.cc b/src/main.cc
index 0ff2213b64..e674d85b13 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -588,6 +588,34 @@ load_cfg()
 	box_cfg();
 }
 
+void
+free_rl_state(void)
+{
+	/* tarantool_lua_free() was formerly reponsible for terminal reset,
+	 * but it is no longer called
+	 */
+	if (isatty(STDIN_FILENO)) {
+		/*
+		 * Restore terminal state. Doesn't hurt if exiting not
+		 * due to a signal.
+		 */
+		rl_cleanup_after_signal();
+	}
+}
+
+void
+tarantool_atexit(void)
+{
+	/* Same checks as in tarantool_free() */
+	if (getpid() != master_pid)
+		return;
+
+	if (!cord_is_main())
+		return;
+
+	free_rl_state();
+}
+
 void
 tarantool_free(void)
 {
@@ -622,16 +650,6 @@ tarantool_free(void)
 #ifdef ENABLE_GCOV
 	__gcov_flush();
 #endif
-	/* tarantool_lua_free() was formerly reponsible for terminal reset,
-	 * but it is no longer called
-	 */
-	if (isatty(STDIN_FILENO)) {
-		/*
-		 * Restore terminal state. Doesn't hurt if exiting not
-		 * due to a signal.
-		 */
-		rl_cleanup_after_signal();
-	}
 	cbus_free();
 #if 0
 	/*
@@ -836,6 +854,15 @@ main(int argc, char **argv)
 		trigger_create(&break_loop_trigger, break_loop, NULL, NULL);
 		trigger_add(&box_on_shutdown, &break_loop_trigger);
 
+		/*
+		 * The call to tarantool_free() below, thanks to
+		 * on_shutdown triggers, works all the time
+		 * except when we panic. So leave the ever-
+		 * necessary cleanups in atexit handler, which
+		 * is executed always.
+		 */
+		atexit(tarantool_atexit);
+
 		if (!loop())
 			panic("%s", "can't init event loop");
 
-- 
GitLab