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:
-rw-r--r--winsup/cygwin/ChangeLog32
-rw-r--r--winsup/cygwin/fhandler_fifo.cc2
-rw-r--r--winsup/cygwin/include/cygwin/signal.h15
-rw-r--r--winsup/cygwin/pinfo.cc326
-rw-r--r--winsup/cygwin/pinfo.h20
-rw-r--r--winsup/cygwin/sigproc.cc73
6 files changed, 219 insertions, 249 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 2667ad1ff..64017900b 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,37 @@
2005-09-28 Christopher Faylor <cgf@timesys.com>
+ 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.
+
+2005-09-28 Christopher Faylor <cgf@timesys.com>
+
* hookapi.cc (hook_or_detect_cygwin): Correct inverted test for whether
to allocate a buffer by always allocating a buffer.
diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc
index 694a51819..14292671a 100644
--- a/winsup/cygwin/fhandler_fifo.cc
+++ b/winsup/cygwin/fhandler_fifo.cc
@@ -99,7 +99,7 @@ fhandler_fifo::open_not_mine (int flags)
commune_result r;
if (p->pid != myself->pid)
{
- r = p->commune_send (PICOM_FIFO, get_win32_name ());
+ r = p->commune_request (PICOM_FIFO, get_win32_name ());
if (r.handles[0] == NULL)
continue; // process doesn't own fifo
debug_printf ("pid %d, handles[0] %p, handles[1] %p", p->pid,
diff --git a/winsup/cygwin/include/cygwin/signal.h b/winsup/cygwin/include/cygwin/signal.h
index a73565c74..bd1d33c04 100644
--- a/winsup/cygwin/include/cygwin/signal.h
+++ b/winsup/cygwin/include/cygwin/signal.h
@@ -42,6 +42,20 @@ typedef struct sigevent
} sigevent_t;
#pragma pack(push,4)
+struct _sigcommune
+{
+ __uint32_t _si_code;
+ void *_si_read_handle;
+ void *_si_write_handle;
+ void *_si_process_handle;
+ union
+ {
+ int _si_fd;
+ void *_si_pipe_fhandler;
+ char *_si_str;
+ };
+};
+
typedef struct
{
int si_signo; /* signal number */
@@ -53,6 +67,7 @@ typedef struct
union
{
__uint32_t __pad[32]; /* plan for future growth */
+ struct _sigcommune _si_commune; /* cygwin ipc */
union
{
/* timers */
diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc
index 2dd727ba1..5c2e2f8a8 100644
--- a/winsup/cygwin/pinfo.cc
+++ b/winsup/cygwin/pinfo.cc
@@ -380,58 +380,24 @@ _pinfo::alive ()
extern char **__argv;
void
-_pinfo::commune_recv ()
+_pinfo::commune_process (siginfo_t& si)
{
char path[CYG_MAX_PATH];
DWORD nr;
- DWORD code;
- HANDLE hp;
- HANDLE __fromthem = NULL;
- HANDLE __tothem = NULL;
+ HANDLE& tothem = si._si_commune._si_write_handle;
+ HANDLE process_sync =
+ OpenSemaphore (SYNCHRONIZE, false, shared_name (path, "commune", si.si_pid));
+ if (process_sync) // FIXME: this test shouldn't be necessary
+ ProtectHandle (process_sync);
- hp = OpenProcess (PROCESS_DUP_HANDLE, false, dwProcessId);
- if (!hp)
- {
- sigproc_printf ("couldn't open handle for pid %d(%u)", pid, dwProcessId);
- hello_pid = -1;
- return;
- }
- if (!DuplicateHandle (hp, fromthem, hMainProc, &__fromthem, 0, false, DUPLICATE_SAME_ACCESS))
- {
- sigproc_printf ("couldn't duplicate fromthem, %E");
- CloseHandle (hp);
- hello_pid = -1;
- return;
- }
-
- if (!DuplicateHandle (hp, tothem, hMainProc, &__tothem, 0, false, DUPLICATE_SAME_ACCESS))
- {
- sigproc_printf ("couldn't duplicate tothem, %E");
- CloseHandle (__fromthem);
- CloseHandle (hp);
- hello_pid = -1;
- return;
- }
-
- hello_pid = 0;
-
- if (!ReadFile (__fromthem, &code, sizeof code, &nr, NULL) || nr != sizeof code)
- {
- CloseHandle (hp);
- /* __seterrno ();*/ // this is run from the signal thread, so don't set errno
- goto out;
- }
-
- switch (code)
+ switch (si._si_commune._si_code)
{
case PICOM_CMDLINE:
{
unsigned n = 1;
- CloseHandle (__fromthem); __fromthem = NULL;
extern int __argc_safe;
const char *argv[__argc_safe + 1];
- CloseHandle (hp);
for (int i = 0; i < __argc_safe; i++)
{
if (IsBadStringPtr (__argv[i], INT32_MAX))
@@ -441,19 +407,19 @@ _pinfo::commune_recv ()
n += strlen (argv[i]) + 1;
}
argv[__argc_safe] = NULL;
- if (!WriteFile (__tothem, &n, sizeof n, &nr, NULL))
+ if (!WriteFile (tothem, &n, sizeof n, &nr, NULL))
{
/*__seterrno ();*/ // this is run from the signal thread, so don't set errno
sigproc_printf ("WriteFile sizeof argv failed, %E");
}
else
for (const char **a = argv; *a; a++)
- if (!WriteFile (__tothem, *a, strlen (*a) + 1, &nr, NULL))
+ if (!WriteFile (tothem, *a, strlen (*a) + 1, &nr, NULL))
{
sigproc_printf ("WriteFile arg %d failed, %E", a - argv);
break;
}
- if (!WriteFile (__tothem, "", 1, &nr, NULL))
+ if (!WriteFile (tothem, "", 1, &nr, NULL))
{
sigproc_printf ("WriteFile null failed, %E");
break;
@@ -462,46 +428,40 @@ _pinfo::commune_recv ()
}
case PICOM_CWD:
{
- CloseHandle (__fromthem); __fromthem = NULL;
- CloseHandle (hp);
unsigned int n = strlen (cygheap->cwd.get (path, 1, 1,
CYG_MAX_PATH)) + 1;
- if (!WriteFile (__tothem, &n, sizeof n, &nr, NULL))
+ if (!WriteFile (tothem, &n, sizeof n, &nr, NULL))
sigproc_printf ("WriteFile sizeof cwd failed, %E");
- else if (!WriteFile (__tothem, path, n, &nr, NULL))
+ else if (!WriteFile (tothem, path, n, &nr, NULL))
sigproc_printf ("WriteFile cwd failed, %E");
break;
}
case PICOM_ROOT:
{
- CloseHandle (__fromthem); __fromthem = NULL;
- CloseHandle (hp);
- unsigned int n;
+ unsigned n;
if (cygheap->root.exists ())
n = strlen (strcpy (path, cygheap->root.posix_path ())) + 1;
else
n = strlen (strcpy (path, "/")) + 1;
- if (!WriteFile (__tothem, &n, sizeof n, &nr, NULL))
+ if (!WriteFile (tothem, &n, sizeof n, &nr, NULL))
sigproc_printf ("WriteFile sizeof root failed, %E");
- else if (!WriteFile (__tothem, path, n, &nr, NULL))
+ else if (!WriteFile (tothem, path, n, &nr, NULL))
sigproc_printf ("WriteFile root failed, %E");
break;
}
case PICOM_FDS:
{
- CloseHandle (__fromthem); __fromthem = NULL;
- CloseHandle (hp);
unsigned int n = 0;
int fd;
cygheap_fdenum cfd;
while ((fd = cfd.next ()) >= 0)
n += sizeof (int);
cfd.rewind ();
- if (!WriteFile (__tothem, &n, sizeof n, &nr, NULL))
+ if (!WriteFile (tothem, &n, sizeof n, &nr, NULL))
sigproc_printf ("WriteFile sizeof fds failed, %E");
else
while ((fd = cfd.next ()) >= 0)
- if (!WriteFile (__tothem, &fd, sizeof fd, &nr, NULL))
+ if (!WriteFile (tothem, &fd, sizeof fd, &nr, NULL))
{
sigproc_printf ("WriteFile fd %d failed, %E", fd);
break;
@@ -510,16 +470,7 @@ _pinfo::commune_recv ()
}
case PICOM_PIPE_FHANDLER:
{
- HANDLE hdl;
- if (!ReadFile (__fromthem, &hdl, sizeof hdl, &nr, NULL)
- || nr != sizeof hdl)
- {
- sigproc_printf ("ReadFile hdl failed, %E");
- CloseHandle (hp);
- goto out;
- }
- CloseHandle (__fromthem); __fromthem = NULL;
- CloseHandle (hp);
+ HANDLE hdl = si._si_commune._si_pipe_fhandler;
unsigned int n = 0;
cygheap_fdenum cfd;
while (cfd.next () >= 0)
@@ -527,59 +478,34 @@ _pinfo::commune_recv ()
{
fhandler_pipe *fh = cfd;
n = sizeof *fh;
- if (!WriteFile (__tothem, &n, sizeof n, &nr, NULL))
+ if (!WriteFile (tothem, &n, sizeof n, &nr, NULL))
sigproc_printf ("WriteFile sizeof hdl failed, %E");
- else if (!WriteFile (__tothem, fh, n, &nr, NULL))
+ else if (!WriteFile (tothem, fh, n, &nr, NULL))
sigproc_printf ("WriteFile hdl failed, %E");
+ break;
}
- if (!n && !WriteFile (__tothem, &n, sizeof n, &nr, NULL))
+ if (!n && !WriteFile (tothem, &n, sizeof n, &nr, NULL))
sigproc_printf ("WriteFile sizeof hdl failed, %E");
break;
}
case PICOM_FD:
{
- int fd;
- if (!ReadFile (__fromthem, &fd, sizeof fd, &nr, NULL)
- || nr != sizeof fd)
- {
- sigproc_printf ("ReadFile fd failed, %E");
- CloseHandle (hp);
- goto out;
- }
- CloseHandle (__fromthem); __fromthem = NULL;
- CloseHandle (hp);
+ int fd = si._si_commune._si_fd;
unsigned int n = 0;
cygheap_fdget cfd (fd);
if (cfd < 0)
n = strlen (strcpy (path, "")) + 1;
else
n = strlen (cfd->get_proc_fd_name (path)) + 1;
- if (!WriteFile (__tothem, &n, sizeof n, &nr, NULL))
+ if (!WriteFile (tothem, &n, sizeof n, &nr, NULL))
sigproc_printf ("WriteFile sizeof fd failed, %E");
- else if (!WriteFile (__tothem, path, n, &nr, NULL))
+ else if (!WriteFile (tothem, path, n, &nr, NULL))
sigproc_printf ("WriteFile fd failed, %E");
break;
}
case PICOM_FIFO:
{
- unsigned len;
- if (!ReadFile (__fromthem, &len, sizeof len, &nr, NULL)
- || nr != sizeof len)
- {
- CloseHandle (hp);
- /* __seterrno ();*/ // this is run from the signal thread, so don't set errno
- goto out;
- }
- /* Get null-terminated path */
- if (!ReadFile (__fromthem, path, len, &nr, NULL)
- || nr != len)
- {
- CloseHandle (hp);
- /* __seterrno ();*/ // this is run from the signal thread, so don't set errno
- goto out;
- }
-
- fhandler_fifo *fh = cygheap->fdtab.find_fifo (path);
+ fhandler_fifo *fh = cygheap->fdtab.find_fifo (si._si_commune._si_str);
HANDLE it[2];
if (fh == NULL)
it[0] = it[1] = NULL;
@@ -587,46 +513,40 @@ _pinfo::commune_recv ()
{
it[0] = fh->get_handle ();
it[1] = fh->get_output_handle ();
- for (int i = 0; i < 2; i++)
- if (!DuplicateHandle (hMainProc, it[i], hp, &it[i], 0, false,
- DUPLICATE_SAME_ACCESS))
- {
- it[0] = it[1] = NULL; /* FIXME: possibly left a handle open in child? */
- break;
- }
- debug_printf ("fifo found %p, %p", it[0], it[1]);
- fh->close_one_end (); /* FIXME: not quite right - need more handshaking */
}
- CloseHandle (hp);
- if (!WriteFile (__tothem, it, sizeof (it), &nr, NULL))
+ debug_printf ("fifo %sfound %p, %p", fh ? "" : "not ", it[0], it[1]);
+ if (!WriteFile (tothem, it, sizeof (it), &nr, NULL))
{
/*__seterrno ();*/ // this is run from the signal thread, so don't set errno
sigproc_printf ("WriteFile read handle failed, %E");
}
-
- ReadFile (__fromthem, &nr, sizeof (nr), &nr, NULL);
+ WaitForSingleObject (process_sync, INFINITE);
+ process_sync = NULL;
+ if (fh)
+ fh->close_one_end ();
break;
}
}
-
-out:
- if (__fromthem)
- CloseHandle (__fromthem);
- if (__tothem)
- CloseHandle (__tothem);
+ if (process_sync)
+ {
+ WaitForSingleObject (process_sync, INFINITE);
+ ForceCloseHandle (process_sync);
+ }
+ CloseHandle (tothem);
}
-#define PIPEBUFSIZE (4096 * sizeof (DWORD))
-
commune_result
-_pinfo::commune_send (DWORD code, ...)
+_pinfo::commune_request (__uint32_t code, ...)
{
- HANDLE fromthem = NULL, tome = NULL;
- HANDLE fromme = NULL, tothem = NULL;
DWORD nr;
commune_result res;
va_list args;
+ siginfo_t si = {0};
+ HANDLE& hp = si._si_commune._si_process_handle;
+ HANDLE& fromthem = si._si_commune._si_read_handle;
+ HANDLE request_sync = NULL;
+ bool locked = false;
va_start (args, code);
@@ -638,86 +558,45 @@ _pinfo::commune_send (DWORD code, ...)
set_errno (ESRCH);
goto err;
}
- if (!CreatePipe (&fromthem, &tome, &sec_all_nih, PIPEBUFSIZE))
- {
- sigproc_printf ("first CreatePipe failed, %E");
- __seterrno ();
- goto err;
- }
- if (!CreatePipe (&fromme, &tothem, &sec_all_nih, PIPEBUFSIZE))
- {
- sigproc_printf ("second CreatePipe failed, %E");
- __seterrno ();
- goto err;
- }
- myself.lock ();
- myself->tothem = tome;
- myself->fromthem = fromme;
- myself->hello_pid = pid;
- if (!WriteFile (tothem, &code, sizeof code, &nr, NULL) || nr != sizeof code)
- {
- __seterrno ();
- goto err;
- }
-
- if (sig_send (this, __SIGCOMMUNE))
- goto err;
- /* FIXME: Need something better than an busy loop here */
- bool isalive;
- for (int i = 0; (isalive = alive ()) && (i < 10000); i++)
- if (myself->hello_pid <= 0)
+ si._si_commune._si_code = code;
+ switch (code)
+ {
+ case PICOM_PIPE_FHANDLER:
+ si._si_commune._si_pipe_fhandler = va_arg (args, HANDLE);
break;
- else
- low_priority_sleep (0);
- CloseHandle (tome);
- tome = NULL;
- CloseHandle (fromme);
- fromme = NULL;
+ case PICOM_FD:
+ si._si_commune._si_fd = va_arg (args, int);
+ break;
- if (!isalive)
- {
- set_errno (ESRCH);
- goto err;
+ case PICOM_FIFO:
+ si._si_commune._si_str = va_arg (args, char *);
+ break;
}
- if (myself->hello_pid < 0)
- {
- set_errno (ENOSYS);
- goto err;
- }
+ myself.lock ();
+ locked = true;
+ char name_buf[CYG_MAX_PATH];
+ request_sync = CreateSemaphore (&sec_none_nih, 0, LONG_MAX,
+ shared_name (name_buf, "commune", myself->pid));
+ if (!request_sync)
+ goto err;
+ ProtectHandle (request_sync);
+
+ si.si_signo = __SIGCOMMUNE;
+ if (sig_send (this, si))
+ goto err;
size_t n;
switch (code)
{
- case PICOM_PIPE_FHANDLER:
- {
- HANDLE hdl = va_arg (args, HANDLE);
- if (!WriteFile (tothem, &hdl, sizeof hdl, &nr, NULL)
- || nr != sizeof hdl)
- {
- __seterrno ();
- goto err;
- }
- }
- goto business_as_usual;
- case PICOM_FD:
- {
- int fd = va_arg (args, int);
- if (!WriteFile (tothem, &fd, sizeof fd, &nr, NULL)
- || nr != sizeof fd)
- {
- __seterrno ();
- goto err;
- }
- }
- goto business_as_usual;
case PICOM_CMDLINE:
case PICOM_CWD:
case PICOM_ROOT:
case PICOM_FDS:
- business_as_usual:
+ case PICOM_FD:
+ case PICOM_PIPE_FHANDLER:
if (!ReadFile (fromthem, &n, sizeof n, &nr, NULL) || nr != sizeof n)
{
__seterrno ();
@@ -741,51 +620,42 @@ _pinfo::commune_send (DWORD code, ...)
break;
case PICOM_FIFO:
{
- char *path = va_arg (args, char *);
- size_t len = strlen (path) + 1;
- if (!WriteFile (tothem, &len, sizeof (len), &nr, NULL)
- || nr != sizeof (len))
- {
- __seterrno ();
- goto err;
- }
- if (!WriteFile (tothem, path, len, &nr, NULL) || nr != len)
- {
- __seterrno ();
- goto err;
- }
-
DWORD x = ReadFile (fromthem, res.handles, sizeof (res.handles), &nr, NULL);
- WriteFile (tothem, &x, sizeof (x), &x, NULL);
- if (!x)
- goto err;
-
- if (nr != sizeof (res.handles))
+ if (!x || nr != sizeof (res.handles))
{
- set_errno (EPIPE);
+ __seterrno ();
goto err;
}
+ for (int i = 0; i < 2; i++)
+ if (!DuplicateHandle (hp, res.handles[i], hMainProc, &res.handles[i],
+ 0, false, DUPLICATE_SAME_ACCESS))
+ {
+ if (i)
+ CloseHandle (res.handles[0]);
+ res.handles[0] = res.handles[1] = NULL; /* FIXME: possibly left a handle open in child? */
+ goto err;
+ }
break;
}
}
- CloseHandle (tothem);
- CloseHandle (fromthem);
goto out;
err:
- if (tome)
- CloseHandle (tome);
- if (fromthem)
- CloseHandle (fromthem);
- if (tothem)
- CloseHandle (tothem);
- if (fromme)
- CloseHandle (fromme);
memset (&res, 0, sizeof (res));
out:
- myself->hello_pid = 0;
- myself.unlock ();
+ if (request_sync)
+ {
+ LONG res;
+ ReleaseSemaphore (request_sync, 1, &res);
+ ForceCloseHandle (request_sync);
+ }
+ if (locked)
+ myself.unlock ();
+ if (hp)
+ CloseHandle (hp);
+ if (fromthem)
+ CloseHandle (fromthem);
return res;
}
@@ -796,7 +666,7 @@ _pinfo::pipe_fhandler (HANDLE hdl, size_t &n)
return NULL;
if (pid == myself->pid)
return NULL;
- commune_result cr = commune_send (PICOM_PIPE_FHANDLER, hdl);
+ commune_result cr = commune_request (PICOM_PIPE_FHANDLER, hdl);
n = cr.n;
return (fhandler_pipe *) cr.s;
}
@@ -809,7 +679,7 @@ _pinfo::fd (int fd, size_t &n)
return NULL;
if (pid != myself->pid)
{
- commune_result cr = commune_send (PICOM_FD, fd);
+ commune_result cr = commune_request (PICOM_FD, fd);
s = cr.s;
n = cr.n;
}
@@ -833,7 +703,7 @@ _pinfo::fds (size_t &n)
return NULL;
if (pid != myself->pid)
{
- commune_result cr = commune_send (PICOM_FDS);
+ commune_result cr = commune_request (PICOM_FDS);
s = cr.s;
n = cr.n;
}
@@ -861,7 +731,7 @@ _pinfo::root (size_t& n)
return NULL;
if (pid != myself->pid)
{
- commune_result cr = commune_send (PICOM_ROOT);
+ commune_result cr = commune_request (PICOM_ROOT);
s = cr.s;
n = cr.n;
}
@@ -884,7 +754,7 @@ _pinfo::cwd (size_t& n)
return NULL;
if (pid != myself->pid)
{
- commune_result cr = commune_send (PICOM_CWD);
+ commune_result cr = commune_request (PICOM_CWD);
s = cr.s;
n = cr.n;
}
@@ -905,7 +775,7 @@ _pinfo::cmdline (size_t& n)
return NULL;
if (pid != myself->pid)
{
- commune_result cr = commune_send (PICOM_CMDLINE);
+ commune_result cr = commune_request (PICOM_CMDLINE);
s = cr.s;
n = cr.n;
}
diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h
index 564f6f798..1462e5f6d 100644
--- a/winsup/cygwin/pinfo.h
+++ b/winsup/cygwin/pinfo.h
@@ -22,8 +22,9 @@ struct commune_result
enum picom
{
+ PICOM_EXTRASTR = 0x80000000,
PICOM_CMDLINE = 1,
- PICOM_FIFO = 2,
+ PICOM_FIFO = PICOM_EXTRASTR | 2,
PICOM_CWD = 3,
PICOM_ROOT = 4,
PICOM_FDS = 5,
@@ -57,9 +58,8 @@ public:
pid_t ppid;
/* dwProcessId contains the processid used for sending signals. It
- * will be reset in a child process when it is capable of receiving
- * signals.
- */
+ will be reset in a child process when it is capable of receiving
+ signals. */
DWORD dwProcessId;
/* Used to spawn a child for fork(), among other things. */
@@ -87,11 +87,6 @@ public:
/* Non-zero if process was stopped by a signal. */
char stopsig;
- /* commune */
- pid_t hello_pid;
- HANDLE tothem;
- HANDLE fromthem;
-
inline void set_has_pgid_children ()
{
if (pgid == pid)
@@ -110,10 +105,10 @@ public:
sig_mask = mask;
}
- void commune_recv ();
- commune_result commune_send (DWORD, ...);
+ void commune_process (siginfo_t&);
+ commune_result commune_request (__uint32_t, ...);
bool alive ();
- fhandler_pipe *pipe_fhandler (HANDLE hdl, size_t &);
+ fhandler_pipe *pipe_fhandler (HANDLE, size_t &);
char *fd (int fd, size_t &);
char *fds (size_t &);
char *root (size_t &);
@@ -156,7 +151,6 @@ public:
HANDLE hProcess;
CRITICAL_SECTION _lock;
bool waiter_ready;
- /* Handle associated with initial Windows pid which started it all. */
class cygthread *wait_thread;
void init (pid_t, DWORD, HANDLE) __attribute__ ((regparm(3)));
pinfo () {}
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 ();