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
lflush(fp)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 */
__srefill(fp)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