X-Git-Url: https://git.xandkar.net/?a=blobdiff_plain;f=x5%2Fkhatus.c;h=62b3774fdb21c18604dfd4da7de1e11f8b1fe926;hb=a415999c271885d6baf38c76b6fcf08ec0c0d2b6;hp=fad399494102841390e6755a8575343fabad7c68;hpb=03ed0008d381dbf3cda334e24842acf7783d3dbe;p=khatus.git diff --git a/x5/khatus.c b/x5/khatus.c index fad3994..62b3774 100644 --- a/x5/khatus.c +++ b/x5/khatus.c @@ -373,7 +373,7 @@ fifo_read_all(Config *cfg, char *buf) { fd_set fds; int maxfd = -1; - int ready; + int ready = 0; struct stat st; FD_ZERO(&fds); @@ -411,24 +411,43 @@ fifo_read_all(Config *cfg, char *buf) debug("ready: %d\n", ready); assert(ready != 0); if (ready < 0) + /* TODO: Do we really want to fail here? */ fatal("%s", strerror(errno)); - for (Fifo *f = cfg->fifos; f; f = f->next) { - if (FD_ISSET(f->fd, &fds)) { - debug("reading: %s\n", f->name); - switch (fifo_read_one(f, buf)) { - case END_OF_FILE: - case FAILURE: - close(f->fd); - f->fd = -1; - break; - case END_OF_MESSAGE: - case RETRY: - break; - default: - assert(0); + while (ready) { + for (Fifo *f = cfg->fifos; f; f = f->next) { + if (FD_ISSET(f->fd, &fds)) { + debug("reading: %s\n", f->name); + switch (fifo_read_one(f, buf)) { + /* + * ### MESSAGE LOSS ### + * is introduced by closing at EOM in addition + * to EOF, since there may be unread messages + * remaining in the pipe. However, + * + * ### INTER-MESSAGE PUSHBACK ### + * is also gained, since pipes block at the + * "open" call. + * + * This is an acceptable trade-off because we + * are a stateless reporter of a _most-recent_ + * status, not a stateful accumulator. + */ + case END_OF_MESSAGE: + case END_OF_FILE: + case FAILURE: + close(f->fd); + f->fd = -1; + ready--; + break; + case RETRY: + break; + default: + assert(0); + } } } } + assert(ready == 0); } int