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
path: root/winsup
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2015-12-03 14:38:19 +0300
committerCorinna Vinschen <corinna@vinschen.de>2015-12-03 14:38:19 +0300
commit89e86492b36cd15876ebb0ed725fbb4308828a9e (patch)
tree213e61fd097ef7204c642840dd71664bb4c3ba1f /winsup
parent8974e06da3c0214613aa27dc08e1de2b02e27231 (diff)
Safely recognize when fork is running from main thread or another pthread
* child_info.h (struct child_info): Add member from_main. * fork.cc (frok::child): Check from_main rather than stackaddr. (frok::parent): Set ch.from_main if running in the main thread. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog6
-rw-r--r--winsup/cygwin/child_info.h3
-rw-r--r--winsup/cygwin/fork.cc3
3 files changed, 10 insertions, 2 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index cffd7c2ca..a24c55ebe 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,9 @@
+2015-12-03 Corinna Vinschen <corinna@vinschen.de>
+
+ * child_info.h (struct child_info): Add member from_main.
+ * fork.cc (frok::child): Check from_main rather than stackaddr.
+ (frok::parent): Set ch.from_main if running in the main thread.
+
2015-12-02 Corinna Vinschen <corinna@vinschen.de>
* child_info.h (CURR_CHILD_INFO_MAGIC): Align to below change.
diff --git a/winsup/cygwin/child_info.h b/winsup/cygwin/child_info.h
index 1ec612788..ddd5b8bc8 100644
--- a/winsup/cygwin/child_info.h
+++ b/winsup/cygwin/child_info.h
@@ -39,7 +39,7 @@ enum child_status
#define EXEC_MAGIC_SIZE sizeof(child_info)
/* Change this value if you get a message indicating that it is out-of-sync. */
-#define CURR_CHILD_INFO_MAGIC 0xc96f5e9U
+#define CURR_CHILD_INFO_MAGIC 0x30ea98f6U
#define NPROCS 256
@@ -109,6 +109,7 @@ public:
void *stackbase; // StackBase of parent thread
size_t guardsize; // size of POSIX guard region or (size_t) -1 if
// user stack
+ bool from_main; // true if started from parent's main thread
char filler[4];
child_info_fork ();
void __reg1 handle_fork ();
diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc
index d4a973eb2..158186781 100644
--- a/winsup/cygwin/fork.cc
+++ b/winsup/cygwin/fork.cc
@@ -149,7 +149,7 @@ frok::child (volatile char * volatile here)
/* If we've played with the stack, stacksize != 0. That means that
fork() was invoked from other than the main thread. Make sure that
the threadinfo information is properly set up. */
- if (fork_info->stackaddr)
+ if (!fork_info->from_main)
{
_main_tls = &_my_tls;
_main_tls->init_thread (NULL, NULL);
@@ -307,6 +307,7 @@ frok::parent (volatile char * volatile stack_here)
ch.forker_finished = forker_finished;
+ ch.from_main = &_my_tls == _main_tls;
ch.stackbase = NtCurrentTeb()->Tib.StackBase;
ch.stackaddr = NtCurrentTeb ()->DeallocationStack;
if (!ch.stackaddr)