X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;f=gui.c;h=ae585b8b3434d6253cc382cf310a3b2560de5ef4;hb=f127354753a643a070958f577f31251a3f58115f;hp=e53d5c73e41e7f665e4d14bb65d4113216a295ba;hpb=18d37ebfe2d78fc0a0c5ade216aa1b13a89bc768;p=paraslash.git diff --git a/gui.c b/gui.c index e53d5c73..ae585b8b 100644 --- a/gui.c +++ b/gui.c @@ -621,7 +621,27 @@ print: return 1; } -static int read_stat_pipe(fd_set *rfds) +static void print_all_items(void) +{ + int i; + + if (!curses_active()) + return; + FOR_EACH_STATUS_ITEM(i) + print_stat_item(i); +} + +static void clear_all_items(void) +{ + int i; + + FOR_EACH_STATUS_ITEM(i) { + free(stat_content[i]); + stat_content[i] = para_strdup(""); + } +} + +static void status_post_select(fd_set *rfds) { static char *buf; static int bufsize, loaded; @@ -629,11 +649,11 @@ static int read_stat_pipe(fd_set *rfds) size_t sz; if (stat_pipe < 0) - return 0; + return; if (loaded >= bufsize) { if (bufsize > 1000 * 1000) { loaded = 0; - return 0; + return; } bufsize += bufsize + 1000; buf = para_realloc(buf, bufsize); @@ -645,33 +665,20 @@ static int read_stat_pipe(fd_set *rfds) ret2 = for_each_stat_item(buf, loaded, update_item); if (ret < 0 || ret2 < 0) { loaded = 0; - return ret2 < 0? ret2 : ret; + PARA_NOTICE_LOG("closing stat pipe: %s\n", para_strerror(-ret)); + close(stat_pipe); + stat_pipe = -1; + clear_all_items(); + free(stat_content[SI_BASENAME]); + stat_content[SI_BASENAME] = + para_strdup("stat command terminated!?"); + print_all_items(); + return; } sz = ret2; /* what is left */ if (sz > 0 && sz < loaded) memmove(buf, buf + loaded - sz, sz); loaded = sz; - return 1; -} - -static void print_all_items(void) -{ - int i; - - if (!curses_active()) - return; - FOR_EACH_STATUS_ITEM(i) - print_stat_item(i); -} - -static void clear_all_items(void) -{ - int i; - - FOR_EACH_STATUS_ITEM(i) { - free(stat_content[i]); - stat_content[i] = para_strdup(""); - } } /* @@ -893,6 +900,19 @@ out: exit(EXIT_FAILURE); } +/* reread configuration, terminate on errors */ +static void reread_conf(void) +{ + /* + * gengetopt might print to stderr and exit on errors. So we have to + * shutdown curses first. + */ + shutdown_curses(); + parse_config_file_or_die(true /* override */); + init_curses(); + print_in_bar(COLOR_MSG, "config file reloaded\n"); +} + /* * React to various signal-related events */ @@ -917,7 +937,7 @@ static void handle_signal(int sig) return; case SIGUSR1: PARA_NOTICE_LOG("got SIGUSR1, rereading configuration\n"); - com_reread_conf(); + reread_conf(); return; case SIGCHLD: check_sigchld(); @@ -956,6 +976,93 @@ success: #define COMMAND_BUF_SIZE 32768 +static void command_pre_select(int mode, fd_set *rfds, int *max_fileno) +{ + /* check command pipe only in COMMAND_MODE */ + if (mode != COMMAND_MODE) + return; + if (command_fds[0] >= 0) + para_fd_set(command_fds[0], rfds, max_fileno); + if (command_fds[1] >= 0) + para_fd_set(command_fds[1], rfds, max_fileno); +} + +static int command_post_select(int mode, fd_set *rfds) +{ + int i, ret; + static char command_buf[2][COMMAND_BUF_SIZE]; + static int cbo[2]; /* command buf offsets */ + static unsigned flags[2]; /* for for_each_line() */ + + if (mode != COMMAND_MODE) + return 0; + for (i = 0; i < 2; i++) { + size_t sz; + if (command_fds[i] < 0) + continue; + ret = read_nonblock(command_fds[i], + command_buf[i] + cbo[i], + COMMAND_BUF_SIZE - 1 - cbo[i], rfds, &sz); + cbo[i] += sz; + sz = cbo[i]; + cbo[i] = for_each_line(flags[i], command_buf[i], cbo[i], + add_output_line, &i); + if (sz != cbo[i]) { /* at least one line found */ + wrefresh(bot.win); + flags[i] = 0; + } + if (ret < 0) { + PARA_NOTICE_LOG("closing command fd %d: %s", + i, para_strerror(-ret)); + close(command_fds[i]); + command_fds[i] = -1; + flags[i] = 0; + cbo[i] = 0; + if (command_fds[!i] < 0) /* both fds closed */ + return -1; + } + if (cbo[i] == COMMAND_BUF_SIZE - 1) { + PARA_NOTICE_LOG("discarding overlong line"); + cbo[i] = 0; + flags[i] = FELF_DISCARD_FIRST; + } + } + return 1; +} + +static void input_pre_select(int mode, fd_set *rfds, int *max_fileno) +{ + if (mode == GETCH_MODE || mode == COMMAND_MODE) + para_fd_set(STDIN_FILENO, rfds, max_fileno); +} + +static int input_post_select(int mode) +{ + int ret; + + switch (mode) { + case COMMAND_MODE: + ret = wgetch(top.win); + if (ret != ERR && ret != KEY_RESIZE) { + if (cmd_pid) + kill(cmd_pid, SIGTERM); + return -1; + } + return 0; + case GETCH_MODE: + ret = wgetch(top.win); + if (ret != ERR && ret != KEY_RESIZE) + return ret; + return 0; + case EXTERNAL_MODE: + if (cmd_pid == 0) + return -1; + return 0; + default: + assert(false); /* bug */ + } +} + /* * This is the core select loop. Besides the (internal) signal * pipe, the following other fds are checked according to the mode: @@ -972,11 +1079,8 @@ success: static int do_select(int mode) { fd_set rfds; - int ret, i, max_fileno; - char command_buf[2][COMMAND_BUF_SIZE] = {"", ""}; - int cbo[2] = {0, 0}; /* command buf offsets */ + int ret, max_fileno; struct timeval tv; - unsigned flags[2] = {0, 0}; /* for for_each_line() */ repeat: tv.tv_sec = conf.timeout_arg / 1000; @@ -987,15 +1091,8 @@ repeat: status_pre_select(&rfds, &max_fileno, &tv); /* signal pipe */ para_fd_set(signal_pipe, &rfds, &max_fileno); - /* command pipe only for COMMAND_MODE */ - if (mode == COMMAND_MODE) { - if (command_fds[0] >= 0) - para_fd_set(command_fds[0], &rfds, &max_fileno); - if (command_fds[1] >= 0) - para_fd_set(command_fds[1], &rfds, &max_fileno); - } - if (mode == GETCH_MODE || mode == COMMAND_MODE) - para_fd_set(STDIN_FILENO, &rfds, &max_fileno); + command_pre_select(mode, &rfds, &max_fileno); + input_pre_select(mode, &rfds, &max_fileno); ret = para_select(max_fileno + 1, &rfds, NULL, &tv); if (ret <= 0) goto check_return; /* skip fd checks */ @@ -1004,69 +1101,14 @@ repeat: if (ret > 0) handle_signal(ret); /* read command pipe if ready */ - if (mode == COMMAND_MODE) { - for (i = 0; i < 2; i++) { - size_t sz; - if (command_fds[i] < 0) - continue; - ret = read_nonblock(command_fds[i], - command_buf[i] + cbo[i], - COMMAND_BUF_SIZE - 1 - cbo[i], &rfds, &sz); - cbo[i] += sz; - sz = cbo[i]; - cbo[i] = for_each_line(flags[i], command_buf[i], cbo[i], - add_output_line, &i); - if (sz != cbo[i]) { /* at least one line found */ - wrefresh(bot.win); - flags[i] = 0; - } - if (ret < 0) { - PARA_NOTICE_LOG("closing command fd %d: %s\n", - i, para_strerror(-ret)); - close(command_fds[i]); - command_fds[i] = -1; - flags[i] = 0; - cbo[i] = 0; - if (command_fds[!i] < 0) /* both fds closed */ - return 0; - } - if (cbo[i] == COMMAND_BUF_SIZE - 1) { - PARA_NOTICE_LOG("discarding overlong line\n"); - cbo[i] = 0; - flags[i] = FELF_DISCARD_FIRST; - } - } - } - ret = read_stat_pipe(&rfds); - if (ret < 0) { - PARA_NOTICE_LOG("closing stat pipe: %s\n", para_strerror(-ret)); - close(stat_pipe); - stat_pipe = -1; - clear_all_items(); - free(stat_content[SI_BASENAME]); - stat_content[SI_BASENAME] = - para_strdup("stat command terminated!?"); - print_all_items(); - } + ret = command_post_select(mode, &rfds); + if (ret < 0) + return 0; + status_post_select(&rfds); check_return: - switch (mode) { - case COMMAND_MODE: - ret = wgetch(top.win); - if (ret != ERR && ret != KEY_RESIZE) { - if (cmd_pid) - kill(cmd_pid, SIGTERM); - return -1; - } - break; - case GETCH_MODE: - ret = wgetch(top.win); - if (ret != ERR && ret != KEY_RESIZE) - return ret; - break; - case EXTERNAL_MODE: - if (cmd_pid == 0) - return 0; - } + ret = input_post_select(mode); + if (ret != 0) + return ret; goto repeat; } @@ -1296,19 +1338,9 @@ static void com_ll_incr(void) print_in_bar(COLOR_MSG, "loglevel set to %d\n", loglevel); } -/* - * reread configuration, terminate on errors - */ static void com_reread_conf(void) { - /* - * gengetopt might print to stderr and exit on errors. So we have to - * shutdown curses first. - */ - shutdown_curses(); - parse_config_file_or_die(true /* override */); - init_curses(); - print_in_bar(COLOR_MSG, "config file reloaded\n"); + reread_conf(); } static void com_help(void)