summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/sigproc.cc
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2005-09-28 22:56:47 +0000
committerChristopher Faylor <me@cgf.cx>2005-09-28 22:56:47 +0000
commit0730fa07632fa954269ed21cbc2f6025dd35f5cf (patch)
tree3dc70659917cef414b51daaddd83d6093cdf3d2b /winsup/cygwin/sigproc.cc
parent503490bb9fd3b8853342128a7961d9f4b9e15d99 (diff)
downloadcygnal-0730fa07632fa954269ed21cbc2f6025dd35f5cf.tar.gz
cygnal-0730fa07632fa954269ed21cbc2f6025dd35f5cf.tar.bz2
cygnal-0730fa07632fa954269ed21cbc2f6025dd35f5cf.zip
Change name from commune_recv to commune_process throughout. Change name from
commune_send to commune_request throughout. * pinfo.h (PICOM_EXTRASTR): New flag. (PICOM_FIFO): Define with new flag. (_pinfo::hello_pid): Delete. (_pinfo::tothem): Delete. (_pinfo::fromthem): Delete. (_pinfo::commune_process): Rename from commune_recv. Add a siginfo_t argument to declaration. (_pinfo::commune_request): Rename from commune_send. Change DWORD to __uint32_t in declaration. * pinfo.cc (_pinfo::commune_process): Rename from commune_recv. Add siginfo_t argument. Use information from argument rather than reading from another pipe. Synchronize with other process's commune event. (_pinfo::commune_request): Rename from commune_send. Change DWORD to __uint32 in argument. Fill out information in new siginfo_t element and rely on extended operation of sig_send rather than trying to deal with synchronization issues here. Use process handle and read pipe information filled out by sig_send to gather information from the other process. * sigproc.cc (sig_send): Take special action if "communing" to ensure synchronization with the other process and to return information about the other process to the caller. (talktome): Accept a siginfo_t and handle arguments. Read additional information from the signal pipe when _si_commune._si_code has the PICOM_EXTRASTR flag set. (wait_sig): Pass the transmitted siginfo_t struct and the pipe handle to talktome. Close pipe read handle as soon as possible after we detect that we're exiting.
Diffstat (limited to 'winsup/cygwin/sigproc.cc')
-rw-r--r--winsup/cygwin/sigproc.cc73
1 files changed, 66 insertions, 7 deletions
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index e27fccdd9..0799a6ac5 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -526,6 +526,7 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
bool its_me;
HANDLE sendsig;
sigpacket pack;
+ bool communing = si.si_signo == __SIGCOMMUNE;
pack.wakeup = NULL;
bool wait_for_completion;
@@ -598,8 +599,29 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
CloseHandle (hp);
goto out;
}
- CloseHandle (hp);
VerifyHandle (sendsig);
+ if (!communing)
+ CloseHandle (hp);
+ else
+ {
+ si._si_commune._si_process_handle = hp;
+
+ HANDLE& tome = si._si_commune._si_write_handle;
+ HANDLE& fromthem = si._si_commune._si_read_handle;
+ if (!CreatePipe (&fromthem, &tome, &sec_all_nih, 0))
+ {
+ sigproc_printf ("CreatePipe for __SIGCOMMUNE failed, %E");
+ __seterrno ();
+ goto out;
+ }
+ if (!DuplicateHandle (hMainProc, tome, hp, &tome, false, 0,
+ DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
+ {
+ sigproc_printf ("DuplicateHandle for __SIGCOMMUNE failed, %E");
+ __seterrno ();
+ goto out;
+ }
+ }
}
sigproc_printf ("sendsig %p, pid %d, signal %d, its_me %d", sendsig, p->pid, si.si_signo, its_me);
@@ -628,8 +650,25 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
ProtectHandle (pack.wakeup);
}
+ char *leader;
+ size_t packsize;
+ if (!communing || !(si._si_commune._si_code & PICOM_EXTRASTR))
+ {
+ leader = (char *) &pack;
+ packsize = sizeof (pack);
+ }
+ else
+ {
+ size_t n = strlen (si._si_commune._si_str);
+ char *p = leader = (char *) alloca (sizeof (pack) + sizeof (n) + n);
+ memcpy (p, &pack, sizeof (pack)); p += sizeof (pack);
+ memcpy (p, &n, sizeof (n)); p += sizeof (n);
+ memcpy (p, si._si_commune._si_str, n); p += n;
+ packsize = p - leader;
+ }
+
DWORD nb;
- if (!WriteFile (sendsig, &pack, sizeof (pack), &nb, NULL) || nb != sizeof (pack))
+ if (!WriteFile (sendsig, leader, packsize, &nb, NULL) || nb != packsize)
{
/* Couldn't send to the pipe. This probably means that the
process is exiting. */
@@ -687,8 +726,16 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
if (wait_for_completion && si.si_signo != __SIGFLUSHFAST)
_my_tls.call_signal_handler ();
+ goto out;
out:
+ if (communing && rc)
+ {
+ if (si._si_commune._si_process_handle)
+ CloseHandle (si._si_commune._si_process_handle);
+ if (si._si_commune._si_read_handle)
+ CloseHandle (si._si_commune._si_read_handle);
+ }
if (pack.wakeup)
ForceCloseHandle (pack.wakeup);
if (si.si_signo != __SIGPENDING)
@@ -921,11 +968,23 @@ stopped_or_terminated (waitq *parent_w, _pinfo *child)
}
static void
-talktome (siginfo_t& si)
+talktome (siginfo_t& si, HANDLE readsig)
{
- pinfo p (si.si_pid, PID_MAP_RW);
- if (p)
- p->commune_recv ();
+ pinfo pi (si.si_pid);
+ if (si._si_commune._si_code & PICOM_EXTRASTR)
+ {
+ size_t n;
+ DWORD nb;
+ if (!ReadFile (readsig, &n, sizeof (n), &nb, NULL) || nb != sizeof (n))
+ return;
+ // FIXME: Is alloca here?
+ si._si_commune._si_str = (char *) alloca (n + 1);
+ if (!ReadFile (readsig, si._si_commune._si_str, n, &nb, NULL) || nb != n)
+ return;
+ si._si_commune._si_str[n] = '\0';
+ }
+ if (pi)
+ pi->commune_process (si);
}
void
@@ -1039,7 +1098,7 @@ wait_sig (VOID *)
switch (pack.si.si_signo)
{
case __SIGCOMMUNE:
- talktome (pack.si);
+ talktome (pack.si, readsig);
break;
case __SIGSTRACE:
strace.hello ();