diff --git a/src/basic/process-util.c b/src/basic/process-util.c index ab563c5105..ececbf97ac 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -21,6 +21,7 @@ #include "alloc-util.h" #include "architecture.h" #include "argv-util.h" +#include "bitfield.h" #include "capability-util.h" #include "cgroup-util.h" #include "dirent-util.h" @@ -804,6 +805,53 @@ int get_process_umask(pid_t pid, mode_t *ret) { return parse_mode(m, ret); } +static int pid_get_sigmask(pid_t pid, const char *field_name, uint64_t *ret) { + _cleanup_free_ char *field = NULL; + int r; + + assert(pid >= 0); + assert(field_name); + assert(ret); + + r = procfs_file_get_field(pid, "status", field_name, &field); + if (r == -ENOENT) + return -ESRCH; + if (r < 0) + return r; + + return safe_atou64_full(field, 16, ret); +} + +static int pidref_has_sigmask(const PidRef *pidref, int sig, const char *field_name) { + uint64_t mask; + int r; + + if (!pidref_is_set(pidref)) + return -ESRCH; + if (pidref_is_remote(pidref)) + return -EREMOTE; + if (!SIGNAL_VALID(sig)) + return -EINVAL; + + r = pid_get_sigmask(pidref->pid, field_name, &mask); + if (r < 0) + return r; + + r = pidref_verify(pidref); + if (r < 0) + return r; + + return BIT_SET(mask, sig - 1); +} + +int pidref_has_sigcgt(const PidRef *pidref, int sig) { + return pidref_has_sigmask(pidref, sig, "SigCgt"); +} + +int pidref_has_sigblk(const PidRef *pidref, int sig) { + return pidref_has_sigmask(pidref, sig, "SigBlk"); +} + /* * Return values: * < 0 : pidref_wait_for_terminate() failed to get the state of the diff --git a/src/basic/process-util.h b/src/basic/process-util.h index 007397704e..56514c8ed8 100644 --- a/src/basic/process-util.h +++ b/src/basic/process-util.h @@ -53,6 +53,8 @@ int pidref_get_ppid_as_pidref(const PidRef *pidref, PidRef *ret); int pid_get_start_time(pid_t pid, usec_t *ret); int pidref_get_start_time(const PidRef *pid, usec_t *ret); int get_process_umask(pid_t pid, mode_t *ret); +int pidref_has_sigcgt(const PidRef *pidref, int sig); +int pidref_has_sigblk(const PidRef *pidref, int sig); static inline bool SIGINFO_CODE_IS_DEAD(int code) { return IN_SET(code, CLD_EXITED, CLD_KILLED, CLD_DUMPED);