unsigned flags[2]; /* passed to for_each_line() */
};
-static int find_cmd_byname(char *name)
+static int find_cmd_byname(const char *name)
{
int i;
/** 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();
}
{
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. */
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);
}
switch (ret) {
case SIGTERM:
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");
* The exec task is responsible for printing the output of the currently
* running executable to the bottom window.
*
- * The signal task performs suitable actions according to any signals received.
- * For example it refreshes all windows on terminal size changes and resets the
- * terminal on \p SIGTERM.
+ * The signal task performs various actions according to signals received. For
+ * example, it reloads the configuration file on SIGUSR1, and it shuts down the
+ * curses system on SIGTERM to restore the terminal settings before exit.
*
* The input task reads single key strokes from stdin. For each key pressed, it
* executes the command handler associated with this key.