fix fclose of permanent (stdin/out/err) streams
authorRich Felker <dalias@aerifal.cx>
Wed, 9 Sep 2015 04:31:07 +0000 (04:31 +0000)
committerRich Felker <dalias@aerifal.cx>
Wed, 9 Sep 2015 04:31:07 +0000 (04:31 +0000)
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.

src/stdio/fclose.c

index 839d88af9bba16c15a15dcb6eaa21d32668673dc..d687a8779b64f2d46b8790165c695b9612d3cc0a 100644 (file)
@@ -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;
 }