1 /*
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * and/or other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16 */
17 /* No user fns here. Pesch 15apr92. */
18
19 #define _DEFAULT_SOURCE
20 #include <_ansi.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <errno.h>
24 #include "local.h"
25
26 static int
lflush(FILE * fp)27 lflush (FILE *fp)
28 {
29 if ((fp->_flags & (__SLBF | __SWR)) == (__SLBF | __SWR))
30 return fflush ( fp);
31 return 0;
32 }
33
34 /*
35 * Refill a stdio buffer.
36 * Return EOF on eof or error, 0 otherwise.
37 */
38
39 int
_srefill(register FILE * fp)40 _srefill (
41 register FILE * fp)
42 {
43 /* make sure stdio is set up */
44
45 CHECK_INIT (ptr, fp);
46
47 fp->_r = 0; /* largely a convenience for callers */
48
49 /* SysV does not make this test; take it out for compatibility */
50 if (fp->_flags & __SEOF)
51 return EOF;
52
53 /* if not already reading, have to be reading and writing */
54 if ((fp->_flags & __SRD) == 0)
55 {
56 if ((fp->_flags & __SRW) == 0)
57 {
58 _REENT_ERRNO(ptr) = EBADF;
59 fp->_flags |= __SERR;
60 return EOF;
61 }
62 /* switch to reading */
63 if (fp->_flags & __SWR)
64 {
65 if (fflush ( fp))
66 return EOF;
67 fp->_flags &= ~__SWR;
68 fp->_w = 0;
69 fp->_lbfsize = 0;
70 }
71 fp->_flags |= __SRD;
72 }
73 else
74 {
75 /*
76 * We were reading. If there is an ungetc buffer,
77 * we must have been reading from that. Drop it,
78 * restoring the previous buffer (if any). If there
79 * is anything in that buffer, return.
80 */
81 if (HASUB (fp))
82 {
83 FREEUB (ptr, fp);
84 if ((fp->_r = fp->_ur) != 0)
85 {
86 fp->_p = fp->_up;
87 return 0;
88 }
89 }
90 }
91
92 if (fp->_bf._base == NULL)
93 _smakebuf ( fp);
94
95 /*
96 * Before reading from a line buffered or unbuffered file,
97 * flush all line buffered output files, per the ANSI C
98 * standard.
99 */
100 if (fp->_flags & (__SLBF | __SNBF))
101 {
102 /* Ignore this file in _fwalk_sglue to avoid potential deadlock. */
103 short orig_flags = fp->_flags;
104 fp->_flags = 1;
105 (void) _fwalk_sglue (lflush, &__sglue);
106 fp->_flags = orig_flags;
107
108 /* Now flush this file without locking it. */
109 if ((fp->_flags & (__SLBF|__SWR)) == (__SLBF|__SWR))
110 _sflush ( fp);
111 }
112
113 fp->_p = fp->_bf._base;
114 fp->_r = fp->_read (fp->_cookie, (char *) fp->_p, fp->_bf._size);
115 if (fp->_r <= 0)
116 {
117 if (fp->_r == 0)
118 fp->_flags |= __SEOF;
119 else
120 {
121 fp->_r = 0;
122 fp->_flags |= __SERR;
123 }
124 return EOF;
125 }
126 return 0;
127 }
128