Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2004-12-03 07:46:00 +0300
committerChristopher Faylor <me@cgf.cx>2004-12-03 07:46:00 +0300
commit82b7b4fd4fba28d054161f104f6bd8471f73ab14 (patch)
tree3231163df0ea1b16d3d89d778f48e51d98e3e76d
parent3ef7d75861f84dae6422dd34205a62a7af1c7676 (diff)
* 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.
-rw-r--r--winsup/cygwin/ChangeLog20
-rw-r--r--winsup/cygwin/child_info.h3
-rw-r--r--winsup/cygwin/fork.cc2
-rw-r--r--winsup/cygwin/pinfo.cc33
-rw-r--r--winsup/cygwin/pinfo.h9
-rw-r--r--winsup/cygwin/sigproc.cc17
-rw-r--r--winsup/cygwin/sigproc.h4
-rw-r--r--winsup/cygwin/spawn.cc29
8 files changed, 69 insertions, 48 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index b8b620e57..82e41ce5f 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,25 @@
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>
+
* pinfo.cc (pinfo::wait): Use better name for cygthread.
2004-12-03 Pierre Humblet <pierre.humblet@ieee.org>
diff --git a/winsup/cygwin/child_info.h b/winsup/cygwin/child_info.h
index 7cbcb6fa5..48186e67c 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 0x83e9a7b7U
+#define CURR_CHILD_INFO_MAGIC 0x694cd4b8U
/* NOTE: Do not make gratuitous changes to the names or organization of the
below class. The layout is checksummed to determine compatibility between
@@ -49,6 +49,7 @@ public:
void *cygheap_max;
DWORD cygheap_reserve_sz;
HANDLE cygheap_h;
+ HANDLE parent_wr_proc_pipe;
unsigned fhandler_union_cb;
};
diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc
index 1dc1e7b8e..4744202af 100644
--- a/winsup/cygwin/fork.cc
+++ b/winsup/cygwin/fork.cc
@@ -401,6 +401,8 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
init_child_info (PROC_FORK, &ch, subproc_ready);
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);
diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc
index a5eb4807f..62dd63d5d 100644
--- a/winsup/cygwin/pinfo.cc
+++ b/winsup/cygwin/pinfo.cc
@@ -32,6 +32,7 @@ details. */
#include "fhandler.h"
#include "cygmalloc.h"
#include "cygtls.h"
+#include "child_info.h"
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
set_myself (HANDLE h)
{
+ extern child_info *child_proc_info;
+
if (!h)
cygheap->pid = cygwin_pid (GetCurrentProcessId ());
myself.init (cygheap->pid, PID_IN_USE | PID_MYSELF, h);
@@ -61,22 +64,19 @@ set_myself (HANDLE h)
static pinfo NO_COPY myself_identity;
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,
- so close it. This could cause problems for the spawn case since there
- is no guarantee that a parent will still be around by the time we get
- here. If so, we would have a handle leak. FIXME? */
- if (parent && parent->wr_proc_pipe)
- CloseHandle (parent->wr_proc_pipe);
+ so close it. */
+ if (child_proc_info->parent_wr_proc_pipe)
+ CloseHandle (child_proc_info->parent_wr_proc_pipe);
if (cygheap->pid_handle)
{
ForceCloseHandle (cygheap->pid_handle);
cygheap->pid_handle = NULL;
}
}
+# undef child_proc_info
return;
}
@@ -704,6 +704,8 @@ proc_waiter (void *arg)
switch (buf)
{
+ case __ALERT_ALIVE:
+ continue;
case 0:
/* Child exited. Do some cleanup and signal myself. */
CloseHandle (vchild.rd_proc_pipe);
@@ -733,7 +735,7 @@ proc_waiter (void *arg)
break;
case SIGCONT:
continue;
- case __SIGREPARENT: /* sigh */
+ case __ALERT_REPARENT: /* sigh */
/* spawn_guts has signalled us that it has just started a new
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
in the child. */
-void
+bool
pinfo::alert_parent (char sig)
{
- DWORD nb;
+ DWORD nb = 0;
/* Send something to our parent. If the parent has gone away,
close the pipe. */
- if (myself->wr_proc_pipe
- && WriteFile (myself->wr_proc_pipe, &sig, 1, &nb, NULL))
+ if (myself->wr_proc_pipe == INVALID_HANDLE_VALUE)
+ /* no parent */;
+ else if (myself->wr_proc_pipe
+ && WriteFile (myself->wr_proc_pipe, &sig, 1, &nb, NULL))
/* all is well */;
else if (GetLastError () != ERROR_BROKEN_PIPE)
debug_printf ("sending %d notification to parent failed, %E", sig);
else
{
HANDLE closeit = myself->wr_proc_pipe;
- myself->wr_proc_pipe = NULL;
+ myself->wr_proc_pipe = INVALID_HANDLE_VALUE;
CloseHandle (closeit);
}
+ return (bool) nb;
}
void
diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h
index b062934da..e1d5d35f6 100644
--- a/winsup/cygwin/pinfo.h
+++ b/winsup/cygwin/pinfo.h
@@ -118,6 +118,12 @@ public:
friend class pinfo;
};
+enum parent_alerter
+{
+ __ALERT_REPARENT = 111, // arbitrary non-signal value
+ __ALERT_ALIVE = 112
+};
+
class pinfo
{
HANDLE h;
@@ -153,7 +159,8 @@ public:
operator _pinfo * () const {return procinfo;}
// operator bool () const {return (int) h;}
void preserve () { destroy = false; }
- void alert_parent (char);
+ bool alert_parent (char);
+ bool parent_alive () { return alert_parent (__ALERT_ALIVE); }
#ifndef _SIGPROC_H
int remember () {system_printf ("remember is not here"); return 0;}
#else
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index 844e80a2b..b1fea5219 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -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
wait_for_sigthread ()
{
diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h
index 9c7807a49..9a432d31f 100644
--- a/winsup/cygwin/sigproc.h
+++ b/winsup/cygwin/sigproc.h
@@ -22,8 +22,7 @@ enum
__SIGDELETE = -(NSIG + 5),
__SIGFLUSHFAST = -(NSIG + 6),
__SIGHOLD = -(NSIG + 7),
- __SIGNOHOLD = -(NSIG + 8),
- __SIGREPARENT = (NSIG + 2)
+ __SIGNOHOLD = -(NSIG + 8)
};
#endif
@@ -55,7 +54,6 @@ struct sigpacket
extern HANDLE signal_arrived;
extern HANDLE sigCONT;
-bool __stdcall my_parent_is_alive ();
void __stdcall sig_dispatch_pending (bool fast = false);
#ifdef _PINFO_H
extern "C" void __stdcall set_signal_mask (sigset_t newmask, sigset_t = myself->getsigmask ());
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index 426ee119f..4eb231efd 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -636,6 +636,7 @@ spawn_guts (const char * prog_arg, const char *const *argv,
ProtectHandle (cygheap->pid_handle);
else
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
@@ -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
the parent doesn't have to bother but what are you gonna do? Cygwin lives in
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;
@@ -784,21 +786,24 @@ spawn_guts (const char * prog_arg, const char *const *argv,
DWORD exec_cygstarted;
if (mode == _P_OVERLAY)
{
- /* Store the old exec_cygstarted since this is used as a crude semaphore for
- detecting when the parent has noticed the change in windows pid for this
- cygwin pid. */
- exec_cygstarted = myself->cygstarted;
- myself->dwProcessId = dwExeced = pi.dwProcessId; /* Reparenting needs this */
- myself.alert_parent (__SIGREPARENT);
+ if (!real_path.iscygexec ())
+ {
+ /* Store the old exec_cygstarted since this is used as a crude semaphore for
+ detecting when the parent has noticed the change in windows pid for this
+ cygwin pid. */
+ exec_cygstarted = myself->cygstarted;
+ myself->dwProcessId = dwExeced = pi.dwProcessId; /* Reparenting needs this */
+ myself.alert_parent (__ALERT_REPARENT);
+ }
CloseHandle (saved_sendsig);
strace.execing = 1;
hExeced = pi.hProcess;
- strcpy (myself->progname, real_path);
+ strcpy (myself->progname, real_path); // FIXME: race?
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"
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). */
if (!myself->wr_proc_pipe)
{
@@ -854,9 +859,9 @@ spawn_guts (const char * prog_arg, const char *const *argv,
else
{
/* 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)
- while (myself->cygstarted == exec_cygstarted)
+ while (myself->cygstarted == exec_cygstarted && myself.parent_alive ())
low_priority_sleep (0);
res = 42;
}