]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - gui.c
gui.c: Remove silly warning on SIGINT.
[paraslash.git] / gui.c
diff --git a/gui.c b/gui.c
index 1421489013dfd56ef6f60bc427ee2e5ad0ae64da..dd7ffeb40b9fbaa6cc41350c1b0eb41a2317d0c1 100644 (file)
--- a/gui.c
+++ b/gui.c
@@ -246,8 +246,8 @@ static char *km_keyname(int c)
 /* Print given number of spaces to curses window. */
 static void add_spaces(WINDOW* win, unsigned int num)
 {
-       char space[] = "                                ";
-       unsigned sz = sizeof(space) - 1; /* number of spaces */
+       const char space[] = "                                ";
+       const unsigned sz = sizeof(space) - 1; /* number of spaces */
 
        while (num >= sz)  {
                waddstr(win, space);
@@ -255,8 +255,7 @@ static void add_spaces(WINDOW* win, unsigned int num)
        }
        if (num > 0) {
                assert(num < sz);
-               space[num] = '\0';
-               waddstr(win, space);
+               waddstr(win, space + sz - num);
        }
 }
 
@@ -499,9 +498,18 @@ static __printf_2_3 void curses_log(int ll, const char *fmt,...)
 /** The log function of para_gui, always set to curses_log(). */
 __printf_2_3 void (*para_log)(int, const char*, ...) = curses_log;
 
+/* Call endwin() to reset the terminal into non-visual mode. */
 static void shutdown_curses(void)
 {
-       def_prog_mode();
+       /*
+        * If para_gui received a terminating signal in external mode, the
+        * terminal can be in an unusable state at this point because the child
+        * process might not have caught the signal. In this case endwin() has
+        * already been called and must not be called again. So we first return
+        * to program mode, then call endwin().
+        */
+       if (!curses_active())
+               reset_prog_mode();
        endwin();
 }
 
@@ -510,13 +518,22 @@ __noreturn __printf_2_3 static void die(int exit_code, const char* fmt, ...)
 {
        va_list argp;
 
+       /* Kill every process in our process group. */
+       para_sigaction(SIGTERM, SIG_IGN);
+       kill(0, SIGTERM);
+       /* Wait up to two seconds for child processes to die. */
+       alarm(2);
+       while (waitpid(0, NULL, 0) >= 0)
+               ; /* nothing */
+       alarm(0);
+       /* mousemask() exists only in ncurses */
+#ifdef NCURSES_MOUSE_VERSION
+       mousemask(~(mmask_t)0, NULL); /* Avoid bad terminal state with xterm. */
+#endif
        shutdown_curses();
        va_start(argp, fmt);
        vfprintf(stderr, fmt, argp);
        va_end(argp);
-       /* kill every process in the process group and exit */
-       para_sigaction(SIGTERM, SIG_IGN);
-       kill(0, SIGTERM);
        exit(exit_code);
 }
 
@@ -920,10 +937,6 @@ static int signal_post_select(struct sched *s, __a_unused void *context)
                die(EXIT_FAILURE, "only the good die young (caught SIGTERM)\n");
                return 1;
        case SIGINT:
-               PARA_WARNING_LOG("caught SIGINT, reset\n");
-               /* Nothing to do. SIGINT killed our child which gets noticed
-                * by do_select and resets everything.
-                */
                return 1;
        case SIGUSR1:
                PARA_NOTICE_LOG("got SIGUSR1, rereading configuration\n");