summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/fork.cc
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2011-05-28 20:09:04 +0000
committerChristopher Faylor <me@cgf.cx>2011-05-28 20:09:04 +0000
commit855108782321cee83378b069fe89343f191ba28c (patch)
treec8f31468bc92438229be72cef33c990d8f069c4d /winsup/cygwin/fork.cc
parentbeaedec5453dec03fa3646f9c98847aaf4c2d9f4 (diff)
downloadcygnal-855108782321cee83378b069fe89343f191ba28c.tar.gz
cygnal-855108782321cee83378b069fe89343f191ba28c.tar.bz2
cygnal-855108782321cee83378b069fe89343f191ba28c.zip
* dll_init.c (dll_list::load_after_fork): Don't clear in_forkee here.
* fork.cc (frok::errmsg): Rename from 'error'. (frok::error): New function. Handle conditional printing of error messages. (frok::parent): Record hchild handle for use by error function. Use throughout. Use error function rather than setting error pointer directly. (fork): Clear is_forkee here. Accommodate rename of 'error' to 'errmsg'. * sigproc.cc (child_info::proc_retry): Detect EXITCODE_FORK_FAILED.
Diffstat (limited to 'winsup/cygwin/fork.cc')
-rw-r--r--winsup/cygwin/fork.cc98
1 files changed, 53 insertions, 45 deletions
diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc
index 59fec4050..3ec7fa8c5 100644
--- a/winsup/cygwin/fork.cc
+++ b/winsup/cygwin/fork.cc
@@ -37,11 +37,13 @@ class frok
{
bool load_dlls;
child_info_fork ch;
- const char *error;
+ const char *errmsg;
int child_pid;
int this_errno;
+ HANDLE hchild;
int __stdcall parent (volatile char * volatile here);
int __stdcall child (volatile char * volatile here);
+ bool error (const char *fmt, ...);
friend int fork ();
};
@@ -163,6 +165,27 @@ sync_with_parent (const char *s, bool hang_self)
}
}
+bool
+frok::error (const char *fmt, ...)
+{
+ DWORD exit_code = ch.exit_code;
+ if (!exit_code && hchild)
+ {
+ exit_code = ch.proc_retry (hchild);
+ if (!exit_code)
+ return false;
+ }
+ if (exit_code != EXITCODE_FORK_FAILED)
+ {
+ va_list ap;
+ static char buf[NT_MAX_PATH + 256];
+ va_start (ap, fmt);
+ __small_vsprintf (buf, fmt, ap);
+ errmsg = buf;
+ }
+ return true;
+}
+
int __stdcall
frok::child (volatile char * volatile here)
{
@@ -282,15 +305,16 @@ frok::parent (volatile char * volatile stack_here)
HANDLE forker_finished;
DWORD rc;
child_pid = -1;
- error = NULL;
this_errno = 0;
bool fix_impersonation = false;
pinfo child;
- static char errbuf[NT_MAX_PATH + 256];
int c_flags = GetPriorityClass (GetCurrentProcess ());
debug_printf ("priority class %d", c_flags);
+ errmsg = NULL;
+ hchild = NULL;
+
/* If we don't have a console, then don't create a console for the
child either. */
HANDLE console_handle = CreateFile ("CONOUT$", GENERIC_WRITE,
@@ -319,7 +343,7 @@ frok::parent (volatile char * volatile stack_here)
if (forker_finished == NULL)
{
this_errno = geterrno_from_win_error ();
- error = "unable to allocate forker_finished event";
+ error ("unable to allocate forker_finished event");
return -1;
}
@@ -376,6 +400,7 @@ frok::parent (volatile char * volatile stack_here)
while (1)
{
+ hchild = NULL;
rc = CreateProcessW (myself->progname, /* image to run */
myself->progname, /* what we send in arg0 */
&sec_none_nih,
@@ -390,8 +415,7 @@ frok::parent (volatile char * volatile stack_here)
if (!rc)
{
this_errno = geterrno_from_win_error ();
- __small_sprintf (errbuf, "CreateProcessW failed for '%W'", myself->progname);
- error = errbuf;
+ error ("CreateProcessW failed for '%W'", myself->progname);
memset (&pi, 0, sizeof (pi));
goto cleanup;
}
@@ -403,24 +427,21 @@ frok::parent (volatile char * volatile stack_here)
}
CloseHandle (pi.hThread);
+ hchild = pi.hProcess;
/* Protect the handle but name it similarly to the way it will
be called in subproc handling. */
- ProtectHandle1 (pi.hProcess, childhProc);
+ ProtectHandle1 (hchild, childhProc);
strace.write_childpid (ch, pi.dwProcessId);
/* Wait for subproc to initialize itself. */
- if (!ch.sync (pi.dwProcessId, pi.hProcess, FORK_WAIT_TIMEOUT))
+ if (!ch.sync (pi.dwProcessId, hchild, FORK_WAIT_TIMEOUT))
{
- DWORD exit_code = ch.proc_retry (pi.hProcess);
- if (!exit_code)
+ if (!error ("forked process died unexpectedly, retry %d, exit code %d",
+ ch.retry, ch.exit_code))
continue;
this_errno = EAGAIN;
- /* Not thread safe, but do we care? */
- __small_sprintf (errbuf, "died waiting for longjmp before initialization, "
- "retry %d, exit code %p", ch.retry, exit_code);
- error = errbuf;
goto cleanup;
}
break;
@@ -436,11 +457,7 @@ frok::parent (volatile char * volatile stack_here)
if (!child)
{
this_errno = get_errno () == ENOMEM ? ENOMEM : EAGAIN;
-#ifdef DEBUGGING
- error = "pinfo failed";
-#else
syscall_printf ("pinfo failed");
-#endif
goto cleanup;
}
@@ -453,7 +470,7 @@ frok::parent (volatile char * volatile stack_here)
/* Fill in fields in the child's process table entry. */
child->dwProcessId = pi.dwProcessId;
- child.hProcess = pi.hProcess;
+ child.hProcess = hchild;
/* Hopefully, this will succeed. The alternative to doing things this
way is to reserve space prior to calling CreateProcess and then fill
@@ -462,16 +479,16 @@ frok::parent (volatile char * volatile stack_here)
we can't actually record the pid in the internal table. */
if (!child.remember (false))
{
- TerminateProcess (pi.hProcess, 1);
+ TerminateProcess (hchild, 1);
this_errno = EAGAIN;
#ifdef DEBUGGING0
- error = "child.remember failed";
+ error ("child remember failed");
#endif
goto cleanup;
}
#ifndef NO_SLOW_PID_REUSE
- slow_pid_reuse (pi.hProcess);
+ slow_pid_reuse (hchild);
#endif
/* CHILD IS STOPPED */
@@ -494,7 +511,7 @@ frok::parent (volatile char * volatile stack_here)
impure_beg = _impure_ptr;
impure_end = _impure_ptr + 1;
}
- rc = child_copy (pi.hProcess, true,
+ rc = child_copy (hchild, true,
"stack", stack_here, ch.stackbottom,
impure, impure_beg, impure_end,
NULL);
@@ -505,11 +522,7 @@ frok::parent (volatile char * volatile stack_here)
if (!rc)
{
this_errno = get_errno ();
- DWORD exit_code;
- if (!GetExitCodeProcess (pi.hProcess, &exit_code))
- exit_code = 0xdeadbeef;
- __small_sprintf (errbuf, "pid %u, exitval %p", pi.dwProcessId, exit_code);
- error = errbuf;
+ error ("pid %u, exitval %p", pi.dwProcessId, ch.exit_code);
goto cleanup;
}
@@ -517,29 +530,23 @@ frok::parent (volatile char * volatile stack_here)
for (dll *d = dlls.istart (DLL_LINK); d; d = dlls.inext ())
{
debug_printf ("copying data/bss of a linked dll");
- if (!child_copy (pi.hProcess, true,
+ if (!child_copy (hchild, true,
"linked dll data", d->p.data_start, d->p.data_end,
"linked dll bss", d->p.bss_start, d->p.bss_end,
NULL))
{
this_errno = get_errno ();
-#ifdef DEBUGGING
- DWORD exit_code;
- if (!GetExitCodeProcess (pi.hProcess, &exit_code))
- exit_code = 0xdeadbeef;
- __small_sprintf (errbuf, "pid %u, exitval %p", pi.dwProcessId, exit_code);
- error = errbuf;
-#endif
+ error ("couldn't copy linked dll data/bss");
goto cleanup;
}
}
/* Start thread, and then wait for it to reload dlls. */
resume_child (forker_finished);
- if (!ch.sync (child->pid, pi.hProcess, FORK_WAIT_TIMEOUT))
+ if (!ch.sync (child->pid, hchild, FORK_WAIT_TIMEOUT))
{
this_errno = EAGAIN;
- error = "died waiting for dll loading";
+ error ("died waiting for dll loading");
goto cleanup;
}
@@ -553,14 +560,14 @@ frok::parent (volatile char * volatile stack_here)
for (dll *d = dlls.istart (DLL_LOAD); d; d = dlls.inext ())
{
debug_printf ("copying data/bss for a loaded dll");
- if (!child_copy (pi.hProcess, true,
+ if (!child_copy (hchild, true,
"loaded dll data", d->p.data_start, d->p.data_end,
"loaded dll bss", d->p.bss_start, d->p.bss_end,
NULL))
{
this_errno = get_errno ();
#ifdef DEBUGGING
- error = "copying data/bss for a loaded dll";
+ error ("copying data/bss for a loaded dll");
#endif
goto cleanup;
}
@@ -582,8 +589,8 @@ cleanup:
__malloc_unlock ();
/* Remember to de-allocate the fd table. */
- if (pi.hProcess && !child.hProcess)
- ForceCloseHandle1 (pi.hProcess, childhProc);
+ if (hchild && !child.hProcess)
+ ForceCloseHandle1 (hchild, childhProc);
if (forker_finished)
ForceCloseHandle (forker_finished);
debug_printf ("returning -1");
@@ -637,6 +644,7 @@ fork ()
else
{
res = grouped.child (esp);
+ in_forkee = false;
ischild = true; /* might have been reset by fork mem copy */
}
}
@@ -649,13 +657,13 @@ fork ()
}
else if (res < 0)
{
- if (!grouped.error)
+ if (!grouped.errmsg)
syscall_printf ("fork failed - child pid %d, errno %d", grouped.child_pid, grouped.this_errno);
else
{
- char buf[strlen (grouped.error) + sizeof ("child %d - , errno 4294967295 ")];
+ char buf[strlen (grouped.errmsg) + sizeof ("child %d - , errno 4294967295 ")];
strcpy (buf, "child %d - ");
- strcat (buf, grouped.error);
+ strcat (buf, grouped.errmsg);
strcat (buf, ", errno %d");
system_printf (buf, grouped.child_pid, grouped.this_errno);
}