Index: fusl/src/stdio/getdelim.c |
diff --git a/fusl/src/stdio/getdelim.c b/fusl/src/stdio/getdelim.c |
new file mode 100644 |
index 0000000000000000000000000000000000000000..1ccd8029238987f05e183c3bfec186287dff89f0 |
--- /dev/null |
+++ b/fusl/src/stdio/getdelim.c |
@@ -0,0 +1,68 @@ |
+#include "stdio_impl.h" |
+#include <string.h> |
+#include <inttypes.h> |
+#include <errno.h> |
+ |
+#define MIN(a,b) ((a)<(b) ? (a) : (b)) |
+ |
+ssize_t getdelim(char **restrict s, size_t *restrict n, int delim, FILE *restrict f) |
+{ |
+ char *tmp; |
+ unsigned char *z; |
+ size_t k; |
+ size_t i=0; |
+ int c; |
+ |
+ FLOCK(f); |
+ |
+ if (!n || !s) { |
+ f->flags |= F_ERR; |
+ FUNLOCK(f); |
+ errno = EINVAL; |
+ return -1; |
+ } |
+ |
+ if (!*s) *n=0; |
+ |
+ for (;;) { |
+ z = memchr(f->rpos, delim, f->rend - f->rpos); |
+ k = z ? z - f->rpos + 1 : f->rend - f->rpos; |
+ if (i+k+1 >= *n) { |
+ if (k >= SIZE_MAX/2-i) goto oom; |
+ size_t m = i+k+2; |
+ if (!z && m < SIZE_MAX/4) m += m/2; |
+ tmp = realloc(*s, m); |
+ if (!tmp) { |
+ m = i+k+2; |
+ tmp = realloc(*s, m); |
+ if (!tmp) goto oom; |
+ } |
+ *s = tmp; |
+ *n = m; |
+ } |
+ memcpy(*s+i, f->rpos, k); |
+ f->rpos += k; |
+ i += k; |
+ if (z) break; |
+ if ((c = getc_unlocked(f)) == EOF) { |
+ if (!i || !feof(f)) { |
+ FUNLOCK(f); |
+ return -1; |
+ } |
+ break; |
+ } |
+ if (((*s)[i++] = c) == delim) break; |
+ } |
+ (*s)[i] = 0; |
+ |
+ FUNLOCK(f); |
+ |
+ return i; |
+oom: |
+ f->flags |= F_ERR; |
+ FUNLOCK(f); |
+ errno = ENOMEM; |
+ return -1; |
+} |
+ |
+weak_alias(getdelim, __getdelim); |