From 831d6fa520ed43d055924607a2d9be7fcc3813e9 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Wed, 30 Oct 2002 21:05:18 +0000 Subject: [PATCH] * 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. --- winsup/cygwin/ChangeLog | 41 ++++++ winsup/cygwin/external.cc | 7 + winsup/cygwin/fhandler.h | 1 + winsup/cygwin/fhandler_proc.cc | 14 +- winsup/cygwin/fhandler_process.cc | 32 +++-- winsup/cygwin/fhandler_registry.cc | 13 +- winsup/cygwin/fhandler_virtual.cc | 13 +- winsup/cygwin/include/sys/cygwin.h | 3 +- winsup/cygwin/miscfuncs.cc | 22 +++ winsup/cygwin/pinfo.cc | 222 +++++++++++++++++++++++++++++ winsup/cygwin/pinfo.h | 27 +++- winsup/cygwin/sigproc.cc | 13 ++ winsup/cygwin/string.h | 64 +++++++++ 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 + + * 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 * 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 (""); + 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, ""); 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 #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