no SCCS file; new copyright; att/bsd/shared
[unix-history] / usr / src / lib / libc / stdio / refill.c
CommitLineData
c9be6cfe
KB
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)
cb631443 12static char sccsid[] = "@(#)refill.c 5.3 (Berkeley) %G%";
c9be6cfe
KB
13#endif /* LIBC_SCCS and not lint */
14
15#include <errno.h>
16#include <stdio.h>
cb631443 17#include <stdlib.h>
c9be6cfe
KB
18#include "local.h"
19
20static
21lflush(fp)
22 FILE *fp;
23{
24
25 if ((fp->_flags & (__SLBF|__SWR)) == __SLBF|__SWR)
5b2b97c1 26 return (__sflush(fp));
c9be6cfe
KB
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) {
5b2b97c1 56 if (__sflush(fp))
c9be6cfe
KB
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}