From c48c3e4bb3d1665f3e9fa2785daafa72dfe59399 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Wed, 19 Nov 2014 15:16:51 -0800 Subject: [PATCH] Fix flockfile(3) and friends for stdin/stdout/stderr too. 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 | 12 ++++++++++++ libc/stdio/fileext.h | 4 ++++ libc/stdio/glue.h | 6 ++++++ libc/stdio/local.h | 4 ++++ libc/stdio/wcio.h | 6 ++++++ 5 files changed, 32 insertions(+) diff --git a/libc/bionic/flockfile.cpp b/libc/bionic/flockfile.cpp index 3381e8eb..b73907cb 100644 --- a/libc/bionic/flockfile.cpp +++ b/libc/bionic/flockfile.cpp @@ -36,12 +36,20 @@ // 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)); } diff --git a/libc/stdio/fileext.h b/libc/stdio/fileext.h index dc89fff7..25b7bda2 100644 --- a/libc/stdio/fileext.h +++ b/libc/stdio/fileext.h @@ -34,6 +34,8 @@ #include +__BEGIN_DECLS + /* * file extension */ @@ -61,4 +63,6 @@ do { \ _FILEEXT_INIT(f); \ } while (0) +__END_DECLS + #endif /* _FILEEXT_H_ */ diff --git a/libc/stdio/glue.h b/libc/stdio/glue.h index 4ead20a8..a9e5d103 100644 --- a/libc/stdio/glue.h +++ b/libc/stdio/glue.h @@ -32,6 +32,10 @@ * SUCH DAMAGE. */ +#include + +__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 diff --git a/libc/stdio/local.h b/libc/stdio/local.h index 13188ee1..46b11f13 100644 --- a/libc/stdio/local.h +++ b/libc/stdio/local.h @@ -41,6 +41,8 @@ #include "wcio.h" #include "fileext.h" +__BEGIN_DECLS + /* * Android <= KitKat had getc/putc macros in 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 diff --git a/libc/stdio/wcio.h b/libc/stdio/wcio.h index 584a3f20..2c1fa3c1 100644 --- a/libc/stdio/wcio.h +++ b/libc/stdio/wcio.h @@ -32,6 +32,10 @@ #ifndef _WCIO_H_ #define _WCIO_H_ +#include + +__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_*/ -- 2.39.2