Cygwin: mmap: allow remapping part of an existing anonymous mapping
[newlib-cygwin.git] / newlib / libc / stdio / refill.c
blobcd71ed1529ba2c94e14fe1cf248bb00bbaad421b
1 /*
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
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.
17 /* No user fns here. Pesch 15apr92. */
19 #include <_ansi.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <errno.h>
23 #include "local.h"
25 static int
26 lflush (struct _reent * ptr __unused, FILE *fp)
28 if ((fp->_flags & (__SLBF | __SWR)) == (__SLBF | __SWR))
29 return _fflush_r (_REENT, fp);
30 return 0;
34 * Refill a stdio buffer.
35 * Return EOF on eof or error, 0 otherwise.
38 int
39 __srefill_r (struct _reent * ptr,
40 register FILE * fp)
42 /* make sure stdio is set up */
44 CHECK_INIT (ptr, fp);
46 fp->_r = 0; /* largely a convenience for callers */
48 /* SysV does not make this test; take it out for compatibility */
49 if (fp->_flags & __SEOF)
50 return EOF;
52 /* if not already reading, have to be reading and writing */
53 if ((fp->_flags & __SRD) == 0)
55 if ((fp->_flags & __SRW) == 0)
57 _REENT_ERRNO(ptr) = EBADF;
58 fp->_flags |= __SERR;
59 return EOF;
61 /* switch to reading */
62 if (fp->_flags & __SWR)
64 if (_fflush_r (ptr, fp))
65 return EOF;
66 fp->_flags &= ~__SWR;
67 fp->_w = 0;
68 fp->_lbfsize = 0;
70 fp->_flags |= __SRD;
72 else
75 * We were reading. If there is an ungetc buffer,
76 * we must have been reading from that. Drop it,
77 * restoring the previous buffer (if any). If there
78 * is anything in that buffer, return.
80 if (HASUB (fp))
82 FREEUB (ptr, fp);
83 if ((fp->_r = fp->_ur) != 0)
85 fp->_p = fp->_up;
86 return 0;
91 if (fp->_bf._base == NULL)
92 __smakebuf_r (ptr, fp);
95 * Before reading from a line buffered or unbuffered file,
96 * flush all line buffered output files, per the ANSI C
97 * standard.
99 if (fp->_flags & (__SLBF | __SNBF))
101 /* Ignore this file in _fwalk_sglue to avoid potential deadlock. */
102 short orig_flags = fp->_flags;
103 fp->_flags = 1;
104 (void) _fwalk_sglue (_GLOBAL_REENT, lflush, &__sglue);
105 fp->_flags = orig_flags;
107 /* Now flush this file without locking it. */
108 if ((fp->_flags & (__SLBF|__SWR)) == (__SLBF|__SWR))
109 __sflush_r (ptr, fp);
112 fp->_p = fp->_bf._base;
113 fp->_r = fp->_read (ptr, fp->_cookie, (char *) fp->_p, fp->_bf._size);
114 if (fp->_r <= 0)
116 if (fp->_r == 0)
117 fp->_flags |= __SEOF;
118 else
120 fp->_r = 0;
121 fp->_flags |= __SERR;
123 return EOF;
125 return 0;