From: Corinna Vinschen Date: Tue, 1 Mar 2022 15:19:41 +0000 (+0100) Subject: Cygwin: /proc//status: Fill SigPnd, SigBlk and SigIgn values with life X-Git-Tag: cygwin-3.4.0~495 X-Git-Url: https://sourceware.org/git/?a=commitdiff_plain;h=9a3c058f661217b6757a464b1b1d8898f88c1567;p=newlib-cygwin.git Cygwin: /proc//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 --- diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc index 7f69027d0..4c42bc015 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 5e04ea3da..ad65e59c1 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 69c1223f3..7e46cfbec 100644 --- a/winsup/cygwin/pinfo.h +++ b/winsup/cygwin/pinfo.h @@ -11,11 +11,17 @@ details. */ #include #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 449777cda..d3f2b0c6a 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;