OSDN Git Service

* external.cc (cygwin_internal): Implement CW_CMDLINE.
authorcgf <cgf>
Wed, 30 Oct 2002 21:05:16 +0000 (21:05 +0000)
committercgf <cgf>
Wed, 30 Oct 2002 21:05:16 +0000 (21:05 +0000)
* pinfo.h (SIGCOMMUNE): New signal type.
(commune_result): New structure for commune functions.
(picom): New enum for commune functions.
(_pinfo::hello_pid): New.  Pid who's communicating with me.
(_pinfo::tothem): New.  Handle of communicating pipe.
(_pinfo::fromthem): Ditto.
(_pinfo::commune_recv): Declare.
(_pinfo::commune_send): Declare.
(_pinfo::alive): Declare.
(_pinfo::cmdline): Declare.
(_pinfo::lock): Declare.
* pinfo.cc (set_myself): Initialize new _pinfo lock.
(_pinfo::alive): Define.  Determines if process still exists.
(_pinfo::commune_recv): Define.  Receive info from another cooperating process.
(_pinfo::commune_send): Define.  Send info to another cooperating process.
(_pinfo::cmdline): Define.  Determine command line of a given process.
* include/sys/cygwin.h (CW_CMDLINE): Define.
*sigproc.cc (talktome): Communicate with any processes who want to talk to me.
(wait_sig): Honor __SIGCOMMUNE.
* fhandler.cc (fhandler_virtual::fixup_after_exec): Declare.
* fhandler_proc.cc: Use malloc/free/realloc throughout rather than cmalloc
since buffers don't need to be propagated to subprocesses.
* fhandler_registry.cc: Ditto.
* fhandler_virtual.cc: Ditto.
(fhandler_virtual::fixup_after_exec): Define.
* fhandler_process.cc: Ditto for malloc/free/realloc.
(process_listin): Add "cmdline".
(fhandler_process::fill_filebuf): Implement PROCESS_CMDLINE.
* miscfuncs.cc (isalpha_array): New array populated with xor values for alpha
characters to switch from one case to another.
* string.h (cygwin_strcasematch): New asm implementation of case match.
* string.h (cygwin_nstrcasematch): New asm implementation of counted case
match.

13 files changed:
winsup/cygwin/ChangeLog
winsup/cygwin/external.cc
winsup/cygwin/fhandler.h
winsup/cygwin/fhandler_proc.cc
winsup/cygwin/fhandler_process.cc
winsup/cygwin/fhandler_registry.cc
winsup/cygwin/fhandler_virtual.cc
winsup/cygwin/include/sys/cygwin.h
winsup/cygwin/miscfuncs.cc
winsup/cygwin/pinfo.cc
winsup/cygwin/pinfo.h
winsup/cygwin/sigproc.cc
winsup/cygwin/string.h

index 8983a8e..6098198 100644 (file)
@@ -1,3 +1,44 @@
+2002-10-30  Christopher Faylor  <cgf@redhat.com>
+
+       * external.cc (cygwin_internal): Implement CW_CMDLINE.
+       * pinfo.h (SIGCOMMUNE): New signal type.
+       (commune_result): New structure for commune functions.
+       (picom): New enum for commune functions.
+       (_pinfo::hello_pid): New.  Pid who's communicating with me.
+       (_pinfo::tothem): New.  Handle of communicating pipe.
+       (_pinfo::fromthem): Ditto.
+       (_pinfo::commune_recv): Declare.
+       (_pinfo::commune_send): Declare.
+       (_pinfo::alive): Declare.
+       (_pinfo::cmdline): Declare.
+       (_pinfo::lock): Declare.
+       * pinfo.cc (set_myself): Initialize new _pinfo lock.
+       (_pinfo::alive): Define. Determines if process still exists.
+       (_pinfo::commune_recv): Define.  Receive info from another cooperating process.
+       (_pinfo::commune_send): Define.  Send info to another cooperating process.
+       (_pinfo::cmdline): Define.  Determine command line of a given process.
+       * include/sys/cygwin.h (CW_CMDLINE): Define.
+
+       *sigproc.cc (talktome): Communicate with any processes who want to talk
+       to me.
+       (wait_sig): Honor __SIGCOMMUNE.
+
+       * fhandler.cc (fhandler_virtual::fixup_after_exec): Declare.
+       * fhandler_proc.cc: Use malloc/free/realloc throughout rather than
+       cmalloc since buffers don't need to be propagated to subprocesses.
+       * fhandler_registry.cc: Ditto.
+       * fhandler_virtual.cc: Ditto.
+       (fhandler_virtual::fixup_after_exec): Define.
+       * fhandler_process.cc: Ditto for malloc/free/realloc.
+       (process_listin): Add "cmdline".
+       (fhandler_process::fill_filebuf): Implement PROCESS_CMDLINE.
+
+       * miscfuncs.cc (isalpha_array): New array populated with xor values for
+       alpha characters to switch from one case to another.
+       * string.h (cygwin_strcasematch): New asm implementation of case match.
+       * string.h (cygwin_nstrcasematch): New asm implementation of counted
+       case match.
+
 2002-10-24  Pierre Humblet <pierre.humblet@ieee.org>
   
        * pwdgrp.h (pwdgrp_read::open): Compare fh to INVALID_HANDLE_VALUE.
index 571ea67..406786d 100644 (file)
@@ -241,6 +241,13 @@ cygwin_internal (cygwin_getinfo_types t, ...)
          extract_nt_dom_user (pw, domain, user);
          return 0;
        }
+      case CW_CMDLINE:
+       {
+         size_t n;
+         pid_t pid = va_arg (arg, pid_t);
+         pinfo p (pid);
+         return (DWORD) p->cmdline (n);
+       }
       default:
        return (DWORD) -1;
     }
index c0846ab..796c3e6 100644 (file)
@@ -1107,6 +1107,7 @@ class fhandler_virtual : public fhandler_base
   int close (void);
   int __stdcall fstat (struct stat *buf, path_conv *pc) __attribute__ ((regparm (3)));
   virtual bool fill_filebuf ();
+  void fixup_after_exec (HANDLE);
 };
 
 class fhandler_proc: public fhandler_virtual
index 86c3c81..f887e8c 100644 (file)
@@ -327,7 +327,7 @@ fhandler_proc::fill_filebuf ()
            uname (&uts_name);
                bufalloc = strlen (uts_name.sysname) + 1 + strlen (uts_name.release) +
                          1 + strlen (uts_name.version) + 2;
-           filebuf = (char *) cmalloc (HEAP_BUF, bufalloc);
+           filebuf = (char *) realloc (filebuf, bufalloc);
                filesize = __small_sprintf (filebuf, "%s %s %s\n", uts_name.sysname,
                             uts_name.release, uts_name.version);
          }
@@ -335,15 +335,13 @@ fhandler_proc::fill_filebuf ()
       }
     case PROC_UPTIME:
       {
-       if (!filebuf)
-         filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 80);
+       filebuf = (char *) realloc (filebuf, bufalloc = 80);
        filesize = format_proc_uptime (filebuf, bufalloc);
        break;
       }
     case PROC_STAT:
       {
-       if (!filebuf)
-         filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
+       filebuf = (char *) realloc (filebuf, bufalloc = 2048);
        filesize = format_proc_stat (filebuf, bufalloc);
        break;
       }
@@ -354,16 +352,14 @@ fhandler_proc::fill_filebuf ()
         * Windows 95/98/me does have the KERNEL/CPUUsage performance counter
         * which is similar.
         */
-       if (!filebuf)
-         filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 16);
+       filebuf = (char *) realloc (filebuf, bufalloc = 16);
        filesize = __small_sprintf (filebuf, "%u.%02u %u.%02u %u.%02u\n",
                                    0, 0, 0, 0, 0, 0);
        break;
       }
     case PROC_MEMINFO:
       {
-       if (!filebuf)
-         filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
+       filebuf = (char *) realloc (filebuf, bufalloc = 2048);
        filesize = format_proc_meminfo (filebuf, bufalloc);
        break;
       }
index 7cbfaa3..a9e8d2f 100644 (file)
@@ -42,6 +42,7 @@ static const int PROCESS_SID = 10;
 static const int PROCESS_CTTY = 11;
 static const int PROCESS_STAT = 12;
 static const int PROCESS_STATM = 13;
+static const int PROCESS_CMDLINE = 14;
 
 static const char * const process_listing[] =
 {
@@ -59,6 +60,7 @@ static const char * const process_listing[] =
   "ctty",
   "stat",
   "statm",
+  "cmdline",
   NULL
 };
 
@@ -264,8 +266,7 @@ fhandler_process::fill_filebuf ()
     case PROCESS_CTTY:
     case PROCESS_PPID:
       {
-       if (!filebuf)
-         filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 40);
+       filebuf = (char *) realloc (filebuf, bufalloc = 40);
        int num;
        switch (fileid)
          {
@@ -295,10 +296,18 @@ fhandler_process::fill_filebuf ()
        filesize = strlen (filebuf);
        break;
       }
+    case PROCESS_CMDLINE:
+      {
+       if (filebuf)
+         free (filebuf);
+       filebuf = p->cmdline (filesize);
+       if (!*filebuf)
+         filebuf = strdup ("<defunct>");
+       break;
+      }
     case PROCESS_EXENAME:
       {
-       if (!filebuf)
-         filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = MAX_PATH);
+       filebuf = (char *) realloc (filebuf, bufalloc = MAX_PATH);
        if (p->process_state & (PID_ZOMBIE | PID_EXITED))
          strcpy (filebuf, "<defunct>");
        else
@@ -317,8 +326,7 @@ fhandler_process::fill_filebuf ()
       }
     case PROCESS_WINPID:
       {
-       if (!filebuf)
-         filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 40);
+       filebuf = (char *) realloc (filebuf, bufalloc = 40);
        __small_sprintf (filebuf, "%d\n", p->dwProcessId);
        filesize = strlen (filebuf);
        break;
@@ -326,8 +334,7 @@ fhandler_process::fill_filebuf ()
     case PROCESS_WINEXENAME:
       {
        int len = strlen (p->progname);
-       if (!filebuf)
-         filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = (len + 2));
+       filebuf = (char *) realloc (filebuf, bufalloc = (len + 2));
        strcpy (filebuf, p->progname);
        filebuf[len] = '\n';
        filesize = len + 1;
@@ -335,22 +342,19 @@ fhandler_process::fill_filebuf ()
       }
     case PROCESS_STATUS:
       {
-       if (!filebuf)
-         filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
+       filebuf = (char *) realloc (filebuf, bufalloc = 2048);
        filesize = format_process_status (*p, filebuf, bufalloc);
        break;
       }
     case PROCESS_STAT:
       {
-       if (!filebuf)
-         filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
+       filebuf = (char *) realloc (filebuf, bufalloc = 2048);
        filesize = format_process_stat (*p, filebuf, bufalloc);
        break;
       }
     case PROCESS_STATM:
       {
-       if (!filebuf)
-         filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
+       filebuf = (char *) realloc (filebuf, bufalloc = 2048);
        filesize = format_process_statm (*p, filebuf, bufalloc);
        break;
       }
index f2e5e21..8a9f27e 100644 (file)
@@ -555,7 +555,7 @@ fhandler_registry::fill_filebuf ()
          goto value_not_found;
        }
       bufalloc = size;
-      filebuf = (char *) cmalloc (HEAP_BUF, bufalloc);
+      filebuf = (char *) malloc (bufalloc);
       error =
        RegQueryValueEx (handle, value_name, NULL, NULL, (BYTE *) filebuf,
                         &size);
@@ -572,14 +572,9 @@ fhandler_registry::fill_filebuf ()
       do
        {
          bufalloc += 1000;
-         if (filebuf)
-           {
-             cfree (filebuf);
-             filebuf = (char *) cmalloc (HEAP_BUF, bufalloc);
-           }
-         error =
-           RegQueryValueEx (handle, value_name, NULL, &type,
-                            (BYTE *) filebuf, &size);
+         filebuf = (char *) realloc (filebuf, bufalloc);
+         error = RegQueryValueEx (handle, value_name, NULL, &type,
+                                  (BYTE *) filebuf, &size);
          if (error != ERROR_SUCCESS && error != ERROR_MORE_DATA)
            {
              if (error != ERROR_FILE_NOT_FOUND)
index 05b9b0f..937caf3 100644 (file)
@@ -34,10 +34,17 @@ fhandler_virtual::fhandler_virtual (DWORD devtype):
 fhandler_virtual::~fhandler_virtual ()
 {
   if (filebuf)
-    cfree (filebuf);
+    free (filebuf);
   filebuf = NULL;
 }
 
+void
+fhandler_virtual::fixup_after_exec (HANDLE)
+{
+  if (filebuf)
+    filebuf = NULL;
+}
+
 DIR *
 fhandler_virtual::opendir (path_conv& pc)
 {
@@ -143,7 +150,7 @@ fhandler_virtual::dup (fhandler_base * child)
   if (!ret)
     {
       fhandler_virtual *fhproc_child = (fhandler_virtual *) child;
-      fhproc_child->filebuf = (char *) cmalloc (HEAP_BUF, filesize);
+      fhproc_child->filebuf = (char *) malloc (filesize);
       fhproc_child->bufalloc = fhproc_child->filesize = filesize;
       fhproc_child->position = position;
       memcpy (fhproc_child->filebuf, filebuf, filesize);
@@ -156,7 +163,7 @@ int
 fhandler_virtual::close ()
 {
   if (filebuf)
-    cfree (filebuf);
+    free (filebuf);
   filebuf = NULL;
   bufalloc = (size_t) -1;
   cygwin_shared->delqueue.process_queue ();
index b912811..54a6d0d 100644 (file)
@@ -70,7 +70,8 @@ typedef enum
     CW_STRACE_TOGGLE,
     CW_STRACE_ACTIVE,
     CW_CYGWIN_PID_TO_WINPID,
-    CW_EXTRACT_DOMAIN_AND_USER
+    CW_EXTRACT_DOMAIN_AND_USER,
+    CW_CMDLINE
   } cygwin_getinfo_types;
 
 #define CW_NEXTPID     0x80000000      // or with pid to get next one
index a6fec0d..fd7ae8e 100644 (file)
@@ -57,8 +57,29 @@ const char case_folded_upper[] NO_COPY = {
  240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
 };
 
+const char isalpha_array[] NO_COPY = {
+   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,   0,   0,   0,   0,   0,
+   0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,   0,   0,   0,   0,   0,
+   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
+};
+
 #define ch_case_eq(ch1, ch2) (cyg_tolower(ch1) == cyg_tolower(ch2))
 
+#if 0
+
 /* Return TRUE if two strings match up to length n */
 extern "C" int __stdcall
 strncasematch (const char *s1, const char *s2, size_t n)
@@ -91,6 +112,7 @@ strcasematch (const char *s1, const char *s2)
     }
   return *s2 == '\0';
 }
+#endif
 
 extern "C" char * __stdcall
 strcasestr (const char *searchee, const char *lookfor)
index 0ffd00e..b294130 100644 (file)
@@ -66,6 +66,7 @@ set_myself (pid_t pid, HANDLE h)
   (void) GetModuleFileName (NULL, myself->progname, sizeof (myself->progname));
   if (!strace.active)
     strace.hello ();
+  InitializeCriticalSection (&myself->lock);
   return;
 }
 
@@ -230,6 +231,227 @@ pinfo::init (pid_t n, DWORD flag, HANDLE in_h)
   destroy = 1;
 }
 
+bool
+_pinfo::alive ()
+{
+  HANDLE h = OpenProcess (PROCESS_QUERY_INFORMATION, false, dwProcessId);
+  if (h)
+    CloseHandle (h);
+  return !!h;
+}
+
+extern char **__argv;
+
+void
+_pinfo::commune_recv ()
+{
+  DWORD nr;
+  DWORD code;
+  HANDLE hp;
+  HANDLE __fromthem = NULL;
+  HANDLE __tothem = NULL;
+
+  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;
+    }
+
+  CloseHandle (hp);
+  hello_pid = 0;
+
+  if (!ReadFile (__fromthem, &code, sizeof code, &nr, NULL) || nr != sizeof code)
+    {
+      /* __seterrno ();*/      // this is run from the signal thread, so don't set errno
+      goto out;
+    }
+
+  switch (code)
+    {
+    case PICOM_CMDLINE:
+      {
+       unsigned n = 1;
+       CloseHandle (__fromthem); __fromthem = NULL;
+       for (char **a = __argv; *a; a++)
+         n += strlen (*a) + 1;
+       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 (char **a = __argv; *a; a++)
+           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))
+           {
+             sigproc_printf ("WriteFile null failed, %E");
+             break;
+           }
+      }
+    }
+
+out:
+  if (__fromthem)
+    CloseHandle (__fromthem);
+  if (__tothem)
+    CloseHandle (__tothem);
+}
+
+#define PIPEBUFSIZE (16 * sizeof (DWORD))
+
+commune_result
+_pinfo::commune_send (DWORD code)
+{
+  HANDLE fromthem = NULL, tome = NULL;
+  HANDLE fromme = NULL, tothem = NULL;
+  DWORD nr;
+  commune_result res;
+  if (!pid || !this)
+    {
+      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 ("first CreatePipe failed, %E");
+      __seterrno ();
+      goto err;
+    }
+  EnterCriticalSection (&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;
+
+  bool isalive;
+  while ((isalive = alive ()))
+    if (myself->hello_pid <= 0)
+      break;
+    else
+      Sleep (0);
+
+  CloseHandle (tome);
+  tome = NULL;
+  CloseHandle (fromme);
+  fromme = NULL;
+
+  if (!isalive)
+    {
+      set_errno (ESRCH);
+      goto err;
+    }
+
+  if (myself->hello_pid < 0)
+    {
+      set_errno (ENOSYS);
+      goto err;
+    }
+
+  size_t n;
+  if (!ReadFile (fromthem, &n, sizeof n, &nr, NULL) || nr != sizeof n)
+    {
+      __seterrno ();
+      goto err;
+    }
+  switch (code)
+    {
+    case PICOM_CMDLINE:
+      res.s = (char *) malloc (n);
+      char *p;
+      for (p = res.s; ReadFile (fromthem, p, n, &nr, NULL); p += nr)
+       continue;
+      if ((unsigned) (p - res.s) != n)
+       {
+         __seterrno ();
+         goto err;
+       }
+      res.n = n;
+      break;
+    }
+  CloseHandle (tothem);
+  CloseHandle (fromthem);
+  goto out;
+
+err:
+  if (tome)
+    CloseHandle (tome);
+  if (fromthem)
+    CloseHandle (fromthem);
+  if (tothem)
+    CloseHandle (tothem);
+  if (fromme)
+    CloseHandle (fromme);
+  res.n = 0;
+out:
+  myself->hello_pid = 0;
+  LeaveCriticalSection (&lock);
+  return res;
+}
+
+char *
+_pinfo::cmdline (size_t& n)
+{
+  char *s;
+  if (!this || !pid)
+    return NULL;
+  if (pid != myself->pid)
+    {
+      commune_result cr = commune_send (PICOM_CMDLINE);
+      s = cr.s;
+      n = cr.n;
+    }
+  else
+    {
+      n = 1;
+      for (char **a = __argv; *a; a++)
+       n += strlen (*a);
+      char *p;
+      p = s = (char *) malloc (n);
+      for (char **a = __argv; *a; a++)
+       {
+         strcpy (p, *a);
+         p = strchr (p, '\0') + 1;
+       }
+      *p = '\0';
+    }
+  return s;
+}
+
 void
 pinfo::release ()
 {
index dcb814b..fe36b5a 100644 (file)
@@ -16,7 +16,7 @@ enum
 {
   __SIGFLUSH       = -2,
   __SIGSTRACE      = -1,
-  __SIGUNUSED      =  0,
+  __SIGCOMMUNE     =  0,
   __SIGOFFSET      =  2
 };
 
@@ -25,6 +25,17 @@ enum
 #include <sys/resource.h>
 #include "thread.h"
 
+struct commune_result
+{
+  char *s;
+  int n;
+};
+
+enum picom
+{
+  PICOM_CMDLINE = 1
+};
+
 class _pinfo
 {
 public:
@@ -81,6 +92,11 @@ public:
 
   /* Non-zero if process was stopped by a signal. */
   char stopsig;
+  
+  /* commune */
+  pid_t hello_pid;
+  HANDLE tothem;
+  HANDLE fromthem;
 
   void exit (UINT n, bool norecord = 0) __attribute__ ((noreturn, regparm(2)));
 
@@ -119,12 +135,19 @@ public:
   }
 
   inline void setthread2signal (void *thr) {thread2signal = (pthread *) thr;}
+  void commune_recv ();
+  commune_result commune_send (DWORD);
+  bool alive ();
+  char *cmdline (size_t &);
+
+  friend void __stdcall set_myself (pid_t, HANDLE);
 
 private:
   struct sigaction sigs[NSIG];
   sigset_t sig_mask;           /* one set for everything to ignore. */
   LONG _sigtodo[NSIG + __SIGOFFSET];
-  pthread *thread2signal;  // NULL means means thread any other means a pthread
+  pthread *thread2signal;  // NULL means thread any other means a pthread
+  CRITICAL_SECTION lock;
 };
 
 class pinfo
index 9fb1fd4..5eeef7f 100644 (file)
@@ -1014,6 +1014,15 @@ stopped_or_terminated (waitq *parent_w, _pinfo *child)
   return -potential_match;
 }
 
+static void
+talktome ()
+{
+  winpids pids;
+  for (unsigned i = 0; i < pids.npids; i++)
+    if (pids[i]->hello_pid == myself->pid)
+      pids[i]->commune_recv ();
+}
+
 /* Process signals by waiting for a semaphore to become signaled.
  * Then scan an in-memory array representing queued signals.
  * Executes in a separate thread.
@@ -1143,6 +1152,10 @@ wait_sig (VOID *self)
                  strace.hello ();
                  break;
 
+               case __SIGCOMMUNE:
+                 talktome ();
+                 break;
+
                /* A normal UNIX signal */
                default:
                  sigproc_printf ("Got signal %d", sig);
index 84dc14c..778bb40 100644 (file)
@@ -38,6 +38,70 @@ strchr (const char *s, int c)
   return res;
 }
 
+extern const char isalpha_array[];
+
+#undef strcasematch
+#define strcasematch cygwin_strcasematch
+
+static inline int
+cygwin_strcasematch (const char *cs, const char *ct)
+{
+  register int __res;
+  int d0, d1;
+  __asm__ ("\
+       .global _isalpha_array                  \n\
+       cld                                     \n\
+       andl    $0xff,%%eax                     \n\
+1:     lodsb                                   \n\
+       scasb                                   \n\
+       je      2f                              \n\
+       xorb    _isalpha_array(%%eax),%%al      \n\
+       cmpb    -1(%%edi),%%al                  \n\
+       jne     3f                              \n\
+2:     testb   %%al,%%al                       \n\
+       jnz     1b                              \n\
+       movl    $1,%%eax                        \n\
+       jmp     4f                              \n\
+3:     xor     %0,%0                           \n\
+4:"
+        :"=a" (__res), "=&S" (d0), "=&D" (d1)
+                    : "1" (cs),   "2" (ct));
+
+  return __res;
+}
+
+#undef strncasematch
+#define strncasematch cygwin_strncasematch
+
+static inline int
+cygwin_strncasematch (const char *cs, const char *ct, size_t n)
+{
+  register int __res;
+  int d0, d1, d2;
+  __asm__ ("\
+       .global _isalpha_array;                 \n\
+       cld                                     \n\
+       andl    $0xff,%%eax                     \n\
+1:     decl    %3                              \n\
+       js      3f                              \n\
+       lodsb                                   \n\
+       scasb                                   \n\
+       je      2f                              \n\
+       xorb    _isalpha_array(%%eax),%%al      \n\
+       cmpb    -1(%%edi),%%al                  \n\
+       jne     4f                              \n\
+2:     testb   %%al,%%al                       \n\
+       jnz     1b                              \n\
+3:     movl    $1,%%eax                        \n\
+       jmp     5f                              \n\
+4:     xor     %0,%0                           \n\
+5:"
+       :"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
+                      :"1" (cs),  "2" (ct), "3" (n));
+
+  return __res;
+}
+
 #ifdef __cplusplus
 }
 #endif