aboutsummaryrefslogtreecommitdiffstats
path: root/main/musl/0010-simplify-refactor-fflush-and-make-fflush_unlocked-an.patch
diff options
context:
space:
mode:
Diffstat (limited to 'main/musl/0010-simplify-refactor-fflush-and-make-fflush_unlocked-an.patch')
-rw-r--r--main/musl/0010-simplify-refactor-fflush-and-make-fflush_unlocked-an.patch102
1 files changed, 102 insertions, 0 deletions
diff --git a/main/musl/0010-simplify-refactor-fflush-and-make-fflush_unlocked-an.patch b/main/musl/0010-simplify-refactor-fflush-and-make-fflush_unlocked-an.patch
new file mode 100644
index 0000000000..ba6483bb78
--- /dev/null
+++ b/main/musl/0010-simplify-refactor-fflush-and-make-fflush_unlocked-an.patch
@@ -0,0 +1,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
+