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 ORIENT (fp, -1);
48
49 fp->_r = 0; /* largely a convenience for callers */
50
51 /* SysV does not make this test; take it out for compatibility */
52 if (fp->_flags & __SEOF)
53 return EOF;
54
55 /* if not already reading, have to be reading and writing */
56 if ((fp->_flags & __SRD) == 0)
57 {
58 if ((fp->_flags & __SRW) == 0)
59 {
60 _REENT_ERRNO(ptr) = EBADF;
61 fp->_flags |= __SERR;
62 return EOF;
63 }
64 /* switch to reading */
65 if (fp->_flags & __SWR)
66 {
67 if (fflush ( fp))
68 return EOF;
69 fp->_flags &= ~__SWR;
70 fp->_w = 0;
71 fp->_lbfsize = 0;
72 }
73 fp->_flags |= __SRD;
74 }
75 else
76 {
77 /*
78 * We were reading. If there is an ungetc buffer,
79 * we must have been reading from that. Drop it,
80 * restoring the previous buffer (if any). If there
81 * is anything in that buffer, return.
82 */
83 if (HASUB (fp))
84 {
85 FREEUB (ptr, fp);
86 if ((fp->_r = fp->_ur) != 0)
87 {
88 fp->_p = fp->_up;
89 return 0;
90 }
91 }
92 }
93
94 if (fp->_bf._base == NULL)
95 _smakebuf ( fp);
96
97 /*
98 * Before reading from a line buffered or unbuffered file,
99 * flush all line buffered output files, per the ANSI C
100 * standard.
101 */
102 if (fp->_flags & (__SLBF | __SNBF))
103 {
104 /* Ignore this file in _fwalk_sglue to avoid potential deadlock. */
105 short orig_flags = fp->_flags;
106 fp->_flags = 1;
107 (void) _fwalk_sglue (lflush, &__sglue);
108 fp->_flags = orig_flags;
109
110 /* Now flush this file without locking it. */
111 if ((fp->_flags & (__SLBF|__SWR)) == (__SLBF|__SWR))
112 _sflush ( fp);
113 }
114
115 fp->_p = fp->_bf._base;
116 fp->_r = fp->_read (fp->_cookie, (char *) fp->_p, fp->_bf._size);
117 if (fp->_r <= 0)
118 {
119 if (fp->_r == 0)
120 fp->_flags |= __SEOF;
121 else
122 {
123 fp->_r = 0;
124 fp->_flags |= __SERR;
125 }
126 return EOF;
127 }
128 return 0;
129 }
130