1*46073Sbostic /*- 2*46073Sbostic * Copyright (c) 1990 The Regents of the University of California. 3*46073Sbostic * All rights reserved. 4*46073Sbostic * 5*46073Sbostic * This code is derived from software contributed to Berkeley by 6*46073Sbostic * Chris Torek. 7*46073Sbostic * 8*46073Sbostic * %sccs.include.redist.c% 9*46073Sbostic */ 10*46073Sbostic 1126643Sdonn #if defined(LIBC_SCCS) && !defined(lint) 12*46073Sbostic static char sccsid[] = "@(#)fgets.c 5.3 (Berkeley) 01/20/91"; 13*46073Sbostic #endif /* LIBC_SCCS and not lint */ 1422131Smckusick 15*46073Sbostic #include <stdio.h> 16*46073Sbostic #include <string.h> 172001Swnj 18*46073Sbostic /* 19*46073Sbostic * Read at most n-1 characters from the given file. 20*46073Sbostic * Stop when a newline has been read, or the count runs out. 21*46073Sbostic * Return first argument, or NULL if no characters were read. 22*46073Sbostic */ 232001Swnj char * 24*46073Sbostic fgets(buf, n, fp) 25*46073Sbostic char *buf; 26*46073Sbostic register size_t n; 27*46073Sbostic register FILE *fp; 282001Swnj { 29*46073Sbostic register size_t len; 30*46073Sbostic register char *s; 31*46073Sbostic register unsigned char *p, *t; 322001Swnj 33*46073Sbostic if (n < 2) /* sanity check */ 34*46073Sbostic return (NULL); 35*46073Sbostic 36*46073Sbostic s = buf; 37*46073Sbostic n--; /* leave space for NUL */ 38*46073Sbostic do { 39*46073Sbostic /* 40*46073Sbostic * If the buffer is empty, refill it. 41*46073Sbostic */ 42*46073Sbostic if ((len = fp->_r) <= 0) { 43*46073Sbostic if (__srefill(fp)) { 44*46073Sbostic /* EOF/error: stop with partial or no line */ 45*46073Sbostic if (s == buf) 46*46073Sbostic return (NULL); 47*46073Sbostic break; 48*46073Sbostic } 49*46073Sbostic len = fp->_r; 50*46073Sbostic } 51*46073Sbostic p = fp->_p; 52*46073Sbostic 53*46073Sbostic /* 54*46073Sbostic * Scan through at most n bytes of the current buffer, 55*46073Sbostic * looking for '\n'. If found, copy up to and including 56*46073Sbostic * newline, and stop. Otherwise, copy entire chunk 57*46073Sbostic * and loop. 58*46073Sbostic */ 59*46073Sbostic if (len > n) 60*46073Sbostic len = n; 61*46073Sbostic t = memchr((void *)p, '\n', len); 62*46073Sbostic if (t != NULL) { 63*46073Sbostic len = ++t - p; 64*46073Sbostic fp->_r -= len; 65*46073Sbostic fp->_p = t; 66*46073Sbostic (void) memcpy((void *)s, (void *)p, len); 67*46073Sbostic s[len] = 0; 68*46073Sbostic return (buf); 69*46073Sbostic } 70*46073Sbostic fp->_r -= len; 71*46073Sbostic fp->_p += len; 72*46073Sbostic (void) memcpy((void *)s, (void *)p, len); 73*46073Sbostic s += len; 74*46073Sbostic } while ((n -= len) != 0); 75*46073Sbostic *s = 0; 76*46073Sbostic return (buf); 772001Swnj } 78