int rbe_lines;
if (!rbe)
return i - 1;
-// fprintf(stderr, "found: %s\n", rbe->msg);
rbe_lines = NUM_LINES(rbe->len);
if (rbe_lines > bot.lines)
return -1;
new->len = len;
new->msg = msg;
old = ringbuffer_add(bot_win_rb, new);
-// fprintf(stderr, "added: %s\n", new->msg);
if (old) {
free(old->msg);
free(old);
static __printf_2_3 void curses_log(int ll, const char *fmt,...)
{
- int color;
- char *msg;
va_list ap;
- unsigned bytes;
- if (ll < loglevel || !curses_active())
+ if (ll < loglevel)
return;
- switch (ll) {
- case LL_DEBUG:
- case LL_INFO:
- case LL_NOTICE:
- color = COLOR_MSG;
- break;
- default:
- color = COLOR_ERRMSG;
- }
va_start(ap, fmt);
- bytes = xvasprintf(&msg, fmt, ap);
+ if (curses_active()) {
+ int color = ll <= LL_NOTICE? COLOR_MSG : COLOR_ERRMSG;
+ char *msg;
+ unsigned bytes = xvasprintf(&msg, fmt, ap);
+ if (bytes > 0 && msg[bytes - 1] == '\n')
+ msg[bytes - 1] = '\0'; /* cut trailing newline */
+ rb_add_entry(color, msg);
+ wrefresh(bot.win);
+ } else if (cmd_pid <= 0) /* no external command running */
+ vfprintf(stderr, fmt, ap);
va_end(ap);
- if (bytes > 0 && msg[bytes - 1] == '\n')
- msg[bytes - 1] = '\0'; /* cut trailing newline */
- rb_add_entry(color, msg);
- wrefresh(bot.win);
}
__printf_2_3 void (*para_log)(int, const char*, ...) = curses_log;
para_install_sighandler(SIGUSR1);
}
-/* kill every process in the process group and exit */
-__noreturn static void kill_pg_and_die(int ret)
-{
- para_sigaction(SIGTERM, SIG_IGN);
- kill(0, SIGTERM);
- exit(ret);
-}
-
static void shutdown_curses(void)
{
def_prog_mode();
endwin();
}
-__noreturn static void finish(int ret)
-{
- shutdown_curses();
- kill_pg_and_die(ret);
-}
-
-/*
- * exit curses and print given message to stdout/stderr
- */
-__noreturn __printf_2_3 static void msg_n_exit(int ret, const char* fmt, ...)
+/* disable curses, print a message, kill running processes and exit */
+__noreturn __printf_2_3 static void die(int exit_code, const char* fmt, ...)
{
va_list argp;
- FILE *outfd = ret? stderr: stdout;
shutdown_curses();
va_start(argp, fmt);
- vfprintf(outfd, fmt, argp);
+ vfprintf(stderr, fmt, argp);
va_end(argp);
- kill_pg_and_die(ret);
+ /* kill every process in the process group and exit */
+ para_sigaction(SIGTERM, SIG_IGN);
+ kill(0, SIGTERM);
+ exit(exit_code);
}
/*
sb.win = newwin(sb.lines, sb.cols, sb_y, 0);
in.win = newwin(in.lines, in.cols, in_y, 0);
if (!top.win || !bot.win || !sb.win || !in.win || !sep.win)
- msg_n_exit(1, "Error: Cannot create curses windows\n");
+ die(EXIT_FAILURE, "Error: Cannot create curses windows\n");
wclear(bot.win);
wclear(sb.win);
wclear(in.win);
static void init_pair_or_die(short pair, short f, short b)
{
if (init_pair(pair, f, b) == ERR)
- msg_n_exit(EXIT_FAILURE, "fatal: init_pair() failed\n");
+ die(EXIT_FAILURE, "fatal: init_pair() failed\n");
}
static void init_colors_or_die(void)
int i;
if (!has_colors())
- msg_n_exit(EXIT_FAILURE, "fatal: No color term\n");
+ die(EXIT_FAILURE, "fatal: No color term\n");
if (start_color() == ERR)
- msg_n_exit(EXIT_FAILURE, "fatal: failed to start colors\n");
+ die(EXIT_FAILURE, "fatal: failed to start colors\n");
FOR_EACH_STATUS_ITEM(i)
if (theme.data[i].len)
init_pair_or_die(i + 1, theme.data[i].fg,
if (curses_active())
return;
if (top.win && refresh() == ERR) /* refresh is really needed */
- msg_n_exit(EXIT_FAILURE, "refresh() failed\n");
+ die(EXIT_FAILURE, "refresh() failed\n");
if (LINES < theme.lines_min || COLS < theme.cols_min)
- msg_n_exit(EXIT_FAILURE, "Error: Terminal (%dx%d) too small"
+ die(EXIT_FAILURE, "Terminal (%dx%d) too small"
" (need at least %dx%d)\n", COLS, LINES,
theme.cols_min, theme.lines_min);
curs_set(0); /* make cursor invisible, ignore errors */
nonl(); /* do not NL->CR/NL on output, always returns OK */
/* don't echo input */
if (noecho() == ERR)
- msg_n_exit(EXIT_FAILURE, "fatal: noecho() failed\n");
+ die(EXIT_FAILURE, "fatal: noecho() failed\n");
/* take input chars one at a time, no wait for \n */
if (cbreak() == ERR)
- msg_n_exit(EXIT_FAILURE, "fatal: cbreak() failed\n");
+ die(EXIT_FAILURE, "fatal: cbreak() failed\n");
init_colors_or_die();
clear(); /* ignore non-fatal errors */
init_wins(theme.top_lines_default);
{
switch (sig) {
case SIGTERM:
- msg_n_exit(EXIT_FAILURE,
- "only the good die young (caught SIGTERM))\n");
+ die(EXIT_FAILURE, "only the good die young (caught SIGTERM)\n");
return;
case SIGWINCH:
if (curses_active()) {
break;
rbe_lines = NUM_LINES(rbe->len);
lines += rbe_lines;
-// fprintf(stderr, "msg: %s\n", rbe->msg);
wattron(bot.win, COLOR_PAIR(rbe->color));
waddstr(bot.win, "\n");
waddstr(bot.win, rbe->msg);
init_curses();
PARA_NOTICE_LOG("config file reloaded\n");
if (check_key_map_args() < 0)
- finish(EXIT_FAILURE);
+ die(EXIT_FAILURE, "invalid key map\n");
}
static void com_help(void)
__noreturn static void com_quit(void)
{
- finish(0);
+ die(EXIT_SUCCESS, "%s", "");
}
static void com_refresh(void)
if (conf.help_given || conf.detailed_help_given)
print_help_and_die();
cf = configfile_exists();
- if (!cf && conf.config_file_given) {
- fprintf(stderr, "can not read config file %s\n",
+ if (!cf && conf.config_file_given)
+ die(EXIT_FAILURE, "can not read config file %s\n",
conf.config_file_arg);
- exit(EXIT_FAILURE);
- }
if (cf) {
struct gui_cmdline_parser_params params = {
.override = 0,
gui_cmdline_parser_config_file(cf, &conf, ¶ms);
loglevel = get_loglevel_by_name(conf.loglevel_arg);
}
- if (check_key_map_args() < 0) {
- fprintf(stderr, "invalid key map\n");
- exit(EXIT_FAILURE);
- }
+ if (check_key_map_args() < 0)
+ die(EXIT_FAILURE, "invalid key map\n");
theme_init(conf.theme_arg, &theme);
setup_signal_handling();
bot_win_rb = ringbuffer_new(RINGBUFFER_SIZE);