]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - interactive.c
Merge topic branch t/overflow into master
[paraslash.git] / interactive.c
index 01f25fb3d52654f3a45413891b0b170b3da5a7a5..e367a65920c53982af55436d7b96ea53138408f8 100644 (file)
@@ -189,8 +189,6 @@ static char **i9e_completer(const char *text, int start, __a_unused int end)
  *
  * This function attaches the i9e input queue to an output queue of \a
  * producer.
- *
- * \return Standard.
  */
 void i9e_attach_to_stdout(struct btr_node *producer)
 {
@@ -258,18 +256,6 @@ static void clear_bottom_line(void)
        rl_point = point;
 }
 
-static bool input_available(void)
-{
-       fd_set rfds;
-       struct timeval tv = {0, 0};
-       int ret;
-
-       FD_ZERO(&rfds);
-       FD_SET(i9ep->ici->fds[0], &rfds);
-       ret = para_select(1, &rfds, NULL, &tv);
-       return ret > 0;
-}
-
 static void i9e_line_handler(char *line)
 {
        int ret;
@@ -294,7 +280,7 @@ free_line:
        free(line);
 }
 
-static int i9e_post_select(__a_unused struct sched *s, __a_unused void *context)
+static int i9e_post_monitor(__a_unused struct sched *s, __a_unused void *context)
 {
        int ret;
        struct i9e_client_info *ici = i9ep->ici;
@@ -310,24 +296,29 @@ static int i9e_post_select(__a_unused struct sched *s, __a_unused void *context)
        ret = 0;
        if (i9ep->caught_sigint)
                goto rm_btrn;
-       while (input_available()) {
+       while (read_ok(i9ep->ici->fds[0]) > 0) {
                if (i9ep->stdout_btrn) {
-                       unsigned len = i9ep->key_sequence_length;
-                       assert(len < sizeof(i9ep->key_sequence) - 1);
-                       buf = i9ep->key_sequence + len;
-                       ret = read(i9ep->ici->fds[0], buf, 1);
-                       if (ret < 0) {
-                               ret = -ERRNO_TO_PARA_ERROR(errno);
-                               goto rm_btrn;
+                       while (i9ep->key_sequence_length < sizeof(i9ep->key_sequence) - 1) {
+                               buf = i9ep->key_sequence + i9ep->key_sequence_length;
+                               ret = read(i9ep->ici->fds[0], buf, 1);
+                               if (ret < 0) {
+                                       ret = -ERRNO_TO_PARA_ERROR(errno);
+                                       goto rm_btrn;
+                               }
+                               if (ret == 0) {
+                                       ret = -E_I9E_EOF;
+                                       goto rm_btrn;
+                               }
+                               buf[1] = '\0';
+                               i9ep->key_sequence_length++;
+                               rl_stuff_char((int)(unsigned char)*buf);
+                               rl_callback_read_char();
+                               if (read_ok(i9ep->ici->fds[0]) <= 0)
+                                       break;
                        }
-                       ret = -E_I9E_EOF;
-                       if (ret == 0)
-                               goto rm_btrn;
-                       buf[1] = '\0';
-                       i9ep->key_sequence_length++;
-                       rl_stuff_char((int)(unsigned char)*buf);
-               }
-               rl_callback_read_char();
+                       i9ep->key_sequence_length = 0;
+               } else
+                       rl_callback_read_char();
                ret = 0;
        }
        if (!i9ep->stdout_btrn)
@@ -369,7 +360,7 @@ out:
        return ret;
 }
 
-static void i9e_pre_select(struct sched *s, __a_unused void *context)
+static void i9e_pre_monitor(struct sched *s, __a_unused void *context)
 {
        int ret;
 
@@ -384,7 +375,7 @@ static void i9e_pre_select(struct sched *s, __a_unused void *context)
                        return;
                }
                if (ret > 0)
-                       para_fd_set(i9ep->ici->fds[1], &s->wfds, &s->max_fileno);
+                       sched_monitor_writefd(i9ep->ici->fds[1], s);
        }
        /*
         * fd[0] might have been reset to blocking mode if our job was moved to
@@ -395,7 +386,7 @@ static void i9e_pre_select(struct sched *s, __a_unused void *context)
        if (ret < 0)
                PARA_WARNING_LOG("set to nonblock failed: (fd0 %d, %s)\n",
                        i9ep->ici->fds[0], para_strerror(-ret));
-       para_fd_set(i9ep->ici->fds[0], &s->rfds, &s->max_fileno);
+       sched_monitor_readfd(i9ep->ici->fds[0], s);
 }
 
 static void update_winsize(void)
@@ -472,8 +463,8 @@ int i9e_open(struct i9e_client_info *ici, struct sched *s)
                return ret;
        i9ep->task = task_register(&(struct task_info) {
                .name = "i9e",
-               .pre_select = i9e_pre_select,
-               .post_select = i9e_post_select,
+               .pre_monitor = i9e_pre_monitor,
+               .post_monitor = i9e_post_monitor,
                .context = i9ep,
        }, s);
 
@@ -600,23 +591,21 @@ void i9e_signal_dispatch(int sig_num)
 }
 
 /**
- * Wrapper for select(2) which does not restart on interrupts.
+ * Wrapper for poll(2) which handles EINTR and returns paraslash error codes.
  *
- * \param n \sa \ref para_select().
- * \param readfds \sa \ref para_select().
- * \param writefds \sa \ref para_select().
- * \param timeout_tv \sa \ref para_select().
+ * \param fds See poll(2).
+ * \param nfds See poll(2).
+ * \param timeout See poll(2).
  *
- * \return \sa \ref para_select().
+ * \return See poll(2).
  *
- * The only difference between this function and \ref para_select() is that
- * \ref i9e_select() returns zero if the select call returned \p EINTR.
+ * The only difference between this function and \ref xpoll() is that \ref
+ * i9e_poll() returns zero if the system call was interrupted while xpoll()
+ * restarts the system call in this case.
  */
-int i9e_select(int n, fd_set *readfds, fd_set *writefds,
-               struct timeval *timeout_tv)
+int i9e_poll(struct pollfd *fds, nfds_t nfds, int timeout)
 {
-       int ret = select(n, readfds, writefds, NULL, timeout_tv);
-
+       int ret = poll(fds, nfds, timeout);
        if (ret < 0) {
                if (errno == EINTR)
                        ret = 0;
@@ -805,3 +794,25 @@ create_matches:
        free(ci.word);
        return ret;
 }
+
+/**
+ * Complete on severity strings.
+ *
+ * \param ci See struct \ref i9e_completer.
+ * \param cr See struct \ref i9e_completer.
+ *
+ * This is used by para_client and para_audioc which need the same completion
+ * primitive for the ll server/audiod command. Both define their own completer
+ * which is implemented as a trivial wrapper that calls this function.
+ */
+void i9e_ll_completer(struct i9e_completion_info *ci,
+               struct i9e_completion_result *cr)
+{
+       char *sev[] = {SEVERITIES, NULL};
+
+       if (ci->word_num != 1) {
+               cr->matches = NULL;
+               return;
+       }
+       i9e_extract_completions(ci->word, sev, &cr->matches);
+}