aboutsummaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2004-11-16 06:02:06 +0000
committerChristopher Faylor <me@cgf.cx>2004-11-16 06:02:06 +0000
commit406439ffc770eec92a7a55997501460063c3c124 (patch)
tree80255c57bfef8741b3f5fd954c2adc0fa5da91b7 /winsup
parente4159ff2b48023606222f71a5f2af1d2bc033bc1 (diff)
downloadnewlib-406439ffc770eec92a7a55997501460063c3c124.zip
newlib-406439ffc770eec92a7a55997501460063c3c124.tar.gz
newlib-406439ffc770eec92a7a55997501460063c3c124.tar.bz2
experimental branch which removes cygwin's reparenting code, in favor of a pipe.
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/child_info.h3
-rw-r--r--winsup/cygwin/cygthread.cc2
-rw-r--r--winsup/cygwin/dcrt0.cc18
-rw-r--r--winsup/cygwin/dtable.cc2
-rw-r--r--winsup/cygwin/exceptions.cc33
-rw-r--r--winsup/cygwin/fork.cc8
-rw-r--r--winsup/cygwin/include/sys/cygwin.h2
-rw-r--r--winsup/cygwin/include/sys/wait.h3
-rw-r--r--winsup/cygwin/pinfo.cc139
-rw-r--r--winsup/cygwin/pinfo.h21
-rw-r--r--winsup/cygwin/signal.cc2
-rw-r--r--winsup/cygwin/sigproc.cc448
-rw-r--r--winsup/cygwin/sigproc.h9
-rw-r--r--winsup/cygwin/spawn.cc43
-rw-r--r--winsup/cygwin/tty.cc2
15 files changed, 292 insertions, 443 deletions
diff --git a/winsup/cygwin/child_info.h b/winsup/cygwin/child_info.h
index 3088bea..e3d643a 100644
--- a/winsup/cygwin/child_info.h
+++ b/winsup/cygwin/child_info.h
@@ -29,7 +29,7 @@ enum
#define EXEC_MAGIC_SIZE sizeof(child_info)
-#define CURR_CHILD_INFO_MAGIC 0x19c16fb6U
+#define CURR_CHILD_INFO_MAGIC 0x568a5527U
/* NOTE: Do not make gratuitous changes to the names or organization of the
below class. The layout is checksummed to determine compatibility between
@@ -45,7 +45,6 @@ public:
HANDLE subproc_ready; // used for synchronization with parent
HANDLE user_h;
HANDLE parent;
- HANDLE pppid_handle;
init_cygheap *cygheap;
void *cygheap_max;
DWORD cygheap_reserve_sz;
diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc
index 7ad860b..e3f3fdc 100644
--- a/winsup/cygwin/cygthread.cc
+++ b/winsup/cygwin/cygthread.cc
@@ -20,7 +20,7 @@ details. */
#undef CloseHandle
-static cygthread NO_COPY threads[32];
+static cygthread NO_COPY threads[128];
#define NTHREADS (sizeof (threads) / sizeof (threads[0]))
DWORD NO_COPY cygthread::main_thread_id;
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index 47cd8b1..eabda1c 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -656,7 +656,6 @@ dll_crt0_0 ()
memory_init ();
else
{
- bool close_ppid_handle = false;
bool close_hexec_proc = false;
switch (child_proc_info->type)
{
@@ -665,12 +664,10 @@ dll_crt0_0 ()
cygheap_fixup_in_child (false);
memory_init ();
set_myself (NULL);
- close_ppid_handle = !!child_proc_info->pppid_handle;
break;
case _PROC_SPAWN:
/* Have to delay closes until after cygheap is setup */
close_hexec_proc = !!spawn_info->hexec_proc;
- close_ppid_handle = !!child_proc_info->pppid_handle;
goto around;
case _PROC_EXEC:
hexec_proc = spawn_info->hexec_proc;
@@ -699,8 +696,6 @@ dll_crt0_0 ()
}
if (close_hexec_proc)
CloseHandle (spawn_info->hexec_proc);
- if (close_ppid_handle)
- CloseHandle (child_proc_info->pppid_handle);
}
_cygtls::init ();
@@ -1014,13 +1009,10 @@ do_exit (int status)
if (exit_state < ES_SIGNAL)
{
exit_state = ES_SIGNAL;
- if (!(n & EXIT_REPARENTING))
- {
- signal (SIGCHLD, SIG_IGN);
- signal (SIGHUP, SIG_IGN);
- signal (SIGINT, SIG_IGN);
- signal (SIGQUIT, SIG_IGN);
- }
+ signal (SIGCHLD, SIG_IGN);
+ signal (SIGHUP, SIG_IGN);
+ signal (SIGINT, SIG_IGN);
+ signal (SIGQUIT, SIG_IGN);
}
if (exit_state < ES_CLOSEALL)
@@ -1112,7 +1104,7 @@ cygwin_exit (int n)
extern "C" void
_exit (int n)
{
- do_exit ((DWORD) n & 0xffff);
+ do_exit (((DWORD) n & 0xff) << 8);
}
extern "C" void
diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc
index cc72a2a..81c84a9 100644
--- a/winsup/cygwin/dtable.cc
+++ b/winsup/cygwin/dtable.cc
@@ -140,7 +140,7 @@ dtable::stdio_init ()
Also, always set them even if we're to pick up our parent's fds
in case they're missed. */
- if (myself->ppid_handle || ISSTATE (myself, PID_CYGPARENT))
+ if (myself->cygstarted || ISSTATE (myself, PID_CYGPARENT))
return;
HANDLE in = GetStdHandle (STD_INPUT_HANDLE);
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index 510f534..2ac1358 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -159,7 +159,7 @@ open_stackdumpfile ()
CREATE_ALWAYS, 0, 0);
if (h != INVALID_HANDLE_VALUE)
{
- if (!myself->ppid_handle)
+ if (!myself->cygstarted)
system_printf ("Dumping stack trace to %s", corefile);
else
debug_printf ("Dumping stack trace to %s", corefile);
@@ -514,7 +514,7 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *)
|| (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_ERR)
{
/* Print the exception to the console */
- if (!myself->ppid_handle)
+ if (!myself->cygstarted)
for (int i = 0; status_info[i].name; i++)
if (status_info[i].code == e.ExceptionCode)
{
@@ -596,13 +596,15 @@ sig_handle_tty_stop (int sig)
_my_tls.incyg = 1;
/* Silently ignore attempts to suspend if there is no accommodating
cygwin parent to deal with this behavior. */
- if (!myself->ppid_handle)
+ if (!myself->cygstarted)
{
myself->process_state &= ~PID_STOPPED;
return;
}
myself->stopsig = sig;
+ char pipesig;
+ DWORD nb;
/* See if we have a living parent. If so, send it a special signal.
It will figure out exactly which pid has stopped by scanning
its list of subprocesses. */
@@ -611,16 +613,12 @@ sig_handle_tty_stop (int sig)
pinfo parent (myself->ppid);
if (NOTSTATE (parent, PID_NOCLDSTOP))
{
- siginfo_t si;
- si.si_signo = SIGCHLD;
- si.si_code = SI_KERNEL;
- si.si_sigval.sival_int = CLD_STOPPED;
- si.si_errno = si.si_pid = si.si_uid = si.si_errno = 0;
- sig_send (parent, si);
+ pipesig = sig;
+ if (!WriteFile (myself->wr_proc_pipe, &pipesig, 1, &nb, NULL))
+ debug_printf ("sending stop notification to parent failed, %E");
}
}
- sigproc_printf ("process %d stopped by signal %d, myself->ppid_handle %p",
- myself->pid, sig, myself->ppid_handle);
+ sigproc_printf ("process %d stopped by signal %d", myself->pid, sig);
HANDLE w4[2];
w4[0] = sigCONT;
w4[1] = signal_arrived;
@@ -629,6 +627,16 @@ sig_handle_tty_stop (int sig)
case WAIT_OBJECT_0:
case WAIT_OBJECT_0 + 1:
reset_signal_arrived ();
+ if (my_parent_is_alive ())
+ {
+ pinfo parent (myself->ppid);
+ if (parent)
+ {
+ sig = SIGCONT;
+ if (!WriteFile (myself->wr_proc_pipe, &sig, 1, &nb, NULL))
+ debug_printf ("sending stop notification to parent failed, %E");
+ }
+ }
break;
default:
api_fatal ("WaitSingleObject failed, %E");
@@ -807,7 +815,7 @@ ctrl_c_handler (DWORD type)
if (!cygwin_finished_initializing)
{
- if (myself->ppid_handle) /* Was this process created by a cygwin process? */
+ if (myself->cygstarted) /* Was this process created by a cygwin process? */
return TRUE; /* Yes. Let the parent eventually handle CTRL-C issues. */
debug_printf ("exiting with status %p", STATUS_CONTROL_C_EXIT);
ExitProcess (STATUS_CONTROL_C_EXIT);
@@ -1097,7 +1105,6 @@ static void
signal_exit (int rc)
{
EnterCriticalSection (&exit_lock);
- rc = EXIT_SIGNAL | (rc << 8);
if (exit_already++)
myself->exit (rc);
diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc
index 187fcdc..52a5b5e 100644
--- a/winsup/cygwin/fork.cc
+++ b/winsup/cygwin/fork.cc
@@ -356,8 +356,6 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
pthread::atforkprepare ();
- subproc_init ();
-
int c_flags = GetPriorityClass (hMainProc) /*|
CREATE_NEW_PROCESS_GROUP*/;
STARTUPINFO si = {0, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL};
@@ -384,7 +382,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
/* Create an inheritable handle to pass to the child process. This will
allow the child to duplicate handles from the parent to itself. */
hParent = NULL;
- if (!DuplicateHandle (hMainProc, hMainProc, hMainProc, &hParent, 0, 1,
+ if (!DuplicateHandle (hMainProc, hMainProc, hMainProc, &hParent, 0, TRUE,
DUPLICATE_SAME_ACCESS))
{
system_printf ("couldn't create handle to myself for child, %E");
@@ -501,8 +499,8 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
ProtectHandle1 (pi.hProcess, childhProc);
/* Fill in fields in the child's process table entry. */
- forked->hProcess = pi.hProcess;
forked->dwProcessId = pi.dwProcessId;
+ forked.hProcess = pi.hProcess;
/* Hopefully, this will succeed. The alternative to doing things this
way is to reserve space prior to calling CreateProcess and then fill
@@ -590,6 +588,8 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
(void) resume_child (pi, forker_finished);
}
+ if (pi.hProcess)
+ ForceCloseHandle1 (pi.hProcess, childhProc);
ForceCloseHandle (subproc_ready);
ForceCloseHandle (pi.hThread);
ForceCloseHandle (forker_finished);
diff --git a/winsup/cygwin/include/sys/cygwin.h b/winsup/cygwin/include/sys/cygwin.h
index 2b42462..b8c9973 100644
--- a/winsup/cygwin/include/sys/cygwin.h
+++ b/winsup/cygwin/include/sys/cygwin.h
@@ -232,7 +232,7 @@ struct external_pinfo
{
pid_t pid;
pid_t ppid;
- HANDLE hProcess;
+ DWORD exitcode;
DWORD dwProcessId, dwSpawnedProcessId;
__uid16_t uid;
__gid16_t gid;
diff --git a/winsup/cygwin/include/sys/wait.h b/winsup/cygwin/include/sys/wait.h
index 9dd8bf7..d070838 100644
--- a/winsup/cygwin/include/sys/wait.h
+++ b/winsup/cygwin/include/sys/wait.h
@@ -1,6 +1,6 @@
/* sys/wait.h
- Copyright 1997, 1998, 2001 Red Hat, Inc.
+ Copyright 1997, 1998, 2001, 2002, 2003, 2004 Red Hat, Inc.
This file is part of Cygwin.
@@ -36,6 +36,7 @@ extern "C" {
#define WEXITSTATUS(w) (((w) >> 8) & 0xff)
#define WTERMSIG(w) ((w) & 0x7f)
#define WSTOPSIG WEXITSTATUS
+#define WCOREDUMP(w) (WIFSIGNALED(w) && (w & 0x80))
pid_t wait (int *);
pid_t waitpid (pid_t, int *, int);
diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc
index 829db2a..f11e1c5 100644
--- a/winsup/cygwin/pinfo.cc
+++ b/winsup/cygwin/pinfo.cc
@@ -24,6 +24,7 @@ details. */
#include "perprocess.h"
#include "environ.h"
#include <assert.h>
+#include <sys/wait.h>
#include <ntdef.h>
#include "ntdll.h"
#include "cygthread.h"
@@ -70,7 +71,13 @@ set_myself (HANDLE h)
if (!strace.active)
strace.hello ();
debug_printf ("myself->dwProcessId %u", myself->dwProcessId);
- InitializeCriticalSection (&myself->lock);
+ InitializeCriticalSection (&myself.lock);
+ if (!h && myself->ppid)
+ {
+ pinfo parent (myself->ppid);
+ if (parent && parent->wr_proc_pipe)
+ CloseHandle (parent->wr_proc_pipe);
+ }
return;
}
@@ -108,6 +115,8 @@ _pinfo::exit (UINT n, bool norecord)
cygthread::terminate ();
if (norecord)
sigproc_terminate ();
+ else
+ exitcode = n;
if (this)
{
if (!norecord)
@@ -259,6 +268,7 @@ pinfo::init (pid_t n, DWORD flag, HANDLE in_h)
procinfo->process_state |= PID_IN_USE | PID_EXECED;
procinfo->pid = myself->pid;
}
+
break;
}
destroy = 1;
@@ -505,7 +515,7 @@ _pinfo::commune_send (DWORD code, ...)
__seterrno ();
goto err;
}
- EnterCriticalSection (&myself->lock);
+ EnterCriticalSection (&myself.lock);
myself->tothem = tome;
myself->fromthem = fromme;
myself->hello_pid = pid;
@@ -609,7 +619,7 @@ err:
out:
myself->hello_pid = 0;
- LeaveCriticalSection (&myself->lock);
+ LeaveCriticalSection (&myself.lock);
return res;
}
@@ -642,6 +652,129 @@ _pinfo::cmdline (size_t& n)
return s;
}
+static DWORD WINAPI
+proc_waiter (void *arg)
+{
+ pinfo vchild = *(pinfo *) arg;
+ vchild.preserve ();
+
+ siginfo_t si;
+ si.si_signo = SIGCHLD;
+ si.si_code = SI_KERNEL;
+ si.si_pid = vchild->pid;
+ si.si_errno = 0;
+#if 0 // FIXME: This is tricky to get right
+ si.si_utime = pchildren[rc]->rusage_self.ru_utime;
+ si.si_stime = pchildren[rc].rusage_self.ru_stime;
+#else
+ si.si_utime = 0;
+ si.si_stime = 0;
+#endif
+ pid_t pid = vchild->pid;
+
+ for (;;)
+ {
+ DWORD nb;
+ char buf = '\0';
+ if (!ReadFile (vchild.rd_proc_pipe, &buf, 1, &nb, NULL)
+ && GetLastError () != ERROR_BROKEN_PIPE)
+ {
+ system_printf ("error on read of child wait pipe %p, %E", vchild.rd_proc_pipe);
+ break;
+ }
+
+ si.si_uid = vchild->uid;
+
+ int proc_todo;
+ switch (buf)
+ {
+ case 0:
+ if (WIFEXITED (vchild->exitcode))
+ si.si_sigval.sival_int = CLD_STOPPED;
+ else if (WCOREDUMP (vchild->exitcode))
+ si.si_sigval.sival_int = CLD_DUMPED;
+ else
+ si.si_sigval.sival_int = CLD_KILLED;
+ CloseHandle (vchild.rd_proc_pipe);
+ vchild.rd_proc_pipe = NULL;
+ si.si_status = vchild->exitcode;
+ // proc_todo = PROC_CHILDTERMINATED;
+ vchild->process_state = PID_ZOMBIE;
+ break;
+ case SIGTTIN:
+ case SIGTTOU:
+ case SIGTSTP:
+ case SIGSTOP:
+ si.si_sigval.sival_int = CLD_STOPPED;
+ // proc_todo = PROC_CHILDSTOPPED;
+ break;
+ case SIGCONT:
+ // proc_todo = PROC_CHILDCONTINUED;
+ continue;
+ default:
+ system_printf ("unknown value %d on proc pipe", buf);
+ continue;
+ }
+
+ /* Send a SIGCHLD to myself. We do this here, rather than in proc_subproc
+ to avoid the proc_subproc lock since the signal thread will eventually
+ be calling proc_subproc and could unnecessarily block. */
+ sig_send (myself_nowait, si);
+
+ /* If we're just stopped or got a continue signal, keep looping.
+ Otherwise, return this thread to the pool. */
+ if (buf != '\0')
+ sigproc_printf ("looping");
+ else
+ break;
+ }
+ sigproc_printf ("exiting wait thread for pid %d", pid);
+ return 0;
+}
+
+int
+pinfo::wait ()
+{
+ HANDLE out;
+ /* FIXME: execed processes should be able to wait for pids that were started
+ by the process which execed them. */
+ if (!CreatePipe (&rd_proc_pipe, &out, &sec_none_nih, 16))
+ {
+ system_printf ("Couldn't create pipe tracker for pid %d, %E",
+ (*this)->pid);
+ return 0;
+ }
+ if (!DuplicateHandle (hMainProc, out, hProcess, &((*this)->wr_proc_pipe), 0,
+ TRUE, DUPLICATE_SAME_ACCESS))
+ {
+ system_printf ("Couldn't duplicate pipe topid %d(%p), %E", (*this)->pid,
+ hProcess);
+ return 0;
+ }
+ CloseHandle (out);
+
+
+#if 1
+ DWORD tid;
+ HANDLE h = CreateThread (&sec_none_nih, 0, proc_waiter, this, 0, &tid);
+ if (!h)
+ sigproc_printf ("tracking thread creation failed for pid %d", (*this)->pid);
+ else
+ CloseHandle (h);
+#else
+ cygthread *h = new cygthread (proc_waiter, this, "sig");
+ if (!h)
+ sigproc_printf ("tracking thread creation failed for pid %d", (*this)->pid);
+ else
+ {
+ h->zap_h ();
+ sigproc_printf ("created tracking thread for pid %d, winpid %p, rd_pipe %p",
+ (*this)->pid, (*this)->dwProcessId, rd_proc_pipe);
+ }
+#endif
+ return 1;
+}
+
void
pinfo::release ()
{
diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h
index aa1fb8c..89e4a6c 100644
--- a/winsup/cygwin/pinfo.h
+++ b/winsup/cygwin/pinfo.h
@@ -36,19 +36,15 @@ public:
constants below. */
DWORD process_state;
- /* If hProcess is set, it's because it came from a
- CreateProcess call. This means it's process relative
- to the thing which created the process. That's ok because
- we only use this handle from the parent. */
- HANDLE hProcess;
+ DWORD exitcode; /* set when process exits */
-#define PINFO_REDIR_SIZE ((char *) &myself.procinfo->hProcess - (char *) myself.procinfo)
+#define PINFO_REDIR_SIZE ((char *) &myself.procinfo->exitcode - (char *) myself.procinfo)
/* Handle associated with initial Windows pid which started it all. */
HANDLE pid_handle;
- /* Handle to the logical parent of this pid. */
- HANDLE ppid_handle;
+ /* True if started by a cygwin process (DWORD for hysterical reasons) */
+ DWORD cygstarted;
/* Parent process id. */
pid_t ppid;
@@ -120,7 +116,9 @@ public:
HANDLE sendsig;
private:
sigset_t sig_mask;
- CRITICAL_SECTION lock;
+public:
+ HANDLE wr_proc_pipe;
+ friend class pinfo;
};
class pinfo
@@ -129,12 +127,16 @@ class pinfo
_pinfo *procinfo;
bool destroy;
public:
+ HANDLE rd_proc_pipe;
+ HANDLE hProcess;
+ CRITICAL_SECTION lock;
void init (pid_t, DWORD, HANDLE = NULL) __attribute__ ((regparm(3)));
pinfo () {}
pinfo (_pinfo *x): procinfo (x) {}
pinfo (pid_t n) {init (n, 0);}
pinfo (pid_t n, DWORD flag) {init (n, flag);}
void release ();
+ int wait ();
~pinfo ()
{
if (destroy && procinfo)
@@ -151,6 +153,7 @@ public:
_pinfo *operator * () const {return procinfo;}
operator _pinfo * () const {return procinfo;}
// operator bool () const {return (int) h;}
+ void preserve() { destroy = false; }
#ifndef _SIGPROC_H
int remember () {system_printf ("remember is not here"); return 0;}
#else
diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc
index bd75dff..f57e0d0 100644
--- a/winsup/cygwin/signal.cc
+++ b/winsup/cygwin/signal.cc
@@ -342,7 +342,7 @@ abort (void)
raise (SIGABRT);
(void) _my_tls.call_signal_handler (); /* Call any signal handler */
- do_exit (1); /* signal handler didn't exit. Goodbye. */
+ do_exit (SIGABRT); /* signal handler didn't exit. Goodbye. */
}
extern "C" int
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index 416761e..1ddb74e 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -42,11 +42,9 @@ details. */
#define PSIZE 63 // Number of processes
-#define wake_wait_subproc() SetEvent (events[0])
-
#define no_signals_available() (!hwait_sig || (myself->sendsig == INVALID_HANDLE_VALUE) || exit_state)
-#define NZOMBIES 256
+#define NPROCS 256
/*
* Global variables
@@ -64,30 +62,15 @@ HANDLE NO_COPY signal_arrived; // Event signaled when a signal has
#define Static static NO_COPY
-/* How long to wait for message/signals. Normally this is infinite.
- On termination, however, these are set to zero as a flag to exit. */
-
-Static DWORD proc_loop_wait = 1000; // Wait for subprocesses to exit
-
HANDLE NO_COPY sigCONT; // Used to "STOP" a process
Static cygthread *hwait_sig; // Handle of wait_sig thread
-Static cygthread *hwait_subproc; // Handle of sig_subproc thread
Static HANDLE wait_sig_inited; // Control synchronization of
// message queue startup
-/* Used by WaitForMultipleObjects. These are handles to child processes.
- */
-Static HANDLE events[PSIZE + 1]; // All my children's handles++
-#define hchildren (events + 1) // Where the children handles begin
-Static int nchildren; // Number of active children
-Static char cpchildren[PSIZE * sizeof (pinfo)]; // All my children info
-Static int nzombies; // Number of deceased children
-Static char czombies[(NZOMBIES + 1) * sizeof (pinfo)]; // All my deceased children info
-
-#define pchildren ((pinfo *) cpchildren)
-#define zombies ((pinfo *) czombies)
-
+Static int nprocs; // Number of deceased children
+Static char cprocs[(NPROCS + 1) * sizeof (pinfo)]; // All my deceased children info
+#define procs ((pinfo *) cprocs)
Static waitq waitq_head = {0, 0, 0, 0, 0, 0, 0};// Start of queue for wait'ing threads
muto NO_COPY *sync_proc_subproc = NULL; // Control access to subproc stuff
@@ -97,9 +80,8 @@ DWORD NO_COPY sigtid = 0; // ID of the signal thread
/* Function declarations */
static int __stdcall checkstate (waitq *) __attribute__ ((regparm (1)));
static __inline__ bool get_proc_lock (DWORD, DWORD);
-static void __stdcall remove_zombie (int);
-static int __stdcall stopped_or_terminated (waitq *, _pinfo *);
-static DWORD WINAPI wait_subproc (VOID *);
+static void __stdcall remove_proc (int);
+static bool __stdcall stopped_or_terminated (waitq *, _pinfo *);
static DWORD WINAPI wait_sig (VOID *arg);
/* wait_sig bookkeeping */
@@ -152,33 +134,13 @@ bool __stdcall
my_parent_is_alive ()
{
bool res;
- if (!myself->ppid_handle)
+ if (myself->cygstarted)
+ res = pid_exists (myself->ppid);
+ else
{
- debug_printf ("No myself->ppid_handle");
+ debug_printf ("Not started by cygwin app");
res = false;
}
- else
- for (int i = 0; i < 2; i++)
- switch (res = WaitForSingleObject (myself->ppid_handle, 0))
- {
- case WAIT_OBJECT_0:
- debug_printf ("parent dead.");
- res = false;
- goto out;
- case WAIT_TIMEOUT:
- debug_printf ("parent still alive");
- res = true;
- goto out;
- case WAIT_FAILED:
- DWORD werr = GetLastError ();
- if (werr == ERROR_INVALID_HANDLE && i == 0)
- continue;
- system_printf ("WFSO for myself->ppid_handle(%p) failed, error %d",
- myself->ppid_handle, werr);
- res = false;
- goto out;
- }
-out:
return res;
}
@@ -193,7 +155,7 @@ wait_for_sigthread ()
}
/* Get the sync_proc_subproc muto to control access to
- * children, zombie arrays.
+ * children, proc arrays.
* Attempt to handle case where process is exiting as we try to grab
* the mutex.
*/
@@ -260,16 +222,11 @@ proc_exists (_pinfo *p)
/* Return 1 if this is one of our children, zero otherwise.
FIXME: This really should be integrated with the rest of the proc_subproc
testing. Scanning these lists twice is inefficient. */
-int __stdcall
+bool __stdcall
mychild (int pid)
{
- for (int i = 0; i < nchildren; i++)
- if (pchildren[i]->pid == pid)
- return 1;
- for (int i = 0; i < nzombies; i++)
- if (zombies[i]->pid == pid)
- return 1;
- return 0;
+ pinfo p (pid);
+ return p && p->ppid == myself->pid;
}
/* Handle all subprocess requests
@@ -283,7 +240,6 @@ proc_subproc (DWORD what, DWORD val)
_pinfo *child;
int clearing;
waitq *w;
- int thiszombie;
#define wval ((waitq *) val)
@@ -301,84 +257,32 @@ proc_subproc (DWORD what, DWORD val)
* (usually called from the main thread)
*/
case PROC_ADDCHILD:
- if (nchildren >= PSIZE - 1)
+ /* Filled up process table? */
+ if (nprocs >= NPROCS)
{
+ sigproc_printf ("proc table overflow: hit %d processes, pid %d\n",
+ nprocs, vchild->pid);
rc = 0;
+ set_errno (EMFILE); // FIXMENOW - what's the right errno?
break;
}
- pchildren[nchildren] = vchild;
- hchildren[nchildren] = vchild->hProcess;
- if (!DuplicateHandle (hMainProc, vchild->hProcess, hMainProc, &vchild->pid_handle,
- 0, 0, DUPLICATE_SAME_ACCESS))
- system_printf ("Couldn't duplicate child handle for pid %d, %E", vchild->pid);
- ProtectHandle1 (vchild->pid_handle, pid_handle);
-
- if (!DuplicateHandle (hMainProc, hMainProc, vchild->hProcess, &vchild->ppid_handle,
- SYNCHRONIZE | PROCESS_DUP_HANDLE, TRUE, 0))
- system_printf ("Couldn't duplicate my handle<%p> for pid %d, %E", hMainProc, vchild->pid);
+
vchild->ppid = myself->pid;
vchild->uid = myself->uid;
vchild->gid = myself->gid;
vchild->pgid = myself->pgid;
vchild->sid = myself->sid;
vchild->ctty = myself->ctty;
+ vchild->cygstarted = true;
vchild->process_state |= PID_INITIALIZING | (myself->process_state & PID_USETTY);
-
- sigproc_printf ("added pid %d to wait list, slot %d, winpid %p, handle %p",
- vchild->pid, nchildren, vchild->dwProcessId,
- vchild->hProcess);
- nchildren++;
-
- wake_wait_subproc ();
- break;
-
- /* A child process had terminated.
- Possibly this is just due to an exec(). Cygwin implements an exec()
- as a "handoff" from one windows process to another. If child->hProcess
- is different from what is recorded in hchildren, then this is an exec().
- Otherwise this is a normal child termination event.
- (called from wait_subproc thread) */
- case PROC_CHILDTERMINATED:
- if (hchildren[val] != pchildren[val]->hProcess)
- {
- sigproc_printf ("pid %d[%d], reparented old hProcess %p, new %p",
- pchildren[val]->pid, val, hchildren[val], pchildren[val]->hProcess);
- HANDLE h = hchildren[val];
- hchildren[val] = pchildren[val]->hProcess; /* Filled out by child */
- ForceCloseHandle1 (h, childhProc);
- ProtectHandle1 (pchildren[val]->hProcess, childhProc);
- rc = 0;
- goto out; // This was an exec()
- }
-
- sigproc_printf ("pid %d[%d] terminated, handle %p, nchildren %d, nzombies %d",
- pchildren[val]->pid, val, hchildren[val], nchildren, nzombies);
-
- thiszombie = nzombies;
- zombies[nzombies] = pchildren[val]; // Add to zombie array
- zombies[nzombies++]->process_state = PID_ZOMBIE;// Walking dead
-
- sigproc_printf ("zombifying [%d], pid %d, handle %p, nchildren %d",
- val, pchildren[val]->pid, hchildren[val], nchildren);
- if ((int) val < --nchildren)
+ procs[nprocs] = vchild;
+ rc = procs[nprocs].wait ();
+ if (rc)
{
- hchildren[val] = hchildren[nchildren];
- pchildren[val] = pchildren[nchildren];
+ sigproc_printf ("added pid %d to proc table, slot %d", vchild->pid,
+ nprocs);
+ nprocs++;
}
-
- /* See if we should care about the this terminated process. If we've
- filled up our table or if we're ignoring SIGCHLD, then we immediately
- remove the process and move on. Otherwise, this process becomes a zombie
- which must be reaped by a wait() call. FIXME: This is a very inelegant
- way to deal with this and could lead to process hangs. */
- if (nzombies >= NZOMBIES)
- {
- sigproc_printf ("zombie table overflow %d", thiszombie);
- remove_zombie (thiszombie);
- }
-
- /* Don't scan the wait queue yet. Caller will send SIGCHLD to this process.
- This will cause an eventual scan of waiters. */
break;
/* Handle a wait4() operation. Allocates an event for the calling
@@ -458,9 +362,10 @@ proc_subproc (DWORD what, DWORD val)
sigproc_printf ("finished clearing");
}
+ // FIXMENOW: What is supposed to happen here?
if (global_sigs[SIGCHLD].sa_handler == (void *) SIG_IGN)
- while (nzombies)
- remove_zombie (0);
+ while (nprocs)
+ remove_proc (0);
break;
}
@@ -492,54 +397,29 @@ _cygtls::remove_wq (DWORD wait)
* Called on process exit.
* Also called by spawn_guts to disassociate any subprocesses from this
* process. Subprocesses will then know to clean up after themselves and
- * will not become zombies.
+ * will not become procs.
*/
void __stdcall
proc_terminate (void)
{
- sigproc_printf ("nchildren %d, nzombies %d", nchildren, nzombies);
+ sigproc_printf ("nprocs %d", nprocs);
/* Signal processing is assumed to be blocked in this routine. */
- if (hwait_subproc)
+ if (nprocs)
{
- proc_loop_wait = 0; // Tell wait_subproc thread to exit
sync_proc_subproc->acquire (WPSP);
- wake_wait_subproc (); // Wake wait_subproc loop
- hwait_subproc = NULL;
(void) proc_subproc (PROC_CLEARWAIT, 1);
- /* Clean out zombie processes from the pid list. */
+ /* Clean out proc processes from the pid list. */
int i;
- for (i = 0; i < nzombies; i++)
+ for (i = 0; i < nprocs; i++)
{
- if (zombies[i]->hProcess)
- {
- ForceCloseHandle1 (zombies[i]->hProcess, childhProc);
- ForceCloseHandle1 (zombies[i]->pid_handle, pid_handle);
- }
- zombies[i]->ppid = 1;
- zombies[i]->process_state = PID_EXITED; /* CGF FIXME - still needed? */
- zombies[i].release (); // FIXME: this breaks older gccs for some reason
+ procs[i]->ppid = 1;
+ if (!proc_exists (procs[i]))
+ procs[i]->process_state = PID_EXITED; /* CGF FIXME - still needed? */
+ procs[i].release ();
}
-
- /* Disassociate my subprocesses */
- for (i = 0; i < nchildren; i++)
- {
- if (!pchildren[i]->hProcess)
- sigproc_printf ("%d(%d) hProcess cleared already?", pchildren[i]->pid,
- pchildren[i]->dwProcessId);
- else
- {
- ForceCloseHandle1 (pchildren[i]->hProcess, childhProc);
- sigproc_printf ("%d(%d) closed child handle", pchildren[i]->pid,
- pchildren[i]->dwProcessId);
- pchildren[i]->ppid = 1;
- if (pchildren[i]->pgid == myself->pid)
- pchildren[i]->process_state |= PID_ORPHANED;
- }
- pchildren[i].release ();
- }
- nchildren = nzombies = 0;
+ nprocs = 0;
sync_proc_subproc->release ();
}
sigproc_printf ("leaving");
@@ -610,7 +490,7 @@ sigproc_init ()
ProtectHandle (wait_sig_inited);
/* sync_proc_subproc is used by proc_subproc. It serialises
- * access to the children and zombie arrays.
+ * access to the children and proc arrays.
*/
new_muto (sync_proc_subproc);
@@ -833,25 +713,6 @@ out:
return rc;
}
-/* Initialize the wait_subproc thread.
- * Called from fork() or spawn() to initialize the handling of subprocesses.
- */
-void __stdcall
-subproc_init (void)
-{
- if (hwait_subproc)
- return;
-
- /* A "wakeup" handle which can be toggled to make wait_subproc reexamine
- * the hchildren array.
- */
- events[0] = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
- hwait_subproc = new cygthread (wait_subproc, NULL, "proc");
- hwait_subproc->zap_h ();
- ProtectHandle (events[0]);
- sigproc_printf ("started wait_subproc thread");
-}
-
/* Initialize some of the memory block passed to child processes
by fork/spawn/exec. */
@@ -864,7 +725,6 @@ init_child_info (DWORD chtype, child_info *ch, HANDLE subproc_ready)
ch->magic = CHILD_INFO_MAGIC;
ch->type = chtype;
ch->subproc_ready = subproc_ready;
- ch->pppid_handle = myself->ppid_handle;
ch->fhandler_union_cb = sizeof (fhandler_union);
ch->user_h = cygwin_user_h;
}
@@ -877,132 +737,98 @@ checkstate (waitq *parent_w)
{
int potential_match = 0;
- sigproc_printf ("nchildren %d, nzombies %d", nchildren, nzombies);
+ sigproc_printf ("nprocs %d", nprocs);
/* Check already dead processes first to see if they match the criteria
- * given in w->next.
- */
- for (int i = 0; i < nzombies; i++)
- switch (stopped_or_terminated (parent_w, zombies[i]))
+ * given in w->next. */
+ int res;
+ for (int i = 0; i < nprocs; i++)
+ if ((res = stopped_or_terminated (parent_w, procs[i])))
{
- case -1:
- potential_match = -1;
- break;
- case 1:
- remove_zombie (i);
+ remove_proc (i);
potential_match = 1;
goto out;
}
- sigproc_printf ("checking alive children");
-
- /* No dead terminated children matched. Check for stopped children. */
- for (int i = 0; i < nchildren; i++)
- switch (stopped_or_terminated (parent_w, pchildren[i]))
- {
- case -1:
- potential_match = -1;
- break;
- case 1:
- potential_match = 1;
- goto out;
- }
+ potential_match = -!!nprocs;
out:
sigproc_printf ("returning %d", potential_match);
return potential_match;
}
-/* Remove a zombie from zombies by swapping it with the last child in the list.
- */
+/* Remove a proc from procs by swapping it with the last child in the list.
+ Also releases shared memory of exited processes. */
static void __stdcall
-remove_zombie (int ci)
+remove_proc (int ci)
{
- sigproc_printf ("removing %d, pid %d, nzombies %d", ci, zombies[ci]->pid,
- nzombies);
-
- if (zombies[ci])
- {
- ForceCloseHandle1 (zombies[ci]->hProcess, childhProc);
- ForceCloseHandle1 (zombies[ci]->pid_handle, pid_handle);
- zombies[ci].release ();
+ if (!proc_exists (procs[ci]))
+ {
+ sigproc_printf ("removing procs[%d], pid %d, nprocs %d", ci, procs[ci]->pid,
+ nprocs);
+ procs[ci].release ();
+ if (ci < --nprocs)
+ procs[ci] = procs[nprocs];
}
-
- if (ci < --nzombies)
- zombies[ci] = zombies[nzombies];
-
- return;
}
/* Check status of child process vs. waitq member.
- *
- * parent_w is the pointer to the parent of the waitq member in question.
- * child is the subprocess being considered.
- *
- * Returns
- * 1 if stopped or terminated child matches parent_w->next criteria
- * -1 if a non-stopped/terminated child matches parent_w->next criteria
- * 0 if child does not match parent_w->next criteria
- */
-static int __stdcall
+
+ parent_w is the pointer to the parent of the waitq member in question.
+ child is the subprocess being considered.
+
+ Returns non-zero if waiting thread released. */
+static bool __stdcall
stopped_or_terminated (waitq *parent_w, _pinfo *child)
{
- int potential_match;
+ int might_match;
waitq *w = parent_w->next;
sigproc_printf ("considering pid %d", child->pid);
if (w->pid == -1)
- potential_match = 1;
+ might_match = 1;
else if (w->pid == 0)
- potential_match = child->pgid == myself->pgid;
+ might_match = child->pgid == myself->pgid;
else if (w->pid < 0)
- potential_match = child->pgid == -w->pid;
+ might_match = child->pgid == -w->pid;
else
- potential_match = (w->pid == child->pid);
+ might_match = (w->pid == child->pid);
- if (!potential_match)
+ if (!might_match)
return 0;
- bool terminated;
+ int terminated;
- if ((terminated = child->process_state == PID_ZOMBIE) ||
- ((w->options & WUNTRACED) && child->stopsig))
- {
- parent_w->next = w->next; /* successful wait. remove from wait queue */
- w->pid = child->pid;
+ if (!((terminated = child->process_state == PID_ZOMBIE) ||
+ ((w->options & WUNTRACED) && child->stopsig)))
+ return 0;
- if (!terminated)
- {
- sigproc_printf ("stopped child");
- w->status = (child->stopsig << 8) | 0x7f;
- child->stopsig = 0;
- }
- else /* Should only get here when child has been moved to the zombies array */
- {
- DWORD status;
- if (!GetExitCodeProcess (child->hProcess, &status))
- status = 0xffff;
- if (status & EXIT_SIGNAL)
- w->status = (status >> 8) & 0xff; /* exited due to signal */
- else
- w->status = (status & 0xff) << 8; /* exited via "exit ()" */
+ parent_w->next = w->next; /* successful wait. remove from wait queue */
+ w->pid = child->pid;
- add_rusage (&myself->rusage_children, &child->rusage_children);
- add_rusage (&myself->rusage_children, &child->rusage_self);
+ if (!terminated)
+ {
+ sigproc_printf ("stopped child");
+ w->status = (child->stopsig << 8) | 0x7f;
+ child->stopsig = 0;
+ }
+ else /* Should only get here when child has been moved to the procs array */
+ {
+ w->status = child->exitcode;
- if (w->rusage)
- {
- add_rusage ((struct rusage *) w->rusage, &child->rusage_children);
- add_rusage ((struct rusage *) w->rusage, &child->rusage_self);
- }
- }
+ add_rusage (&myself->rusage_children, &child->rusage_children);
+ add_rusage (&myself->rusage_children, &child->rusage_self);
- if (!SetEvent (w->ev)) /* wake up wait4 () immediately */
- system_printf ("couldn't wake up wait event %p, %E", w->ev);
- return 1;
+ if (w->rusage)
+ {
+ add_rusage ((struct rusage *) w->rusage, &child->rusage_children);
+ add_rusage ((struct rusage *) w->rusage, &child->rusage_self);
+ }
}
- return -potential_match;
+ if (!SetEvent (w->ev)) /* wake up wait4 () immediately */
+ system_printf ("couldn't wake up wait event %p, %E", w->ev);
+ return true;
}
static void
@@ -1083,6 +909,7 @@ wait_sig (VOID *self)
myself->process_state &= ~PID_INITIALIZING;
sigproc_printf ("myself->dwProcessId %u", myself->dwProcessId);
+#if 0
/* If we've been execed, then there is still a stub left in the previous
windows process waiting to see if it's started a cygwin process or not.
Signalling subproc_ready indicates that we are a cygwin process. */
@@ -1098,6 +925,7 @@ wait_sig (VOID *self)
static pinfo NO_COPY myself_identity;
myself_identity.init (cygwin_pid (myself->dwProcessId), PID_EXECED);
}
+#endif
SetEvent (wait_sig_inited);
sigtid = GetCurrentThreadId ();
@@ -1215,85 +1043,3 @@ wait_sig (VOID *self)
sigproc_printf ("done");
ExitThread (0);
}
-
-/* Wait for subprocesses to terminate. Executes in a separate thread. */
-static DWORD WINAPI
-wait_subproc (VOID *)
-{
- sigproc_printf ("starting");
- int errloop = 0;
-
- for (;;)
- {
- DWORD rc = WaitForMultipleObjects (nchildren + 1, events, FALSE,
- proc_loop_wait);
- if (!proc_loop_wait)
- break;
- if (rc == WAIT_TIMEOUT)
- continue;
-
- if (rc == WAIT_FAILED)
- {
- /* It's ok to get an ERROR_INVALID_HANDLE since another thread may have
- closed a handle in the children[] array. So, we try looping a couple
- of times to stabilize. FIXME - this is not foolproof. Probably, this
- thread should be responsible for closing the children. */
- if (!errloop++)
- proc_subproc (PROC_NOTHING, 0); // Just synchronize and continue
- if (errloop < 10)
- continue;
-
- system_printf ("wait failed. nchildren %d, wait %d, %E",
- nchildren, proc_loop_wait);
-
- for (int i = 0; i <= nchildren; i++)
- if ((rc = WaitForSingleObject (events[i], 0)) == WAIT_OBJECT_0 ||
- rc == WAIT_TIMEOUT)
- continue;
- else if (i == 0)
- system_printf ("nchildren %d, event[%d] %p, %E", nchildren, i, events[i]);
- else
- {
- system_printf ("nchildren %d, event[%d] %p, pchildren[%d] %p, events[0] %p, %E",
- nchildren, i, events[i], i - 1, (_pinfo *) pchildren[i - 1], events[0]);
- system_printf ("pid %d, dwProcessId %u, hProcess %p, progname '%s'",
- pchildren[i - 1]->pid, pchildren[i - 1]->dwProcessId,
- pchildren[i - 1]->hProcess, pchildren[i - 1]->progname);
- }
- break;
- }
-
- errloop = 0;
- rc -= WAIT_OBJECT_0;
- if (rc-- != 0)
- {
- siginfo_t si;
- si.si_signo = SIGCHLD;
- si.si_code = SI_KERNEL;
- si.si_pid = pchildren[rc]->pid;
- si.si_uid = pchildren[rc]->uid;
- si.si_errno = 0;
- GetExitCodeProcess (hchildren[rc], (DWORD *) &si.si_status);
-#if 0 // FIXME: This is tricky to get right
- si.si_utime = pchildren[rc]->rusage_self.ru_utime;
- si.si_stime = pchildren[rc].rusage_self.ru_stime;
-#else
- si.si_utime = 0;
- si.si_stime = 0;
-#endif
- rc = proc_subproc (PROC_CHILDTERMINATED, rc);
-
- /* Send a SIGCHLD to myself. We do this here, rather than in proc_subproc
- to avoid the proc_subproc lock since the signal thread will eventually
- be calling proc_subproc and could unnecessarily block. */
- if (rc)
- sig_send (myself_nowait, si);
- }
- sigproc_printf ("looping");
- }
-
- ForceCloseHandle (events[0]);
- events[0] = NULL;
- sigproc_printf ("done");
- ExitThread (0);
-}
diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h
index 776d1d9..8f648b1 100644
--- a/winsup/cygwin/sigproc.h
+++ b/winsup/cygwin/sigproc.h
@@ -12,10 +12,6 @@ details. */
#define _SIGPROC_H
#include <signal.h>
-#define EXIT_SIGNAL 0x010000
-#define EXIT_REPARENTING 0x020000
-#define EXIT_NOCLOSEALL 0x040000
-
#ifdef NSIG
enum
{
@@ -38,7 +34,9 @@ enum procstuff
PROC_CHILDTERMINATED = 2, // a child died
PROC_CLEARWAIT = 3, // clear all waits - signal arrived
PROC_WAIT = 4, // setup for wait() for subproc
- PROC_NOTHING = 5 // nothing, really
+ PROC_CHILDSTOPPED = 5, // register process as "stopped"
+ PROC_CHILDCONTINUED = 6, // remove process from "stopped" list
+ PROC_NOTHING = 7 // nothing, really
};
struct sigpacket
@@ -77,7 +75,6 @@ int __stdcall proc_subproc (DWORD, DWORD) __attribute__ ((regparm (2)));
class _pinfo;
void __stdcall proc_terminate ();
void __stdcall sigproc_init ();
-void __stdcall subproc_init ();
void __stdcall sigproc_terminate ();
bool __stdcall proc_exists (_pinfo *) __attribute__ ((regparm(1)));
bool __stdcall pid_exists (pid_t) __attribute__ ((regparm(1)));
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index db4210b..43bd148 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -385,7 +385,7 @@ spawn_guts (const char * prog_arg, const char *const *argv,
chtype = PROC_EXEC;
HANDLE subproc_ready;
- if (chtype != PROC_EXEC)
+ if (1 || chtype != PROC_EXEC)
subproc_ready = NULL;
else
{
@@ -808,7 +808,7 @@ spawn_guts (const char * prog_arg, const char *const *argv,
goto out;
}
child->dwProcessId = pi.dwProcessId;
- child->hProcess = pi.hProcess;
+ child.hProcess = pi.hProcess;
if (!child.remember ())
{
syscall_printf ("process table full");
@@ -837,7 +837,7 @@ spawn_guts (const char * prog_arg, const char *const *argv,
res = 0;
exited = false;
- MALLOC_CHECK;
+#if 0
if (mode == _P_OVERLAY)
{
int nwait = 3;
@@ -859,9 +859,7 @@ spawn_guts (const char * prog_arg, const char *const *argv,
reset_signal_arrived ();
continue;
case WAIT_OBJECT_0 + 2:
- if (my_parent_is_alive ())
- res |= EXIT_REPARENTING;
- else if (!myself->ppid_handle)
+ if (!myself->cygstarted)
{
nwait = 2;
sigproc_terminate ();
@@ -885,41 +883,15 @@ spawn_guts (const char * prog_arg, const char *const *argv,
}
ForceCloseHandle (subproc_ready);
-
- sigproc_printf ("res %p", res);
-
- if (res & EXIT_REPARENTING)
- {
- /* Try to reparent child process.
- * Make handles to child available to parent process and exit with
- * EXIT_REPARENTING status. Wait() syscall in parent will then wait
- * for newly created child.
- */
- HANDLE oldh = myself->hProcess;
- HANDLE h = myself->ppid_handle;
- sigproc_printf ("parent handle %p", h);
- int rc = DuplicateHandle (hMainProc, pi.hProcess, h, &myself->hProcess,
- 0, FALSE, DUPLICATE_SAME_ACCESS);
- sigproc_printf ("%d = DuplicateHandle, oldh %p, newh %p",
- rc, oldh, myself->hProcess);
- VerifyHandle (myself->hProcess);
- if (!rc && my_parent_is_alive ())
- {
- system_printf ("Reparent failed, parent handle %p, %E", h);
- system_printf ("my dwProcessId %d, myself->dwProcessId %d",
- GetCurrentProcessId (), myself->dwProcessId);
- system_printf ("old hProcess %p, hProcess %p", oldh, myself->hProcess);
- }
- }
-
+ sigproc_printf ("P_OVERLAY res %p", res);
}
+#endif
- MALLOC_CHECK;
+ ForceCloseHandle1 (pi.hProcess, childhProc);
switch (mode)
{
case _P_OVERLAY:
- ForceCloseHandle1 (pi.hProcess, childhProc);
myself->exit (res, 1);
break;
case _P_WAIT:
@@ -986,7 +958,6 @@ spawnve (int mode, const char *path, const char *const *argv,
case _P_WAIT:
case _P_DETACH:
case _P_SYSTEM:
- subproc_init ();
ret = spawn_guts (path, argv, envp, mode);
#ifdef NEWVFORK
if (vf)
diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc
index edad95c..ef77bd5 100644
--- a/winsup/cygwin/tty.cc
+++ b/winsup/cygwin/tty.cc
@@ -57,7 +57,7 @@ ttyslot (void)
void __stdcall
tty_init (void)
{
- if (!myself->ppid_handle && NOTSTATE (myself, PID_CYGPARENT))
+ if (!myself->cygstarted && NOTSTATE (myself, PID_CYGPARENT))
cygheap->fdtab.get_debugger_info ();
if (NOTSTATE (myself, PID_USETTY))