aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2002-10-30 21:05:18 +0000
committerChristopher Faylor <me@cgf.cx>2002-10-30 21:05:18 +0000
commit831d6fa520ed43d055924607a2d9be7fcc3813e9 (patch)
treef79c2bc5524f448accc0d407fc5b3b5c8ff9e0f4
parent4c8eba2cf384878e76b5d13acf0d7b22db531463 (diff)
* 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.
-rw-r--r--winsup/cygwin/ChangeLog41
-rw-r--r--winsup/cygwin/external.cc7
-rw-r--r--winsup/cygwin/fhandler.h1
-rw-r--r--winsup/cygwin/fhandler_proc.cc14
-rw-r--r--winsup/cygwin/fhandler_process.cc32
-rw-r--r--winsup/cygwin/fhandler_registry.cc13
-rw-r--r--winsup/cygwin/fhandler_virtual.cc13
-rw-r--r--winsup/cygwin/include/sys/cygwin.h3
-rw-r--r--winsup/cygwin/miscfuncs.cc22
-rw-r--r--winsup/cygwin/pinfo.cc222
-rw-r--r--winsup/cygwin/pinfo.h27
-rw-r--r--winsup/cygwin/sigproc.cc13
-rw-r--r--winsup/cygwin/string.h64
13 files changed, 434 insertions, 38 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 8983a8e61..6098198be 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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.
diff --git a/winsup/cygwin/external.cc b/winsup/cygwin/external.cc
index 571ea6742..406786d7c 100644
--- a/winsup/cygwin/external.cc
+++ b/winsup/cygwin/external.cc
@@ -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;
}
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index c0846ab9a..796c3e6bb 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -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
diff --git a/winsup/cygwin/fhandler_proc.cc b/winsup/cygwin/fhandler_proc.cc
index 86c3c81fb..f887e8cb7 100644
--- a/winsup/cygwin/fhandler_proc.cc
+++ b/winsup/cygwin/fhandler_proc.cc
@@ -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;
}
diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc
index 7cbfaa3cd..a9e8d2f0c 100644
--- a/winsup/cygwin/fhandler_process.cc
+++ b/winsup/cygwin/fhandler_process.cc
@@ -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;
}
diff --git a/winsup/cygwin/fhandler_registry.cc b/winsup/cygwin/fhandler_registry.cc
index f2e5e2145..8a9f27ed9 100644
--- a/winsup/cygwin/fhandler_registry.cc
+++ b/winsup/cygwin/fhandler_registry.cc
@@ -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)
diff --git a/winsup/cygwin/fhandler_virtual.cc b/winsup/cygwin/fhandler_virtual.cc
index 05b9b0f6c..937caf352 100644
--- a/winsup/cygwin/fhandler_virtual.cc
+++ b/winsup/cygwin/fhandler_virtual.cc
@@ -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 ();
diff --git a/winsup/cygwin/include/sys/cygwin.h b/winsup/cygwin/include/sys/cygwin.h
index b9128119e..54a6d0d5c 100644
--- a/winsup/cygwin/include/sys/cygwin.h
+++ b/winsup/cygwin/include/sys/cygwin.h
@@ -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
diff --git a/winsup/cygwin/miscfuncs.cc b/winsup/cygwin/miscfuncs.cc
index a6fec0ddc..fd7ae8edf 100644
--- a/winsup/cygwin/miscfuncs.cc
+++ b/winsup/cygwin/miscfuncs.cc
@@ -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)
diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc
index 0ffd00edd..b294130d7 100644
--- a/winsup/cygwin/pinfo.cc
+++ b/winsup/cygwin/pinfo.cc
@@ -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 ()
{
diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h
index dcb814bcc..fe36b5a27 100644
--- a/winsup/cygwin/pinfo.h
+++ b/winsup/cygwin/pinfo.h
@@ -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
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index 9fb1fd498..5eeef7f35 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -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);
diff --git a/winsup/cygwin/string.h b/winsup/cygwin/string.h
index 84dc14cb7..778bb40ac 100644
--- a/winsup/cygwin/string.h
+++ b/winsup/cygwin/string.h
@@ -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