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