2 * Copyright (c) 1990 The Regents of the University of California.
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.
20 <<fflush>>, <<fflush_unlocked>>---flush buffered file output
33 int fflush(FILE *<[fp]>);
37 int fflush_unlocked(FILE *<[fp]>);
40 int _fflush_r(struct _reent *<[reent]>, FILE *<[fp]>);
44 int _fflush_unlocked_r(struct _reent *<[reent]>, FILE *<[fp]>);
47 The <<stdio>> output functions can buffer output before delivering it
48 to the host system, in order to minimize the overhead of system calls.
50 Use <<fflush>> to deliver any such pending output (for the file
51 or stream identified by <[fp]>) to the host system.
53 If <[fp]> is <<NULL>>, <<fflush>> delivers pending output from all
56 Additionally, if <[fp]> is a seekable input stream visiting a file
57 descriptor, set the position of the file descriptor to match next
58 unread byte, useful for obeying POSIX semantics when ending a process
59 without consuming all input from the stream.
61 <<fflush_unlocked>> is a non-thread-safe version of <<fflush>>.
62 <<fflush_unlocked>> may only safely be used within a scope
63 protected by flockfile() (or ftrylockfile()) and funlockfile(). This
64 function may safely be used in a multi-threaded program if and only
65 if they are called while the invoking thread owns the (FILE *)
66 object, as is the case after a successful call to the flockfile() or
67 ftrylockfile() functions. If threads are disabled, then
68 <<fflush_unlocked>> is equivalent to <<fflush>>.
70 The alternate functions <<_fflush_r>> and <<_fflush_unlocked_r>> are
71 reentrant versions, where the extra argument <[reent]> is a pointer to
72 a reentrancy structure, and <[fp]> must not be NULL.
75 <<fflush>> returns <<0>> unless it encounters a write error; in that
76 situation, it returns <<EOF>>.
79 ANSI C requires <<fflush>>. The behavior on input streams is only
80 specified by POSIX, and not all implementations follow POSIX rules.
82 <<fflush_unlocked>> is a BSD extension also provided by GNU libc.
84 No supporting OS subroutines are required.
92 #ifdef __IMPL_UNLOCKED__
93 #define _fflush_r _fflush_unlocked_r
94 #define fflush fflush_unlocked
97 #ifndef __IMPL_UNLOCKED__
98 /* Flush a single file, or (if fp is NULL) all files. */
100 /* Core function which does not lock file pointer. This gets called
101 directly from __srefill. */
103 __sflush_r (struct _reent
*ptr
,
106 register unsigned char *p
;
107 register _READ_WRITE_BUFSIZE_TYPE n
;
108 register _READ_WRITE_RETURN_TYPE t
;
112 if ((flags
& __SWR
) == 0)
114 #ifdef _FSEEK_OPTIMIZATION
115 /* For a read stream, an fflush causes the next seek to be
116 unoptimized (i.e. forces a system-level seek). This conforms
117 to the POSIX and SUSv3 standards. */
118 fp
->_flags
|= __SNPT
;
121 /* For a seekable stream with buffered read characters, we will attempt
122 a seek to the current position now. A subsequent read will then get
123 the next byte from the file rather than the buffer. This conforms
124 to the POSIX and SUSv3 standards. Note that the standards allow
125 this seek to be deferred until necessary, but we choose to do it here
126 to make the change simpler, more contained, and less likely
127 to miss a code scenario. */
128 if ((fp
->_r
> 0 || fp
->_ur
> 0) && fp
->_seek
!= NULL
)
131 #ifdef __LARGE64_FILES
137 /* Save last errno and set errno to 0, so we can check if a device
138 returns with a valid position -1. We restore the last errno if
139 no other error condition has been encountered. */
140 tmp_errno
= _REENT_ERRNO(ptr
);
141 _REENT_ERRNO(ptr
) = 0;
142 /* Get the physical position we are at in the file. */
143 if (fp
->_flags
& __SOFF
)
144 curoff
= fp
->_offset
;
147 /* We don't know current physical offset, so ask for it.
148 Only ESPIPE and EINVAL are ignorable. */
149 #ifdef __LARGE64_FILES
150 if (fp
->_flags
& __SL64
)
151 curoff
= fp
->_seek64 (ptr
, fp
->_cookie
, 0, SEEK_CUR
);
154 curoff
= fp
->_seek (ptr
, fp
->_cookie
, 0, SEEK_CUR
);
155 if (curoff
== -1L && _REENT_ERRNO(ptr
) != 0)
158 if (_REENT_ERRNO(ptr
) == ESPIPE
|| _REENT_ERRNO(ptr
) == EINVAL
)
161 _REENT_ERRNO(ptr
) = tmp_errno
;
164 fp
->_flags
|= __SERR
;
168 if (fp
->_flags
& __SRD
)
170 /* Current offset is at end of buffer. Compensate for
171 characters not yet read. */
176 /* Now physically seek to after byte last read. */
177 #ifdef __LARGE64_FILES
178 if (fp
->_flags
& __SL64
)
179 curoff
= fp
->_seek64 (ptr
, fp
->_cookie
, curoff
, SEEK_SET
);
182 curoff
= fp
->_seek (ptr
, fp
->_cookie
, curoff
, SEEK_SET
);
183 if (curoff
!= -1 || _REENT_ERRNO(ptr
) == 0
184 || _REENT_ERRNO(ptr
) == ESPIPE
|| _REENT_ERRNO(ptr
) == EINVAL
)
186 /* Seek successful or ignorable error condition.
187 We can clear read buffer now. */
188 #ifdef _FSEEK_OPTIMIZATION
189 fp
->_flags
&= ~__SNPT
;
192 fp
->_p
= fp
->_bf
._base
;
193 if ((fp
->_flags
& __SOFF
) && (curoff
!= -1 || _REENT_ERRNO(ptr
) == 0))
194 fp
->_offset
= curoff
;
195 _REENT_ERRNO(ptr
) = tmp_errno
;
201 fp
->_flags
|= __SERR
;
207 if ((p
= fp
->_bf
._base
) == NULL
)
209 /* Nothing to flush. */
212 n
= fp
->_p
- p
; /* write this much */
215 * Set these immediately to avoid problems with longjmp
216 * and to allow exchange buffering (via setvbuf) in user
220 fp
->_w
= flags
& (__SLBF
| __SNBF
) ? 0 : fp
->_bf
._size
;
224 t
= fp
->_write (ptr
, fp
->_cookie
, (char *) p
, n
);
227 fp
->_flags
|= __SERR
;
236 #ifdef _STDIO_BSD_SEMANTICS
237 /* Called from cleanup_stdio(). At exit time, we don't need file locking,
238 and we don't want to move the underlying file pointer unless we're
241 __sflushw_r (struct _reent
*ptr
,
244 return (fp
->_flags
& __SWR
) ? __sflush_r (ptr
, fp
) : 0;
248 #endif /* __IMPL_UNLOCKED__ */
251 _fflush_r (struct _reent
*ptr
,
257 /* For REENT_SMALL platforms, it is possible we are being
258 called for the first time on a std stream. This std
259 stream can belong to a reentrant struct that is not
260 _REENT. If CHECK_INIT gets called below based on _REENT,
261 we will end up changing said file pointers to the equivalent
262 std stream off of _REENT. This causes unexpected behavior if
263 there is any data to flush on the _REENT std stream. There
264 are two alternatives to fix this: 1) make a reentrant fflush
265 or 2) simply recognize that this file has nothing to flush
266 and return immediately before performing a CHECK_INIT. Choice
267 2 is implemented here due to its simplicity. */
268 if (fp
->_bf
._base
== NULL
)
270 #endif /* _REENT_SMALL */
272 CHECK_INIT (ptr
, fp
);
277 _newlib_flockfile_start (fp
);
278 ret
= __sflush_r (ptr
, fp
);
279 _newlib_flockfile_end (fp
);
286 fflush (register FILE * fp
)
289 return _fwalk_sglue (_GLOBAL_REENT
, _fflush_r
, &__sglue
);
291 return _fflush_r (_REENT
, fp
);
294 #endif /* _REENT_ONLY */