146111Sbostic /*- 246111Sbostic * Copyright (c) 1990 The Regents of the University of California. 346111Sbostic * All rights reserved. 446111Sbostic * 546111Sbostic * This code is derived from software contributed to Berkeley by 646111Sbostic * Chris Torek. 746111Sbostic * 846111Sbostic * %sccs.include.redist.c% 946111Sbostic */ 1046111Sbostic 1146111Sbostic #if defined(LIBC_SCCS) && !defined(lint) 12*46216Sbostic static char sccsid[] = "@(#)refill.c 5.2 (Berkeley) 02/01/91"; 1346111Sbostic #endif /* LIBC_SCCS and not lint */ 1446111Sbostic 1546111Sbostic #include <errno.h> 1646111Sbostic #include <stdio.h> 1746111Sbostic #include "local.h" 1846111Sbostic 1946111Sbostic static 2046111Sbostic lflush(fp) 2146111Sbostic FILE *fp; 2246111Sbostic { 2346111Sbostic 2446111Sbostic if ((fp->_flags & (__SLBF|__SWR)) == __SLBF|__SWR) 25*46216Sbostic return (__sflush(fp)); 2646111Sbostic return (0); 2746111Sbostic } 2846111Sbostic 2946111Sbostic /* 3046111Sbostic * Refill a stdio buffer. 3146111Sbostic * Return EOF on eof or error, 0 otherwise. 3246111Sbostic */ 3346111Sbostic __srefill(fp) 3446111Sbostic register FILE *fp; 3546111Sbostic { 3646111Sbostic 3746111Sbostic /* make sure stdio is set up */ 3846111Sbostic if (!__sdidinit) 3946111Sbostic __sinit(); 4046111Sbostic 4146111Sbostic fp->_r = 0; /* largely a convenience for callers */ 4246111Sbostic 4346111Sbostic /* SysV does not make this test; take it out for compatibility */ 4446111Sbostic if (fp->_flags & __SEOF) 4546111Sbostic return (EOF); 4646111Sbostic 4746111Sbostic /* if not already reading, have to be reading and writing */ 4846111Sbostic if ((fp->_flags & __SRD) == 0) { 4946111Sbostic if ((fp->_flags & __SRW) == 0) { 5046111Sbostic errno = EBADF; 5146111Sbostic return (EOF); 5246111Sbostic } 5346111Sbostic /* switch to reading */ 5446111Sbostic if (fp->_flags & __SWR) { 55*46216Sbostic if (__sflush(fp)) 5646111Sbostic return (EOF); 5746111Sbostic fp->_flags &= ~__SWR; 5846111Sbostic fp->_w = 0; 5946111Sbostic fp->_lbfsize = 0; 6046111Sbostic } 6146111Sbostic fp->_flags |= __SRD; 6246111Sbostic } else { 6346111Sbostic /* 6446111Sbostic * We were reading. If there is an ungetc buffer, 6546111Sbostic * we must have been reading from that. Drop it, 6646111Sbostic * restoring the previous buffer (if any). If there 6746111Sbostic * is anything in that buffer, return. 6846111Sbostic */ 6946111Sbostic if (HASUB(fp)) { 7046111Sbostic FREEUB(fp); 7146111Sbostic if ((fp->_r = fp->_ur) != 0) { 7246111Sbostic fp->_p = fp->_up; 7346111Sbostic return (0); 7446111Sbostic } 7546111Sbostic } 7646111Sbostic } 7746111Sbostic 7846111Sbostic if (fp->_bf._base == NULL) 7946111Sbostic __smakebuf(fp); 8046111Sbostic 8146111Sbostic /* 8246111Sbostic * Before reading from a line buffered or unbuffered file, 8346111Sbostic * flush all line buffered output files, per the ANSI C 8446111Sbostic * standard. 8546111Sbostic */ 8646111Sbostic if (fp->_flags & (__SLBF|__SNBF)) 8746111Sbostic (void) _fwalk(lflush); 8846111Sbostic fp->_p = fp->_bf._base; 8946111Sbostic fp->_r = (*fp->_read)(fp->_cookie, (char *)fp->_p, fp->_bf._size); 9046111Sbostic fp->_flags &= ~__SMOD; /* buffer contents are again pristine */ 9146111Sbostic if (fp->_r <= 0) { 9246111Sbostic if (fp->_r == 0) 9346111Sbostic fp->_flags |= __SEOF; 9446111Sbostic else { 9546111Sbostic fp->_r = 0; 9646111Sbostic fp->_flags |= __SERR; 9746111Sbostic } 9846111Sbostic return (EOF); 9946111Sbostic } 10046111Sbostic return (0); 10146111Sbostic } 102