aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2022-03-01 16:19:41 +0100
committerCorinna Vinschen <corinna@vinschen.de>2022-03-01 16:23:24 +0100
commit9a3c058f661217b6757a464b1b1d8898f88c1567 (patch)
treed3a30f2fca28039851d1b6a41d99db48505577a2
parent195169186bfd58e45aaa31236575fb9d5957adad (diff)
downloadnewlib-9a3c058f661217b6757a464b1b1d8898f88c1567.zip
newlib-9a3c058f661217b6757a464b1b1d8898f88c1567.tar.gz
newlib-9a3c058f661217b6757a464b1b1d8898f88c1567.tar.bz2
Cygwin: /proc/<PID>/status: Fill SigPnd, SigBlk and SigIgn values with life
So far the values of SigPnd and SigBlk were always 0 and SigIgn was incorrectly set to the block mask of the current thread of the calling process. Fix that by adding a _pinfo::siginfo method and a PICOM_SIGINFO message to allow to request actual signal info of any running process. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
-rw-r--r--winsup/cygwin/fhandler_process.cc9
-rw-r--r--winsup/cygwin/pinfo.cc51
-rw-r--r--winsup/cygwin/pinfo.h18
-rw-r--r--winsup/cygwin/sigproc.cc4
4 files changed, 70 insertions, 12 deletions
diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc
index 7f69027..4c42bc0 100644
--- a/winsup/cygwin/fhandler_process.cc
+++ b/winsup/cygwin/fhandler_process.cc
@@ -1199,6 +1199,8 @@ format_process_status (void *data, char *&destbuf)
int state = 'R';
const char *state_str = "unknown";
size_t vmsize = 0, vmrss = 0, vmdata = 0, vmlib = 0, vmtext = 0, vmshare = 0;
+ sigset_t pnd = 0, blk = 0, ign = 0;
+ bool fetch_siginfo = false;
PWCHAR last_slash = wcsrchr (p->progname, L'\\');
sys_wcstombs (cmd, NAME_MAX + 1, last_slash ? last_slash + 1 : p->progname);
@@ -1221,13 +1223,16 @@ format_process_status (void *data, char *&destbuf)
{
case 'O':
state_str = "running";
+ fetch_siginfo = true;
break;
case 'D':
case 'S':
state_str = "sleeping";
+ fetch_siginfo = true;
break;
case 'R':
state_str = "runnable";
+ fetch_siginfo = true;
break;
case 'Z':
state_str = "zombie";
@@ -1238,6 +1243,8 @@ format_process_status (void *data, char *&destbuf)
}
get_mem_values (p->dwProcessId, vmsize, vmrss, vmtext, vmdata,
vmlib, vmshare);
+ if (fetch_siginfo)
+ p->siginfo (pnd, blk, ign);
/* The real uid value for *this* process is stored at cygheap->user.real_uid
but we can't get at the real uid value for any other process, so
just fake it as p->uid. Similar for p->gid. */
@@ -1270,7 +1277,7 @@ format_process_status (void *data, char *&destbuf)
vmsize * kb_per_page, 0UL, vmrss * kb_per_page,
vmdata * kb_per_page, 0UL, vmtext * kb_per_page,
vmlib * kb_per_page,
- 0, 0, _my_tls.sigmask
+ pnd, blk, ign
);
}
diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc
index 5e04ea3..ad65e59 100644
--- a/winsup/cygwin/pinfo.cc
+++ b/winsup/cygwin/pinfo.cc
@@ -668,6 +668,20 @@ commune_process (void *arg)
sigproc_printf ("WritePipeOverlapped root failed, %E");
break;
}
+ case PICOM_SIGINFO:
+ {
+ sigproc_printf ("processing PICOM_SIGINFO");
+ commune_result cr;
+ sigpending (&cr.pnd);
+ cr.pnd = sig_send (myself, __SIGPENDINGALL, NULL);
+ cr.blk = cygheap->compute_sigblkmask ();
+ for (int sig = 1; sig < NSIG; ++sig)
+ if (global_sigs[sig].sa_handler == SIG_IGN)
+ cr.ign |= SIGTOMASK (sig);
+ if (!WritePipeOverlapped (tothem, &cr, sizeof cr, &nr, 1000L))
+ sigproc_printf ("WritePipeOverlapped siginfo failed, %E");
+ break;
+ }
case PICOM_FDS:
{
sigproc_printf ("processing PICOM_FDS");
@@ -788,16 +802,13 @@ commune_result
_pinfo::commune_request (__uint32_t code, ...)
{
DWORD nr;
- commune_result res;
+ commune_result res = { 0 };
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;
- res.s = NULL;
- res.n = 0;
-
if (!pid)
{
set_errno (ESRCH);
@@ -877,6 +888,14 @@ _pinfo::commune_request (__uint32_t code, ...)
res.n = p - res.s;
}
break;
+ case PICOM_SIGINFO:
+ if (!ReadPipeOverlapped (fromthem, &res, sizeof res, &nr, 1000L)
+ || nr != sizeof res)
+ {
+ __seterrno ();
+ goto err;
+ }
+ break;
}
goto out;
@@ -996,6 +1015,30 @@ _pinfo::root (size_t& n)
return s;
}
+int
+_pinfo::siginfo (sigset_t &pnd, sigset_t &blk, sigset_t &ign)
+{
+ if (!pid)
+ return -1;
+ if (pid != myself->pid && !ISSTATE (this, PID_NOTCYGWIN))
+ {
+ commune_result cr = commune_request (PICOM_SIGINFO);
+ pnd = cr.pnd;
+ blk = cr.blk;
+ ign = cr.ign;
+ }
+ else
+ {
+ pnd = sig_send (myself, __SIGPENDING, NULL);
+ blk = cygheap->compute_sigblkmask ();
+ ign = 0;
+ for (int sig = 1; sig < NSIG; ++sig)
+ if (global_sigs[sig].sa_handler == SIG_IGN)
+ ign |= SIGTOMASK (sig);
+ }
+ return -1;
+}
+
static HANDLE
open_commune_proc_parms (DWORD pid, PRTL_USER_PROCESS_PARAMETERS prupp)
{
diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h
index 69c1223..7e46cfb 100644
--- a/winsup/cygwin/pinfo.h
+++ b/winsup/cygwin/pinfo.h
@@ -11,11 +11,17 @@ details. */
#include <sys/resource.h>
#include "thread.h"
-struct commune_result
+union commune_result
{
- char *s;
- DWORD n;
- HANDLE handles[2];
+ struct {
+ char *s;
+ size_t n;
+ };
+ struct {
+ sigset_t pnd;
+ sigset_t blk;
+ sigset_t ign;
+ };
};
enum picom
@@ -28,7 +34,8 @@ enum picom
PICOM_FD = 5,
PICOM_PIPE_FHANDLER = 6,
PICOM_FILE_PATHCONV = 7,
- PICOM_ENVIRON = 8
+ PICOM_ENVIRON = 8,
+ PICOM_SIGINFO = 9
};
#define EXITCODE_SET 0x8000000
@@ -109,6 +116,7 @@ public:
char *cmdline (size_t &);
char *environ (size_t &);
char *win_heap_info (size_t &);
+ int siginfo (sigset_t &, sigset_t &, sigset_t &);
bool set_ctty (class fhandler_termios *, int);
bool alert_parent (char);
int __reg2 kill (siginfo_t&);
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index 449777c..d3f2b0c 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -683,7 +683,7 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
sigset_t pending;
if (!its_me)
pack.mask = NULL;
- else if (si.si_signo == __SIGPENDING)
+ else if (si.si_signo == __SIGPENDING || si.si_signo == __SIGPENDINGALL)
pack.mask = &pending;
else if (si.si_signo == __SIGFLUSH || si.si_signo > 0)
{
@@ -801,7 +801,7 @@ out:
}
if (pack.wakeup)
ForceCloseHandle (pack.wakeup);
- if (si.si_signo != __SIGPENDING)
+ if (si.si_signo != __SIGPENDING && si.si_signo != __SIGPENDINGALL)
/* nothing */;
else if (!rc)
rc = pending;