bcopy => memcpy (safe in all these cases) for ANSI (sigh)
[unix-history] / usr / src / lib / libc / stdio / fgets.c
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
* %sccs.include.redist.c%
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)fgets.c 5.5 (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
#include <string.h>
/*
* Read at most n-1 characters from the given file.
* Stop when a newline has been read, or the count runs out.
* Return first argument, or NULL if no characters were read.
*/
char *
fgets(buf, n, fp)
char *buf;
register size_t n;
register FILE *fp;
{
register size_t len;
register char *s;
register unsigned char *p, *t;
if (n < 2) /* sanity check */
return (NULL);
s = buf;
n--; /* leave space for NUL */
do {
/*
* If the buffer is empty, refill it.
*/
if ((len = fp->_r) <= 0) {
if (__srefill(fp)) {
/* EOF/error: stop with partial or no line */
if (s == buf)
return (NULL);
break;
}
len = fp->_r;
}
p = fp->_p;
/*
* Scan through at most n bytes of the current buffer,
* looking for '\n'. If found, copy up to and including
* newline, and stop. Otherwise, copy entire chunk
* and loop.
*/
if (len > n)
len = n;
t = memchr((void *)p, '\n', len);
if (t != NULL) {
len = ++t - p;
fp->_r -= len;
fp->_p = t;
(void)memcpy((void *)s, (void *)p, len);
s[len] = 0;
return (buf);
}
fp->_r -= len;
fp->_p += len;
(void)memcpy((void *)s, (void *)p, len);
s += len;
} while ((n -= len) != 0);
*s = 0;
return (buf);
}