summaryrefslogtreecommitdiff
path: root/src/stdio/fclose.c
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2015-09-09 04:31:07 +0000
committerRich Felker <dalias@aerifal.cx>2015-09-09 04:31:07 +0000
commit426a0e2912c07f0e86feee2ed12f24a808eac2f4 (patch)
treec6c38c6d1fb8959d4614567c38c34da93228bae4 /src/stdio/fclose.c
parentd8be1bc0193f45d3900f8466f26d1411b7f919c3 (diff)
downloadmusl-426a0e2912c07f0e86feee2ed12f24a808eac2f4.tar.gz
fix fclose of permanent (stdin/out/err) streams
this fixes a bug reported by Nuno Gonçalves. previously, calling fclose on stdin or stdout resulted in deadlock at exit time, since __stdio_exit attempts to lock these streams to flush/seek them, and has no easy way of knowing that they were closed. conceptually, leaving a FILE stream locked on fclose is valid since, in the abstract machine, it ceases to exist. but to satisfy the implementation-internal assumption in __stdio_exit that it can access these streams unconditionally, we need to unlock them. it's also necessary that fclose leaves permanent streams in a state where __stdio_exit will not attempt any further operations on them. fortunately, the call to fflush already yields this property.
Diffstat (limited to 'src/stdio/fclose.c')
-rw-r--r--src/stdio/fclose.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/src/stdio/fclose.c b/src/stdio/fclose.c
index 839d88af..d687a877 100644
--- a/src/stdio/fclose.c
+++ b/src/stdio/fclose.c
@@ -9,7 +9,7 @@ int fclose(FILE *f)
int r;
int perm;
- FFINALLOCK(f);
+ FLOCK(f);
__unlist_locked_file(f);
@@ -26,6 +26,7 @@ int fclose(FILE *f)
if (f->getln_buf) free(f->getln_buf);
if (!perm) free(f);
-
+ else FUNLOCK(f);
+
return r;
}