diff options
author | David Oberhollenzer <david.oberhollenzer@tele2.at> | 2018-02-25 14:33:19 +0100 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@tele2.at> | 2018-03-24 17:04:20 +0100 |
commit | 9a88f7da453eadc72d8f333700dbd80777feecd1 (patch) | |
tree | 8a096e37123ece1d20bcb4d0ae8e064bdd39747a /lib/src/rdline.c |
Initial commit
Signed-off-by: David Oberhollenzer <david.oberhollenzer@tele2.at>
Diffstat (limited to 'lib/src/rdline.c')
-rw-r--r-- | lib/src/rdline.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/lib/src/rdline.c b/lib/src/rdline.c new file mode 100644 index 0000000..591c713 --- /dev/null +++ b/lib/src/rdline.c @@ -0,0 +1,54 @@ +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include <ctype.h> + +#include "util.h" + +char *rdline(int fd) +{ + size_t i = 0, bufsiz = 0, newsz; + char c, *new, *buffer = NULL; + int ret; + + for (;;) { + switch (read(fd, &c, 1)) { + case 0: + if (i == 0) { + errno = 0; + return NULL; + } + c = '\0'; + break; + case 1: + if (c == '\n') + c = '\0'; + break; + default: + if (errno == EINTR) + continue; + goto fail; + } + + if (i == bufsiz) { + newsz = bufsiz ? bufsiz * 2 : 16; + new = realloc(buffer, newsz); + + if (new == NULL) + goto fail; + + buffer = new; + bufsiz = newsz; + } + + buffer[i++] = c; + if (c == '\0') + break; + } + return buffer; +fail: + ret = errno; + free(buffer); + errno = ret; + return NULL; +} |