* commit '90138639a50495fd63238524e9a0a0758cd574c6': Ensure we initialize stdin/stdout/stderr's recursive mutexes.
This commit is contained in:
		@@ -58,6 +58,7 @@ libc_common_src_files := \
 | 
			
		||||
    bionic/siginterrupt.c \
 | 
			
		||||
    bionic/sigsetmask.c \
 | 
			
		||||
    bionic/system_properties_compat.c \
 | 
			
		||||
    stdio/findfp.c \
 | 
			
		||||
    stdio/snprintf.c\
 | 
			
		||||
    stdio/sprintf.c \
 | 
			
		||||
    stdio/stdio_ext.cpp \
 | 
			
		||||
@@ -399,7 +400,6 @@ libc_upstream_openbsd_src_files := \
 | 
			
		||||
    upstream-openbsd/lib/libc/stdio/fgetwc.c \
 | 
			
		||||
    upstream-openbsd/lib/libc/stdio/fgetws.c \
 | 
			
		||||
    upstream-openbsd/lib/libc/stdio/fileno.c \
 | 
			
		||||
    upstream-openbsd/lib/libc/stdio/findfp.c \
 | 
			
		||||
    upstream-openbsd/lib/libc/stdio/flags.c \
 | 
			
		||||
    upstream-openbsd/lib/libc/stdio/fmemopen.c \
 | 
			
		||||
    upstream-openbsd/lib/libc/stdio/fopen.c \
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,10 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "local.h"
 | 
			
		||||
#include "glue.h"
 | 
			
		||||
#include "thread_private.h"
 | 
			
		||||
#include "private/thread_private.h"
 | 
			
		||||
 | 
			
		||||
#define ALIGNBYTES (sizeof(uintptr_t) - 1)
 | 
			
		||||
#define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) &~ ALIGNBYTES)
 | 
			
		||||
 | 
			
		||||
int	__sdidinit;
 | 
			
		||||
 | 
			
		||||
@@ -47,9 +50,7 @@ int	__sdidinit;
 | 
			
		||||
 | 
			
		||||
#define	std(flags, file) \
 | 
			
		||||
	{0,0,0,flags,file,{0},0,__sF+file,__sclose,__sread,__sseek,__swrite, \
 | 
			
		||||
	 {(unsigned char *)(__sFext+file), 0}}
 | 
			
		||||
/*	 p r w flags file _bf z  cookie      close    read    seek    write 
 | 
			
		||||
	 ext */
 | 
			
		||||
	    {(unsigned char *)(__sFext+file), 0},NULL,0,{0},{0},{0},0,0}
 | 
			
		||||
 | 
			
		||||
				/* the usual - (stdin + stdout + stderr) */
 | 
			
		||||
static FILE usual[FOPEN_MAX - 3];
 | 
			
		||||
@@ -162,17 +163,26 @@ void
 | 
			
		||||
__sinit(void)
 | 
			
		||||
{
 | 
			
		||||
	_THREAD_PRIVATE_MUTEX(__sinit_mutex);
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	_THREAD_PRIVATE_MUTEX_LOCK(__sinit_mutex);
 | 
			
		||||
	if (__sdidinit)
 | 
			
		||||
		goto out;	/* bail out if caller lost the race */
 | 
			
		||||
	for (i = 0; i < FOPEN_MAX - 3; i++) {
 | 
			
		||||
	if (__sdidinit) {
 | 
			
		||||
		/* bail out if caller lost the race */
 | 
			
		||||
		_THREAD_PRIVATE_MUTEX_UNLOCK(__sinit_mutex);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Initialize stdin/stdout/stderr (for the recursive mutex). http://b/18208568. */
 | 
			
		||||
	for (size_t i = 0; i < 3; ++i) {
 | 
			
		||||
		_FILEEXT_SETUP(__sF+i, __sFext+i);
 | 
			
		||||
	}
 | 
			
		||||
	/* Initialize the pre-allocated (but initially unused) streams. */
 | 
			
		||||
	for (size_t i = 0; i < FOPEN_MAX - 3; ++i) {
 | 
			
		||||
		_FILEEXT_SETUP(usual+i, usualext+i);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* make sure we clean up on exit */
 | 
			
		||||
	__atexit_register_cleanup(_cleanup); /* conservative */
 | 
			
		||||
	__sdidinit = 1;
 | 
			
		||||
out: 
 | 
			
		||||
 | 
			
		||||
	_THREAD_PRIVATE_MUTEX_UNLOCK(__sinit_mutex);
 | 
			
		||||
}
 | 
			
		||||
@@ -29,6 +29,23 @@
 | 
			
		||||
 | 
			
		||||
#include "TemporaryFile.h"
 | 
			
		||||
 | 
			
		||||
TEST(stdio, flockfile_18208568_stderr) {
 | 
			
		||||
  // Check that we have a _recursive_ mutex for flockfile.
 | 
			
		||||
  flockfile(stderr);
 | 
			
		||||
  feof(stderr); // We don't care about the result, but this needs to take the lock.
 | 
			
		||||
  funlockfile(stderr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(stdio, flockfile_18208568_regular) {
 | 
			
		||||
  // We never had a bug for streams other than stdin/stdout/stderr, but test anyway.
 | 
			
		||||
  FILE* fp = fopen("/dev/null", "w");
 | 
			
		||||
  ASSERT_TRUE(fp != NULL);
 | 
			
		||||
  flockfile(fp);
 | 
			
		||||
  feof(fp);
 | 
			
		||||
  funlockfile(fp);
 | 
			
		||||
  fclose(fp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(stdio, tmpfile_fileno_fprintf_rewind_fgets) {
 | 
			
		||||
  FILE* fp = tmpfile();
 | 
			
		||||
  ASSERT_TRUE(fp != NULL);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user