process-util: Add helpers to check for signal handler presence
Add new pidref_has_sigcgt() and pidref_has_sigblk() helpers. These read the SigCgt and SigBlk bitmasks from /proc/<pid>/status to detect either traditional signal handlers installed via sigaction(2), or blocked signals that are typically handled via signalfd(2), such as through sd_event_add_signal(). Both mechanisms represent valid ways to handle a signal without invoking the default action. Share the parsing and pidref verification between the two public helpers.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user