From: Andre Noll Date: Fri, 3 Jan 2014 18:16:51 +0000 (+0000) Subject: gui: Move external command handling out of do_select(). X-Git-Tag: v0.5.3~12^2~17 X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=commitdiff_plain;h=2436fd444428d2549575fe40484ffae9dc11e58e gui: Move external command handling out of do_select(). This commit moves the part of do_select() that deals with external commands to separate functions, command_pre_select() and command_post_select(). This change shortens do_select() considerably and is another step towards the goal of using the paraslash scheduling system also for para_gui. One thing to note is that the new command_post_select() returns -1 if both both fds are closed, i.e. when the currently running command has terminated. This value gets translated back to zero in do_select(), preserving the current semantics. --- diff --git a/gui.c b/gui.c index 318418ea..5f51cfce 100644 --- a/gui.c +++ b/gui.c @@ -976,6 +976,60 @@ 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; +} + /* * This is the core select loop. Besides the (internal) signal * pipe, the following other fds are checked according to the mode: @@ -992,11 +1046,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; @@ -1007,13 +1058,7 @@ 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); - } + command_pre_select(mode, &rfds, &max_fileno); if (mode == GETCH_MODE || mode == COMMAND_MODE) para_fd_set(STDIN_FILENO, &rfds, &max_fileno); ret = para_select(max_fileno + 1, &rfds, NULL, &tv); @@ -1024,39 +1069,9 @@ 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 = command_post_select(mode, &rfds); + if (ret < 0) + return 0; status_post_select(&rfds); check_return: switch (mode) {