+/*
+ * Destroy a process structure that resulted from a call to forkproc(), but
+ * which must be returned to the system because of a subsequent failure
+ * preventing it from becoming active.
+ *
+ * Parameters: p The incomplete process from forkproc()
+ * lock Whether or not the signal lock was held
+ * when calling forkproc().
+ *
+ * Returns: (void)
+ *
+ * Note: This function should only be used in an error handler following
+ * a call to forkproc(). The 'lock' paramenter should be the same
+ * as the lock parameter passed to forkproc().
+ *
+ * Operations occur in reverse order of those in forkproc().
+ */
+void
+forkproc_free(proc_t p, int lock)
+{
+
+ /* Drop the signal lock, if it was held */
+ if (lock) {
+ proc_signalend(p, 0);
+ proc_transend(p, 0);
+ }
+
+ /*
+ * If we have our own copy of the resource limits structure, we
+ * need to free it. If it's a shared copy, we need to drop our
+ * reference on it.
+ */
+ proc_limitdrop(p, 0);
+ p->p_limit = NULL;
+
+#if SYSV_SHM
+ /* Need to drop references to the shared memory segment(s), if any */
+ if (p->vm_shm) {
+ /*
+ * Use shmexec(): we have no address space, so no mappings
+ *
+ * XXX Yes, the routine is badly named.
+ */
+ shmexec(p);
+ }
+#endif
+
+ /* Need to undo the effects of the fdcopy(), if any */
+ fdfree(p);
+
+ /*
+ * Drop the reference on a text vnode pointer, if any
+ * XXX This code is broken in forkproc(); see <rdar://4256419>;
+ * XXX if anyone ever uses this field, we will be extremely unhappy.
+ */
+ if (p->p_textvp) {
+ vnode_rele(p->p_textvp);
+ p->p_textvp = NULL;
+ }
+
+ /* Stop the profiling clock */
+ stopprofclock(p);
+
+ /* Release the credential reference */
+ kauth_cred_unref(&p->p_ucred);
+
+ proc_list_lock();
+ /* Decrement the count of processes in the system */
+ nprocs--;
+ proc_list_unlock();
+
+ thread_call_free(p->p_rcall);
+
+ /* Free allocated memory */
+ FREE_ZONE(p->p_sigacts, sizeof *p->p_sigacts, M_SIGACTS);
+ FREE_ZONE(p->p_stats, sizeof *p->p_stats, M_PSTATS);
+ proc_checkdeadrefs(p);
+ FREE_ZONE(p, sizeof *p, M_PROC);
+}
+
+
+/*
+ * forkproc
+ *
+ * Description: Create a new process structure, given a parent process
+ * structure.
+ *
+ * Parameters: parent The parent process
+ * lock If the signal lock should be taken on
+ * the newly created process.
+ *
+ * Returns: !NULL The new process structure
+ * NULL Error (insufficient free memory)
+ *
+ * Note: When successful, the newly created process structure is
+ * partially initialized; if a caller needs to deconstruct the
+ * returned structure, they must call forkproc_free() to do so.
+ */
+proc_t
+forkproc(proc_t parent, int lock)