* child_info.h (child_info_fork::parent_wr_proc_pipe): New element.
* fork.cc (fork_parent): Set parent_wr_proc. * pinfo.cc (set_myself): Close child_proc_info->parent_wr_proc if it exists rather than trying to get value from parent _pinfo. * pinfo.h (enum parent_aleter): New enum. (pinfo::alert_parent): Declare as returning a value. (pinfo::parent_alive): New function. * pinfo.cc (pinfo::alert_parent): Set wr_proc_pipe to invalid non-NULL value when parent disappears. Return success of operation. (proc_waiter): Use __ALERT_* enum for control since these are not really signals. Implement __ALERT_ALIVE. * sigproc.cc (my_parent_is_alive): Eliminate. * sigproc.h (my_parent_is_alive): Ditto for declaration. (__SIGREPARENT): Eliminate.
This commit is contained in:
parent
3ef7d75861
commit
82b7b4fd4f
|
@ -1,3 +1,23 @@
|
||||||
|
2004-12-02 Christopher Faylor <cgf@timesys.com>
|
||||||
|
|
||||||
|
* child_info.h (child_info_fork::parent_wr_proc_pipe): New element.
|
||||||
|
* fork.cc (fork_parent): Set parent_wr_proc.
|
||||||
|
* pinfo.cc (set_myself): Close child_proc_info->parent_wr_proc if it
|
||||||
|
exists rather than trying to get value from parent _pinfo.
|
||||||
|
|
||||||
|
2004-12-02 Christopher Faylor <cgf@timesys.com>
|
||||||
|
|
||||||
|
* pinfo.h (enum parent_aleter): New enum.
|
||||||
|
(pinfo::alert_parent): Declare as returning a value.
|
||||||
|
(pinfo::parent_alive): New function.
|
||||||
|
* pinfo.cc (pinfo::alert_parent): Set wr_proc_pipe to invalid non-NULL
|
||||||
|
value when parent disappears. Return success of operation.
|
||||||
|
(proc_waiter): Use __ALERT_* enum for control since these are not really signals.
|
||||||
|
Implement __ALERT_ALIVE.
|
||||||
|
* sigproc.cc (my_parent_is_alive): Eliminate.
|
||||||
|
* sigproc.h (my_parent_is_alive): Ditto for declaration.
|
||||||
|
(__SIGREPARENT): Eliminate.
|
||||||
|
|
||||||
2004-12-02 Christopher Faylor <cgf@timesys.com>
|
2004-12-02 Christopher Faylor <cgf@timesys.com>
|
||||||
|
|
||||||
* pinfo.cc (pinfo::wait): Use better name for cygthread.
|
* pinfo.cc (pinfo::wait): Use better name for cygthread.
|
||||||
|
|
|
@ -29,7 +29,7 @@ enum
|
||||||
|
|
||||||
#define EXEC_MAGIC_SIZE sizeof(child_info)
|
#define EXEC_MAGIC_SIZE sizeof(child_info)
|
||||||
|
|
||||||
#define CURR_CHILD_INFO_MAGIC 0x83e9a7b7U
|
#define CURR_CHILD_INFO_MAGIC 0x694cd4b8U
|
||||||
|
|
||||||
/* NOTE: Do not make gratuitous changes to the names or organization of the
|
/* NOTE: Do not make gratuitous changes to the names or organization of the
|
||||||
below class. The layout is checksummed to determine compatibility between
|
below class. The layout is checksummed to determine compatibility between
|
||||||
|
@ -49,6 +49,7 @@ public:
|
||||||
void *cygheap_max;
|
void *cygheap_max;
|
||||||
DWORD cygheap_reserve_sz;
|
DWORD cygheap_reserve_sz;
|
||||||
HANDLE cygheap_h;
|
HANDLE cygheap_h;
|
||||||
|
HANDLE parent_wr_proc_pipe;
|
||||||
unsigned fhandler_union_cb;
|
unsigned fhandler_union_cb;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -401,6 +401,8 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
|
||||||
init_child_info (PROC_FORK, &ch, subproc_ready);
|
init_child_info (PROC_FORK, &ch, subproc_ready);
|
||||||
|
|
||||||
ch.forker_finished = forker_finished;
|
ch.forker_finished = forker_finished;
|
||||||
|
ch.parent_wr_proc_pipe = myself->wr_proc_pipe == INVALID_HANDLE_VALUE
|
||||||
|
? NULL : myself->wr_proc_pipe;
|
||||||
|
|
||||||
stack_base (ch);
|
stack_base (ch);
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ details. */
|
||||||
#include "fhandler.h"
|
#include "fhandler.h"
|
||||||
#include "cygmalloc.h"
|
#include "cygmalloc.h"
|
||||||
#include "cygtls.h"
|
#include "cygtls.h"
|
||||||
|
#include "child_info.h"
|
||||||
|
|
||||||
static char NO_COPY pinfo_dummy[sizeof (_pinfo)] = {0};
|
static char NO_COPY pinfo_dummy[sizeof (_pinfo)] = {0};
|
||||||
|
|
||||||
|
@ -43,6 +44,8 @@ pinfo NO_COPY myself ((_pinfo *)&pinfo_dummy); // Avoid myself != NULL checks
|
||||||
void __stdcall
|
void __stdcall
|
||||||
set_myself (HANDLE h)
|
set_myself (HANDLE h)
|
||||||
{
|
{
|
||||||
|
extern child_info *child_proc_info;
|
||||||
|
|
||||||
if (!h)
|
if (!h)
|
||||||
cygheap->pid = cygwin_pid (GetCurrentProcessId ());
|
cygheap->pid = cygwin_pid (GetCurrentProcessId ());
|
||||||
myself.init (cygheap->pid, PID_IN_USE | PID_MYSELF, h);
|
myself.init (cygheap->pid, PID_IN_USE | PID_MYSELF, h);
|
||||||
|
@ -61,22 +64,19 @@ set_myself (HANDLE h)
|
||||||
static pinfo NO_COPY myself_identity;
|
static pinfo NO_COPY myself_identity;
|
||||||
myself_identity.init (cygwin_pid (myself->dwProcessId), PID_EXECED);
|
myself_identity.init (cygwin_pid (myself->dwProcessId), PID_EXECED);
|
||||||
}
|
}
|
||||||
else if (myself->ppid)
|
else if (myself->wr_proc_pipe)
|
||||||
{
|
{
|
||||||
/* here if forked/spawned */
|
|
||||||
pinfo parent (myself->ppid);
|
|
||||||
/* We've inherited the parent's wr_proc_pipe. We don't need it,
|
/* We've inherited the parent's wr_proc_pipe. We don't need it,
|
||||||
so close it. This could cause problems for the spawn case since there
|
so close it. */
|
||||||
is no guarantee that a parent will still be around by the time we get
|
if (child_proc_info->parent_wr_proc_pipe)
|
||||||
here. If so, we would have a handle leak. FIXME? */
|
CloseHandle (child_proc_info->parent_wr_proc_pipe);
|
||||||
if (parent && parent->wr_proc_pipe)
|
|
||||||
CloseHandle (parent->wr_proc_pipe);
|
|
||||||
if (cygheap->pid_handle)
|
if (cygheap->pid_handle)
|
||||||
{
|
{
|
||||||
ForceCloseHandle (cygheap->pid_handle);
|
ForceCloseHandle (cygheap->pid_handle);
|
||||||
cygheap->pid_handle = NULL;
|
cygheap->pid_handle = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
# undef child_proc_info
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -704,6 +704,8 @@ proc_waiter (void *arg)
|
||||||
|
|
||||||
switch (buf)
|
switch (buf)
|
||||||
{
|
{
|
||||||
|
case __ALERT_ALIVE:
|
||||||
|
continue;
|
||||||
case 0:
|
case 0:
|
||||||
/* Child exited. Do some cleanup and signal myself. */
|
/* Child exited. Do some cleanup and signal myself. */
|
||||||
CloseHandle (vchild.rd_proc_pipe);
|
CloseHandle (vchild.rd_proc_pipe);
|
||||||
|
@ -733,7 +735,7 @@ proc_waiter (void *arg)
|
||||||
break;
|
break;
|
||||||
case SIGCONT:
|
case SIGCONT:
|
||||||
continue;
|
continue;
|
||||||
case __SIGREPARENT: /* sigh */
|
case __ALERT_REPARENT: /* sigh */
|
||||||
/* spawn_guts has signalled us that it has just started a new
|
/* spawn_guts has signalled us that it has just started a new
|
||||||
subprocess which will take over this cygwin pid. */
|
subprocess which will take over this cygwin pid. */
|
||||||
|
|
||||||
|
@ -830,23 +832,26 @@ pinfo::wait ()
|
||||||
|
|
||||||
/* function to send a "signal" to the parent when something interesting happens
|
/* function to send a "signal" to the parent when something interesting happens
|
||||||
in the child. */
|
in the child. */
|
||||||
void
|
bool
|
||||||
pinfo::alert_parent (char sig)
|
pinfo::alert_parent (char sig)
|
||||||
{
|
{
|
||||||
DWORD nb;
|
DWORD nb = 0;
|
||||||
/* Send something to our parent. If the parent has gone away,
|
/* Send something to our parent. If the parent has gone away,
|
||||||
close the pipe. */
|
close the pipe. */
|
||||||
if (myself->wr_proc_pipe
|
if (myself->wr_proc_pipe == INVALID_HANDLE_VALUE)
|
||||||
&& WriteFile (myself->wr_proc_pipe, &sig, 1, &nb, NULL))
|
/* no parent */;
|
||||||
|
else if (myself->wr_proc_pipe
|
||||||
|
&& WriteFile (myself->wr_proc_pipe, &sig, 1, &nb, NULL))
|
||||||
/* all is well */;
|
/* all is well */;
|
||||||
else if (GetLastError () != ERROR_BROKEN_PIPE)
|
else if (GetLastError () != ERROR_BROKEN_PIPE)
|
||||||
debug_printf ("sending %d notification to parent failed, %E", sig);
|
debug_printf ("sending %d notification to parent failed, %E", sig);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HANDLE closeit = myself->wr_proc_pipe;
|
HANDLE closeit = myself->wr_proc_pipe;
|
||||||
myself->wr_proc_pipe = NULL;
|
myself->wr_proc_pipe = INVALID_HANDLE_VALUE;
|
||||||
CloseHandle (closeit);
|
CloseHandle (closeit);
|
||||||
}
|
}
|
||||||
|
return (bool) nb;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -118,6 +118,12 @@ public:
|
||||||
friend class pinfo;
|
friend class pinfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum parent_alerter
|
||||||
|
{
|
||||||
|
__ALERT_REPARENT = 111, // arbitrary non-signal value
|
||||||
|
__ALERT_ALIVE = 112
|
||||||
|
};
|
||||||
|
|
||||||
class pinfo
|
class pinfo
|
||||||
{
|
{
|
||||||
HANDLE h;
|
HANDLE h;
|
||||||
|
@ -153,7 +159,8 @@ public:
|
||||||
operator _pinfo * () const {return procinfo;}
|
operator _pinfo * () const {return procinfo;}
|
||||||
// operator bool () const {return (int) h;}
|
// operator bool () const {return (int) h;}
|
||||||
void preserve () { destroy = false; }
|
void preserve () { destroy = false; }
|
||||||
void alert_parent (char);
|
bool alert_parent (char);
|
||||||
|
bool parent_alive () { return alert_parent (__ALERT_ALIVE); }
|
||||||
#ifndef _SIGPROC_H
|
#ifndef _SIGPROC_H
|
||||||
int remember () {system_printf ("remember is not here"); return 0;}
|
int remember () {system_printf ("remember is not here"); return 0;}
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -125,23 +125,6 @@ signal_fixup_after_exec ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Determine if the parent process is alive.
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool __stdcall
|
|
||||||
my_parent_is_alive ()
|
|
||||||
{
|
|
||||||
bool res;
|
|
||||||
if (myself->cygstarted)
|
|
||||||
res = pid_exists (myself->ppid);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
debug_printf ("Not started by cygwin app");
|
|
||||||
res = false;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void __stdcall
|
void __stdcall
|
||||||
wait_for_sigthread ()
|
wait_for_sigthread ()
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,8 +22,7 @@ enum
|
||||||
__SIGDELETE = -(NSIG + 5),
|
__SIGDELETE = -(NSIG + 5),
|
||||||
__SIGFLUSHFAST = -(NSIG + 6),
|
__SIGFLUSHFAST = -(NSIG + 6),
|
||||||
__SIGHOLD = -(NSIG + 7),
|
__SIGHOLD = -(NSIG + 7),
|
||||||
__SIGNOHOLD = -(NSIG + 8),
|
__SIGNOHOLD = -(NSIG + 8)
|
||||||
__SIGREPARENT = (NSIG + 2)
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -55,7 +54,6 @@ struct sigpacket
|
||||||
extern HANDLE signal_arrived;
|
extern HANDLE signal_arrived;
|
||||||
extern HANDLE sigCONT;
|
extern HANDLE sigCONT;
|
||||||
|
|
||||||
bool __stdcall my_parent_is_alive ();
|
|
||||||
void __stdcall sig_dispatch_pending (bool fast = false);
|
void __stdcall sig_dispatch_pending (bool fast = false);
|
||||||
#ifdef _PINFO_H
|
#ifdef _PINFO_H
|
||||||
extern "C" void __stdcall set_signal_mask (sigset_t newmask, sigset_t = myself->getsigmask ());
|
extern "C" void __stdcall set_signal_mask (sigset_t newmask, sigset_t = myself->getsigmask ());
|
||||||
|
|
|
@ -636,6 +636,7 @@ spawn_guts (const char * prog_arg, const char *const *argv,
|
||||||
ProtectHandle (cygheap->pid_handle);
|
ProtectHandle (cygheap->pid_handle);
|
||||||
else
|
else
|
||||||
system_printf ("duplicate to pid_handle failed, %E");
|
system_printf ("duplicate to pid_handle failed, %E");
|
||||||
|
ciresrv.parent_wr_proc_pipe = myself->wr_proc_pipe;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Start the process in a suspended state. Needed so that any potential parent will
|
/* Start the process in a suspended state. Needed so that any potential parent will
|
||||||
|
@ -643,7 +644,8 @@ spawn_guts (const char * prog_arg, const char *const *argv,
|
||||||
to handle exec'ed windows processes since cygwin processes are smart enough that
|
to handle exec'ed windows processes since cygwin processes are smart enough that
|
||||||
the parent doesn't have to bother but what are you gonna do? Cygwin lives in
|
the parent doesn't have to bother but what are you gonna do? Cygwin lives in
|
||||||
a windows world. */
|
a windows world. */
|
||||||
flags |= CREATE_SUSPENDED;
|
if (mode != _P_OVERLAY || !real_path.iscygexec ())
|
||||||
|
flags |= CREATE_SUSPENDED;
|
||||||
|
|
||||||
const char *runpath = null_app_name ? NULL : (const char *) real_path;
|
const char *runpath = null_app_name ? NULL : (const char *) real_path;
|
||||||
|
|
||||||
|
@ -784,21 +786,24 @@ spawn_guts (const char * prog_arg, const char *const *argv,
|
||||||
DWORD exec_cygstarted;
|
DWORD exec_cygstarted;
|
||||||
if (mode == _P_OVERLAY)
|
if (mode == _P_OVERLAY)
|
||||||
{
|
{
|
||||||
/* Store the old exec_cygstarted since this is used as a crude semaphore for
|
if (!real_path.iscygexec ())
|
||||||
detecting when the parent has noticed the change in windows pid for this
|
{
|
||||||
cygwin pid. */
|
/* Store the old exec_cygstarted since this is used as a crude semaphore for
|
||||||
exec_cygstarted = myself->cygstarted;
|
detecting when the parent has noticed the change in windows pid for this
|
||||||
myself->dwProcessId = dwExeced = pi.dwProcessId; /* Reparenting needs this */
|
cygwin pid. */
|
||||||
myself.alert_parent (__SIGREPARENT);
|
exec_cygstarted = myself->cygstarted;
|
||||||
|
myself->dwProcessId = dwExeced = pi.dwProcessId; /* Reparenting needs this */
|
||||||
|
myself.alert_parent (__ALERT_REPARENT);
|
||||||
|
}
|
||||||
CloseHandle (saved_sendsig);
|
CloseHandle (saved_sendsig);
|
||||||
strace.execing = 1;
|
strace.execing = 1;
|
||||||
hExeced = pi.hProcess;
|
hExeced = pi.hProcess;
|
||||||
strcpy (myself->progname, real_path);
|
strcpy (myself->progname, real_path); // FIXME: race?
|
||||||
close_all_files ();
|
close_all_files ();
|
||||||
/* If wr_proc_pipe doesn't exist then this process was not started by a cygwin
|
/* If wr_proc_pipe is NULL then this process was not started by a cygwin
|
||||||
process. So, we need to wait around until the process we've just "execed"
|
process. So, we need to wait around until the process we've just "execed"
|
||||||
dies. Use our own wait facility to wait for our own pid to exit (there
|
dies. Use our own wait facility to wait for our own pid to exit (there
|
||||||
is some minor special case code in proc_waiter and friends to accommodeate
|
is some minor special case code in proc_waiter and friends to accommodate
|
||||||
this). */
|
this). */
|
||||||
if (!myself->wr_proc_pipe)
|
if (!myself->wr_proc_pipe)
|
||||||
{
|
{
|
||||||
|
@ -854,9 +859,9 @@ spawn_guts (const char * prog_arg, const char *const *argv,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Loop, waiting for parent to notice pid change, if exec_cygstarted.
|
/* Loop, waiting for parent to notice pid change, if exec_cygstarted.
|
||||||
In theory this wait should be a no-op. */
|
In theory this wait should usually be a no-op. */
|
||||||
if (exec_cygstarted)
|
if (exec_cygstarted)
|
||||||
while (myself->cygstarted == exec_cygstarted)
|
while (myself->cygstarted == exec_cygstarted && myself.parent_alive ())
|
||||||
low_priority_sleep (0);
|
low_priority_sleep (0);
|
||||||
res = 42;
|
res = 42;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue