diff --git a/src/basic/pidref.c b/src/basic/pidref.c index f41460938c1..e1ad697af0c 100644 --- a/src/basic/pidref.c +++ b/src/basic/pidref.c @@ -6,6 +6,7 @@ #include "parse-util.h" #include "pidref.h" #include "process-util.h" +#include "signal-util.h" int pidref_set_pid(PidRef *pidref, pid_t pid) { int fd; @@ -143,3 +144,30 @@ int pidref_kill_and_sigcont(PidRef *pidref, int sig) { return 0; } + +int pidref_sigqueue(PidRef *pidref, int sig, int value) { + + if (!pidref) + return -ESRCH; + + if (pidref->fd >= 0) { + siginfo_t si; + + /* We can't use structured initialization here, since the structure contains various unions + * and these fields lie in overlapping (carefully aligned) unions that LLVM is allergic to + * allow assignments to */ + zero(si); + si.si_signo = sig; + si.si_code = SI_QUEUE; + si.si_pid = getpid_cached(); + si.si_uid = getuid(); + si.si_value.sival_int = value; + + return RET_NERRNO(pidfd_send_signal(pidref->fd, sig, &si, 0)); + } + + if (pidref->pid > 0) + return RET_NERRNO(sigqueue(pidref->pid, sig, (const union sigval) { .sival_int = value })); + + return -ESRCH; +} diff --git a/src/basic/pidref.h b/src/basic/pidref.h index 2411e510f13..6998a865e7f 100644 --- a/src/basic/pidref.h +++ b/src/basic/pidref.h @@ -25,5 +25,6 @@ void pidref_done(PidRef *pidref); int pidref_kill(PidRef *pidref, int sig); int pidref_kill_and_sigcont(PidRef *pidref, int sig); +int pidref_sigqueue(PidRef *pidfref, int sig, int value); #define TAKE_PIDREF(p) TAKE_GENERIC((p), PidRef, PIDREF_NULL)