From a939686807dd8e832939fddf514040fdba7077d8 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Sat, 18 Mar 2006 19:17:21 +0000 Subject: * child_info.h (CURR_CHILD_INFO_MAGIC): Regenerate. (child_info::retry): Move here from fork subclass. (child_info::exit_code): New field. (child_info::retry_count): Max retry count for process start. (child_info::proc_retry): Declare new function. (child_info_fork::retry): Move to parent. (child_info_fork::fork_retry): Ditto. * dcrt0.cc (child_info::fork_retry): Rename and move. (child_info_fork::handle_failure): Move. (dll_crt0_0): Initialize console handler based on whether we have a controlling tty or not. Avoid nonsensical check for fork where it can never occur. * environ.cc (set_proc_retry): Rename from set_fork_retry. Set retry_count in child_info. (parse_thing): Reflect above change. * exceptions.cc (dummy_ctrl_c_handler): Remove unused variable name. (ctrl_c_handler): Always return TRUE for the annoying CTRL_LOGOFF_EVENT. * fhandler_termios.cc (fhandler_termios::tcsetpgrp): Remove call to init_console_handler. * fhandler_tty.cc (fhandler_tty_slave::open): Just call mange_console_count here and let it decide what to do with initializing console control handling. * fork.cc (fork_retry): Remove definition. (frok::parent): Define static errbuf and use in error messages (not thread safe yet). Close pi.hThread as soon as possible. Protect pi.hProcess as soon as possible. Don't set retry_count. That happens automatically in the constructor now. Accommodate name change from fork_retry to proc_retry. * init.cc (dll_entry): Turn off ctrl-c handling early until we know how it is supposed to be handled. * pinfo.cc (_pinfo::dup_proc_pipe): Remember original proc pipe value for failure error message. Tweak debug message slightly. * sigproc.cc (child_info::retry_count): Define. (child_info::child_info): Initialize retry count. (child_info::sync): Set exit code if process dies before synchronization. (child_info::proc_retry): Rename from child_info_fork::fork_retry. Use previously derived exit code. Be more defensive about what is classified as an error exit. (child_info_fork::handle_failure): Move here from dcrt0.cc. * spawn.cc (spawn_guts): Maintain error mode when starting new process to avoid annoying pop ups. Move deimpersonate call within new loop. Move envblock freeing to end. Loop if process dies prematurely with bad exit code. * syscalls.cc (init_console_handler): Remove hopefully unneeded call to init_console_handler. --- winsup/cygwin/fork.cc | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) (limited to 'winsup/cygwin/fork.cc') diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index 260960895..0360d1a52 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -33,8 +33,6 @@ details. */ #define NPIDS_HELD 4 -int fork_retry = 5; - /* Timeout to wait for child to start, parent to init child, etc. */ /* FIXME: Once things stabilize, bump up to a few minutes. */ #define FORK_WAIT_TIMEOUT (300 * 1000) /* 300 seconds */ @@ -171,6 +169,7 @@ frok::child (void *) sync_with_parent ("loaded dlls", true); } + init_console_handler (myself->ctty >= 0); ForceCloseHandle1 (fork_info->forker_finished, forker_finished); pthread::atforkchild (); @@ -221,6 +220,7 @@ frok::parent (void *stack_here) this_errno = 0; bool fix_impersonation = false; pinfo child; + static char errbuf[256]; pthread::atforkprepare (); @@ -290,7 +290,6 @@ frok::parent (void *stack_here) myself->progname, myself->progname, c_flags, &si, &pi); bool locked = __malloc_lock (); time_t start_time; - ch.retry = fork_retry; while (1) { start_time = time (NULL); @@ -321,22 +320,25 @@ frok::parent (void *stack_here) ResumeThread (pi.hThread); } + CloseHandle (pi.hThread); + + /* Protect the handle but name it similarly to the way it will + be called in subproc handling. */ + ProtectHandle1 (pi.hProcess, childhProc); + strace.write_childpid (ch, pi.dwProcessId); /* Wait for subproc to initialize itself. */ if (!ch.sync (pi.dwProcessId, pi.hProcess, FORK_WAIT_TIMEOUT)) { - DWORD exit_code = ch.fork_retry (pi.hProcess); + DWORD exit_code = ch.proc_retry (pi.hProcess); if (!exit_code) continue; this_errno = EAGAIN; /* Not thread safe, but do we care? */ - static char buf[sizeof("died waiting for longjmp before " - "initialization, retry 4294967295, " - "exit code 0xfffffffff")]; - __small_sprintf (buf, "died waiting for longjmp before initialization, " + __small_sprintf (errbuf, "died waiting for longjmp before initialization, " "retry %d, exit code %p", ch.retry, exit_code); - error = buf; + error = errbuf; goto cleanup; } break; @@ -367,11 +369,6 @@ frok::parent (void *stack_here) cygheap->user.reimpersonate (); fix_impersonation = false; - ProtectHandle (pi.hThread); - /* Protect the handle but name it similarly to the way it will - be called in subproc handling. */ - ProtectHandle1 (pi.hProcess, childhProc); - /* Fill in fields in the child's process table entry. */ child->dwProcessId = pi.dwProcessId; child.hProcess = pi.hProcess; @@ -426,6 +423,11 @@ frok::parent (void *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; goto cleanup; } @@ -440,7 +442,11 @@ frok::parent (void *stack_here) { this_errno = get_errno (); #ifdef DEBUGGING - error = "fork_copy for linked dll data/bss failed"; + 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 goto cleanup; } @@ -481,10 +487,8 @@ frok::parent (void *stack_here) resume_child (forker_finished); } - ForceCloseHandle (pi.hThread); ForceCloseHandle (forker_finished); forker_finished = NULL; - pi.hThread = NULL; pthread::atforkparent (); return child_pid; @@ -499,8 +503,6 @@ cleanup: /* Remember to de-allocate the fd table. */ if (pi.hProcess && !child.hProcess) ForceCloseHandle1 (pi.hProcess, childhProc); - if (pi.hThread) - ForceCloseHandle (pi.hThread); if (forker_finished) ForceCloseHandle (forker_finished); debug_printf ("returning -1"); -- cgit v1.2.3