[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