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