* Copyright (c) 1990 The Regents of the University of California.
* This code is derived from software contributed to Berkeley by
* %sccs.include.redist.c%
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid
[] = "@(#)fgetln.c 5.4 (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
* Expand the line buffer. Return -1 on error.
* The `new size' does not account for a terminating '\0',
if (fp
->_lb
._size
>= newsize
)
if ((p
= realloc(fp
->_lb
._base
, newsize
)) == NULL
)
* Get an input line. The returned pointer often (but not always)
* points into a stdio buffer. Fgetline does not alter the text of
* the returned line (which is thus not a C string because it will
* not necessarily end with '\0'), but does allow callers to modify
* it if they wish. Thus, we set __SMOD in case the caller does.
register unsigned char *p
;
/* make sure there is input */
if (fp
->_r
<= 0 && __srefill(fp
)) {
/* look for a newline in the input */
if ((p
= memchr((void *)fp
->_p
, '\n', fp
->_r
)) != NULL
) {
* Found one. Flag buffer as modified to keep fseek from
* `optimising' a backward seek, in case the user stomps on
p
++; /* advance over it */
*lenp
= len
= p
- fp
->_p
;
* We have to copy the current buffered data to the line buffer.
* As a bonus, though, we can leave off the __SMOD.
* OPTIMISTIC is length that we (optimistically) expect will
* accomodate the `rest' of the string, on each trip through the
for (len
= fp
->_r
, off
= 0;; len
+= fp
->_r
) {
* Make sure there is room for more bytes. Copy data from
* file buffer to line buffer, refill file and look for
* newline. The loop stops only when we find a newline.
if (__slbexpand(fp
, len
+ OPTIMISTIC
))
(void)memcpy((void *)(fp
->_lb
._base
+ off
), (void *)fp
->_p
,
break; /* EOF or error: return partial line */
if ((p
= memchr((void *)fp
->_p
, '\n', fp
->_r
)) == NULL
)
/* got it: finish up the line (like code above) */
if (__slbexpand(fp
, len
))
(void)memcpy((void *)(fp
->_lb
._base
+ off
), (void *)fp
->_p
,
return ((char *)fp
->_lb
._base
);