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:
Diffstat (limited to 'winsup/cygwin/fork.cc')
-rw-r--r--winsup/cygwin/fork.cc49
1 files changed, 29 insertions, 20 deletions
diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc
index 720d62a4c..f7b9aa880 100644
--- a/winsup/cygwin/fork.cc
+++ b/winsup/cygwin/fork.cc
@@ -262,6 +262,11 @@ frok::parent (volatile char * volatile stack_here)
int c_flags = GetPriorityClass (GetCurrentProcess ());
debug_printf ("priority class %d", c_flags);
+ /* Per MSDN, this must be specified even if lpEnvironment is set to NULL,
+ otherwise UNICODE characters in the parent environment are not copied
+ correctly to the child. Omitting it may scramble %PATH% on non-English
+ systems. */
+ c_flags |= CREATE_UNICODE_ENVIRONMENT;
errmsg = NULL;
hchild = NULL;
@@ -302,17 +307,17 @@ frok::parent (volatile char * volatile stack_here)
ch.forker_finished = forker_finished;
+ PTEB teb = NtCurrentTeb ();
ch.stackbottom = _tlsbase;
ch.stacktop = (void *) _tlstop;
- ch.stackaddr = 0;
+ ch.stackaddr = teb->DeallocationStack;
ch.guardsize = 0;
if (&_my_tls != _main_tls)
{
/* We have not been started from the main thread. Fetch the
information required to set up the thread stack identically
in the child. */
- PTEB teb = NtCurrentTeb ();
- if (!teb->DeallocationStack)
+ if (!ch.stackaddr)
{
/* Pthread with application-provided stack. Don't set up a
PAGE_GUARD page. guardsize == -1 is used in alloc_stack_hard_way
@@ -320,15 +325,11 @@ frok::parent (volatile char * volatile stack_here)
ch.stackaddr = _my_tls.tid->attr.stackaddr;
ch.guardsize = (size_t) -1;
}
- else
- {
- ch.stackaddr = teb->DeallocationStack;
- /* If it's a pthread, fetch guardsize from thread attributes. */
- if (_my_tls.tid)
- ch.guardsize = _my_tls.tid->attr.guardsize;
- }
+ else if (_my_tls.tid)
+ /* If it's a pthread, fetch guardsize from thread attributes. */
+ ch.guardsize = _my_tls.tid->attr.guardsize;
}
- debug_printf ("stack - bottom %p, top %p, addr %p, guardsize %p",
+ debug_printf ("stack - bottom %p, top %p, addr %p, guardsize %ly",
ch.stackbottom, ch.stacktop, ch.stackaddr, ch.guardsize);
PROCESS_INFORMATION pi;
@@ -340,7 +341,7 @@ frok::parent (volatile char * volatile stack_here)
si.lpReserved2 = (LPBYTE) &ch;
si.cbReserved2 = sizeof (ch);
- syscall_printf ("CreateProcessW (%W, %W, 0, 0, 1, %p, 0, 0, %p, %p)",
+ syscall_printf ("CreateProcessW (%W, %W, 0, 0, 1, %y, 0, 0, %p, %p)",
myself->progname, myself->progname, c_flags, &si, &pi);
bool locked = __malloc_lock ();
time_t start_time = time (NULL);
@@ -355,7 +356,11 @@ frok::parent (volatile char * volatile stack_here)
{
hchild = NULL;
rc = CreateProcessW (myself->progname, /* image to run */
- myself->progname, /* what we send in arg0 */
+ GetCommandLineW (), /* Take same space for command
+ line as in parent to make
+ sure child stack is allocated
+ in the same memory location
+ as in parent. */
&sec_none_nih,
&sec_none_nih,
TRUE, /* inherit handles from parent */
@@ -598,14 +603,18 @@ fork ()
ischild = !!setjmp (grouped.ch.jmp);
- volatile char * volatile esp;
- __asm__ volatile ("movl %%esp,%0": "=r" (esp));
+ volatile char * volatile stackp;
+#ifdef __x86_64__
+ __asm__ volatile ("movq %%rsp,%0": "=r" (stackp));
+#else
+ __asm__ volatile ("movl %%esp,%0": "=r" (stackp));
+#endif
if (!ischild)
- res = grouped.parent (esp);
+ res = grouped.parent (stackp);
else
{
- res = grouped.child (esp);
+ res = grouped.child (stackp);
in_forkee = false;
ischild = true; /* might have been reset by fork mem copy */
}
@@ -664,12 +673,12 @@ child_copy (HANDLE hp, bool write, ...)
{
char *low = va_arg (args, char *);
char *high = va_arg (args, char *);
- DWORD todo = high - low;
+ SIZE_T todo = high - low;
char *here;
for (here = low; here < high; here += todo)
{
- DWORD done = 0;
+ SIZE_T done = 0;
if (here + todo > high)
todo = high - here;
int res;
@@ -684,7 +693,7 @@ child_copy (HANDLE hp, bool write, ...)
__seterrno ();
/* If this happens then there is a bug in our fork
implementation somewhere. */
- system_printf ("%s %s copy failed, %p..%p, done %d, windows pid %u, %E",
+ system_printf ("%s %s copy failed, %p..%p, done %lu, windows pid %u, %E",
what, huh[write], low, high, done, myself->dwProcessId);
goto err;
}