Revision: 23486 http://trac.macosforge.org/projects/launchd/changeset/23486 Author: zarzycki@apple.com Date: 2008-01-18 09:50:12 -0800 (Fri, 18 Jan 2008) Log Message: ----------- <rdar://problem/5692704> SpringBoard needs custom launchd job management API Modified Paths: -------------- trunk/launchd/src/launchd_core_logic.c trunk/launchd/src/liblaunch_public.h trunk/launchd/src/libvproc.c trunk/launchd/src/libvproc_private.h trunk/launchd/src/protocol_job.defs Modified: trunk/launchd/src/launchd_core_logic.c =================================================================== --- trunk/launchd/src/launchd_core_logic.c 2008-01-18 17:49:34 UTC (rev 23485) +++ trunk/launchd/src/launchd_core_logic.c 2008-01-18 17:50:12 UTC (rev 23486) @@ -325,7 +325,7 @@ cpu_type_t *j_binpref; size_t j_binpref_cnt; mach_port_t j_port; - mach_port_t wait_reply_port; + mach_port_t wait_reply_port; /* we probably should switch to a list of waiters */ uid_t mach_uid; jobmgr_t mgr; char **argv; @@ -365,7 +365,7 @@ currently_ignored:1, forced_peers_to_demand_mode:1, setnice:1, hopefully_exits_last:1, removal_pending:1, legacy_LS_job:1, sent_sigkill:1, debug_before_kill:1, weird_bootstrap:1, start_on_mount:1, per_user:1, hopefully_exits_first:1, deny_unknown_mslookups:1, unload_at_mig_return:1, abandon_pg:1, - poll_for_vfs_changes:1, __junk:12; + poll_for_vfs_changes:1, can_kickstart:1, __junk:11; mode_t mask; const char label[0]; }; @@ -1636,12 +1636,41 @@ } } +static void +policy_setup(launch_data_t obj, const char *key, void *context) +{ + job_t j = context; + bool found_key = false; + + switch (key[0]) { + case 'c': + case 'C': + if (strcasecmp(key, LAUNCH_JOBPOLICY_CANKICKSTARTOTHERJOBS) == 0) { + j->can_kickstart = launch_data_get_bool(obj); + found_key = true; + } + break; + default: + break; + } + + if (unlikely(!found_key)) { + job_log(j, LOG_WARNING, "Unknown policy: %s", key); + } +} + void job_import_dictionary(job_t j, const char *key, launch_data_t value) { launch_data_t tmp; switch (key[0]) { + case 'p': + case 'P': + if (strcasecmp(key, LAUNCH_JOBKEY_POLICIES) == 0) { + launch_data_dict_iterate(value, policy_setup, j); + } + break; case 'k': case 'K': if (strcasecmp(key, LAUNCH_JOBKEY_KEEPALIVE) == 0) { @@ -6525,6 +6554,61 @@ } 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; + } + + runtime_get_caller_creds(&ldc); + + if (!j->can_kickstart || (ldc.euid != 0 && ldc.euid != geteuid())) { + return BOOTSTRAP_NOT_PRIVILEGED; + } + + if (unlikely(!(otherj = job_find(targetlabel)))) { + return BOOTSTRAP_UNKNOWN_SERVICE; + } + + 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; +} + +kern_return_t job_mig_wait(job_t j, mach_port_t srp, integer_t *waitstatus) { if (!launchd_assumes(j != NULL)) { Modified: trunk/launchd/src/liblaunch_public.h =================================================================== --- trunk/launchd/src/liblaunch_public.h 2008-01-18 17:49:34 UTC (rev 23485) +++ trunk/launchd/src/liblaunch_public.h 2008-01-18 17:50:12 UTC (rev 23486) @@ -100,7 +100,10 @@ #define LAUNCH_JOBKEY_THROTTLEINTERVAL "ThrottleInterval" #define LAUNCH_JOBKEY_LAUNCHONLYONCE "LaunchOnlyOnce" #define LAUNCH_JOBKEY_ABANDONPROCESSGROUP "AbandonProcessGroup" +#define LAUNCH_JOBKEY_POLICIES "Policies" +#define LAUNCH_JOBPOLICY_CANKICKSTARTOTHERJOBS "CanKickStartOtherJobs" + #define LAUNCH_JOBINETDCOMPATIBILITY_WAIT "Wait" #define LAUNCH_JOBKEY_MACH_RESETATCLOSE "ResetAtClose" Modified: trunk/launchd/src/libvproc.c =================================================================== --- trunk/launchd/src/libvproc.c 2008-01-18 17:49:34 UTC (rev 23485) +++ trunk/launchd/src/libvproc.c 2008-01-18 17:50:12 UTC (rev 23486) @@ -389,6 +389,7 @@ { mach_msg_type_number_t outdata_cnt, tmp_cnt; vm_offset_t outdata = 0; + struct timeval tv; struct logmsg_s *lm; if (!func) { @@ -411,7 +412,10 @@ lm->msg += (size_t)lm; lm->session_name += (size_t)lm; - func(&lm->when, lm->from_pid, lm->about_pid, lm->sender_uid, lm->sender_gid, lm->pri, + tv.tv_sec = lm->when / USEC_PER_SEC; + tv.tv_usec = lm->when % USEC_PER_SEC; + + func(&tv, lm->from_pid, lm->about_pid, lm->sender_uid, lm->sender_gid, lm->pri, lm->from_name, lm->about_name, lm->session_name, lm->msg); tmp_cnt -= lm->obj_sz; @@ -553,6 +557,26 @@ } vproc_err_t +_vproc_kickstart_by_label(const char *label, pid_t *out_pid, mach_port_t *out_port_name) +{ + if (vproc_mig_embedded_kickstart(bootstrap_port, (char *)label, out_pid, out_port_name) == 0) { + return NULL; + } + + return (vproc_err_t)_vproc_kickstart_by_label; +} + +vproc_err_t +_vproc_wait_by_label(const char *label, int *out_wstatus) +{ + if (vproc_mig_embedded_wait(bootstrap_port, (char *)label, out_wstatus) == 0) { + return NULL; + } + + return (vproc_err_t)_vproc_wait_by_label; +} + +vproc_err_t _vproc_set_global_on_demand(bool state) { int64_t val = state ? ~0 : 0; Modified: trunk/launchd/src/libvproc_private.h =================================================================== --- trunk/launchd/src/libvproc_private.h 2008-01-18 17:49:34 UTC (rev 23485) +++ trunk/launchd/src/libvproc_private.h 2008-01-18 17:50:12 UTC (rev 23486) @@ -61,6 +61,8 @@ vproc_err_t _vprocmgr_log_drain(vproc_t vp, pthread_mutex_t *optional_mutex_around_callback, _vprocmgr_log_drain_callback_t func); vproc_err_t _vproc_send_signal_by_label(const char *label, int sig); +vproc_err_t _vproc_kickstart_by_label(const char *label, pid_t *out_pid, mach_port_t *out_port_name); +vproc_err_t _vproc_wait_by_label(const char *label, int *out_wstatus); void _vproc_log(int pri, const char *msg, ...) __attribute__((format(printf, 2, 3))); void _vproc_log_error(int pri, const char *msg, ...) __attribute__((format(printf, 2, 3))); Modified: trunk/launchd/src/protocol_job.defs =================================================================== --- trunk/launchd/src/protocol_job.defs 2008-01-18 17:49:34 UTC (rev 23485) +++ trunk/launchd/src/protocol_job.defs 2008-01-18 17:50:12 UTC (rev 23486) @@ -168,3 +168,14 @@ routine log_forward( __bs_port : job_t; __inval : pointer_t); + +routine embedded_kickstart( + __bs_port : job_t; + __label : name_t; + out __pid : pid_t; + out __name_port : mach_port_t); + +routine embedded_wait( + __bs_port : job_t; + __label : name_t; + out __waitval : integer_t);
participants (1)
-
source_changes@macosforge.org