diff options
author | Dominique Martinet <asmadeus@codewreck.org> | 2022-01-28 20:20:12 +0900 |
---|---|---|
committer | Dominique Martinet <asmadeus@codewreck.org> | 2022-01-28 20:20:12 +0900 |
commit | 33883107171af9a683a11feaac6c3dd7b7991fff (patch) | |
tree | ddda178daffde9c7ebfb48484f14119100945eca | |
parent | d1726fd170b088e45e439e5b8308a650ddbf2ee3 (diff) |
if buffer is full from the start then there is no space
left for the next read, leave some room left in that case
also add some input generator for testing while we're here
-rwxr-xr-x | input.sh | 40 | ||||
-rw-r--r-- | tailburst.c | 29 |
2 files changed, 60 insertions, 9 deletions
diff --git a/input.sh b/input.sh new file mode 100755 index 0000000..00b6dca --- /dev/null +++ b/input.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +TEXT=() + +case "$1" in +1) + t="" + for _ in {1..2000}; do + t+="0123456789" + done + TEXT=("$t" one) + ;; +2) + t="" + for _ in {1..100}; do + t+="0123456789"$'\n' + done + for _ in {1..5}; do + TEXT+=("$t""0123456789") + done + ;; +3) + t="" + for _ in {1..100}; do + t+="0123456789" + done + for _ in {1..5}; do + t="$t"$'\n'"$t" + done + TEXT=("$t" one) + ;; +*) + TEXT=($'one\ntwo\nthree' one two $'three\nfour' five) + ;; +esac + +for t in "${TEXT[@]}"; do + printf "%s\n" "$t" + sleep 1 +done diff --git a/tailburst.c b/tailburst.c index b5b919e..e150e8c 100644 --- a/tailburst.c +++ b/tailburst.c @@ -6,7 +6,7 @@ #include <errno.h> #include <stdlib.h> -#define BUFLEN 1024 +#define MAXBUFLEN 8096 #define DEBUG 0 #define pr_debug(fmt, args...) if (DEBUG) printf(fmt, ##args) @@ -55,8 +55,14 @@ ssize_t fdgetline(int fd, struct getline_states *line) { /* search from here */ while (1) { + size_t toread = line->size - line->read - 1; + /* if there is no current line we need to keep some leeway + * for the next read... */ + if (!line->cur) + toread /= 2; errno = 0; - nread = read(fd, line->base + line->read, line->size - line->read - 1); + nread = read(fd, line->base + line->read, toread); + pr_debug("read %zd/%zd (%d)\n", nread, toread, errno); if (nread < 0) { if (errno == EAGAIN) return 0; @@ -66,7 +72,6 @@ ssize_t fdgetline(int fd, struct getline_states *line) { /* EOF */ return -1; } - pr_debug("read %zd\n", nread); line->read += nread; line->base[line->read] = '\0'; @@ -75,17 +80,20 @@ ssize_t fdgetline(int fd, struct getline_states *line) { line->cur = line->next; line->next = str + 1; str[0] = '\0'; - pr_debug("found stuff, %p %p %p: %s\n", str, line->base, line->cur, line->cur); + pr_debug("found stuff, %p %p %p: %s\n", + str, line->base, line->cur, line->cur); return 1; } /* realloc bigger buffer and try again if sensible */ - if (line->size - line->read > 100) + if (line->size - line->read > line->size / 2) continue; - if (line->size > 1024) { + if (line->size > MAXBUFLEN / 2) { /* pretend this was a full line.. */ line->cur = line->next; line->next = line->base + line->read; + pr_debug("returning full line early, %p %p %p: %s\n", + str, line->base, line->cur, line->cur); return 1; } line->size *= 2; @@ -95,13 +103,14 @@ ssize_t fdgetline(int fd, struct getline_states *line) { if (newbase == NULL) return -ENOMEM; if (line->cur) { - pr_debug("base-cur was %p-%p, new %p-%p\n", line->base, line->cur, newbase, newbase + (line->cur - line->base)); + pr_debug("base-cur was %p-%p, new %p-%p\n", + line->base, line->cur, newbase, + newbase + (line->cur - line->base)); line->cur = newbase + (line->cur - line->base); } line->next = newbase + (line->next - line->base); line->base = newbase; } - pr_debug("read failed? %zd %d\n", nread, errno); if (errno) return -errno; @@ -113,7 +122,7 @@ ssize_t fdgetline(int fd, struct getline_states *line) { int main(int argc, char **argv) { int flags, fd = 0; - ssize_t nread; + ssize_t nread = 0; struct pollfd pollfd; struct getline_states line = { 0 }; @@ -141,6 +150,8 @@ int main(int argc, char **argv) /* throttle in case something tries to wake us up every few ms... */ sleep(1); } + pr_debug("done, nread: %zd\n", nread); + free(line.base); return 0; } |