X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=gui.c;h=7bb74e6f484a2ab0731f77a121b95d06af1b2c93;hp=68a271a898a49a82f6499bd145cd9956e1c4a5f3;hb=23b121a85984baa9252f4b4c0b8c4f186e394bb7;hpb=ef0508ee41853a36a60676714ff1deecf9bb930d diff --git a/gui.c b/gui.c index 68a271a8..7bb74e6f 100644 --- a/gui.c +++ b/gui.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "gui.cmdline.h" #include "para.h" @@ -287,14 +288,20 @@ static char *configfile_exists(void) return file_exists(tmp)? tmp: NULL; } -/* - * print num spaces to curses window - */ +/* Print given number of spaces to curses window. */ static void add_spaces(WINDOW* win, unsigned int num) { - while (num > 0) { - num--; - waddstr(win, " "); + char space[] = " "; + unsigned sz = sizeof(space); + + while (num >= sz) { + waddstr(win, space); + num -= sz; + } + if (num > 0) { + assert(num < sz); + space[num] = '\0'; + waddstr(win, space); } } @@ -533,7 +540,8 @@ static void setup_signal_handling(void) para_sigaction(SIGHUP, SIG_IGN); } -__noreturn static void do_exit(int ret) +/* 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); @@ -552,7 +560,7 @@ static void shutdown_curses(void) __noreturn static void finish(int ret) { shutdown_curses(); - do_exit(ret); + kill_pg_and_die(ret); } /* @@ -567,7 +575,7 @@ __noreturn __printf_2_3 static void msg_n_exit(int ret, const char* fmt, ...) va_start(argp, fmt); vfprintf(outfd, fmt, argp); va_end(argp); - do_exit(ret); + kill_pg_and_die(ret); } static void print_welcome(void) @@ -923,30 +931,33 @@ static void handle_signal(int sig) } } -static int open_stat_pipe(void) +static void status_pre_select(fd_set *rfds, int *max_fileno, struct timeval *tv) { - static int init = 1; + static struct timeval next_exec, atm, diff; int ret, fds[3] = {0, 1, 0}; pid_t pid; - if (init) - init = 0; - else - /* - * Sleep a bit to avoid a busy loop. As the call to sleep() may - * be interrupted by SIGCHLD, we simply wait until the call - * succeeds. - */ - while (sleep(2)) - ; /* nothing */ + if (stat_pipe >= 0) + goto success; + /* Avoid busy loop */ + gettimeofday(&atm, NULL); + if (tv_diff(&next_exec, &atm, &diff) > 0) { + if (tv_diff(&diff, tv, NULL) < 0) + *tv = diff; + return; + } + next_exec.tv_sec = atm.tv_sec + 2; ret = para_exec_cmdline_pid(&pid, conf.stat_cmd_arg, fds); if (ret < 0) - return ret; + return; ret = mark_fd_nonblocking(fds[1]); - if (ret >= 0) - return fds[1]; - close(fds[1]); - return ret; + if (ret < 0) { + close(fds[1]); + return; + } + stat_pipe = fds[1]; +success: + para_fd_set(stat_pipe, rfds, max_fileno); } #define COMMAND_BUF_SIZE 32768 @@ -978,10 +989,7 @@ repeat: // ret = refresh_status(); FD_ZERO(&rfds); max_fileno = 0; - if (stat_pipe < 0) - stat_pipe = open_stat_pipe(); - if (stat_pipe >= 0) - para_fd_set(stat_pipe, &rfds, &max_fileno); + status_pre_select(&rfds, &max_fileno, &tv); /* signal pipe */ para_fd_set(signal_pipe, &rfds, &max_fileno); /* command pipe only for COMMAND_MODE */ @@ -1011,7 +1019,7 @@ repeat: COMMAND_BUF_SIZE - 1 - cbo[i], &rfds, &sz); cbo[i] += sz; sz = cbo[i]; - cbo[i] = for_each_line(command_buf[i], cbo[i], + cbo[i] = for_each_line(0, command_buf[i], cbo[i], add_output_line, &i); if (sz != cbo[i]) wrefresh(bot.win);