[launchd-changes] [23234] trunk/launchd
source_changes at macosforge.org
source_changes at macosforge.org
Wed Apr 25 16:40:49 PDT 2007
Revision: 23234
http://trac.macosforge.org/projects/launchd/changeset/23234
Author: zarzycki at apple.com
Date: 2007-04-25 16:40:49 -0700 (Wed, 25 Apr 2007)
Log Message:
-----------
<rdar://problem/5063706> _vprocmgr_move_subset_to_user should set environment variables
This is the beginning of the end for launch_msg() being implemented via Unix
sockets (they're good for networking, but clumbsy for local IPC).
Modified Paths:
--------------
trunk/launchd/src/launchd_core_logic.c
trunk/launchd/src/liblaunch.c
trunk/launchd/src/libvproc.c
trunk/launchd/src/libvproc_private.h
trunk/launchd/src/protocol_job.defs
Added Paths:
-----------
trunk/launchd/src/liblaunch_internal.h
trunk/launchd/testing/vproc_swap_complex.c
Modified: trunk/launchd/src/launchd_core_logic.c
===================================================================
--- trunk/launchd/src/launchd_core_logic.c 2007-04-24 19:48:38 UTC (rev 23233)
+++ trunk/launchd/src/launchd_core_logic.c 2007-04-25 23:40:49 UTC (rev 23234)
@@ -75,6 +75,7 @@
#include "liblaunch_public.h"
#include "liblaunch_private.h"
+#include "liblaunch_internal.h"
#include "libbootstrap_public.h"
#include "libbootstrap_private.h"
#include "libvproc_public.h"
@@ -262,6 +263,7 @@
static void job_export_all2(jobmgr_t jm, launch_data_t where);
static void jobmgr_callback(void *obj, struct kevent *kev);
static void jobmgr_setup_env_from_other_jobs(jobmgr_t jm);
+static void jobmgr_export_env_from_other_jobs(jobmgr_t jm, launch_data_t dict);
static struct machservice *jobmgr_lookup_service(jobmgr_t jm, const char *name, bool check_parent, pid_t target_pid);
static void jobmgr_logv(jobmgr_t jm, int pri, int err, const char *msg, va_list ap) __attribute__((format(printf, 4, 0)));
static void jobmgr_log(jobmgr_t jm, int pri, const char *msg, ...) __attribute__((format(printf, 3, 4)));
@@ -2326,12 +2328,43 @@
_exit(EXIT_FAILURE);
}
-void jobmgr_setup_env_from_other_jobs(jobmgr_t jm)
+void
+jobmgr_export_env_from_other_jobs(jobmgr_t jm, launch_data_t dict)
{
+ launch_data_t tmp;
struct envitem *ei;
job_t ji;
if (jm->parentmgr) {
+ jobmgr_export_env_from_other_jobs(jm->parentmgr, dict);
+ } else {
+ char **tmpenviron = environ;
+ for (; *tmpenviron; tmpenviron++) {
+ char envkey[1024];
+ launch_data_t s = launch_data_alloc(LAUNCH_DATA_STRING);
+ launch_data_set_string(s, strchr(*tmpenviron, '=') + 1);
+ strncpy(envkey, *tmpenviron, sizeof(envkey));
+ *(strchr(envkey, '=')) = '\0';
+ launch_data_dict_insert(dict, s, envkey);
+ }
+ }
+
+ LIST_FOREACH(ji, &jm->jobs, sle) {
+ SLIST_FOREACH(ei, &ji->global_env, sle) {
+ if ((tmp = launch_data_new_string(ei->value))) {
+ launch_data_dict_insert(dict, tmp, ei->key);
+ }
+ }
+ }
+}
+
+void
+jobmgr_setup_env_from_other_jobs(jobmgr_t jm)
+{
+ struct envitem *ei;
+ job_t ji;
+
+ if (jm->parentmgr) {
jobmgr_setup_env_from_other_jobs(jm->parentmgr);
}
@@ -4500,6 +4533,76 @@
}
kern_return_t
+job_mig_swap_complex(job_t j, vproc_gsk_t inkey, vproc_gsk_t outkey,
+ vm_offset_t inval, mach_msg_type_number_t invalCnt,
+ vm_offset_t *outval, mach_msg_type_number_t *outvalCnt)
+{
+ const char *action;
+ launch_data_t input_obj, output_obj;
+ size_t data_offset = 0;
+
+ *outvalCnt = 10 * 1024 * 1024;
+
+ if (!launchd_assumes(j != NULL)) {
+ return BOOTSTRAP_NO_MEMORY;
+ }
+
+ if (inkey && outkey && !job_assumes(j, inkey == outkey)) {
+ return 1;
+ }
+
+ if (inkey && outkey) {
+ action = "Swapping";
+ } else if (inkey) {
+ action = "Setting";
+ } else {
+ action = "Getting";
+ }
+
+ job_log(j, LOG_DEBUG, "%s key: %u", action, inkey ? inkey : outkey);
+
+ if (invalCnt && !job_assumes(j, (input_obj = launch_data_unpack((void *)inval, invalCnt, NULL, 0, &data_offset, NULL)) != NULL)) {
+ return 1;
+ }
+
+ switch (outkey) {
+ case VPROC_GSK_ENVIRONMENT:
+ mig_allocate(outval, *outvalCnt);
+ if (!job_assumes(j, *outval != 0)) {
+ return 1;
+ }
+ if (job_assumes(j, (output_obj = launch_data_alloc(LAUNCH_DATA_DICTIONARY)))) {
+ jobmgr_export_env_from_other_jobs(j->mgr, output_obj);
+ }
+ if (!job_assumes(j, launch_data_pack(output_obj, (void *)*outval, *outvalCnt, NULL, NULL) != 0)) {
+ mig_deallocate(*outval, *outvalCnt);
+ return 1;
+ }
+ break;
+ case 0:
+ *outval = 0;
+ *outvalCnt = 0;
+ break;
+ default:
+ return 1;
+ }
+
+ if (invalCnt) switch (inkey) {
+ case VPROC_GSK_ENVIRONMENT:
+ job_assumes(j, false);
+ break;
+ case 0:
+ break;
+ default:
+ return 1;
+ }
+
+ mig_deallocate(inval, invalCnt);
+
+ return 0;
+}
+
+kern_return_t
job_mig_swap_integer(job_t j, vproc_gsk_t inkey, vproc_gsk_t outkey, int64_t inval, int64_t *outval)
{
const char *action;
@@ -4584,10 +4687,6 @@
break;
case 0:
break;
- case VPROC_GSK_IS_MANAGED:
- case VPROC_GSK_LAST_EXIT_STATUS:
- case VPROC_GSK_MGR_UID:
- case VPROC_GSK_MGR_PID:
default:
kr = 1;
break;
Modified: trunk/launchd/src/liblaunch.c
===================================================================
--- trunk/launchd/src/liblaunch.c 2007-04-24 19:48:38 UTC (rev 23233)
+++ trunk/launchd/src/liblaunch.c 2007-04-25 23:40:49 UTC (rev 23234)
@@ -21,6 +21,7 @@
#include "config.h"
#include "liblaunch_public.h"
#include "liblaunch_private.h"
+#include "liblaunch_internal.h"
#include <mach/mach.h>
#include <libkern/OSByteOrder.h>
@@ -139,8 +140,6 @@
int fd;
};
-static size_t launch_data_pack(launch_data_t d, void *where, size_t len, int *fd_where, size_t *fdslotsleft);
-static launch_data_t launch_data_unpack(void *data, size_t data_size, int *fds, size_t fd_cnt, size_t *data_offset, size_t *fdoffset);
static launch_data_t launch_data_array_pop_first(launch_data_t where);
static int _fd(int fd);
static void launch_client_init(void);
Added: trunk/launchd/src/liblaunch_internal.h
===================================================================
--- trunk/launchd/src/liblaunch_internal.h (rev 0)
+++ trunk/launchd/src/liblaunch_internal.h 2007-04-25 23:40:49 UTC (rev 23234)
@@ -0,0 +1,30 @@
+#ifndef _LAUNCH_INTERNAL_H_
+#define _LAUNCH_INTERNAL_H_
+/*
+ * Copyright (c) 2007 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_APACHE_LICENSE_HEADER_START@
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @APPLE_APACHE_LICENSE_HEADER_END@
+ */
+
+#pragma GCC visibility push(default)
+
+size_t launch_data_pack(launch_data_t d, void *where, size_t len, int *fd_where, size_t *fdslotsleft);
+launch_data_t launch_data_unpack(void *data, size_t data_size, int *fds, size_t fd_cnt, size_t *data_offset, size_t *fdoffset);
+
+#pragma GCC visibility pop
+
+#endif
Modified: trunk/launchd/src/libvproc.c
===================================================================
--- trunk/launchd/src/libvproc.c 2007-04-24 19:48:38 UTC (rev 23233)
+++ trunk/launchd/src/libvproc.c 2007-04-25 23:40:49 UTC (rev 23234)
@@ -33,6 +33,7 @@
#include "liblaunch_public.h"
#include "liblaunch_private.h"
+#include "liblaunch_internal.h"
#include "protocol_vproc.h"
@@ -57,9 +58,16 @@
return vproc_mig_post_fork_ping(bootstrap_port, mach_task_self()) == 0 ? NULL : _vproc_post_fork_ping;
}
+static void
+setup_env_hack(const launch_data_t obj, const char *key, void *context __attribute__((unused)))
+{
+ setenv(key, launch_data_get_string(obj), 1);
+}
+
vproc_err_t
_vprocmgr_move_subset_to_user(uid_t target_user, char *session_type)
{
+ launch_data_t output_obj;
kern_return_t kr = 1;
mach_port_t puc = 0, which_port = bootstrap_port;
bool is_bkgd = (strcmp(session_type, VPROCMGR_SESSION_BACKGROUND) == 0);
@@ -84,7 +92,18 @@
cached_pid = -1;
- return kr == 0 ? NULL : (vproc_err_t)_vprocmgr_move_subset_to_user;
+ if (kr) {
+ return (vproc_err_t)_vprocmgr_move_subset_to_user;
+ }
+
+ if (vproc_swap_complex(NULL, VPROC_GSK_ENVIRONMENT, NULL, &output_obj) == NULL) {
+ if (launch_data_get_type(output_obj) == LAUNCH_DATA_DICTIONARY) {
+ launch_data_dict_iterate(output_obj, setup_env_hack, NULL);
+ launch_data_free(output_obj);
+ }
+ }
+
+ return NULL;
}
@@ -304,6 +323,55 @@
return parent_port;
}
+vproc_err_t
+vproc_swap_complex(vproc_t vp __attribute__((unused)), vproc_gsk_t key, launch_data_t inval, launch_data_t *outval)
+{
+ size_t data_offset = 0, good_enough_size = 10*1024*1024;
+ mach_msg_type_number_t indata_cnt = 0, outdata_cnt;
+ vm_offset_t indata = 0, outdata = 0;
+ launch_data_t out_obj;
+ void *rval = vproc_swap_complex;
+ void *buf = NULL;
+
+ if (inval) {
+ if (!(buf = malloc(good_enough_size))) {
+ goto out;
+ }
+
+ if ((indata_cnt = launch_data_pack(inval, buf, good_enough_size, NULL, NULL)) == 0) {
+ goto out;
+ }
+
+ indata = (vm_offset_t)buf;
+ }
+
+ if (vproc_mig_swap_complex(bootstrap_port, inval ? key : 0, outval ? key : 0, indata, indata_cnt, &outdata, &outdata_cnt) != 0) {
+ goto out;
+ }
+
+ if (outval) {
+ if (!(out_obj = launch_data_unpack((void *)outdata, outdata_cnt, NULL, 0, &data_offset, NULL))) {
+ goto out;
+ }
+
+ if (!(*outval = launch_data_copy(out_obj))) {
+ goto out;
+ }
+ }
+
+ rval = NULL;
+out:
+ if (buf) {
+ free(buf);
+ }
+
+ if (outdata) {
+ mig_deallocate(outdata, outdata_cnt);
+ }
+
+ return rval;
+}
+
void *
reboot2(uint64_t flags)
{
Modified: trunk/launchd/src/libvproc_private.h
===================================================================
--- trunk/launchd/src/libvproc_private.h 2007-04-24 19:48:38 UTC (rev 23233)
+++ trunk/launchd/src/libvproc_private.h 2007-04-25 23:40:49 UTC (rev 23234)
@@ -24,6 +24,7 @@
#include <sys/cdefs.h>
#include <sys/syslog.h>
#include <stdbool.h>
+#include <launch.h>
__BEGIN_DECLS
@@ -39,9 +40,11 @@
VPROC_GSK_START_INTERVAL,
VPROC_GSK_IDLE_TIMEOUT,
VPROC_GSK_EXIT_TIMEOUT,
+ VPROC_GSK_ENVIRONMENT,
} vproc_gsk_t;
vproc_err_t vproc_swap_integer(vproc_t vp, vproc_gsk_t key, int64_t *inval, int64_t *outval);
+vproc_err_t vproc_swap_complex(vproc_t vp, vproc_gsk_t key, launch_data_t inval, launch_data_t *outval);
vproc_err_t _vproc_get_last_exit_status(int *wstatus);
vproc_err_t _vproc_set_global_on_demand(bool val);
Modified: trunk/launchd/src/protocol_job.defs
===================================================================
--- trunk/launchd/src/protocol_job.defs 2007-04-24 19:48:38 UTC (rev 23233)
+++ trunk/launchd/src/protocol_job.defs 2007-04-25 23:40:49 UTC (rev 23234)
@@ -156,3 +156,10 @@
__bs_port : job_t;
__target_port : mach_port_t;
__sessiontype : name_t);
+
+routine swap_complex(
+ __bs_port : job_t;
+ __inkey : vproc_gsk_t;
+ __outkey : vproc_gsk_t;
+ __inval : pointer_t;
+ out __outval : pointer_t, dealloc);
Added: trunk/launchd/testing/vproc_swap_complex.c
===================================================================
--- trunk/launchd/testing/vproc_swap_complex.c (rev 0)
+++ trunk/launchd/testing/vproc_swap_complex.c 2007-04-25 23:40:49 UTC (rev 23234)
@@ -0,0 +1,28 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <assert.h>
+#include <vproc.h>
+#include <vproc_priv.h>
+
+static void my_callback(const launch_data_t obj, const char *key, void *context);
+
+int main(void)
+{
+ launch_data_t output_obj = NULL;
+
+ assert(vproc_swap_complex(NULL, VPROC_GSK_ENVIRONMENT, NULL, &output_obj) == 0);
+
+ assert(launch_data_get_type(output_obj) == LAUNCH_DATA_DICTIONARY);
+
+ launch_data_dict_iterate(output_obj, my_callback, stdout);
+
+ return 0;
+}
+
+void
+my_callback(const launch_data_t obj, const char *key, void *context)
+{
+ fprintf(context, "%s == %s\n", key, launch_data_get_string(obj));
+}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/launchd-changes/attachments/20070425/43e7c758/attachment.html
More information about the launchd-changes
mailing list