#include #include #include #include #include #include #include #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; }