1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
From c002668eb0352e619ea7064e4940b397b4a6e68d Mon Sep 17 00:00:00 2001
From: Rich Felker <dalias@aerifal.cx>
Date: Sun, 18 Sep 2016 21:45:47 -0400
Subject: [PATCH 10/11] simplify/refactor fflush and make fflush_unlocked an
alias for fflush
previously, fflush_unlocked was an alias for an internal backend that
was called by fflush, either for its argument or in a loop for each
file if a null pointer was passed. since the logic for the latter was
in the main fflush function, fflush_unlocked crashed when passed a
null pointer, rather than flushing all open files. since
fflush_unlocked is not a standard function and has no specification,
it's not clear whether it should be expected to accept null pointers
like fflush does, but a reasonable argument could be made that it
should.
this patch eliminates the helper function, simplifying fflush, and
makes fflush_unlocked an alias for fflush, which is valid because the
two functions agree in their behavior in all cases where their
behavior is defined (the unlocked version has undefined behavior if
another thread could hold locks).
---
src/stdio/fflush.c | 53 +++++++++++++++++++++++------------------------------
1 file changed, 23 insertions(+), 30 deletions(-)
diff --git a/src/stdio/fflush.c b/src/stdio/fflush.c
index 3f462c8..c288106 100644
--- a/src/stdio/fflush.c
+++ b/src/stdio/fflush.c
@@ -1,11 +1,30 @@
#include "stdio_impl.h"
-static int __fflush_unlocked(FILE *f)
+/* stdout.c will override this if linked */
+static FILE *volatile dummy = 0;
+weak_alias(dummy, __stdout_used);
+
+int fflush(FILE *f)
{
+ if (!f) {
+ int r = __stdout_used ? fflush(__stdout_used) : 0;
+
+ for (f=*__ofl_lock(); f; f=f->next)
+ if (f->wpos > f->wbase) r |= fflush(f);
+ __ofl_unlock();
+
+ return r;
+ }
+
+ FLOCK(f);
+
/* If writing, flush output */
if (f->wpos > f->wbase) {
f->write(f, 0, 0);
- if (!f->wpos) return EOF;
+ if (!f->wpos) {
+ FUNLOCK(f);
+ return EOF;
+ }
}
/* If reading, sync position, per POSIX */
@@ -15,34 +34,8 @@ static int __fflush_unlocked(FILE *f)
f->wpos = f->wbase = f->wend = 0;
f->rpos = f->rend = 0;
+ FUNLOCK(f);
return 0;
}
-/* stdout.c will override this if linked */
-static FILE *volatile dummy = 0;
-weak_alias(dummy, __stdout_used);
-
-int fflush(FILE *f)
-{
- int r;
-
- if (f) {
- FLOCK(f);
- r = __fflush_unlocked(f);
- FUNLOCK(f);
- return r;
- }
-
- r = __stdout_used ? fflush(__stdout_used) : 0;
-
- for (f=*__ofl_lock(); f; f=f->next) {
- FLOCK(f);
- if (f->wpos > f->wbase) r |= __fflush_unlocked(f);
- FUNLOCK(f);
- }
- __ofl_unlock();
-
- return r;
-}
-
-weak_alias(__fflush_unlocked, fflush_unlocked);
+weak_alias(fflush, fflush_unlocked);
--
2.10.1
|