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