gui: Use variable-sized input buffer for the audiod pipe.
[paraslash.git] / gui.c
diff --git a/gui.c b/gui.c
index f08976d..21770ca 100644 (file)
--- a/gui.c
+++ b/gui.c
@@ -203,24 +203,6 @@ static int para_open_audiod_pipe(char *cmd)
        return ret;
 }
 
-static int read_audiod_pipe(int fd, line_handler_t *line_handler)
-{
-       static char buf[4096];
-       const ssize_t bufsize = sizeof(buf) - 1;
-       static ssize_t loaded;
-       ssize_t ret;
-
-       if (loaded >= bufsize)
-               loaded = 0;
-       ret = read(fd, buf + loaded, bufsize - loaded);
-       if (ret > 0) {
-               loaded += ret;
-               buf[loaded] = '\0';
-               loaded = for_each_line(buf, loaded, line_handler, NULL);
-       }
-       return ret;
-}
-
 static int find_cmd_byname(char *name)
 {
        int i;
@@ -489,12 +471,14 @@ static int add_output_line(char *line, __a_unused void *data)
        return 1;
 }
 
+static int loglevel;
+
 __printf_2_3 void para_log(int ll, const char *fmt,...)
 {
        int color;
        char *msg;
 
-       if (ll < conf.loglevel_arg || !curses_active)
+       if (ll < loglevel || !curses_active)
                return;
        switch (ll) {
                case LL_DEBUG:
@@ -519,13 +503,12 @@ static void setup_signal_handling(void)
        para_install_sighandler(SIGCHLD);
        para_install_sighandler(SIGWINCH);
        para_install_sighandler(SIGUSR1);
-//     signal(SIGPIPE, SIG_IGN);
-       signal(SIGHUP, SIG_IGN);
+       para_sigaction(SIGHUP, SIG_IGN);
 }
 
 __noreturn static void do_exit(int ret)
 {
-       signal(SIGTERM, SIG_IGN);
+       para_sigaction(SIGTERM, SIG_IGN);
        kill(0, SIGTERM);
        exit(ret);
 }
@@ -562,8 +545,7 @@ __noreturn __printf_2_3 static void msg_n_exit(int ret, const char* fmt, ...)
 
 static void print_welcome(void)
 {
-       int ll = conf.loglevel_arg;
-       if (ll > LL_NOTICE)
+       if (loglevel > LL_NOTICE)
                return;
        outputf(COLOR_WELCOME, "Welcome to para_gui " PACKAGE_VERSION
                " \"" CODENAME "\". Theme: %s", theme.name);
@@ -687,6 +669,43 @@ static void print_stat_item(int i)
        wrefresh(top.win);
 }
 
+/*
+ * print status line if line starts with known command.
+ */
+static int update_item(int item_num, char *buf)
+{
+       free(stat_content[item_num]);
+       stat_content[item_num] = para_strdup(buf);
+       print_stat_item(item_num);
+       return 1;
+}
+
+static int read_audiod_pipe(int fd)
+{
+       static char *buf;
+       static int bufsize, loaded;
+       int ret;
+
+       if (loaded >= bufsize) {
+               if (bufsize > 1000 * 1000) {
+                       loaded = 0;
+                       return 0;
+               }
+               bufsize += bufsize + 1000;
+               buf = para_realloc(buf, bufsize);
+       }
+       assert(loaded < bufsize);
+       ret = read(fd, buf + loaded, bufsize - loaded);
+       if (ret <= 0)
+               return ret;
+       loaded += ret;
+       ret = for_each_stat_item(buf, loaded, update_item);
+       if (ret < 0)
+               return ret;
+       loaded = ret;
+       return 1;
+}
+
 static void print_all_items(void)
 {
        int i;
@@ -769,26 +788,6 @@ reap_next_child:
        goto reap_next_child;
 }
 
-/*
- * print status line if line starts with known command.
- */
-static int check_stat_line(char *line, __a_unused void *data)
-{
-       int i;
-
-//     PARA_INFO_LOG("%s: checking: %s\n", __func__, line);
-       i = stat_line_valid(line);
-       if (i >= 0) {
-               line += strlen(status_item_list[i]) + 1;
-               if (*line == ' ')
-                       line++;
-               free(stat_content[i]);
-               stat_content[i] = para_strdup(line);
-               print_stat_item(i);
-       }
-       return 1;
-}
-
 /*
  * This sucker modifies its first argument. *handler and *arg are
  * pointers to 0-terminated strings (inside line). Crap.
@@ -859,8 +858,8 @@ static void handle_signal(int sig)
                return;
        case SIGINT:
                PARA_WARNING_LOG("caught SIGINT, reset");
-               /* Nothing to do. SIGINT killed our child, para_client stat.
-                * This get noticed by do_select which resets everything
+               /* Nothing to do. SIGINT killed our child which gets noticed
+                * by do_select and resets everything.
                 */
                return;
        case SIGUSR1:
@@ -895,7 +894,7 @@ static int open_audiod_pipe(void)
  * when any key is pressed.
  *
  * EXTERNAL_MODE: Check only signal pipe. Used when an external command
- * is running. During that thime curses is disabled.  Returns when
+ * is running. During that time curses is disabled.  Returns when
  * cmd_pid == 0.
  */
 static int do_select(int mode)
@@ -946,7 +945,7 @@ repeat:
                }
        }
        if (audiod_pipe >= 0 && FD_ISSET(audiod_pipe, &rfds))
-               if (read_audiod_pipe(audiod_pipe, check_stat_line) <= 0) {
+               if (read_audiod_pipe(audiod_pipe) <= 0) {
                        close(audiod_pipe);
                        audiod_pipe = -1;
                        clear_all_items();
@@ -1091,13 +1090,14 @@ static void com_page_up(void)
 {
        unsigned lines;
        int fvr = first_visible_rbe(&lines);
+
        if (fvr < 0 || fvr + 1 >= ringbuffer_filled(bot_win_rb)) {
                print_in_bar(COLOR_ERRMSG, "top of buffer is shown\n");
                return;
        }
        scroll_position = fvr + 1;
        for (; scroll_position > 0; scroll_position--) {
-               fvr = first_visible_rbe(&lines);
+               first_visible_rbe(&lines);
                if (lines == bot.lines)
                        break;
        }
@@ -1168,24 +1168,24 @@ err_out:
 
 static void com_ll_decr(void)
 {
-       if (conf.loglevel_arg <= LL_DEBUG) {
+       if (loglevel <= LL_DEBUG) {
                print_in_bar(COLOR_ERRMSG,
                        "loglevel already at maximal verbosity\n");
                return;
        }
-       conf.loglevel_arg--;
-       print_in_bar(COLOR_MSG, "loglevel set to %d\n", conf.loglevel_arg);
+       loglevel--;
+       print_in_bar(COLOR_MSG, "loglevel set to %d\n", loglevel);
 }
 
 static void com_ll_incr(void)
 {
-       if (conf.loglevel_arg >= LL_EMERG) {
+       if (loglevel >= LL_EMERG) {
                print_in_bar(COLOR_ERRMSG,
-                       "loglevel already at miminal verbosity\n");
+                       "loglevel already at minimal verbosity\n");
                return;
        }
-       conf.loglevel_arg++;
-       print_in_bar(COLOR_MSG, "loglevel set to %d\n", conf.loglevel_arg);
+       loglevel++;
+       print_in_bar(COLOR_MSG, "loglevel set to %d\n", loglevel);
 }
 
 /*
@@ -1391,6 +1391,7 @@ int main(int argc, char *argv[])
                };
                gui_cmdline_parser_config_file(cf, &conf, &params);
        }
+       loglevel = get_loglevel_by_name(conf.loglevel_arg);
        if (check_key_map_args() < 0) {
                fprintf(stderr, "invalid key map in config file\n");
                exit(EXIT_FAILURE);