#include "errno-util.h"
#include "fd-util.h"
#include "missing_syscall.h"
+#include "missing_wait.h"
#include "parse-util.h"
#include "pidref.h"
#include "process-util.h"
return pidref->pid == getpid_cached();
}
+int pidref_wait(const PidRef *pidref, siginfo_t *ret, int options) {
+ int r;
+
+ if (!pidref_is_set(pidref))
+ return -ESRCH;
+
+ if (pidref->pid == 1 || pidref->pid == getpid_cached())
+ return -ECHILD;
+
+ siginfo_t si = {};
+
+ if (pidref->fd >= 0) {
+ r = RET_NERRNO(waitid(P_PIDFD, pidref->fd, &si, options));
+ if (r >= 0) {
+ if (ret)
+ *ret = si;
+ return r;
+ }
+ if (r != -EINVAL) /* P_PIDFD was added in kernel 5.4 only */
+ return r;
+ }
+
+ r = RET_NERRNO(waitid(P_PID, pidref->pid, &si, options));
+ if (r >= 0 && ret)
+ *ret = si;
+ return r;
+}
+
+int pidref_wait_for_terminate(const PidRef *pidref, siginfo_t *ret) {
+ int r;
+
+ for (;;) {
+ r = pidref_wait(pidref, ret, WEXITED);
+ if (r != -EINTR)
+ return r;
+ }
+}
+
static void pidref_hash_func(const PidRef *pidref, struct siphash *state) {
siphash24_compress_typesafe(pidref->pid, state);
}
int pidref_kill(const PidRef *pidref, int sig);
int pidref_kill_and_sigcont(const PidRef *pidref, int sig);
-int pidref_sigqueue(const PidRef *pidfref, int sig, int value);
+int pidref_sigqueue(const PidRef *pidref, int sig, int value);
+
+int pidref_wait(const PidRef *pidref, siginfo_t *siginfo, int options);
+int pidref_wait_for_terminate(const PidRef *pidref, siginfo_t *ret);
+
+static inline void pidref_done_sigkill_wait(PidRef *pidref) {
+ if (!pidref_is_set(pidref))
+ return;
+
+ (void) pidref_kill(pidref, SIGKILL);
+ (void) pidref_wait_for_terminate(pidref, NULL);
+ pidref_done(pidref);
+}
int pidref_verify(const PidRef *pidref);