summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/ChangeLog50
-rw-r--r--winsup/cygwin/child_info.h8
-rw-r--r--winsup/cygwin/dcrt0.cc33
-rw-r--r--winsup/cygwin/environ.cc7
-rw-r--r--winsup/cygwin/exceptions.cc6
-rw-r--r--winsup/cygwin/fhandler_termios.cc1
-rw-r--r--winsup/cygwin/fhandler_tty.cc4
-rw-r--r--winsup/cygwin/fork.cc40
-rw-r--r--winsup/cygwin/init.cc5
-rw-r--r--winsup/cygwin/pinfo.cc8
-rw-r--r--winsup/cygwin/sigproc.cc50
-rw-r--r--winsup/cygwin/spawn.cc40
-rw-r--r--winsup/cygwin/syscalls.cc1
-rw-r--r--winsup/cygwin/winsup.h3
14 files changed, 170 insertions, 86 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index cb12f151b..aaeac479b 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,53 @@
+2006-03-18 Christopher Faylor <cgf@timesys.com>
+
+ * 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.
+
2006-03-15 Christopher Faylor <cgf@timesys.com>
* cygheap.cc (init_cygheap::manage_console_count): Turn console control
diff --git a/winsup/cygwin/child_info.h b/winsup/cygwin/child_info.h
index 87da6e453..efca03465 100644
--- a/winsup/cygwin/child_info.h
+++ b/winsup/cygwin/child_info.h
@@ -29,7 +29,7 @@ enum child_info_types
#define EXEC_MAGIC_SIZE sizeof(child_info)
-#define CURR_CHILD_INFO_MAGIC 0x88e640f7U
+#define CURR_CHILD_INFO_MAGIC 0x482b2eaU
/* NOTE: Do not make gratuitous changes to the names or organization of the
below class. The layout is checksummed to determine compatibility between
@@ -50,11 +50,15 @@ public:
DWORD cygheap_reserve_sz;
unsigned char straced;
unsigned fhandler_union_cb;
+ int retry; // number of times we've tried to start child process
+ DWORD exit_code; // process exit code
+ static int retry_count;// retry count;
child_info (unsigned, child_info_types, bool);
child_info (): subproc_ready (NULL), parent (NULL) {}
~child_info ();
void ready (bool);
bool sync (int, HANDLE&, DWORD) __attribute__ ((regparm (3)));
+ DWORD proc_retry (HANDLE);
};
class mount_info;
@@ -68,11 +72,9 @@ public:
jmp_buf jmp; // where child will jump to
void *stacktop; // location of top of parent stack
void *stackbottom; // location of bottom of parent stack
- int retry; // number of times we've tried to fork
child_info_fork ();
void handle_fork ();
bool handle_failure (DWORD);
- DWORD fork_retry (HANDLE);
};
class fhandler_base;
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index c309fb36c..52281c9f2 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -642,33 +642,6 @@ get_cygwin_startup_info ()
return res;
}
-DWORD
-child_info_fork::fork_retry (HANDLE h)
-{
- DWORD exit_code;
- if (!GetExitCodeProcess (h, &exit_code))
- return STILL_ACTIVE; /* should never happen */
- switch (exit_code)
- {
- case STATUS_CONTROL_C_EXIT:
- case STATUS_DLL_INIT_FAILED:
- case STATUS_DLL_INIT_FAILED_LOGOFF:
- case EXITCODE_RETRY:
- if (retry-- > 0)
- return 0;
- break;
- }
- return exit_code;
-}
-
-bool
-child_info_fork::handle_failure (DWORD err)
-{
- if (retry > 0)
- ExitProcess (EXITCODE_RETRY);
- return 0;
-}
-
#define dll_data_start &_data_start__
#define dll_data_end &_data_end__
#define dll_bss_start &_bss_start__
@@ -736,7 +709,7 @@ dll_crt0_0 ()
if (!child_proc_info)
{
memory_init ();
- init_console_handler (myself->ctty >= 0);
+ init_console_handler (!!GetConsoleCP ());
}
else
{
@@ -757,8 +730,7 @@ dll_crt0_0 ()
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
h = NULL;
set_myself (h);
- if (child_proc_info->type != _PROC_FORK)
- child_proc_info->ready (true);
+ child_proc_info->ready (true);
__argc = spawn_info->moreinfo->argc;
__argv = spawn_info->moreinfo->argv;
envp = spawn_info->moreinfo->envp;
@@ -773,7 +745,6 @@ dll_crt0_0 ()
}
break;
}
- init_console_handler (myself->ctty >= 0);
}
user_data->resourcelocks->Init ();
diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc
index 28bfe3959..1c934349f 100644
--- a/winsup/cygwin/environ.cc
+++ b/winsup/cygwin/environ.cc
@@ -39,7 +39,6 @@ static bool envcache = true;
#ifdef USE_SERVER
extern bool allow_server;
#endif
-extern int fork_retry;
static char **lastenviron;
@@ -520,9 +519,9 @@ set_chunksize (const char *buf)
}
static void
-set_fork_retry (const char *buf)
+set_proc_retry (const char *buf)
{
- fork_retry = strtoul (buf, NULL, 0);
+ child_info::retry_count = strtoul (buf, NULL, 0);
}
static void
@@ -594,7 +593,7 @@ static struct parse_thing
{"tty", {NULL}, set_process_state, NULL, {{0}, {PID_USETTY}}},
{"winsymlinks", {&allow_winsymlinks}, justset, NULL, {{false}, {true}}},
{"transparent_exe", {&transparent_exe}, justset, NULL, {{false}, {true}}},
- {"fork_retry", {func: set_fork_retry}, isfunc, NULL, {{0}, {5}}},
+ {"proc_retry", {func: set_proc_retry}, isfunc, NULL, {{0}, {5}}},
{NULL, {0}, justset, 0, {{0}, {0}}}
};
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index 53294cd63..dabfeab62 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -94,7 +94,7 @@ NO_COPY static struct
/* Initialization code. */
BOOL WINAPI
-dummy_ctrl_c_handler (DWORD dwCtrlType)
+dummy_ctrl_c_handler (DWORD)
{
return TRUE;
}
@@ -103,6 +103,7 @@ void
init_console_handler (bool install_handler)
{
BOOL res;
+
while (SetConsoleCtrlHandler (ctrl_c_handler, FALSE))
continue;
if (install_handler)
@@ -113,6 +114,7 @@ init_console_handler (bool install_handler)
res = SetConsoleCtrlHandler (dummy_ctrl_c_handler, TRUE);
if (!res)
system_printf ("SetConsoleCtrlHandler failed, %E");
+ return;
}
extern "C" void
@@ -946,7 +948,7 @@ ctrl_c_handler (DWORD type)
if (has_visible_window_station ())
sig_send (myself_nowait, SIGHUP);
#endif
- return FALSE;
+ return TRUE;
}
}
diff --git a/winsup/cygwin/fhandler_termios.cc b/winsup/cygwin/fhandler_termios.cc
index 9b1098fca..3475f5ed5 100644
--- a/winsup/cygwin/fhandler_termios.cc
+++ b/winsup/cygwin/fhandler_termios.cc
@@ -82,7 +82,6 @@ fhandler_termios::tcsetpgrp (const pid_t pgid)
{
case bg_ok:
tc->setpgid (pgid);
- init_console_handler (!!is_console ());
res = 0;
break;
case bg_signalled:
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 24ba4e347..2cf551a9f 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -576,9 +576,7 @@ fhandler_tty_slave::open (int flags, mode_t)
set_output_handle (to_master_local);
set_open_status ();
- if (cygheap->manage_console_count ("fhandler_tty_slave::open", 1) == 1
- && !output_done_event && fhandler_console::need_invisible ())
- init_console_handler (TRUE);
+ cygheap->manage_console_count ("fhandler_tty_slave::open", 1);
// FIXME: Do this better someday
arch = (fhandler_tty_slave *) cmalloc (HEAP_ARCHETYPES, sizeof (*this));
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");
diff --git a/winsup/cygwin/init.cc b/winsup/cygwin/init.cc
index 342bb1cfe..f8b6cd652 100644
--- a/winsup/cygwin/init.cc
+++ b/winsup/cygwin/init.cc
@@ -128,11 +128,12 @@ dll_entry (HANDLE h, DWORD reason, void *static_load)
switch (reason)
{
case DLL_PROCESS_ATTACH:
+ wincap.init ();
+ init_console_handler (false);
+
cygwin_hmodule = (HMODULE) h;
dynamically_loaded = (static_load == NULL);
- wincap.init ();
-
/* Is the stack at an unusual address? This is, an address which
is in the usual space occupied by the process image, but below
the auto load address of DLLs?
diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc
index 146b43238..cacfc7913 100644
--- a/winsup/cygwin/pinfo.cc
+++ b/winsup/cygwin/pinfo.cc
@@ -927,7 +927,8 @@ bool
_pinfo::dup_proc_pipe (HANDLE hProcess)
{
DWORD flags = DUPLICATE_SAME_ACCESS;
- /* Grr. Can't set DUPLICATE_CLOSE_SOURCE for exec case because we could be
+ HANDLE orig_wr_proc_pipe = wr_proc_pipe;
+ /* Can't set DUPLICATE_CLOSE_SOURCE for exec case because we could be
execing a non-cygwin process and we need to set the exit value before the
parent sees it. */
if (this != myself || is_toplevel_proc)
@@ -935,11 +936,12 @@ _pinfo::dup_proc_pipe (HANDLE hProcess)
bool res = DuplicateHandle (hMainProc, wr_proc_pipe, hProcess, &wr_proc_pipe,
0, FALSE, flags);
if (!res && WaitForSingleObject (hProcess, 0) != WAIT_OBJECT_0)
- system_printf ("DuplicateHandle failed, pid %d, hProcess %p, %E", pid, hProcess);
+ system_printf ("DuplicateHandle failed, pid %d, hProcess %p, wr_proc_pipe %p, %E",
+ pid, hProcess, orig_wr_proc_pipe);
else
{
wr_proc_pipe_owner = dwProcessId;
- sigproc_printf ("closed wr_proc_pipe %p for pid %d(%u)", wr_proc_pipe,
+ sigproc_printf ("duped wr_proc_pipe %p for pid %d(%u)", wr_proc_pipe,
pid, dwProcessId);
res = true;
}
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index 4cd538c32..a213a5607 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -523,7 +523,7 @@ sig_send (_pinfo *p, int sig)
else
{
#ifdef DEBUGGING
- system_printf ("signal %d sent to %p while signals are on hold", p, sig);
+ system_printf ("signal %d sent to %p while signals are on hold", sig, p);
#endif
return -1;
}
@@ -767,6 +767,7 @@ out:
return rc;
}
+int child_info::retry_count = 10;
/* Initialize some of the memory block passed to child processes
by fork/spawn/exec. */
@@ -785,6 +786,7 @@ child_info::child_info (unsigned in_cb, child_info_types chtype, bool need_subpr
cygheap = ::cygheap;
cygheap_max = ::cygheap_max;
straced = strace.attached ();
+ retry = child_info::retry_count;
/* Create an inheritable handle to pass to the child process. This will
allow the child to duplicate handles from the parent to itself. */
parent = NULL;
@@ -862,21 +864,63 @@ child_info::sync (pid_t pid, HANDLE& hProcess, DWORD howlong)
else
{
if (x != nsubproc_ready)
- res = type != _PROC_FORK;
+ {
+ res = false;
+ GetExitCodeProcess (hProcess, &exit_code);
+ }
else
{
+ res = true;
+ exit_code = STILL_ACTIVE;
if (type == _PROC_EXEC && myself->wr_proc_pipe)
{
ForceCloseHandle1 (hProcess, childhProc);
hProcess = NULL;
}
- res = true;
}
sigproc_printf ("pid %u, WFMO returned %d, res %d", pid, x, res);
}
return res;
}
+DWORD
+child_info::proc_retry (HANDLE h)
+{
+ switch (exit_code)
+ {
+ case STILL_ACTIVE: /* shouldn't happen */
+ sigproc_printf ("STILL_ACTIVE? How'd we get here?");
+ break;
+ case STATUS_CONTROL_C_EXIT:
+ case STATUS_DLL_INIT_FAILED:
+ case STATUS_DLL_INIT_FAILED_LOGOFF:
+ case EXITCODE_RETRY:
+ if (retry-- > 0)
+ exit_code = 0;
+ break;
+ /* Count down non-recognized exit codes more quickly since they aren't
+ due to known conditions. */
+ default:
+ if ((exit_code & 0xc0000000) != 0xc0000000)
+ break;
+ if ((retry -= 2) < 0)
+ retry = 0;
+ else
+ exit_code = 0;
+ }
+ if (!exit_code)
+ ForceCloseHandle1 (h, childhProc);
+ return exit_code;
+}
+
+bool
+child_info_fork::handle_failure (DWORD err)
+{
+ if (retry > 0)
+ ExitProcess (EXITCODE_RETRY);
+ return 0;
+}
+
/* Check the state of all of our children to see if any are stopped or
* terminated.
*/
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index cac02d988..16955bbb7 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -438,12 +438,13 @@ spawn_guts (const char * prog_arg, const char *const *argv,
linebuf one_line;
child_info_spawn ch;
- char *envblock;
+ char *envblock = NULL;
path_conv real_path;
bool reset_sendsig = false;
bool null_app_name = false;
STARTUPINFO si = {0, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL};
+ int looped = 0;
myfault efault;
if (efault.faulted ())
@@ -600,7 +601,7 @@ spawn_guts (const char * prog_arg, const char *const *argv,
int flags = GetPriorityClass (hMainProc);
sigproc_printf ("priority class %d", flags);
- flags |= CREATE_DEFAULT_ERROR_MODE | CREATE_SEPARATE_WOW_VDM;
+ flags |= /* CREATE_DEFAULT_ERROR_MODE | */CREATE_SEPARATE_WOW_VDM;
if (mode == _P_DETACH)
flags |= DETACHED_PROCESS;
@@ -649,7 +650,6 @@ spawn_guts (const char * prog_arg, const char *const *argv,
cygbench ("spawn-guts");
cygheap->fdtab.set_file_pointers_for_exec ();
- cygheap->user.deimpersonate ();
moreinfo->envp = build_env (envp, envblock, moreinfo->envc, real_path.iscygexec ());
if (!moreinfo->envp || !envblock)
@@ -669,6 +669,9 @@ spawn_guts (const char * prog_arg, const char *const *argv,
effective vs. real ids.
FIXME: If ruid != euid and ruid != saved_uid we currently give
up on ruid. The new process will have ruid == euid. */
+loop:
+ cygheap->user.deimpersonate ();
+
if (!cygheap->user.issetuid ()
|| (cygheap->user.saved_uid == cygheap->user.real_uid
&& cygheap->user.saved_gid == cygheap->user.real_gid
@@ -726,9 +729,6 @@ spawn_guts (const char * prog_arg, const char *const *argv,
if (mode != _P_OVERLAY || !rc)
cygheap->user.reimpersonate ();
- if (envblock)
- free (envblock);
-
/* Set errno now so that debugging messages from it appear before our
final debugging message [this is a general rule for debugging
messages]. */
@@ -776,7 +776,8 @@ spawn_guts (const char * prog_arg, const char *const *argv,
strace.execing = 1;
myself.hProcess = hExeced = pi.hProcess;
strcpy (myself->progname, real_path); // FIXME: race?
- close_all_files (true);
+ if (!looped)
+ close_all_files (true);
sigproc_printf ("new process name %s", myself->progname);
/* If wr_proc_pipe doesn't exist then this process was not started by a cygwin
process. So, we need to wait around until the process we've just "execed"
@@ -791,10 +792,13 @@ spawn_guts (const char * prog_arg, const char *const *argv,
dup_proc_pipe essentially a no-op. */
if (!newargv.win16_exe && myself->wr_proc_pipe)
{
- myself->sync_proc_pipe (); /* Make sure that we own wr_proc_pipe
- just in case we've been previously
- execed. */
- myself.zap_cwd ();
+ if (!looped)
+ {
+ myself->sync_proc_pipe (); /* Make sure that we own wr_proc_pipe
+ just in case we've been previously
+ execed. */
+ myself.zap_cwd ();
+ }
myself->dup_proc_pipe (pi.hProcess);
}
pid = myself->pid;
@@ -852,8 +856,16 @@ spawn_guts (const char * prog_arg, const char *const *argv,
{
case _P_OVERLAY:
myself.hProcess = pi.hProcess;
- if (synced && WaitForSingleObject (pi.hProcess, 0) == WAIT_TIMEOUT
- && !myself->wr_proc_pipe)
+ if (!synced)
+ {
+ if (ch.proc_retry (pi.hProcess) == 0)
+ {
+ looped++;
+ goto loop;
+ }
+ }
+ else if (!myself->wr_proc_pipe
+ && WaitForSingleObject (pi.hProcess, 0) == WAIT_TIMEOUT)
{
extern bool is_toplevel_proc;
is_toplevel_proc = true;
@@ -880,6 +892,8 @@ spawn_guts (const char * prog_arg, const char *const *argv,
}
out:
+ if (envblock)
+ free (envblock);
pthread_cleanup_pop (1);
return (int) res;
}
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 758949398..3b976c0d3 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -1987,7 +1987,6 @@ setpgid (pid_t pid, pid_t pgid)
if (p->pid != p->pgid)
p->set_has_pgid_children (0);
res = 0;
- // init_console_handler (FALSE);
}
}
diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h
index 3695f4917..73ef0a59f 100644
--- a/winsup/cygwin/winsup.h
+++ b/winsup/cygwin/winsup.h
@@ -302,9 +302,10 @@ bool mmap_is_attached_page (ULONG_PTR);
int winprio_to_nice (DWORD) __attribute__ ((regparm (1)));
DWORD nice_to_winprio (int &) __attribute__ ((regparm (1)));
-bool __stdcall create_pipe (PHANDLE hr, PHANDLE, LPSECURITY_ATTRIBUTES, DWORD)
+bool __stdcall create_pipe (PHANDLE, PHANDLE, LPSECURITY_ATTRIBUTES, DWORD)
__attribute__ ((regparm (3)));
#define CreatePipe create_pipe
+
inline bool flush_file_buffers (HANDLE h)
{
return (GetFileType (h) != FILE_TYPE_PIPE) ? FlushFileBuffers (h) : true;