diff options
author | Christopher Faylor <me@cgf.cx> | 2005-09-28 22:56:47 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2005-09-28 22:56:47 +0000 |
commit | 0730fa07632fa954269ed21cbc2f6025dd35f5cf (patch) | |
tree | 3dc70659917cef414b51daaddd83d6093cdf3d2b /winsup/cygwin/sigproc.cc | |
parent | 503490bb9fd3b8853342128a7961d9f4b9e15d99 (diff) | |
download | cygnal-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.cc | 73 |
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 (); |