[launchd-changes] [23264] trunk/launchd/src
source_changes at macosforge.org
source_changes at macosforge.org
Fri May 25 13:44:01 PDT 2007
Revision: 23264
http://trac.macosforge.org/projects/launchd/changeset/23264
Author: zarzycki at 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);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/launchd-changes/attachments/20070525/6d26629f/attachment.html
More information about the launchd-changes
mailing list