summaryrefslogtreecommitdiff
path: root/sigs.py
diff options
context:
space:
mode:
Diffstat (limited to 'sigs.py')
-rwxr-xr-xsigs.py59
1 files changed, 59 insertions, 0 deletions
diff --git a/sigs.py b/sigs.py
new file mode 100755
index 0000000..abad48f
--- /dev/null
+++ b/sigs.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python3
+"""
+Prints the registered signals for a Linux process.
+"""
+import signal, subprocess, sys
+
+keyword = sys.argv[1]
+try:
+ pid = int(keyword)
+except ValueError:
+ pids = subprocess.check_output(["pgrep", keyword],
+ universal_newlines=True).split()
+ if len(pids) == 1:
+ pid = int(pids[0])
+ else:
+ if not pids:
+ print("No such process: %s", keyword)
+ else:
+ print("More than one process:", *pids)
+ sys.exit(1)
+
+def bits(n):
+ i = 0
+ while n:
+ if n & 1:
+ yield i
+ n >>= 1
+ i += 1
+
+def print_sigs(sigset):
+ # Note 32 and 33 are unusable, those are used by nptl(7):
+ sigs = {
+ 32: "(NPTL thread cancellation)",
+ 33: "(NPTL POSIX timers)",
+ }
+ for name in dir(signal):
+ if not name.startswith("SIG") or name.startswith("SIG_"):
+ continue
+ signum = int(getattr(signal, name))
+ sigs[signum] = name
+ for bit in bits(sigset):
+ signum = bit + 1
+ if signal.SIGRTMIN < signum <= signal.SIGRTMAX:
+ signame = "SIGRTMIN+%d" % (signum - signal.SIGRTMIN)
+ elif signum in sigs:
+ signame = sigs[signum]
+ else:
+ signame = "(signal %d)" % signum
+ print(" %016x %2d %s" % (1 << bit, signum, signame))
+
+with open("/proc/%d/status" % pid) as f:
+ for line in f:
+ if not any(line.startswith("Sig%s" % suffix)
+ for suffix in ("Pnd", "Blk", "Ign", "Cgt")):
+ continue
+ key, val = line.split()
+ sigset = int(val, 16)
+ print("%s %016x" % (key, sigset))
+ print_sigs(sigset)