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