OSDN Git Service

Change name from commune_recv to commune_process throughout. Change name from
authorcgf <cgf>
Wed, 28 Sep 2005 22:56:40 +0000 (22:56 +0000)
committercgf <cgf>
Wed, 28 Sep 2005 22:56:40 +0000 (22:56 +0000)
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.

winsup/cygwin/ChangeLog
winsup/cygwin/fhandler_fifo.cc
winsup/cygwin/include/cygwin/signal.h
winsup/cygwin/pinfo.cc
winsup/cygwin/pinfo.h
winsup/cygwin/sigproc.cc

index 2667ad1..6401790 100644 (file)
@@ -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.
 
index 694a518..1429267 100644 (file)
@@ -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,
index a73565c..bd1d33c 100644 (file)
@@ -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 */
index 2dd727b..5c2e2f8 100644 (file)
@@ -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;
     }
index 564f6f7..1462e5f 100644 (file)
@@ -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 () {}
index e27fccd..0799a6a 100644 (file)
@@ -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 ();