summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/fork.cc
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/fork.cc')
-rw-r--r--winsup/cygwin/fork.cc50
1 files changed, 28 insertions, 22 deletions
diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc
index 8a5e5bfa0..01b9dbc23 100644
--- a/winsup/cygwin/fork.cc
+++ b/winsup/cygwin/fork.cc
@@ -167,11 +167,11 @@ sync_with_child (PROCESS_INFORMATION &pi, HANDLE subproc_ready,
*/
if (errcode != STATUS_CONTROL_C_EXIT)
{
- system_printf ("child %u(%p) died before initialization with status code %p",
- cygwin_pid (pi.dwProcessId), pi.hProcess, errcode);
- system_printf ("*** child state %s", s);
+ system_printf ("child %u(%p) died before initialization with status code %p",
+ cygwin_pid (pi.dwProcessId), pi.hProcess, errcode);
+ system_printf ("*** child state %s", s);
#ifdef DEBUGGING
- abort ();
+ try_to_debug ();
#endif
}
set_errno (EAGAIN);
@@ -212,13 +212,13 @@ sync_with_parent (const char *s, bool hang_self)
switch (psync_rc)
{
case WAIT_TIMEOUT:
- api_fatal ("WFSO timed out for %s", s);
+ api_fatal ("WFSO timed out %s", s);
break;
case WAIT_FAILED:
if (GetLastError () == ERROR_INVALID_HANDLE &&
WaitForSingleObject (fork_info->forker_finished, 1) != WAIT_FAILED)
break;
- api_fatal ("WFSO failed for %s, fork_finished %p, %E", s,
+ api_fatal ("WFSO failed %s, fork_finished %p, %E", s,
fork_info->forker_finished);
break;
default:
@@ -243,6 +243,17 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
sigproc_printf ("hParent %p, child 1 first_dll %p, load_dlls %d", hParent,
first_dll, load_dlls);
+ /* 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->stacksize)
+ {
+ _main_tls = &_my_tls;
+ _main_tls->init_thread (NULL, NULL);
+ _main_tls->local_clib = *_impure_ptr;
+ _impure_ptr = &_main_tls->local_clib;
+ }
+
#ifdef DEBUGGING
char c;
if (GetEnvironmentVariable ("FORKDEBUG", &c, 1))
@@ -257,18 +268,6 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
}
#endif
- /* If we've played with the stack, stacksize != 0. That means that
- fork() was invoked from other than the main thread. Make sure that
- when the "main" thread exits it calls do_exit, like a normal process.
- Exit with a status code of 0. */
- if (fork_info->stacksize)
- {
- _main_tls = &_my_tls;
- _main_tls->init_thread (NULL, NULL);
- _main_tls->local_clib = *_impure_ptr;
- _impure_ptr = &_main_tls->local_clib;
- }
-
set_file_api_mode (current_codepage);
MALLOC_CHECK;
@@ -307,7 +306,8 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
#endif
pinfo_fixup_after_fork ();
- signal_fixup_after_fork ();
+ _my_tls.fixup_after_fork ();
+ sigproc_init ();
/* Set thread local stuff to zero. Under Windows 95/98 this is sometimes
non-zero, for some reason.
@@ -320,6 +320,7 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
fixup_timers_after_fork ();
wait_for_sigthread ();
cygbench ("fork-child");
+ cygwin_finished_initializing = true;
return 0;
}
@@ -458,7 +459,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
syscall_printf ("CreateProcess (%s, %s, 0, 0, 1, %x, 0, 0, %p, %p)",
myself->progname, myself->progname, c_flags, &si, &pi);
- __malloc_lock ();
+ bool locked = __malloc_lock ();
void *newheap;
newheap = cygheap_setup_for_child (&ch, cygheap->fdtab.need_fixup_before ());
rc = CreateProcess (myself->progname, /* image to run */
@@ -483,6 +484,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
/* Restore impersonation */
cygheap->user.reimpersonate ();
cygheap_setup_for_child_cleanup (newheap, &ch, 0);
+ __malloc_unlock ();
return -1;
}
@@ -573,6 +575,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
dll_bss_start, dll_bss_end, impure_beg, impure_end, NULL);
__malloc_unlock ();
+ locked = false;
MALLOC_CHECK;
if (!rc)
goto cleanup;
@@ -622,6 +625,9 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
/* Common cleanup code for failure cases */
cleanup:
+ if (locked)
+ __malloc_unlock ();
+
/* Remember to de-allocate the fd table. */
if (pi.hProcess)
ForceCloseHandle1 (pi.hProcess, childhProc);
@@ -725,7 +731,7 @@ vfork ()
debug_printf ("cygheap->ctty_on_hold %p, cygheap->open_fhs %d", cygheap->ctty_on_hold, cygheap->open_fhs);
int res = cygheap->fdtab.vfork_child_dup () ? 0 : -1;
debug_printf ("%d = vfork()", res);
- call_signal_handler_now (); // FIXME: racy
+ _my_tls.call_signal_handler (); // FIXME: racy
vf->tls = _my_tls;
return res;
}
@@ -757,7 +763,7 @@ vfork ()
debug_printf ("exiting vfork, pid %d", pid);
sig_dispatch_pending ();
- call_signal_handler_now (); // FIXME: racy
+ _my_tls.call_signal_handler (); // FIXME: racy
_my_tls = vf->tls;
return pid;
#endif