1*46111Sbostic /*- 2*46111Sbostic * Copyright (c) 1990 The Regents of the University of California. 3*46111Sbostic * All rights reserved. 4*46111Sbostic * 5*46111Sbostic * This code is derived from software contributed to Berkeley by 6*46111Sbostic * Chris Torek. 7*46111Sbostic * 8*46111Sbostic * %sccs.include.redist.c% 9*46111Sbostic */ 10*46111Sbostic 11*46111Sbostic #if defined(LIBC_SCCS) && !defined(lint) 12*46111Sbostic static char sccsid[] = "@(#)refill.c 5.1 (Berkeley) 01/20/91"; 13*46111Sbostic #endif /* LIBC_SCCS and not lint */ 14*46111Sbostic 15*46111Sbostic #include <errno.h> 16*46111Sbostic #include <stdio.h> 17*46111Sbostic #include "local.h" 18*46111Sbostic 19*46111Sbostic static 20*46111Sbostic lflush(fp) 21*46111Sbostic FILE *fp; 22*46111Sbostic { 23*46111Sbostic 24*46111Sbostic if ((fp->_flags & (__SLBF|__SWR)) == __SLBF|__SWR) 25*46111Sbostic return (fflush(fp)); 26*46111Sbostic return (0); 27*46111Sbostic } 28*46111Sbostic 29*46111Sbostic /* 30*46111Sbostic * Refill a stdio buffer. 31*46111Sbostic * Return EOF on eof or error, 0 otherwise. 32*46111Sbostic */ 33*46111Sbostic __srefill(fp) 34*46111Sbostic register FILE *fp; 35*46111Sbostic { 36*46111Sbostic 37*46111Sbostic /* make sure stdio is set up */ 38*46111Sbostic if (!__sdidinit) 39*46111Sbostic __sinit(); 40*46111Sbostic 41*46111Sbostic fp->_r = 0; /* largely a convenience for callers */ 42*46111Sbostic 43*46111Sbostic /* SysV does not make this test; take it out for compatibility */ 44*46111Sbostic if (fp->_flags & __SEOF) 45*46111Sbostic return (EOF); 46*46111Sbostic 47*46111Sbostic /* if not already reading, have to be reading and writing */ 48*46111Sbostic if ((fp->_flags & __SRD) == 0) { 49*46111Sbostic if ((fp->_flags & __SRW) == 0) { 50*46111Sbostic errno = EBADF; 51*46111Sbostic return (EOF); 52*46111Sbostic } 53*46111Sbostic /* switch to reading */ 54*46111Sbostic if (fp->_flags & __SWR) { 55*46111Sbostic if (fflush(fp)) 56*46111Sbostic return (EOF); 57*46111Sbostic fp->_flags &= ~__SWR; 58*46111Sbostic fp->_w = 0; 59*46111Sbostic fp->_lbfsize = 0; 60*46111Sbostic } 61*46111Sbostic fp->_flags |= __SRD; 62*46111Sbostic } else { 63*46111Sbostic /* 64*46111Sbostic * We were reading. If there is an ungetc buffer, 65*46111Sbostic * we must have been reading from that. Drop it, 66*46111Sbostic * restoring the previous buffer (if any). If there 67*46111Sbostic * is anything in that buffer, return. 68*46111Sbostic */ 69*46111Sbostic if (HASUB(fp)) { 70*46111Sbostic FREEUB(fp); 71*46111Sbostic if ((fp->_r = fp->_ur) != 0) { 72*46111Sbostic fp->_p = fp->_up; 73*46111Sbostic return (0); 74*46111Sbostic } 75*46111Sbostic } 76*46111Sbostic } 77*46111Sbostic 78*46111Sbostic if (fp->_bf._base == NULL) 79*46111Sbostic __smakebuf(fp); 80*46111Sbostic 81*46111Sbostic /* 82*46111Sbostic * Before reading from a line buffered or unbuffered file, 83*46111Sbostic * flush all line buffered output files, per the ANSI C 84*46111Sbostic * standard. 85*46111Sbostic */ 86*46111Sbostic if (fp->_flags & (__SLBF|__SNBF)) 87*46111Sbostic (void) _fwalk(lflush); 88*46111Sbostic fp->_p = fp->_bf._base; 89*46111Sbostic fp->_r = (*fp->_read)(fp->_cookie, (char *)fp->_p, fp->_bf._size); 90*46111Sbostic fp->_flags &= ~__SMOD; /* buffer contents are again pristine */ 91*46111Sbostic if (fp->_r <= 0) { 92*46111Sbostic if (fp->_r == 0) 93*46111Sbostic fp->_flags |= __SEOF; 94*46111Sbostic else { 95*46111Sbostic fp->_r = 0; 96*46111Sbostic fp->_flags |= __SERR; 97*46111Sbostic } 98*46111Sbostic return (EOF); 99*46111Sbostic } 100*46111Sbostic return (0); 101*46111Sbostic } 102