146073Sbostic /*- 2*61180Sbostic * Copyright (c) 1990, 1993 3*61180Sbostic * The Regents of the University of California. All rights reserved. 446073Sbostic * 546073Sbostic * This code is derived from software contributed to Berkeley by 646073Sbostic * Chris Torek. 746073Sbostic * 846073Sbostic * %sccs.include.redist.c% 946073Sbostic */ 1046073Sbostic 1126643Sdonn #if defined(LIBC_SCCS) && !defined(lint) 12*61180Sbostic static char sccsid[] = "@(#)fgets.c 8.1 (Berkeley) 06/04/93"; 1346073Sbostic #endif /* LIBC_SCCS and not lint */ 1422131Smckusick 1546073Sbostic #include <stdio.h> 1646073Sbostic #include <string.h> 172001Swnj 1846073Sbostic /* 1946073Sbostic * Read at most n-1 characters from the given file. 2046073Sbostic * Stop when a newline has been read, or the count runs out. 2146073Sbostic * Return first argument, or NULL if no characters were read. 2246073Sbostic */ 232001Swnj char * 2446073Sbostic fgets(buf, n, fp) 2546073Sbostic char *buf; 2646073Sbostic register size_t n; 2746073Sbostic register FILE *fp; 282001Swnj { 2946073Sbostic register size_t len; 3046073Sbostic register char *s; 3146073Sbostic register unsigned char *p, *t; 322001Swnj 3346073Sbostic if (n < 2) /* sanity check */ 3446073Sbostic return (NULL); 3546073Sbostic 3646073Sbostic s = buf; 3746073Sbostic n--; /* leave space for NUL */ 3846073Sbostic do { 3946073Sbostic /* 4046073Sbostic * If the buffer is empty, refill it. 4146073Sbostic */ 4246073Sbostic if ((len = fp->_r) <= 0) { 4346073Sbostic if (__srefill(fp)) { 4446073Sbostic /* EOF/error: stop with partial or no line */ 4546073Sbostic if (s == buf) 4646073Sbostic return (NULL); 4746073Sbostic break; 4846073Sbostic } 4946073Sbostic len = fp->_r; 5046073Sbostic } 5146073Sbostic p = fp->_p; 5246073Sbostic 5346073Sbostic /* 5446073Sbostic * Scan through at most n bytes of the current buffer, 5546073Sbostic * looking for '\n'. If found, copy up to and including 5646073Sbostic * newline, and stop. Otherwise, copy entire chunk 5746073Sbostic * and loop. 5846073Sbostic */ 5946073Sbostic if (len > n) 6046073Sbostic len = n; 6146073Sbostic t = memchr((void *)p, '\n', len); 6246073Sbostic if (t != NULL) { 6346073Sbostic len = ++t - p; 6446073Sbostic fp->_r -= len; 6546073Sbostic fp->_p = t; 6658451Storek (void)memcpy((void *)s, (void *)p, len); 6746073Sbostic s[len] = 0; 6846073Sbostic return (buf); 6946073Sbostic } 7046073Sbostic fp->_r -= len; 7146073Sbostic fp->_p += len; 7258451Storek (void)memcpy((void *)s, (void *)p, len); 7346073Sbostic s += len; 7446073Sbostic } while ((n -= len) != 0); 7546073Sbostic *s = 0; 7646073Sbostic return (buf); 772001Swnj } 78