/* Taken from uClibc and adapted to GLiv */ /* Copyright (C) 2004 Manuel Novoa III * * GNU Library General Public License (LGPL) version 2 or later. * * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details. */ #include #include #ifndef HAVE_GETDELIM #include "getdelim.h" #endif /* Note: There is a defect in this function. (size_t vs ssize_t). */ /* glibc function -- * Return -1 if error or EOF prior to any chars read. * Return number of chars read (including possible delimiter but not * the terminating nul) otherwise. * * NOTE: If we need to allocate a buffer, we do so prior to attempting * a reading. So space may be allocated even if initially at EOF. */ #define GETDELIM_GROWBY 64 ssize_t getdelim(char ** lineptr, size_t * n, int delimiter, FILE * stream) { char *buf; ssize_t pos = -1; int c; if (lineptr && n && stream) { if (!(buf = *lineptr)) { /* If passed NULL for buffer, */ *n = 0; /* ignore value passed and treat size as 0. */ } /* Within the loop, pos is actually the current buffer index + 2, * because we want to make sure we have enough space to store * an additional char plus a nul terminator. */ pos = 1; do { if (pos >= *n) { if (!(buf = realloc(buf, *n + GETDELIM_GROWBY))) { pos = -1; break; } *n += GETDELIM_GROWBY; *lineptr = buf; } if ((c = fgetc(stream)) != EOF) { buf[++pos - 2] = c; if (c != delimiter) { continue; } } /* We're done, so correct pos back to being the current index. */ if ((pos -= 2) >= 0) { buf[++pos] = 0; } break; } while (1); } return pos; }