Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/lib/libc/stdio/fflush.c
39476 views
1
/*-
2
* SPDX-License-Identifier: BSD-3-Clause
3
*
4
* Copyright (c) 1990, 1993
5
* The Regents of the University of California. All rights reserved.
6
*
7
* This code is derived from software contributed to Berkeley by
8
* Chris Torek.
9
*
10
* Redistribution and use in source and binary forms, with or without
11
* modification, are permitted provided that the following conditions
12
* are met:
13
* 1. Redistributions of source code must retain the above copyright
14
* notice, this list of conditions and the following disclaimer.
15
* 2. Redistributions in binary form must reproduce the above copyright
16
* notice, this list of conditions and the following disclaimer in the
17
* documentation and/or other materials provided with the distribution.
18
* 3. Neither the name of the University nor the names of its contributors
19
* may be used to endorse or promote products derived from this software
20
* without specific prior written permission.
21
*
22
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32
* SUCH DAMAGE.
33
*/
34
35
#include "namespace.h"
36
#include <errno.h>
37
#include <stdio.h>
38
#include "un-namespace.h"
39
#include "libc_private.h"
40
#include "local.h"
41
42
static int sflush_locked(FILE *);
43
44
/*
45
* Flush a single file, or (if fp is NULL) all files.
46
* MT-safe version
47
*/
48
int
49
fflush(FILE *fp)
50
{
51
int retval;
52
53
if (fp == NULL)
54
return (_fwalk(sflush_locked));
55
FLOCKFILE_CANCELSAFE(fp);
56
57
/*
58
* There is disagreement about the correct behaviour of fflush()
59
* when passed a file which is not open for writing. According to
60
* the ISO C standard, the behaviour is undefined.
61
* Under linux, such an fflush returns success and has no effect;
62
* under Windows, such an fflush is documented as behaving instead
63
* as fpurge().
64
* Given that applications may be written with the expectation of
65
* either of these two behaviours, the only safe (non-astonishing)
66
* option is to return EBADF and ask that applications be fixed.
67
* SUSv3 now requires that fflush() returns success on a read-only
68
* stream.
69
*
70
*/
71
if ((fp->_flags & (__SWR | __SRW)) == 0)
72
retval = 0;
73
else
74
retval = __sflush(fp);
75
FUNLOCKFILE_CANCELSAFE();
76
return (retval);
77
}
78
79
/*
80
* Flush a single file, or (if fp is NULL) all files.
81
* Non-MT-safe version
82
*/
83
int
84
__fflush(FILE *fp)
85
{
86
int retval;
87
88
if (fp == NULL)
89
return (_fwalk(sflush_locked));
90
if ((fp->_flags & (__SWR | __SRW)) == 0)
91
retval = 0;
92
else
93
retval = __sflush(fp);
94
return (retval);
95
}
96
97
__weak_reference(__fflush, fflush_unlocked);
98
99
int
100
__sflush(FILE *fp)
101
{
102
unsigned char *p;
103
int n, f, t;
104
105
f = fp->_flags;
106
if ((f & __SWR) == 0)
107
return (0);
108
109
if ((p = fp->_bf._base) == NULL)
110
return (0);
111
112
n = fp->_p - p; /* write this much */
113
114
/*
115
* Set these immediately to avoid problems with longjmp and to allow
116
* exchange buffering (via setvbuf) in user write function.
117
*/
118
fp->_p = p;
119
fp->_w = f & (__SLBF|__SNBF) ? 0 : fp->_bf._size;
120
121
for (; n > 0; n -= t, p += t) {
122
t = _swrite(fp, (char *)p, n);
123
if (t <= 0) {
124
if (p > fp->_p)
125
/* Some was written. */
126
memmove(fp->_p, p, n);
127
/* Reset _p and _w. */
128
fp->_p += n;
129
if ((fp->_flags & __SNBF) == 0)
130
fp->_w -= n;
131
fp->_flags |= __SERR;
132
return (EOF);
133
}
134
}
135
return (0);
136
}
137
138
static int
139
sflush_locked(FILE *fp)
140
{
141
int ret;
142
143
FLOCKFILE_CANCELSAFE(fp);
144
ret = __sflush(fp);
145
FUNLOCKFILE_CANCELSAFE();
146
return (ret);
147
}
148
149