Fix flockfile(3) and friends for stdin/stdout/stderr too.
authorElliott Hughes <enh@google.com>
Wed, 19 Nov 2014 23:16:51 +0000 (15:16 -0800)
committerElliott Hughes <enh@google.com>
Wed, 19 Nov 2014 23:16:51 +0000 (15:16 -0800)
stdin/stdout/stderr are special; their mutexes are initialized by
__sinit. There's no unit test for this, because __sinit has already
been called by the time the first unit test runs, but you could
reproduce this failure with a trivial main() that calls flockfile
or ftrylockfile on one of the standard streams before otherwise
using stdio.

Bug: 18208568
Change-Id: I28d232cf05a9f198a2bed61854d8047b23d2091d

libc/bionic/flockfile.cpp
libc/stdio/fileext.h
libc/stdio/glue.h
libc/stdio/local.h
libc/stdio/wcio.h

index 3381e8eb9bea173a54bab680d9ad3da9ceac601e..b73907cbcbe31b4caefa62578af8b0695fe78a9c 100644 (file)
 // struct __sfileext (see fileext.h).
 
 void flockfile(FILE* fp) {
+  if (!__sdidinit) {
+    __sinit();
+  }
+
   if (fp != NULL) {
     pthread_mutex_lock(&_FLOCK(fp));
   }
 }
 
 int ftrylockfile(FILE* fp) {
+  if (!__sdidinit) {
+    __sinit();
+  }
+
   // The specification for ftrylockfile() says it returns 0 on success,
   // or non-zero on error. So return an errno code directly on error.
   if (fp == NULL) {
@@ -52,6 +60,10 @@ int ftrylockfile(FILE* fp) {
 }
 
 void funlockfile(FILE* fp) {
+  if (!__sdidinit) {
+    __sinit();
+  }
+
   if (fp != NULL) {
     pthread_mutex_unlock(&_FLOCK(fp));
   }
index dc89fff718c570836fb77046381a35ed192ee0dd..25b7bda245c74dd09a5d2c4cb8cb37ee38a925ae 100644 (file)
@@ -34,6 +34,8 @@
 
 #include <pthread.h>
 
+__BEGIN_DECLS
+
 /*
  * file extension
  */
@@ -61,4 +63,6 @@ do { \
        _FILEEXT_INIT(f); \
 } while (0)
 
+__END_DECLS
+
 #endif /* _FILEEXT_H_ */
index 4ead20a81edcb49890ac563e707ff46bf1413df1..a9e5d1030bb901e6744c9fec2f0ae9cf378660b7 100644 (file)
  * SUCH DAMAGE.
  */
 
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
 /*
  * The first few FILEs are statically allocated; others are dynamically
  * allocated and linked in via this glue structure.
@@ -44,3 +48,5 @@ struct glue {
 
 /* This was referenced by a couple of different pieces of middleware and the Crystax NDK. */
 __LIBC64_HIDDEN__ extern struct glue __sglue;
+
+__END_DECLS
index 13188ee1bc48c6b46c151ceaa13e39e2c33e1387..46b11f13af4d5052848d35e69a4c6235492eec1b 100644 (file)
@@ -41,6 +41,8 @@
 #include "wcio.h"
 #include "fileext.h"
 
+__BEGIN_DECLS
+
 /*
  * Android <= KitKat had getc/putc macros in <stdio.h> that referred
  * to __srget/__swbuf, so those symbols need to be public for LP32
@@ -137,3 +139,5 @@ extern int __sfvwrite(FILE *, struct __suio *);
 wint_t __fputwc_unlock(wchar_t wc, FILE *fp);
 
 #pragma GCC visibility pop
+
+__END_DECLS
index 584a3f209eda041e4bbe9a12099bd577f3b20fd7..2c1fa3c17070fde0946d880a3952580f07985d9a 100644 (file)
 #ifndef _WCIO_H_
 #define _WCIO_H_
 
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
 /* minimal requirement of SUSv2 */
 #define WCIO_UNGETWC_BUFSIZE 1
 
@@ -78,4 +82,6 @@ do {\
 #define WCIO_INIT(fp) \
        memset(&(_EXT(fp)->_wcio), 0, sizeof(struct wchar_io_data))
 
+__END_DECLS
+
 #endif /*_WCIO_H_*/