Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2013-01-09 18:23:44 +0400
committerCorinna Vinschen <corinna@vinschen.de>2013-01-09 18:23:44 +0400
commit85d8e389cd331c9d2fc7396b02c1ddc30066556b (patch)
treee56a0d64e552e7f1348dd2e123cca672717af026 /winsup/cygwin
parent7dadae9fbc57fbae92c30a02c1d7127d1df668e2 (diff)
* dcrt0.cc (main_thread_sinit): New inline function. Fix and explain
a stdio initialization issue. (dll_crt0_1): Call main_thread_sinit rather than __sinit.
Diffstat (limited to 'winsup/cygwin')
-rw-r--r--winsup/cygwin/ChangeLog6
-rw-r--r--winsup/cygwin/dcrt0.cc27
2 files changed, 31 insertions, 2 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 28f7c3861..b5b6430d5 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,9 @@
+2013-01-09 Corinna Vinschen <corinna@vinschen.de>
+
+ * dcrt0.cc (main_thread_sinit): New inline function. Fix and explain
+ a stdio initialization issue.
+ (dll_crt0_1): Call main_thread_sinit rather than __sinit.
+
2013-01-07 Christopher Faylor <me.cygwin2013@cgf.cx>
* thread.cc (pthread_rwlock::lookup_reader): Remove parameter: always
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index b55dd9069..cbe1b282f 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -1,7 +1,7 @@
/* dcrt0.cc -- essentially the main() for the Cygwin dll
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
- 2007, 2008, 2009, 2010, 2011, 2012 Red Hat, Inc.
+ 2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
This file is part of Cygwin.
@@ -788,6 +788,29 @@ dll_crt0_0 ()
debug_printf ("finished dll_crt0_0 initialization");
}
+static inline void
+main_thread_sinit ()
+{
+ __sinit (_impure_ptr);
+ /* At this point, _impure_ptr == _global_impure_ptr == _GLOBAL_REENT is
+ initialized, but _REENT == _my_tls.local_clib doesn't know about it.
+ It has been copied over from _GLOBAL_REENT in _cygtls::init_thread
+ *before* the initialization took place.
+
+ As soon as the main thread calls a stdio function, this would be
+ rectified. But if another thread calls a stdio function on
+ stdin/out/err before the main thread does, all the required
+ initialization of stdin/out/err will be done, but _REENT->__sdidinit
+ is *still* 0. This in turn will result in a call to __sinit in the
+ wrong spot. The input or output buffer will be NULLed and nothing is
+ read or written in the first stdio function call in the main thread.
+
+ To fix this issue we have to copy over the relevant part of _GLOBAL_REENT
+ to _REENT here again. */
+ _REENT->__sdidinit = -1;
+ _REENT->__cleanup = _GLOBAL_REENT->__cleanup;
+}
+
/* Take over from libc's crt0.o and start the application. Note the
various special cases when Cygwin DLL is being runtime loaded (as
opposed to being link-time loaded by Cygwin apps) from a non
@@ -869,7 +892,7 @@ dll_crt0_1 (void *)
longjmp (fork_info->jmp, true);
}
- __sinit (_impure_ptr);
+ main_thread_sinit ();
#ifdef DEBUGGING
{