diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 0fbb6055f..f567cbeac 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,12 @@
+2006-03-20  Christopher Faylor  <cgf@timesys.com>
+
+	* dcrt0.cc (dll_crt0_0): Call SetErrorMode earlier.
+	* pinfo.cc (_pinfo::dup_proc_pipe): Reset wr_proc_pipe on failure.
+	Return previous pipe handle.
+	* pinfo.h (_pinfo::dup_proc_pipe): Reflect change to return value.
+	* spawn.cc (spawn_guts): Restore previous proc pipe on retry or if
+	process exits before synchronization.
+
 2006-03-20  Christopher Faylor  <cgf@timesys.com>
 
 	* child_info.h (child_status): New enum.
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index 0518ac28f..5f7f2708b 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -702,6 +702,8 @@ dll_crt0_0 ()
   init_global_security ();
   initial_env ();
 
+  SetErrorMode (SEM_FAILCRITICALERRORS);
+
   /* Initialize signal processing here, early, in the hopes that the creation
      of a thread early in the process will cause more predictability in memory
      layout for the main thread. */
@@ -727,7 +729,6 @@ dll_crt0_0 ()
   if (wincap.has_security ())
     OpenProcessToken (hMainProc, MAXIMUM_ALLOWED, &hProcToken);
 
-  SetErrorMode (SEM_FAILCRITICALERRORS);
   device::init ();
   do_global_ctors (&__CTOR_LIST__, 1);
   cygthread::init ();
diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc
index cc64e2f81..6c9cdab16 100644
--- a/winsup/cygwin/pinfo.cc
+++ b/winsup/cygwin/pinfo.cc
@@ -925,7 +925,7 @@ proc_waiter (void *arg)
   return 0;
 }
 
-bool
+HANDLE
 _pinfo::dup_proc_pipe (HANDLE hProcess)
 {
   DWORD flags = DUPLICATE_SAME_ACCESS;
@@ -938,8 +938,11 @@ _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, wr_proc_pipe %p, %E",
-		   pid, hProcess, orig_wr_proc_pipe);
+    {
+      wr_proc_pipe = orig_wr_proc_pipe;
+      system_printf ("DuplicateHandle failed, pid %d, hProcess %p, wr_proc_pipe %p, %E",
+		     pid, hProcess, wr_proc_pipe);
+    }
   else
     {
       wr_proc_pipe_owner = dwProcessId;
@@ -947,7 +950,7 @@ _pinfo::dup_proc_pipe (HANDLE hProcess)
 		      pid, dwProcessId);
       res = true;
     }
-  return res;
+  return orig_wr_proc_pipe;
 }
 
 /* function to set up the process pipe and kick off proc_waiter */
diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h
index fbd73dab9..0367f38e1 100644
--- a/winsup/cygwin/pinfo.h
+++ b/winsup/cygwin/pinfo.h
@@ -116,7 +116,7 @@ public:
   char *cwd (size_t &);
   char *cmdline (size_t &);
   void set_ctty (class tty_min *, int, class fhandler_tty_slave *);
-  bool dup_proc_pipe (HANDLE) __attribute__ ((regparm(2)));
+  HANDLE dup_proc_pipe (HANDLE) __attribute__ ((regparm(2)));
   void sync_proc_pipe ();
   bool alert_parent (char);
   int __stdcall kill (siginfo_t&) __attribute__ ((regparm (2)));
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index 4b48de59e..3a0209764 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -445,6 +445,7 @@ spawn_guts (const char * prog_arg, const char *const *argv,
   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;
+  HANDLE orig_wr_proc_pipe = NULL;
 
   myfault efault;
   if (efault.faulted ())
@@ -795,11 +796,11 @@ loop:
 	  if (!looped)
 	    {
 	      myself->sync_proc_pipe ();	/* Make sure that we own wr_proc_pipe
-					       just in case we've been previously
-					       execed. */
+						   just in case we've been previously
+						   execed. */
 	      myself.zap_cwd ();
 	    }
-	  myself->dup_proc_pipe (pi.hProcess);
+	  orig_wr_proc_pipe = myself->dup_proc_pipe (pi.hProcess);
 	}
       pid = myself->pid;
     }
@@ -858,6 +859,11 @@ loop:
       myself.hProcess = pi.hProcess;
       if (!synced)
 	{
+	  if (orig_wr_proc_pipe)
+	    {
+	      myself->wr_proc_pipe_owner = GetCurrentProcessId ();
+	      myself->wr_proc_pipe = orig_wr_proc_pipe;
+	    }
 	  if (ch.proc_retry (pi.hProcess) == 0)
 	    {
 	      looped++;