+ /* Create a new thread for the child process */
+ result = thread_create(child_task, &child_thread);
+ if (result != KERN_SUCCESS) {
+ printf("execve: thread_create failed. Code: %d\n", result);
+ task_deallocate(child_task);
+ child_task = NULL;
+ }
+bad:
+ thread_yield_internal(1);
+
+ return(child_thread);
+}
+
+
+/*
+ * procdup
+ *
+ * Description: Givben a parent process, provide a duplicate task and thread
+ * for a child process of that parent.
+ *
+ * Parameters: parent Parent process to use as the template
+ * child Child process to duplicate into
+ *
+ * Returns: !NULL Child process thread pointer
+ * NULL Failure (unspecified)
+ *
+ * Note: Most of the heavy lifting is done by fork_create_child(); this
+ * function exists more or less to deal with the 64 bit commpage,
+ * which requires explicit inheritance, the x86 commpage, which
+ * should not need explicit mapping any more, but apparently does,
+ * and to be variant for the bootstrap process.
+ *
+ * There is a special case where the system is being bootstraped,
+ * where this function will be called from cloneproc(), called in
+ * turn from bsd_utaskbootstrap(). In this case, we are acting
+ * to create a task and thread (and uthread) for the benefit of
+ * the kernel process - the first process in the system (PID 0).
+ *
+ * In that specific case, we will *not* pass a parent task, since
+ * there is *not* parent task present to pass.
+ *
+ * XXX: This function should go away; the variance can moved into
+ * XXX: cloneproc(), and the 64bit commpage code can be moved into
+ * XXX: fork_create_child(), after the x86 commpage inheritance is
+ * XXX: corrected.
+ */
+thread_t
+procdup(proc_t parent, proc_t child)
+{
+ thread_t child_thread;
+ task_t child_task;
+
+ if (parent->task == kernel_task)
+ child_thread = fork_create_child(TASK_NULL, child, FALSE, FALSE);
+ else
+ child_thread = fork_create_child(parent->task, child, TRUE, (parent->p_flag & P_LP64));
+
+ if (child_thread != NULL) {
+ child_task = get_threadtask(child_thread);
+ if (parent->p_flag & P_LP64) {
+ task_set_64bit(child_task, TRUE);
+ OSBitOrAtomic(P_LP64, (UInt32 *)&child->p_flag);
+#ifdef __ppc__
+ /* LP64todo - clean up hacked mapping of commpage */
+ /*
+ * PPC51: ppc64 is limited to 51-bit addresses.
+ * Memory above that limit is handled specially at
+ * the pmap level.
+ */
+ pmap_map_sharedpage(child_task, get_map_pmap(get_task_map(child_task)));
+#endif /* __ppc__ */
+ } else {
+ task_set_64bit(child_task, FALSE);
+ OSBitAndAtomic(~((uint32_t)P_LP64), (UInt32 *)&child->p_flag);
+ }
+ }
+
+ return(child_thread);