1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- /* Copyright (C) 2004 Manuel Novoa III <mjn3@codepoet.org>
- *
- * GNU Library General Public License (LGPL) version 2 or later.
- *
- * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
- */
- #include "_stdio.h"
- libc_hidden_proto(getdelim)
- libc_hidden_proto(__fgetc_unlocked)
- /* 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 **__restrict lineptr, size_t *__restrict n,
- int delimiter, register FILE *__restrict stream)
- {
- register char *buf;
- ssize_t pos = -1;
- int c;
- __STDIO_AUTO_THREADLOCK_VAR;
- if (!lineptr || !n || !stream) { /* Be compatable with glibc... even */
- __set_errno(EINVAL); /* though I think we should assert here */
- } else {
- __STDIO_AUTO_THREADLOCK(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 = __GETC_UNLOCKED(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);
- __STDIO_AUTO_THREADUNLOCK(stream);
- }
- return pos;
- }
- libc_hidden_def(getdelim)
|