summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDominique Martinet <asmadeus@codewreck.org>2022-01-28 20:20:12 +0900
committerDominique Martinet <asmadeus@codewreck.org>2022-01-28 20:20:12 +0900
commit33883107171af9a683a11feaac6c3dd7b7991fff (patch)
treeddda178daffde9c7ebfb48484f14119100945eca
parentd1726fd170b088e45e439e5b8308a650ddbf2ee3 (diff)
fix long line againHEADmaster
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-xinput.sh40
-rw-r--r--tailburst.c29
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;
}