X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=src%2Fstdio%2Fgetdelim.c;h=1ccd8029238987f05e183c3bfec186287dff89f0;hb=b6e1fe0d5e78dac647e85d49c2d537bb071ba49e;hp=20d345d1da604114a33640e94fbacffd65e91887;hpb=e3cd6c5c265cd481db6e0c5b529855d99f0bda30;p=musl diff --git a/src/stdio/getdelim.c b/src/stdio/getdelim.c index 20d345d1..1ccd8029 100644 --- a/src/stdio/getdelim.c +++ b/src/stdio/getdelim.c @@ -1,8 +1,11 @@ #include "stdio_impl.h" +#include +#include +#include #define MIN(a,b) ((a)<(b) ? (a) : (b)) -ssize_t getdelim(char **s, size_t *n, int delim, FILE *f) +ssize_t getdelim(char **restrict s, size_t *restrict n, int delim, FILE *restrict f) { char *tmp; unsigned char *z; @@ -10,29 +13,32 @@ ssize_t getdelim(char **s, size_t *n, int delim, FILE *f) 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; - FLOCK(f); - for (;;) { z = memchr(f->rpos, delim, f->rend - f->rpos); k = z ? z - f->rpos + 1 : f->rend - f->rpos; - if (i+k >= *n) { + if (i+k+1 >= *n) { if (k >= SIZE_MAX/2-i) goto oom; - *n = i+k+2; - if (*n < SIZE_MAX/4) *n *= 2; - tmp = realloc(*s, *n); + size_t m = i+k+2; + if (!z && m < SIZE_MAX/4) m += m/2; + tmp = realloc(*s, m); if (!tmp) { - *n = i+k+2; - tmp = realloc(*s, *n); + 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; @@ -53,7 +59,10 @@ ssize_t getdelim(char **s, size_t *n, int delim, FILE *f) return i; oom: + f->flags |= F_ERR; FUNLOCK(f); errno = ENOMEM; return -1; } + +weak_alias(getdelim, __getdelim);