summaryrefslogtreecommitdiffstats
path: root/tailburst.c
diff options
context:
space:
mode:
Diffstat (limited to 'tailburst.c')
-rw-r--r--tailburst.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/tailburst.c b/tailburst.c
new file mode 100644
index 0000000..4f4ce49
--- /dev/null
+++ b/tailburst.c
@@ -0,0 +1,103 @@
+#include <stdio.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#define BUFLEN 1024
+
+struct getline_states {
+ char *base;
+ char *cur;
+ size_t size;
+ size_t read;
+ char *next;
+};
+
+ssize_t fdgetline(int fd, struct getline_states *line) {
+ char *str;
+ ssize_t nread;
+
+ if (line->base == NULL) {
+ /* First pass: init state */
+ line->size = 120;
+ line->base = malloc(line->size);
+ if (line->base == NULL)
+ return -ENOMEM;
+ line->base[0] = '\0';
+ line->read = 0;
+ line->next = NULL;
+ }
+
+ /* Skip after previously returned line */
+ if (line->next)
+ line->cur = line->next;
+ else
+ line->cur = line->base;
+
+ /* Do we already have a full line in buffer? */
+ if (str = strchr(line->cur, '\n')) {
+ line->next = str+1;
+ str[0] = '\0';
+ return str - line->cur;
+ }
+
+ /* No such luck, move current to base and read what we can */
+ if (line->cur != line->base) {
+ line->read -= line->cur - line->base;
+ memmove(line->base, line->cur, line->read);
+ line->cur = line->base;
+ }
+
+ while ((nread = read(fd, line->base + line->read, line->size - line->read)) > 0 ) {
+ line->read += nread;
+
+ /* Check if we have a full line now */
+ if (str = strchr(line->base, '\n')) {
+ line->next = str+1;
+ str[0] = '\0';
+ return str - line->base;
+ }
+
+ /* realloc bigger buffer and try again */
+ line->size *= 2;
+ line->base = realloc(line->base, line->size);
+ if (line->base == NULL)
+ return -ENOMEM;
+ }
+
+ if (errno)
+ return -errno;
+
+ return 0; /* no line read */
+}
+
+
+int main(int argc, char **argv)
+{
+ int flags, fd = 0, rc;
+ size_t len = 0;
+ ssize_t nread;
+ char buf[BUFLEN];
+ struct pollfd pollfd;
+ struct getline_states line = { 0 };
+
+ /* make stream non-block */
+ #if 0
+ flags = fcntl(fd, F_GETFL);
+ flags |= O_NONBLOCK;
+ fcntl(fd, F_SETFL, flags);
+ #endif
+
+ pollfd.fd = fd;
+ pollfd.events = POLLIN;
+ while ((nread = fdgetline(fd, &line)) > 0) {
+ if (poll(&pollfd, 1, 100) == 0) {
+ printf("%s\n", line.cur);
+ }
+ }
+
+ return 0;
+}