Revision: 23264 http://trac.macosforge.org/projects/launchd/changeset/23264 Author: zarzycki@apple.com Date: 2007-05-25 13:44:01 -0700 (Fri, 25 May 2007) Log Message: ----------- <rdar://problem/4991686> spawn_via_launchd: specify quarantine and seatbelt information Modified Paths: -------------- trunk/launchd/src/launchd_core_logic.c trunk/launchd/src/launchd_mig_types.defs trunk/launchd/src/liblaunch_private.h trunk/launchd/src/libvproc.c trunk/launchd/src/libvproc_internal.h trunk/launchd/src/protocol_job.defs Modified: trunk/launchd/src/launchd_core_logic.c =================================================================== --- trunk/launchd/src/launchd_core_logic.c 2007-05-24 20:54:19 UTC (rev 23263) +++ trunk/launchd/src/launchd_core_logic.c 2007-05-25 20:44:01 UTC (rev 23264) @@ -72,6 +72,7 @@ #include <ctype.h> #include <glob.h> #include <spawn.h> +#include <sandbox.h> #include "liblaunch_public.h" #include "liblaunch_private.h" @@ -194,6 +195,7 @@ static bool limititem_update(job_t j, int w, rlim_t r); static void limititem_delete(job_t j, struct limititem *li); static void limititem_setup(launch_data_t obj, const char *key, void *context); +static void seatbelt_setup_flags(launch_data_t obj, const char *key, void *context); typedef enum { NETWORK_UP = 1, @@ -297,7 +299,7 @@ #if DO_RUSAGE_SUMMATION struct rusage ru; #endif - binpref_t j_binpref; + cpu_type_t *j_binpref; size_t j_binpref_cnt; mach_port_t j_port; mach_port_t wait_reply_port; @@ -313,6 +315,10 @@ char *stderrpath; struct machservice *lastlookup; unsigned int lastlookup_gennum; + char *seatbelt_profile; + uint64_t seatbelt_flags; + void *quarantine_data; + size_t quarantine_data_sz; pid_t p; int argc; int last_exit_status; @@ -354,6 +360,7 @@ static void job_import_integer(job_t j, const char *key, long long value); static void job_import_dictionary(job_t j, const char *key, launch_data_t value); static void job_import_array(job_t j, const char *key, launch_data_t value); +static void job_import_opaque(job_t j, const char *key, launch_data_t value); static bool job_set_global_on_demand(job_t j, bool val); static void job_watch(job_t j); static void job_ignore(job_t j); @@ -376,7 +383,6 @@ static void job_callback_read(job_t j, int ident); static job_t job_new_anonymous(jobmgr_t jm, pid_t anonpid); static job_t job_new(jobmgr_t jm, const char *label, const char *prog, const char *const *argv); -static job_t job_new_spawn(job_t j, const char *label, const char *path, const char *workingdir, const char *const *argv, const char *const *env, mode_t *u_mask, bool w4d); static job_t job_new_via_mach_init(job_t j, const char *cmd, uid_t uid, bool ond); static const char *job_prog(job_t j); static pid_t job_get_pid(job_t j); @@ -773,6 +779,12 @@ if (j->stderrpath) { free(j->stderrpath); } + if (j->seatbelt_profile) { + free(j->seatbelt_profile); + } + if (j->quarantine_data) { + free(j->quarantine_data); + } if (j->start_interval) { job_assumes(j, kevent_mod((uintptr_t)&j->start_interval, EVFILT_TIMER, EV_DELETE, 0, 0, NULL) != -1); } @@ -921,64 +933,6 @@ return 0; } -job_t -job_new_spawn(job_t j, const char *label, const char *path, const char *workingdir, const char *const *argv, const char *const *env, mode_t *u_mask, bool w4d) -{ - job_t jr; - size_t i; - - if ((jr = job_find(label)) != NULL) { - errno = EEXIST; - return NULL; - } - - jr = job_new(j->mgr, label, path, argv); - - if (!jr) { - return NULL; - } - - job_reparent_hack(jr, NULL); - - if (getpid() == 1) { - struct ldcred ldc; - - runtime_get_caller_creds(&ldc); - jr->mach_uid = ldc.uid; - } - - jr->unload_at_exit = true; - jr->wait4pipe_eof = true; - jr->stall_before_exec = w4d; - - if (workingdir) { - jr->workingdir = strdup(workingdir); - } - - if (u_mask) { - jr->mask = *u_mask; - jr->setmask = true; - } - - if (env) for (i = 0; env[i]; i++) { - char *eqoff, tmpstr[strlen(env[i]) + 1]; - - strcpy(tmpstr, env[i]); - - eqoff = strchr(tmpstr, '='); - - if (!eqoff) { - job_log(jr, LOG_WARNING, "Environmental variable missing '=' separator: %s", tmpstr); - continue; - } - - *eqoff = '\0'; - envitem_new(jr, tmpstr, eqoff + 1, false); - } - - return jr; -} - job_t job_new_anonymous(jobmgr_t jm, pid_t anonpid) { @@ -1357,6 +1311,8 @@ where2put = &j->stdoutpath; } else if (strcasecmp(key, LAUNCH_JOBKEY_STANDARDERRORPATH) == 0) { where2put = &j->stderrpath; + } else if (strcasecmp(key, LAUNCH_JOBKEY_SANDBOXPROFILE) == 0) { + where2put = &j->seatbelt_profile; } break; default: @@ -1426,7 +1382,10 @@ if (-1 == kevent_mod((uintptr_t)&j->start_interval, EVFILT_TIMER, EV_ADD, NOTE_SECONDS, value, j)) { job_log_error(j, LOG_ERR, "adding kevent timer"); } + } else if (strcasecmp(key, LAUNCH_JOBKEY_SANDBOXFLAGS) == 0) { + j->seatbelt_flags = value; } + break; default: job_log(j, LOG_WARNING, "Unknown key for integer: %s", key); @@ -1435,6 +1394,26 @@ } void +job_import_opaque(job_t j, const char *key, launch_data_t value) +{ + switch (key[0]) { + case 'q': + case 'Q': + if (strcasecmp(key, LAUNCH_JOBKEY_QUARANTINEDATA) == 0) { + size_t tmpsz = launch_data_get_opaque_size(value); + + if (job_assumes(j, j->quarantine_data = malloc(tmpsz))) { + memcpy(j->quarantine_data, launch_data_get_opaque(value), tmpsz); + j->quarantine_data_sz = tmpsz; + } + } + break; + default: + break; + } +} + +void job_import_dictionary(job_t j, const char *key, launch_data_t value) { launch_data_t tmp; @@ -1477,6 +1456,8 @@ calendarinterval_new_from_obj(j, value); } else if (strcasecmp(key, LAUNCH_JOBKEY_SOFTRESOURCELIMITS) == 0) { launch_data_dict_iterate(value, limititem_setup, j); + } else if (strcasecmp(key, LAUNCH_JOBKEY_SANDBOXFLAGS) == 0) { + launch_data_dict_iterate(value, seatbelt_setup_flags, j); } break; case 'h': @@ -1552,6 +1533,13 @@ case 'B': if (strcasecmp(key, LAUNCH_JOBKEY_BONJOURFDS) == 0) { socketgroup_setup(value, LAUNCH_JOBKEY_BONJOURFDS, j); + } else if (strcasecmp(key, LAUNCH_JOBKEY_BINARYORDERPREFERENCE) == 0) { + if (job_assumes(j, j->j_binpref = malloc(value_cnt * sizeof(*j->j_binpref)))) { + j->j_binpref_cnt = value_cnt; + for (i = 0; i < value_cnt; i++) { + j->j_binpref[i] = launch_data_get_integer(launch_data_array_get_index(value, i)); + } + } } break; case 's': @@ -1596,6 +1584,9 @@ case LAUNCH_DATA_ARRAY: job_import_array(j, key, obj); break; + case LAUNCH_DATA_OPAQUE: + job_import_opaque(j, key, obj); + break; default: job_log(j, LOG_WARNING, "Unknown value type '%d' for key: %s", kind, key); break; @@ -2374,6 +2365,27 @@ signal(i, SIG_DFL); } + if (j->quarantine_data) { + qtn_proc_t qp; + + if (job_assumes(j, qp = qtn_proc_alloc())) { + if (job_assumes(j, qtn_proc_init_with_data(qp, j->quarantine_data, j->quarantine_data_sz) == 0)) { + job_assumes(j, qtn_proc_apply_to_self(qp) == 0); + } + } + } + + if (j->seatbelt_profile) { + char *seatbelt_err_buf = NULL; + + if (!job_assumes(j, sandbox_init(j->seatbelt_profile, j->seatbelt_flags, &seatbelt_err_buf) != -1)) { + if (seatbelt_err_buf) { + job_log(j, LOG_ERR, "Sandbox failed to init: %s", seatbelt_err_buf); + } + goto out_bad; + } + } + if (j->prog) { errno = posix_spawn(&junk_pid, j->inetcompat ? file2exec : j->prog, NULL, &spattr, (char *const*)argv, environ); job_log_error(j, LOG_ERR, "posix_spawn(\"%s\", ...)", j->prog); @@ -2382,6 +2394,7 @@ job_log_error(j, LOG_ERR, "posix_spawnp(\"%s\", ...)", argv[0]); } +out_bad: _exit(EXIT_FAILURE); } @@ -3231,6 +3244,25 @@ } void +seatbelt_setup_flags(launch_data_t obj, const char *key, void *context) +{ + job_t j = context; + + if (launch_data_get_type(obj) != LAUNCH_DATA_BOOL) { + job_log(j, LOG_WARNING, "Sandbox flag value must be boolean: %s", key); + return; + } + + if (launch_data_get_bool(obj) == false) { + return; + } + + if (strcasecmp(key, LAUNCH_JOBKEY_SANDBOX_NAMED) == 0) { + j->seatbelt_flags |= SANDBOX_NAMED; + } +} + +void limititem_setup(launch_data_t obj, const char *key, void *context) { job_t j = context; @@ -5320,8 +5352,6 @@ kr = _vproc_grab_subset(target_subset, &reqport, &rcvright, &out_obj_array, &l2l_ports, &l2l_port_cnt); - job_log(j, LOG_NOTICE, "@@@@@ kr == 0x%x", kr); - if (!job_assumes(j, kr == 0)) { goto out; } @@ -5343,11 +5373,11 @@ job_assumes(j, obj_at_idx = launch_data_array_get_index(out_obj_array, l2l_i)); job_assumes(j, tmp = launch_data_dict_lookup(obj_at_idx, TAKE_SUBSET_PID)); - job_assumes(j, target_pid = launch_data_get_integer(tmp)); + target_pid = launch_data_get_integer(tmp); job_assumes(j, tmp = launch_data_dict_lookup(obj_at_idx, TAKE_SUBSET_PERPID)); - job_assumes(j, serv_perpid = launch_data_get_bool(tmp)); + serv_perpid = launch_data_get_bool(tmp); job_assumes(j, tmp = launch_data_dict_lookup(obj_at_idx, TAKE_SUBSET_NAME)); - job_assumes(j, serv_name = launch_data_get_string(tmp)); + serv_name = launch_data_get_string(tmp); j_for_service = jobmgr_find_by_pid(jmr, target_pid, true); @@ -5647,19 +5677,12 @@ } kern_return_t -job_mig_spawn(job_t j, _internal_string_t charbuf, mach_msg_type_number_t charbuf_cnt, - uint32_t argc, uint32_t envc, uint64_t flags, uint16_t mig_umask, - binpref_t bin_pref, uint32_t binpref_cnt, pid_t *child_pid, mach_port_t *obsvr_port) +job_mig_spawn(job_t j, vm_offset_t indata, mach_msg_type_number_t indataCnt, pid_t *child_pid, mach_port_t *obsvr_port) { + launch_data_t input_obj = NULL; + size_t data_offset = 0; + struct ldcred ldc; job_t jr; - size_t offset = 0; - char *tmpp; - const char **argv = NULL, **env = NULL; - const char *label = NULL; - const char *path = NULL; - const char *workingdir = NULL; - size_t argv_i = 0, env_i = 0; - struct ldcred ldc; runtime_get_caller_creds(&ldc); @@ -5672,38 +5695,15 @@ return VPROC_ERR_TRY_PER_USER; } - argv = alloca((argc + 1) * sizeof(char *)); - memset(argv, 0, (argc + 1) * sizeof(char *)); - - if (envc > 0) { - env = alloca((envc + 1) * sizeof(char *)); - memset(env, 0, (envc + 1) * sizeof(char *)); + if (indataCnt == 0) { + return 1; } - while (offset < charbuf_cnt) { - tmpp = charbuf + offset; - offset += strlen(tmpp) + 1; - if (!label) { - label = tmpp; - } else if (argc > 0) { - argv[argv_i] = tmpp; - argv_i++; - argc--; - } else if (envc > 0) { - env[env_i] = tmpp; - env_i++; - envc--; - } else if (flags & SPAWN_HAS_PATH) { - path = tmpp; - flags &= ~SPAWN_HAS_PATH; - } else if (flags & SPAWN_HAS_WDIR) { - workingdir = tmpp; - flags &= ~SPAWN_HAS_WDIR; - } + if (!job_assumes(j, (input_obj = launch_data_unpack((void *)indata, indataCnt, NULL, 0, &data_offset, NULL)) != NULL)) { + return 1; } - jr = job_new_spawn(j, label, path, workingdir, argv, env, flags & SPAWN_HAS_UMASK ? &mig_umask : NULL, - flags & SPAWN_WANTS_WAIT4DEBUGGER); + jr = job_import2(input_obj); if (jr == NULL) switch (errno) { case EEXIST: @@ -5712,9 +5712,17 @@ return BOOTSTRAP_NO_MEMORY; } - memcpy(jr->j_binpref, bin_pref, sizeof(jr->j_binpref)); - jr->j_binpref_cnt = binpref_cnt; + job_reparent_hack(jr, NULL); + if (getpid() == 1) { + jr->mach_uid = ldc.uid; + } + + jr->unload_at_exit = true; + jr->wait4pipe_eof = true; + jr->stall_before_exec = jr->wait4debugger; + jr->wait4debugger = false; + jr = job_dispatch(jr, true); if (!job_assumes(j, jr != NULL)) { @@ -5726,12 +5734,12 @@ return BOOTSTRAP_NO_MEMORY; } - job_log(j, LOG_INFO, "Spawned with flags:%s", flags & SPAWN_WANTS_WAIT4DEBUGGER ? " stopped": ""); + job_log(j, LOG_INFO, "Spawned"); *child_pid = job_get_pid(jr); *obsvr_port = jr->j_port; - mig_deallocate((vm_address_t)charbuf, charbuf_cnt); + mig_deallocate(indata, indataCnt); return BOOTSTRAP_SUCCESS; } Modified: trunk/launchd/src/launchd_mig_types.defs =================================================================== --- trunk/launchd/src/launchd_mig_types.defs 2007-05-24 20:54:19 UTC (rev 23263) +++ trunk/launchd/src/launchd_mig_types.defs 2007-05-25 20:44:01 UTC (rev 23264) @@ -30,13 +30,10 @@ type vproc_gsk_t = integer_t; type logmsg_t = c_string[*:2048]; type cmd_t = c_string[512]; -type cmd_array_t = ^array [] of cmd_t; type name_t = c_string[128]; type name_array_t = ^array [] of name_t; -type _internal_string_t = ^array [] of char; type bootstrap_status_t = integer_t; type bootstrap_status_array_t = ^array [] of bootstrap_status_t; -type binpref_t = array [8] of integer_t; type job_t = mach_port_t intran: job_t job_mig_intran(mach_port_t) Modified: trunk/launchd/src/liblaunch_private.h =================================================================== --- trunk/launchd/src/liblaunch_private.h 2007-05-24 20:54:19 UTC (rev 23263) +++ trunk/launchd/src/liblaunch_private.h 2007-05-25 20:44:01 UTC (rev 23264) @@ -24,6 +24,7 @@ #include <sys/types.h> #include <launch.h> #include <unistd.h> +#include <quarantine.h> #pragma GCC visibility push(default) @@ -45,9 +46,15 @@ #define LAUNCH_KEY_BATCHCONTROL "BatchControl" #define LAUNCH_KEY_BATCHQUERY "BatchQuery" +#define LAUNCH_JOBKEY_QUARANTINEDATA "QuarantineData" +#define LAUNCH_JOBKEY_SANDBOXPROFILE "SandboxProfile" +#define LAUNCH_JOBKEY_SANDBOXFLAGS "SandboxFlags" +#define LAUNCH_JOBKEY_SANDBOX_NAMED "Named" + #define LAUNCH_JOBKEY_ENTERKERNELDEBUGGERBEFOREKILL "EnterKernelDebuggerBeforeKill" #define LAUNCH_JOBKEY_PERJOBMACHSERVICES "PerJobMachServices" #define LAUNCH_JOBKEY_SERVICEIPC "ServiceIPC" +#define LAUNCH_JOBKEY_BINARYORDERPREFERENCE "BinaryOrderPreference" #define LAUNCH_JOBKEY_MACH_KUNCSERVER "kUNCServer" #define LAUNCH_JOBKEY_MACH_EXCEPTIONSERVER "ExceptionServer" @@ -106,9 +113,12 @@ mach_port_t * spawn_observer_port; const cpu_type_t * spawn_binpref; size_t spawn_binpref_cnt; + const qtn_proc_t spawn_quarantine; + const char * spawn_seatbelt_profile; + const uint64_t * spawn_seatbelt_flags; }; -#define spawn_via_launchd(a, b, c) _spawn_via_launchd(a, b, c, 1) +#define spawn_via_launchd(a, b, c) _spawn_via_launchd(a, b, c, 2) pid_t _spawn_via_launchd( const char *label, const char *const *argv, Modified: trunk/launchd/src/libvproc.c =================================================================== --- trunk/launchd/src/libvproc.c 2007-05-24 20:54:19 UTC (rev 23263) +++ trunk/launchd/src/libvproc.c 2007-05-25 20:44:01 UTC (rev 23264) @@ -172,75 +172,115 @@ pid_t _spawn_via_launchd(const char *label, const char *const *argv, const struct spawn_via_launchd_attr *spawn_attrs, int struct_version) { - kern_return_t kr; + size_t i, good_enough_size = 10*1024*1024; + mach_msg_type_number_t indata_cnt = 0; + vm_offset_t indata = 0; + mach_port_t obsvr_port = MACH_PORT_NULL; + launch_data_t tmp, tmp_array, in_obj; const char *const *tmpp; - size_t len, buf_len = strlen(label) + 1; - char *buf = strdup(label); - uint64_t flags = 0; - uint32_t argc = 0; - uint32_t envc = 0; - binpref_t bin_pref; - size_t binpref_cnt = 0, binpref_max = sizeof(bin_pref) / sizeof(bin_pref[0]); + kern_return_t kr = 1; + void *buf = NULL; pid_t p = -1; - mode_t u_mask = CMASK; - mach_port_t obsvr_port = MACH_PORT_NULL; - memset(&bin_pref, 0, sizeof(bin_pref)); + if ((in_obj = launch_data_alloc(LAUNCH_DATA_DICTIONARY)) == NULL) { + goto out; + } - for (tmpp = argv; *tmpp; tmpp++) { - argc++; - len = strlen(*tmpp) + 1; - buf = reallocf(buf, buf_len + len); - strcpy(buf + buf_len, *tmpp); - buf_len += len; + if ((tmp = launch_data_new_string(label)) == NULL) { + goto out; } + launch_data_dict_insert(in_obj, tmp, LAUNCH_JOBKEY_LABEL); + + if ((tmp_array = launch_data_alloc(LAUNCH_DATA_ARRAY)) == NULL) { + goto out; + } + + for (i = 0; *argv; i++, argv++) { + tmp = launch_data_new_string(*argv); + if (tmp == NULL) { + goto out; + } + + launch_data_array_set_index(tmp_array, tmp, i); + } + + launch_data_dict_insert(in_obj, tmp_array, LAUNCH_JOBKEY_PROGRAMARGUMENTS); + if (spawn_attrs) switch (struct_version) { + case 2: + if (spawn_attrs->spawn_quarantine) { + char qbuf[QTN_SERIALIZED_DATA_MAX]; + size_t qbuf_sz = QTN_SERIALIZED_DATA_MAX; + + if (qtn_proc_to_data(spawn_attrs->spawn_quarantine, qbuf, &qbuf_sz) == 0) { + tmp = launch_data_new_opaque(qbuf, qbuf_sz); + launch_data_dict_insert(in_obj, tmp, LAUNCH_JOBKEY_QUARANTINEDATA); + } + } + + if (spawn_attrs->spawn_seatbelt_profile) { + tmp = launch_data_new_string(spawn_attrs->spawn_seatbelt_profile); + launch_data_dict_insert(in_obj, tmp, LAUNCH_JOBKEY_SANDBOXPROFILE); + } + + if (spawn_attrs->spawn_seatbelt_flags) { + tmp = launch_data_new_integer(*spawn_attrs->spawn_seatbelt_flags); + launch_data_dict_insert(in_obj, tmp, LAUNCH_JOBKEY_SANDBOXFLAGS); + } + + /* fall through */ case 1: if (spawn_attrs->spawn_binpref) { - if (spawn_attrs->spawn_binpref_cnt < binpref_max) { - binpref_max = spawn_attrs->spawn_binpref_cnt; + tmp_array = launch_data_alloc(LAUNCH_DATA_ARRAY); + for (i = 0; i < spawn_attrs->spawn_binpref_cnt; i++) { + tmp = launch_data_new_integer(spawn_attrs->spawn_binpref[i]); + launch_data_array_set_index(tmp_array, tmp, i); } - - for (; binpref_cnt < binpref_max; binpref_cnt++) { - bin_pref[binpref_cnt] = spawn_attrs->spawn_binpref[binpref_cnt]; - } + launch_data_dict_insert(in_obj, tmp_array, LAUNCH_JOBKEY_BINARYORDERPREFERENCE); } - + /* fall through */ case 0: if (spawn_attrs->spawn_flags & SPAWN_VIA_LAUNCHD_STOPPED) { - flags |= SPAWN_WANTS_WAIT4DEBUGGER; + tmp = launch_data_new_bool(true); + launch_data_dict_insert(in_obj, tmp, LAUNCH_JOBKEY_WAITFORDEBUGGER); } if (spawn_attrs->spawn_env) { + launch_data_t tmp_dict = launch_data_alloc(LAUNCH_DATA_DICTIONARY); + for (tmpp = spawn_attrs->spawn_env; *tmpp; tmpp++) { - envc++; - len = strlen(*tmpp) + 1; - buf = reallocf(buf, buf_len + len); - strcpy(buf + buf_len, *tmpp); - buf_len += len; + char *eqoff, tmpstr[strlen(*tmpp) + 1]; + + strcpy(tmpstr, *tmpp); + + eqoff = strchr(tmpstr, '='); + + if (!eqoff) { + goto out; + } + + *eqoff = '\0'; + + launch_data_dict_insert(tmp_dict, launch_data_new_string(eqoff + 1), tmpstr); } + + launch_data_dict_insert(in_obj, tmp_dict, LAUNCH_JOBKEY_ENVIRONMENTVARIABLES); } if (spawn_attrs->spawn_path) { - flags |= SPAWN_HAS_PATH; - len = strlen(spawn_attrs->spawn_path) + 1; - buf = reallocf(buf, buf_len + len); - strcpy(buf + buf_len, spawn_attrs->spawn_path); - buf_len += len; + tmp = launch_data_new_string(spawn_attrs->spawn_path); + launch_data_dict_insert(in_obj, tmp, LAUNCH_JOBKEY_PROGRAM); } if (spawn_attrs->spawn_chdir) { - flags |= SPAWN_HAS_WDIR; - len = strlen(spawn_attrs->spawn_chdir) + 1; - buf = reallocf(buf, buf_len + len); - strcpy(buf + buf_len, spawn_attrs->spawn_chdir); - buf_len += len; + tmp = launch_data_new_string(spawn_attrs->spawn_chdir); + launch_data_dict_insert(in_obj, tmp, LAUNCH_JOBKEY_WORKINGDIRECTORY); } if (spawn_attrs->spawn_umask) { - flags |= SPAWN_HAS_UMASK; - u_mask = *spawn_attrs->spawn_umask; + tmp = launch_data_new_integer(*spawn_attrs->spawn_umask); + launch_data_dict_insert(in_obj, tmp, LAUNCH_JOBKEY_UMASK); } break; @@ -248,29 +288,44 @@ break; } - kr = vproc_mig_spawn(bootstrap_port, buf, buf_len, argc, envc, flags, u_mask, bin_pref, binpref_cnt, &p, &obsvr_port); + if (!(buf = malloc(good_enough_size))) { + goto out; + } + if ((indata_cnt = launch_data_pack(in_obj, buf, good_enough_size, NULL, NULL)) == 0) { + goto out; + } + + indata = (vm_offset_t)buf; + + kr = vproc_mig_spawn(bootstrap_port, indata, indata_cnt, &p, &obsvr_port); + if (kr == VPROC_ERR_TRY_PER_USER) { mach_port_t puc; if (vproc_mig_lookup_per_user_context(bootstrap_port, 0, &puc) == 0) { - kr = vproc_mig_spawn(puc, buf, buf_len, argc, envc, flags, u_mask, bin_pref, binpref_cnt, &p, &obsvr_port); + kr = vproc_mig_spawn(puc, indata, indata_cnt, &p, &obsvr_port); mach_port_deallocate(mach_task_self(), puc); } } - free(buf); +out: + if (in_obj) { + launch_data_free(in_obj); + } - if (kr == BOOTSTRAP_SUCCESS) { + if (buf) { + free(buf); + } + + switch (kr) { + case BOOTSTRAP_SUCCESS: if (spawn_attrs && spawn_attrs->spawn_observer_port) { *spawn_attrs->spawn_observer_port = obsvr_port; } else { mach_port_deallocate(mach_task_self(), obsvr_port); } return p; - } - - switch (kr) { case BOOTSTRAP_NOT_PRIVILEGED: errno = EPERM; break; case BOOTSTRAP_NO_MEMORY: @@ -278,6 +333,7 @@ default: errno = EINVAL; break; } + return -1; } Modified: trunk/launchd/src/libvproc_internal.h =================================================================== --- trunk/launchd/src/libvproc_internal.h 2007-05-24 20:54:19 UTC (rev 23263) +++ trunk/launchd/src/libvproc_internal.h 2007-05-25 20:44:01 UTC (rev 23264) @@ -29,7 +29,6 @@ typedef char * logmsg_t; typedef pid_t * pid_array_t; typedef mach_port_t vproc_mig_t; -typedef integer_t binpref_t[8]; #ifdef protocol_vproc_MSG_COUNT /* HACK */ Modified: trunk/launchd/src/protocol_job.defs =================================================================== --- trunk/launchd/src/protocol_job.defs 2007-05-24 20:54:19 UTC (rev 23263) +++ trunk/launchd/src/protocol_job.defs 2007-05-25 20:44:01 UTC (rev 23264) @@ -109,13 +109,7 @@ routine spawn( __bs_port : job_t; - __chars : _internal_string_t; - __argc : uint32_t; - __envc : uint32_t; - __flags : uint64_t; - __umask : uint16_t; - __binpref : binpref_t; - __binpref_cnt : uint32_t; + __indata : pointer_t; out __pid : pid_t; out __obsvr_port : mach_port_make_send_t);
participants (1)
-
source_changes@macosforge.org