[launchd-changes] [23574] trunk/launchd/src

source_changes at macosforge.org source_changes at macosforge.org
Thu Mar 27 14:18:34 PDT 2008


Revision: 23574
          http://trac.macosforge.org/projects/launchd/changeset/23574
Author:   zarzycki at apple.com
Date:     2008-03-27 14:18:33 -0700 (Thu, 27 Mar 2008)

Log Message:
-----------
<rdar://problem/5752398> Need a darwin clean/dirty API

Modified Paths:
--------------
    trunk/launchd/src/Makefile.am
    trunk/launchd/src/Makefile.in
    trunk/launchd/src/launchd.plist.5
    trunk/launchd/src/launchd_core_logic.c
    trunk/launchd/src/liblaunch_public.h
    trunk/launchd/src/libvproc.c
    trunk/launchd/src/libvproc_internal.h
    trunk/launchd/src/libvproc_private.h
    trunk/launchd/src/libvproc_public.h
    trunk/launchd/src/protocol_job.defs

Modified: trunk/launchd/src/Makefile.am
===================================================================
--- trunk/launchd/src/Makefile.am	2008-03-27 01:40:55 UTC (rev 23573)
+++ trunk/launchd/src/Makefile.am	2008-03-27 21:18:33 UTC (rev 23574)
@@ -1,5 +1,5 @@
 CWARN = -Wall -Wextra -Waggregate-return -Wfloat-equal -Wshadow -Wpacked -Wmissing-prototypes -Wmissing-declarations -Werror # gcc4.2: -Wstrict-overflow=4 # -Wpadded -Wconversion -Wstrict-aliasing=2
-CTUNE = -fvisibility=hidden # gcc4.2: -fdiagnostics-show-option # -fstrict-aliasing
+CTUNE = -fvisibility=hidden -freorder-blocks # gcc4.2: -fdiagnostics-show-option # -fstrict-aliasing
 CMISC = -isysroot $(SDKROOT) -F$(SDKROOT)/System/Library/PrivateFrameworks -D__MigTypeCheck=1 -Dmig_external=__private_extern__ -D_DARWIN_USE_64_BIT_INODE=1
 AM_CFLAGS = $(CTUNE) $(CMISC) $(CWARN)
 AM_LDFLAGS = -Wl,-syslibroot,$(SDKROOT)
@@ -57,7 +57,7 @@
 SystemStarter_SOURCES = StartupItems.c IPC.c SystemStarter.c
 endif
 
-launchd_CFLAGS = -mdynamic-no-pic $(AM_CFLAGS) -freorder-blocks
+launchd_CFLAGS = -mdynamic-no-pic $(AM_CFLAGS)
 launchd_LDFLAGS = $(AM_LDFLAGS) -lbsm
 launchd_SOURCES = launchd.c launchd_core_logic.c launchd_unix_ipc.c protocol_vprocServer.c notifyServer.c launchd_internalUser.c launchd_internalServer.c job_replyUser.c launchd_runtime.c launchd_runtime_kill.c job_forwardUser.c mach_excServer.c
 

Modified: trunk/launchd/src/Makefile.in
===================================================================
--- trunk/launchd/src/Makefile.in	2008-03-27 01:40:55 UTC (rev 23573)
+++ trunk/launchd/src/Makefile.in	2008-03-27 21:18:33 UTC (rev 23574)
@@ -243,7 +243,7 @@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 CWARN = -Wall -Wextra -Waggregate-return -Wfloat-equal -Wshadow -Wpacked -Wmissing-prototypes -Wmissing-declarations -Werror # gcc4.2: -Wstrict-overflow=4 # -Wpadded -Wconversion -Wstrict-aliasing=2
-CTUNE = -fvisibility=hidden # gcc4.2: -fdiagnostics-show-option # -fstrict-aliasing
+CTUNE = -fvisibility=hidden -freorder-blocks # gcc4.2: -fdiagnostics-show-option # -fstrict-aliasing
 CMISC = -isysroot $(SDKROOT) -F$(SDKROOT)/System/Library/PrivateFrameworks -D__MigTypeCheck=1 -Dmig_external=__private_extern__ -D_DARWIN_USE_64_BIT_INODE=1
 AM_CFLAGS = $(CTUNE) $(CMISC) $(CWARN)
 AM_LDFLAGS = -Wl,-syslibroot,$(SDKROOT)
@@ -262,7 +262,7 @@
 @DO_EMBEDDED_MAGIC_FALSE@@LIBS_ONLY_FALSE at SystemStarter_CFLAGS = -mdynamic-no-pic $(AM_CFLAGS)
 @DO_EMBEDDED_MAGIC_FALSE@@LIBS_ONLY_FALSE at SystemStarter_LDFLAGS = $(AM_LDFLAGS) -framework CoreFoundation -framework IOKit
 @DO_EMBEDDED_MAGIC_FALSE@@LIBS_ONLY_FALSE at SystemStarter_SOURCES = StartupItems.c IPC.c SystemStarter.c
- at LIBS_ONLY_FALSE@launchd_CFLAGS = -mdynamic-no-pic $(AM_CFLAGS) -freorder-blocks
+ at LIBS_ONLY_FALSE@launchd_CFLAGS = -mdynamic-no-pic $(AM_CFLAGS)
 @LIBS_ONLY_FALSE at launchd_LDFLAGS = $(AM_LDFLAGS) -lbsm
 @LIBS_ONLY_FALSE at launchd_SOURCES = launchd.c launchd_core_logic.c launchd_unix_ipc.c protocol_vprocServer.c notifyServer.c launchd_internalUser.c launchd_internalServer.c job_replyUser.c launchd_runtime.c launchd_runtime_kill.c job_forwardUser.c mach_excServer.c
 @LIBS_ONLY_FALSE at launchproxy_LDFLAGS = $(AM_LDFLAGS) $(LIBS_SECURITY)

Modified: trunk/launchd/src/launchd.plist.5
===================================================================
--- trunk/launchd/src/launchd.plist.5	2008-03-27 01:40:55 UTC (rev 23573)
+++ trunk/launchd/src/launchd.plist.5	2008-03-27 21:18:33 UTC (rev 23574)
@@ -123,6 +123,16 @@
 to use the
 .Xr glob 3
 mechanism to update the program arguments before invocation.
+.It Sy EnableTransactions <boolean>
+This flag instructs
+.Nm launchd
+that the job promises to use
+.Xr vproc_transaction_begin 3
+and
+.Xr vproc_transaction_end 3
+to track outstanding transactions that need to be reconciled before the process can safely terminate. If no outstanding transactions are in progress, then
+.Nm launchd
+is free to send the SIGKILL signal.
 .It Sy OnDemand <boolean>
 This key was used in Mac OS X 10.4 to control whether a job was kept alive or not. The default was true.
 This key has been deprecated and replaced in Mac OS X 10.5 with the more powerful KeepAlive option.

Modified: trunk/launchd/src/launchd_core_logic.c
===================================================================
--- trunk/launchd/src/launchd_core_logic.c	2008-03-27 01:40:55 UTC (rev 23573)
+++ trunk/launchd/src/launchd_core_logic.c	2008-03-27 21:18:33 UTC (rev 23574)
@@ -50,6 +50,7 @@
 #include <sys/ioctl.h>
 #include <sys/mount.h>
 #include <sys/pipe.h>
+#include <sys/mman.h>
 #include <net/if.h>
 #include <netinet/in.h>
 #include <netinet/in_var.h>
@@ -360,6 +361,7 @@
 	char *stdoutpath;
 	char *stderrpath;
 	char *alt_exc_handler;
+	struct vproc_shmem_s *shmem;
 	struct machservice *lastlookup;
 	unsigned int lastlookup_gennum;
 #if HAVE_SANDBOX
@@ -384,14 +386,14 @@
 	uint64_t start_time;
 	uint32_t min_run_time;
 	uint32_t start_interval;
-	unsigned short checkedin:1, anonymous:1, debug:1, inetcompat:1, inetcompat_wait:1,
+	bool checkedin:1, anonymous:1, debug:1, inetcompat:1, inetcompat_wait:1,
 		     ondemand:1, session_create:1, low_pri_io:1, no_init_groups:1, priv_port_has_senders:1,
 		     importing_global_env:1, importing_hard_limits:1, setmask:1, legacy_mach_job:1, start_pending:1,
 		     globargv:1, wait4debugger:1, internal_exc_handler:1, stall_before_exec:1, only_once:1,
 		     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, deny_job_creation:1, __junk:11;
+		     poll_for_vfs_changes:1, deny_job_creation:1, kill_via_shmem:1, sent_kill_via_shmem:1;
 	mode_t mask;
 	const char label[0];
 };
@@ -561,19 +563,40 @@
 INTERNAL_ABI void
 job_stop(job_t j)
 {
+	int32_t newval = 1;
+
 	if (unlikely(!j->p || j->anonymous)) {
 		return;
 	}
 
-	job_assumes(j, runtime_kill(j->p, SIGTERM) != -1);
+	if (j->kill_via_shmem) {
+		if (j->shmem) {
+			if (!j->sent_kill_via_shmem) {
+				j->shmem->vp_shmem_flags |= VPROC_SHMEM_EXITING;
+				newval = __sync_sub_and_fetch(&j->shmem->vp_shmem_transaction_cnt, 1);
+				j->sent_kill_via_shmem = true;
+			} else {
+				newval = j->shmem->vp_shmem_transaction_cnt;
+			}
+		} else {
+			newval = -1;
+		}
+	}
+
 	j->sent_sigterm_time = runtime_get_opaque_time();
 
-	if (j->exit_timeout) {
-		job_assumes(j, kevent_mod((uintptr_t)&j->exit_timeout, EVFILT_TIMER,
-					EV_ADD|EV_ONESHOT, NOTE_SECONDS, j->exit_timeout, j) != -1);
+	if (newval < 0) {
+		job_kill(j);
+	} else {
+		job_assumes(j, runtime_kill(j->p, SIGTERM) != -1);
+
+		if (j->exit_timeout) {
+			job_assumes(j, kevent_mod((uintptr_t)&j->exit_timeout, EVFILT_TIMER,
+						EV_ADD|EV_ONESHOT, NOTE_SECONDS, j->exit_timeout, j) != -1);
+		}
+
+		job_log(j, LOG_DEBUG, "Sent SIGTERM signal");
 	}
-
-	job_log(j, LOG_DEBUG, "Sent SIGTERM signal");
 }
 
 INTERNAL_ABI launch_data_t
@@ -1453,6 +1476,9 @@
 		if (strcasecmp(key, LAUNCH_JOBKEY_ENABLEGLOBBING) == 0) {
 			j->globargv = value;
 			found_key = true;
+		} else if (strcasecmp(key, LAUNCH_JOBKEY_ENABLETRANSACTIONS) == 0) {
+			j->kill_via_shmem = value;
+			found_key = true;
 		} else if (strcasecmp(key, LAUNCH_JOBKEY_ENTERKERNELDEBUGGERBEFOREKILL) == 0) {
 			j->debug_before_kill = value;
 			found_key = true;
@@ -2203,6 +2229,10 @@
 
 	job_log(j, LOG_DEBUG, "Reaping");
 
+	if (j->shmem) {
+		job_assumes(j, munmap(j->shmem, getpagesize()) == 0);
+	}
+
 	if (unlikely(j->weird_bootstrap)) {
 		mach_msg_size_t mxmsgsz = sizeof(union __RequestUnion__job_mig_protocol_vproc_subsystem);
 
@@ -2335,6 +2365,7 @@
 	}
 	j->last_exit_status = status;
 	j->sent_sigkill = false;
+	j->sent_kill_via_shmem = false;
 	j->p = 0;
 
 	/*
@@ -5402,6 +5433,36 @@
 }
 
 kern_return_t
+job_mig_setup_shmem(job_t j, mach_port_t *shmem_port)
+{
+	memory_object_size_t size_of_page, size_of_page_orig;
+	kern_return_t kr;
+
+	if (!launchd_assumes(j != NULL)) {
+		return BOOTSTRAP_NO_MEMORY;
+	}
+
+	if (unlikely(j->anonymous)) {
+		return BOOTSTRAP_NOT_PRIVILEGED;
+	}
+
+	size_of_page_orig = size_of_page = getpagesize();
+
+	if (!job_assumes(j, j->shmem = mmap(NULL, size_of_page, PROT_READ|PROT_WRITE, MAP_ANON, -1, 0))) {
+		return BOOTSTRAP_NO_MEMORY;
+	}
+
+	kr = mach_make_memory_entry_64(mach_task_self(), &size_of_page,
+			(memory_object_offset_t)((long)j->shmem), VM_PROT_DEFAULT, shmem_port, 0);
+
+	if (job_assumes(j, kr == 0)) {
+		job_assumes(j, size_of_page == size_of_page_orig);
+	}
+
+	return kr;
+}
+
+kern_return_t
 job_mig_create_server(job_t j, cmd_t server_cmd, uid_t server_uid, boolean_t on_demand, mach_port_t *server_portp)
 {
 	struct ldcred *ldc = runtime_get_caller_creds();

Modified: trunk/launchd/src/liblaunch_public.h
===================================================================
--- trunk/launchd/src/liblaunch_public.h	2008-03-27 01:40:55 UTC (rev 23573)
+++ trunk/launchd/src/liblaunch_public.h	2008-03-27 21:18:33 UTC (rev 23574)
@@ -101,6 +101,7 @@
 #define LAUNCH_JOBKEY_LAUNCHONLYONCE		"LaunchOnlyOnce"
 #define LAUNCH_JOBKEY_ABANDONPROCESSGROUP	"AbandonProcessGroup"
 #define LAUNCH_JOBKEY_POLICIES			"Policies"
+#define LAUNCH_JOBKEY_ENABLETRANSACTIONS	"EnableTransactions"
 
 #define LAUNCH_JOBPOLICY_DENYCREATINGOTHERJOBS	"DenyCreatingOtherJobs"
 

Modified: trunk/launchd/src/libvproc.c
===================================================================
--- trunk/launchd/src/libvproc.c	2008-03-27 01:40:55 UTC (rev 23573)
+++ trunk/launchd/src/libvproc.c	2008-03-27 21:18:33 UTC (rev 23574)
@@ -32,6 +32,7 @@
 #include <unistd.h>
 #include <syslog.h>
 #include <pthread.h>
+#include <signal.h>
 #if HAVE_QUARANTINE
 #include <quarantine.h>
 #endif
@@ -44,10 +45,142 @@
 
 #include "reboot2.h"
 
+#define likely(x)	__builtin_expect((bool)(x), true)
+#define unlikely(x)	__builtin_expect((bool)(x), false)
+
 static mach_port_t get_root_bootstrap_port(void);
 
+const char *__crashreporter_info__; /* this should get merged with other versions of the symbol */
+
 static int64_t cached_pid = -1;
+static struct vproc_shmem_s *vproc_shmem;
 
+static void
+vproc_shmem_init(void)
+{
+	vm_address_t vm_addr = 0;
+	mach_port_t shmem_port;
+	kern_return_t kr;
+
+	kr = vproc_mig_setup_shmem(bootstrap_port, &shmem_port);
+
+	if (unlikely(kr)) {
+		abort();
+	}
+
+	kr = vm_map_64(mach_task_self(), &vm_addr, getpagesize(), 0, true, shmem_port, 0, false,
+			VM_PROT_READ|VM_PROT_WRITE, VM_PROT_READ|VM_PROT_WRITE, VM_INHERIT_NONE);
+
+	if (unlikely(kr)) {
+		abort();
+	}
+
+	vproc_shmem = (struct vproc_shmem_s *)vm_addr;
+}
+
+vproc_transaction_t
+vproc_transaction_begin(vproc_t vp __attribute__((unused)))
+{
+	vproc_transaction_t vpt = (vproc_transaction_t)vproc_shmem_init; /* we need a "random" variable that is testable */
+
+	_basic_vproc_transaction_begin();
+
+	return vpt;
+}
+
+void
+_basic_vproc_transaction_begin(void)
+{
+	int64_t newval;
+
+	if (unlikely(vproc_shmem == NULL)) {
+		vproc_shmem_init();
+		if (vproc_shmem == NULL) {
+			return;
+		}
+	}
+
+	newval = __sync_add_and_fetch(&vproc_shmem->vp_shmem_transaction_cnt, 1);
+
+	if (unlikely(newval < 1)) {
+		if (vproc_shmem->vp_shmem_flags & VPROC_SHMEM_EXITING) {
+			raise(SIGKILL);
+			__crashreporter_info__ = "raise(SIGKILL) failed";
+		} else {
+			__crashreporter_info__ = "Unbalanced: vproc_transaction_begin()";
+		}
+		abort();
+	}
+}
+
+void
+vproc_transaction_end(vproc_t vp __attribute__((unused)), vproc_transaction_t vpt)
+{
+	if (unlikely(vpt != (vproc_transaction_t)vproc_shmem_init)) {
+		__crashreporter_info__ = "Bogus transaction handle passed to vproc_transaction_end() ";
+		abort();
+	}
+
+	_basic_vproc_transaction_end();
+}
+
+void
+_basic_vproc_transaction_end(void)
+{
+	int32_t newval = __sync_sub_and_fetch(&vproc_shmem->vp_shmem_transaction_cnt, 1);
+
+	if (unlikely(newval < 0)) {
+		if (vproc_shmem->vp_shmem_flags & VPROC_SHMEM_EXITING) {
+			raise(SIGKILL);
+			__crashreporter_info__ = "raise(SIGKILL) failed";
+		} else {
+			__crashreporter_info__ = "Unbalanced: vproc_transaction_end()";
+		}
+		abort();
+	}
+}
+
+vproc_standby_t
+vproc_standby_begin(vproc_t vp __attribute__((unused)))
+{
+	vproc_standby_t vpsb = (vproc_standby_t)vproc_shmem_init; /* we need a "random" variable that is testable */
+	int64_t newval;
+
+	if (unlikely(vproc_shmem == NULL)) {
+		vproc_shmem_init();
+		if (vproc_shmem == NULL) {
+			return NULL;
+		}
+	}
+
+	newval = __sync_add_and_fetch(&vproc_shmem->vp_shmem_standby_cnt, 1);
+
+	if (unlikely(newval < 1)) {
+		__crashreporter_info__ = "Unbalanced: vproc_standby_begin()";
+		abort();
+	}
+
+	return vpsb;
+}
+
+void
+vproc_standby_end(vproc_t vp __attribute__((unused)), vproc_standby_t vpt)
+{
+	int32_t newval;
+
+	if (unlikely(vpt != (vproc_standby_t)vproc_shmem_init)) {
+		__crashreporter_info__ = "Bogus standby handle passed to vproc_standby_end() ";
+		abort();
+	}
+
+	newval = __sync_sub_and_fetch(&vproc_shmem->vp_shmem_standby_cnt, 1);
+
+	if (unlikely(newval < 0)) {
+		__crashreporter_info__ = "Unbalanced: vproc_standby_end()";
+		abort();
+	}
+}
+
 kern_return_t
 _vproc_grab_subset(mach_port_t bp, mach_port_t *reqport, mach_port_t *rcvright, launch_data_t *outval,
 		mach_port_array_t *ports, mach_msg_type_number_t *portCnt)

Modified: trunk/launchd/src/libvproc_internal.h
===================================================================
--- trunk/launchd/src/libvproc_internal.h	2008-03-27 01:40:55 UTC (rev 23573)
+++ trunk/launchd/src/libvproc_internal.h	2008-03-27 21:18:33 UTC (rev 23574)
@@ -33,6 +33,14 @@
 typedef pid_t * pid_array_t;
 typedef mach_port_t vproc_mig_t;
 
+#define VPROC_SHMEM_EXITING	0x1
+
+struct vproc_shmem_s {
+	int32_t vp_shmem_transaction_cnt;
+	int32_t vp_shmem_standby_cnt;
+	int32_t vp_shmem_flags;
+};
+
 #ifdef protocol_vproc_MSG_COUNT
 /* HACK */
 #include "launchd_core_logic.h"

Modified: trunk/launchd/src/libvproc_private.h
===================================================================
--- trunk/launchd/src/libvproc_private.h	2008-03-27 01:40:55 UTC (rev 23573)
+++ trunk/launchd/src/libvproc_private.h	2008-03-27 21:18:33 UTC (rev 23574)
@@ -76,6 +76,9 @@
 
 vproc_err_t _vprocmgr_move_subset_to_user(uid_t target_user, const char *session_type);
 
+void _basic_vproc_transaction_begin(void);
+void _basic_vproc_transaction_end(void);
+
 #pragma GCC visibility pop
 
 __END_DECLS

Modified: trunk/launchd/src/libvproc_public.h
===================================================================
--- trunk/launchd/src/libvproc_public.h	2008-03-27 01:40:55 UTC (rev 23573)
+++ trunk/launchd/src/libvproc_public.h	2008-03-27 21:18:33 UTC (rev 23574)
@@ -67,8 +67,8 @@
  *
  * launchd jobs should update their property lists accordingly.
  *
- * LaunchServices uses private methods to coordinate whether GUI applications
- * have opted into this design.
+ * We plan to have LaunchServices use private methods to coordinate
+ * whether GUI applications have opted into this design.
  */
 
 /*!
@@ -80,22 +80,28 @@
 typedef struct vproc_transaction_s *vproc_transaction_t;
 
 /*!
- * @function vproc_transaction_prepare
+ * @function vproc_transaction_begin
  *
+ * @param	virtual_proc
+ * This is meant for future API improvements. Pass NULL for now.
+ *
  * @result
- * Returns an opaque handle to be passed to vproc_transaction_complete().
+ * Returns an opaque handle to be passed to vproc_transaction_end().
  *
  * @abstract
  * Call this API before creating data that needs to be saved via I/O later.
  */
 vproc_transaction_t
-vproc_transaction_prepare(void);
+vproc_transaction_begin(vproc_t virtual_proc);
 
 /*!
- * @function vproc_transaction_complete
+ * @function vproc_transaction_end
  *
+ * @param	virtual_proc
+ * This is meant for future API improvements. Pass NULL for now.
+ *
  * @param	handle
- * The handle previously created with vproc_transaction_prepare().
+ * The handle previously created with vproc_transaction_begin().
  *
  * @abstract
  * Call this API after the data has either been flushed or otherwise resolved.
@@ -104,7 +110,7 @@
  * Calling this API with the same handle more than once is undefined.
  */
 void
-vproc_transaction_complete(vproc_transaction_t handle);
+vproc_transaction_end(vproc_t virtual_proc, vproc_transaction_t handle);
 
 /*!
  * @typedef	vproc_standby_t
@@ -115,23 +121,29 @@
 typedef struct vproc_standby_s *vproc_standby_t;
 
 /*!
- * @function vproc_standby_prepare
+ * @function vproc_standby_begin
  *
+ * @param	virtual_proc
+ * This is meant for future API improvements. Pass NULL for now.
+ *
  * @result
- * Returns an opaque handle to be passed to vproc_standby_complete().
+ * Returns an opaque handle to be passed to vproc_standby_end().
  *
  * @abstract
  * Call this API before registering notifications. For example: timers network
  * state change, or when monitoring keyboard/mouse events.
  */
 vproc_standby_t
-vproc_standby_prepare(void);
+vproc_standby_begin(vproc_t virtual_proc);
 
 /*!
- * @function vproc_standby_complete
+ * @function vproc_standby_end
  *
+ * @param	virtual_proc
+ * This is meant for future API improvements. Pass NULL for now.
+ *
  * @param	handle
- * The handle previously created with vproc_standby_prepare().
+ * The handle previously created with vproc_standby_begin().
  *
  * @abstract
  * Call this API when deregistering notifications.
@@ -140,7 +152,7 @@
  * Calling this API with the same handle more than once is undefined.
  */
 void
-vproc_standby_complete(vproc_standby_t handle);
+vproc_standby_end(vproc_t virtual_proc, vproc_standby_t handle);
 
 #pragma GCC visibility pop
 

Modified: trunk/launchd/src/protocol_job.defs
===================================================================
--- trunk/launchd/src/protocol_job.defs	2008-03-27 01:40:55 UTC (rev 23573)
+++ trunk/launchd/src/protocol_job.defs	2008-03-27 21:18:33 UTC (rev 23574)
@@ -95,7 +95,9 @@
 		__requestor_port: mach_port_t;
 	out	__subset_port	: mach_port_make_send_t);
 
-skip;	/* create_service prior to 10.6 */
+routine setup_shmem(
+		__bs_port	: job_t;
+	out	__shmem_port	: mach_port_move_send_t);
 
 routine take_subset(
 		__bs_port	: job_t;

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/launchd-changes/attachments/20080327/dbfcd375/attachment-0001.html 


More information about the launchd-changes mailing list