From: Stefan Sperling Subject: use polling read in gotsh/got-fetch-pack To: gameoftrees@openbsd.org Date: Fri, 3 May 2024 11:10:42 +0200 This patch attempts to avoid an issue seen on got.g.o where a gotsh process was stuck forever trying to read from stdin, which is a socket. We should probably make this timeout configurable since essentially caps our time spent waiting for input from the Git/Got client before we drop the connection. I don't know if 30 seconds is a reasonable limit. We'll see how it works in practice. Tests are passing and I have this running on got.g.o. ok? diff /home/stsp/src/got commit - 7268d4618603a3243f53ced23fc7ccc40f7d0693 path + /home/stsp/src/got blob - 8f7e6fc6016a235ad21bdb871cd462f6715956a3 file + lib/pkt.c --- lib/pkt.c +++ lib/pkt.c @@ -24,21 +24,25 @@ #include "got_error.h" #include "got_lib_pkt.h" +#include "got_lib_poll.h" +#define GOT_PKT_TIMEOUT 30 + const struct got_error * got_pkt_readn(ssize_t *off, int fd, void *buf, size_t n) { - ssize_t r; + const struct got_error *err; + size_t len; - *off = 0; - while (*off != n) { - r = read(fd, buf + *off, n - *off); - if (r == -1) - return got_error_from_errno("read"); - if (r == 0) - return got_error(GOT_ERR_EOF); - *off += r; - } + err = got_poll_read_full_timeout(fd, &len, buf, n, n, + GOT_PKT_TIMEOUT); + if (err) + return err; + + /* XXX size_t -> ssize_t */ + if (len > SSIZE_MAX) + return got_error(GOT_ERR_RANGE); + *off = len; return NULL; }