| /* 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 <features.h> | 
 |  | 
 | #ifdef __USE_GNU | 
 | #include "_stdio.h" | 
 |  | 
 |  | 
 |  | 
 | /* 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) | 
 | #endif |