int event_add_child_pidref(
sd_event *e,
- sd_event_source **s,
+ sd_event_source **ret,
const PidRef *pid,
int options,
sd_event_child_handler_t callback,
void *userdata) {
+ int r;
+
+ assert(e);
+
if (!pidref_is_set(pid))
return -ESRCH;
- if (pid->fd >= 0)
- return sd_event_add_child_pidfd(e, s, pid->fd, options, callback, userdata);
+ if (pidref_is_remote(pid))
+ return -EREMOTE;
+
+ if (pid->fd < 0)
+ return sd_event_add_child(e, ret, pid->pid, options, callback, userdata);
+
+ _cleanup_close_ int copy_fd = fcntl(pid->fd, F_DUPFD_CLOEXEC, 3);
+ if (copy_fd < 0)
+ return -errno;
+
+ _cleanup_(sd_event_source_unrefp) sd_event_source *s = NULL;
+ r = sd_event_add_child_pidfd(e, &s, copy_fd, options, callback, userdata);
+ if (r < 0)
+ return r;
+
+ r = sd_event_source_set_child_pidfd_own(s, true);
+ if (r < 0)
+ return r;
+
+ TAKE_FD(copy_fd);
+
+ if (ret)
+ *ret = TAKE_PTR(s);
+ else {
+ r = sd_event_source_set_floating(s, true);
+ if (r < 0)
+ return r;
+ }
- return sd_event_add_child(e, s, pid->pid, options, callback, userdata);
+ return 0;
}
int event_source_get_child_pidref(sd_event_source *s, PidRef *ret) {
log_debug_errno(r, "Failed allocate memory pressure event source, ignoring: %m");
/* Exit when the child exits */
- (void) event_add_child_pidref(event, NULL, &child_pidref, WEXITED, on_child_exit, NULL);
+ r = event_add_child_pidref(event, /* ret_event_source= */ NULL, &child_pidref, WEXITED, on_child_exit, /* userdata= */ NULL);
+ if (r < 0)
+ return log_error_errno(r, "Failed to watch qemu process: &m");
_cleanup_(osc_context_closep) sd_id128_t osc_context_id = SD_ID128_NULL;
_cleanup_(pty_forward_freep) PTYForward *forward = NULL;