+kern_return_t
+job_mig_embedded_wait(job_t j, name_t targetlabel, integer_t *waitstatus)
+{
+ job_t otherj;
+
+ if (!launchd_assumes(j != NULL)) {
+ return BOOTSTRAP_NO_MEMORY;
+ }
+
+ if (unlikely(!(otherj = job_find(targetlabel)))) {
+ return BOOTSTRAP_UNKNOWN_SERVICE;
+ }
+
+ *waitstatus = j->last_exit_status;
+
+ return 0;
+}
+
+kern_return_t
+job_mig_embedded_kickstart(job_t j, name_t targetlabel, pid_t *out_pid, mach_port_t *out_name_port)
+{
+ struct ldcred ldc;
+ kern_return_t kr;
+ job_t otherj;
+
+ if (!launchd_assumes(j != NULL)) {
+ return BOOTSTRAP_NO_MEMORY;
+ }
+
+ if (unlikely(!(otherj = job_find(targetlabel)))) {
+ return BOOTSTRAP_UNKNOWN_SERVICE;
+ }
+
+ runtime_get_caller_creds(&ldc);
+
+ if (ldc.euid != 0 && ldc.euid != geteuid()
+#if TARGET_OS_EMBEDDED
+ && j->username && otherj->username
+ && strcmp(j->username, otherj->username) != 0
+#endif
+ ) {
+ return BOOTSTRAP_NOT_PRIVILEGED;
+ }
+
+ otherj = job_dispatch(otherj, true);
+
+ if (!job_assumes(j, otherj && otherj->p)) {
+ return BOOTSTRAP_NO_MEMORY;
+ }
+
+ kr = task_name_for_pid(mach_task_self(), otherj->p, out_name_port);
+ if (!job_assumes(j, kr == 0)) {
+ return kr;
+ }
+
+ *out_pid = otherj->p;
+
+ return 0;
+}
+