Index: trunk/src/emx/Makefile
===================================================================
--- trunk/src/emx/Makefile	(revision 1460)
+++ trunk/src/emx/Makefile	(revision 1461)
@@ -200,5 +200,5 @@
 #	must use the shell.
 EMXOMF = $(call GETTOOL2,emxomf)
-DO.EMXOMF = $(EMXOMF) $(strip $1 -o) $@ $(if $<,$<, $(subst /omf/,/aout/,$(@:.obj=.o)) )
+DO.EMXOMF = $(EMXOMF) $(strip $1 -o) $@ $(if $<,$<, $(subst /omf-prof/,/aout-prof/,$(subst /omf-log/,/aout-log/,$(subst /omf/,/aout/,$(@:.obj=.o)))) )
 
 # How to copy some file to installation directory
@@ -343,6 +343,10 @@
 	@$(call ECHO,smak don't generate rules anylonger!)
 
-# The general a.out -> OMF conversion rule for object files
+# The general a.out -> OMF conversion rules for object files
 $.omf/%.obj: 	
+	$(call DO.EMXOMF)
+$.omf-log/%.obj: 	
+	$(call DO.EMXOMF)
+$.omf-prof/%.obj: 	
 	$(call DO.EMXOMF)
 
Index: trunk/src/emx/include/InnoTekLIBC/fork.h
===================================================================
--- trunk/src/emx/include/InnoTekLIBC/fork.h	(revision 1460)
+++ trunk/src/emx/include/InnoTekLIBC/fork.h	(revision 1461)
@@ -494,10 +494,9 @@
     /* Priority of this callback */
     unsigned                uPriority;
-    /** Pointer to the next record in a sorted callback list.
-     * @remark This is initialized to point to self in order to shut up the compiler.
-     * (Encountered some limitations of the GNU inline assmebler which prevents me from
-     * referencing the symbol.)
-     */
-    struct __libc_ForkCallback *pNext;
+    /** Pointer to self.
+     * This is a hack to allow the callbacks to be static without gcc
+     * optimizing them away as unused.
+     */
+    const struct __libc_ForkCallback *pSelf;
 } __LIBC_FORKCALLBACK, *__LIBC_PFORKCALLBACK;
 
@@ -513,5 +512,5 @@
  */
 #define _FORK_PARENT1(uPriority, pfnCallback) \
-    static __LIBC_FORKCALLBACK __fork_parent1_##pfnCallback = { pfnCallback, uPriority, &__fork_parent1_##pfnCallback }; \
+    static const __LIBC_FORKCALLBACK __fork_parent1_##pfnCallback = { pfnCallback, uPriority, &__fork_parent1_##pfnCallback }; \
     __asm__ (".stabs \"___fork_parent1__\", 25, 0, 0, ___fork_parent1_" #pfnCallback);
 
@@ -526,5 +525,5 @@
  */
 #define _FORK_CHILD1(uPriority, pfnCallback) \
-    static __LIBC_FORKCALLBACK __fork_child1_##pfnCallback  = { pfnCallback, uPriority, &__fork_child1_##pfnCallback  }; \
+    static const __LIBC_FORKCALLBACK __fork_child1_##pfnCallback  = { pfnCallback, uPriority, &__fork_child1_##pfnCallback  }; \
     __asm__ (".stabs \"___fork_child1__\",  25, 0, 0, ___fork_child1_" #pfnCallback );
 
Index: trunk/src/emx/include/InnoTekLIBC/sharedpm.h
===================================================================
--- trunk/src/emx/include/InnoTekLIBC/sharedpm.h	(revision 1460)
+++ trunk/src/emx/include/InnoTekLIBC/sharedpm.h	(revision 1461)
@@ -233,7 +233,9 @@
     /** Pointer to fork handle which a child should use when spawned by fork(). */
     void                       *pvForkHandle;
+    /** Creation timestamp. */
+    unsigned                    uTimestamp;
 
     /** Reserved pool pointer field with default value 0. */
-    unsigned                    aReserved[40 - 13];
+    unsigned                    aReserved[40 - 14];
 
     /** Number of possible pointers to shared memory starting at pvInherit.
@@ -243,4 +245,8 @@
     /** Pointer to data inherited from the parent process. */
     __LIBC_PSPMINHERIT volatile pInherit;
+    /** Pointer to data inherited from the parent process when it's locked.
+     * When locked pInherit is NULL and this member points to the data instead.
+     * This prevents spmAlloc() from reclaiming it while it's in use. */
+    __LIBC_PSPMINHERIT volatile pInheritLocked;
 } __LIBC_SPMPROCESS, *__LIBC_PSPMPROCESS;
 
@@ -367,4 +373,28 @@
 
 /**
+ * Gets the inherit data associated with the current process.
+ * This call prevents it from being release by underrun handling.
+ *
+ * @returns Pointer to inherit data.
+ *          The caller must call __libc_spmInheritRelease() when done.
+ * @returns NULL and errno if no inherit data.
+ */
+__LIBC_PSPMINHERIT  __libc_spmInheritRequest(void);
+
+/**
+ * Releases the inherit data locked by the __libc_spmInheritRequest() call.
+ *
+ * @returns 0 on success.
+ * @returns -1 and errno on failure.
+ */
+int  __libc_spmInheritRelease(void);
+
+/**
+ * Frees the inherit data of this process.
+ * This is called when the executable is initialized.
+ */
+void  __libc_spmInheritFree(void);
+
+/**
  * Create an embryo related to the current process.
  *
Index: trunk/src/emx/src/lib/libc.def
===================================================================
--- trunk/src/emx/src/lib/libc.def	(revision 1460)
+++ trunk/src/emx/src/lib/libc.def	(revision 1461)
@@ -1118,2 +1118,3 @@
     ; new stuff.
 
+    "___libc_SpmCheck" @1140
Index: trunk/src/emx/src/lib/libc.smak
===================================================================
--- trunk/src/emx/src/lib/libc.smak	(revision 1460)
+++ trunk/src/emx/src/lib/libc.smak	(revision 1461)
@@ -57,5 +57,53 @@
 LIBC.IMPLIB     := $.omf/libc_dll.lib $.aout/libc_dll.a
 LIBC.DEF        := $.omf/libc.def
-LIBC.OBJS       := $.omf/src/lib/startup/dll0hifork.obj $.omf/src/lib/startup/dllinit.obj
+LIBC.OBJS.COMMON := \
+	$.omf/src/lib/sys/libcfork.obj \
+	$.omf/src/lib/sys/sharedpm.obj \
+	$.omf/src/lib/sys/__initdll.obj \
+	$.omf/src/lib/malloc/_heapvoting.obj \
+	$.omf/src/lib/process/fmutex.obj \
+	$.omf/src/lib/sys/DosCreateEventSemEx.obj \
+	$.omf/src/lib/sys/DosEx.obj \
+	$.omf/src/lib/str/386/bzero.obj \
+	$.omf/src/lib/sys/386/__init_environ.obj \
+	$.omf/src/lib/malloc/_hmalloc.obj \
+	$.omf/src/lib/malloc/_hinitheap.obj \
+	$.omf/src/lib/sys/heaphigh.obj \
+	$.omf/src/lib/sys/DosAllocMemEx.obj \
+	$.omf/src/lib/malloc/ucreate2.obj \
+	$.omf/src/lib/malloc/iaddmem.obj \
+	$.omf/src/lib/malloc/imisc.obj \
+	$.omf/src/lib/malloc/uopen.obj \
+	$.omf/src/lib/sys/DosOpenEventSemEx.obj \
+	$.omf/src/lib/malloc/umalloc.obj \
+	$.omf/src/lib/malloc/ialloc.obj \
+	$.omf/src/lib/sys/largefileio.obj \
+	$.omf/src/lib/sys/filehandles.obj \
+	$.omf/src/lib/malloc/_hcalloc.obj \
+	$.omf/src/lib/malloc/ucalloc.obj \
+	$.omf/src/lib/startup/dllinit.obj \
+	$.omf/src/lib/startup/startup.obj \
+	$.omf/src/lib/startup/ctor1.obj \
+	$.omf/src/lib/sys/tcpipver.obj \
+	$.omf/src/lib/sys/tcpipver43.obj \
+	$.omf/src/lib/sys/pathrewrite.obj \
+	$.omf/src/lib/app/getenv.obj \
+	$.omf/src/lib/str/386/strlen.obj \
+	$.omf/src/lib/str/strncmp.obj \
+	$.omf/src/lib/app/stdio.obj \
+	$.omf/src/lib/process/fmutex2.obj \
+	$.omf/src/lib/io/_tmp.obj \
+	$.omf/src/lib/process/thread_internals.obj \
+	$.omf/src/lib/sys/b_threadInit.obj \
+	$.omf/src/lib/malloc/malloc.obj \
+	$.omf/src/lib/malloc/initr.obj \
+	$.omf/src/lib/malloc/_linitheap.obj \
+	$.omf/src/lib/sys/uflags.obj \
+	$.omf/src/lib/sys/sbrk.obj \
+	$.omf/src/lib/sys/heap.obj \
+	$.omf/src/lib/sys/__init.obj
+LIBC.OBJS       := \
+	$.omf/src/lib/startup/dll0hifork.obj \
+	$(LIBC.OBJS.COMMON)
 LIBC.LIBS       := $.omf/libc_s.lib $.omf/libc_app.lib
 LIBC.DEPS       := $(LIBC.STUB) $.omf/libc_alias.lib
@@ -65,5 +113,7 @@
 LIBC.PRF.DLL	:= $(LIBC.DLL:.dll=.prf)
 LIBC.PRF.DEF    := $.omf/libc.prf.def
-LIBC.PRF.OBJS   := $.omf/src/lib/startup/dll0hifork.obj $.omf-prof/src/lib/startup/dllinit.obj
+LIBC.PRF.OBJS   := \
+	$.omf/src/lib/startup/dll0hifork.obj \
+	$(subst /omf/,/omf-prof/,$(LIBC.OBJS.COMMON))
 LIBC.PRF.LIBS   := $.omf-prof/libc_p_s.lib $.omf-prof/libc_app_p.lib
 LIBC.PRF.DEPS   := $(LIBC.DEPS)
@@ -72,5 +122,7 @@
 LIBC.ELH.DLL	:= $(LIBC.DLL:.dll=.elh)
 LIBC.ELH.DEF    := $.omf/libc.elh.def
-LIBC.ELH.OBJS   := $(LIBC.OBJS)
+LIBC.ELH.OBJS   := \
+	$.omf/src/lib/startup/dll0hifork.obj \
+	$.omf/src/lib/startup/dllinit.obj
 LIBC.ELH.LIBS   := $(LIBC.LIBS)
 LIBC.ELH.DEPS   := $(LIBC.DEPS)
@@ -79,5 +131,7 @@
 LIBC.LOG.DLL	:= $(LIBC.DLL:.dll=.logchk)
 LIBC.LOG.DEF    := $(LIBC.DEF)
-LIBC.LOG.OBJS   := $.omf/src/lib/startup/dll0hifork.obj $.omf/src/lib/startup/dllinit.obj
+LIBC.LOG.OBJS   := \
+	$.omf/src/lib/startup/dll0hifork.obj \
+	$(subst /omf/,/omf-log/,$(LIBC.OBJS.COMMON))
 LIBC.LOG.LIBS   := $.omf-log/libc_l_s.lib $.omf-log/libc_app_l.lib
 LIBC.LOG.DEPS   := $(LIBC.DEPS)
Index: trunk/src/emx/src/lib/startup/startup.c
===================================================================
--- trunk/src/emx/src/lib/startup/startup.c	(revision 1460)
+++ trunk/src/emx/src/lib/startup/startup.c	(revision 1461)
@@ -55,16 +55,19 @@
  *      - dll0.s gets control and calls __init_dll in sys/__initdll.c
  *          - __init_dll calls __libc_HeapVote() to do the heap voting.
- *          - __init_dll calls __init_os_version() to set _osminor,_osmajor globals.
+ *          - __init_dll initiates the _osminor and _osmajor globals.
+ *          - __init_dll initiates _sys_gcbVirtualAddressLimit global.
  *          - __init_dll initiates _sys_pid and _sys_ppid globals.
- *          - __init_dll creates _sys_heap_fmutex and _sys_gmtxHimem.
+ *          - __init_dll creates _sys_heap_fmutex, _sys_gmtxHimem and __libc_gmtxExec.
  *          - __init_dll then initiates __libc_gpTLS with an allocated TLS ULONG.
  *            The thread structure it self isn't initialized untill it's actually
  *            referenced, and when it is there is static structure for the first
  *            thread needing its per thread area.
- *          - __init_dll calls __init_environ() which initializes environ and _org_environ.
- *              - __init_environ() will call _hmalloc() thus initiating the high heap.
+ *          - __init_dll calls _sys_init_environ() which initializes environ and _org_environ.
+ *              - _sys_init_environ() will call _hmalloc() thus initiating the high heap.
+ *          - __init_dll calls __libc_spmSelf() which checks initiates SPM and gets
+ *            any inherited properties.
  *          - __init_dll calls _sys_init_largefileio() which checks for LFN APIs.
- *          - __init_dll calls _sys_init_filehandles() which initiates filehandle table.
- *              - _sys_init_filehandles() will call _hmalloc() and a number of OS/2 APIs
+ *          - __init_dll calls __libc_fhInit() which initiates filehandle table.
+ *              - __libc_fhInit() will call _hmalloc() and a number of OS/2 APIs
  *                to figure out what handles was inherited.
  *          - __init_dll then intializes _sys_clock0_ms with the current MS count.
@@ -100,4 +103,6 @@
  *          - __init() parse the commandline creating argv and it's strings using the
  *            allocated stack space.
+ *          - __init() calls __libc_spmInheritFree() to release the inherit data (shared)
+ *            associated with the current process.
  *          - __init() installs the exception handler.
  *          - __init() set the signal focus.
@@ -112,3 +117,4 @@
  *
  * @todo update this with file handle changes!
+ * @todo update this with fork and performance changes!
  */
Index: trunk/src/emx/src/lib/sys/__init.c
===================================================================
--- trunk/src/emx/src/lib/sys/__init.c	(revision 1460)
+++ trunk/src/emx/src/lib/sys/__init.c	(revision 1461)
@@ -26,4 +26,5 @@
 #include <alloca.h>
 #include <InnoTekLIBC/thread.h>
+#include <InnoTekLIBC/sharedpm.h>
 #define __LIBC_LOG_GROUP    __LIBC_LOG_GRP_INITTERM
 #include <InnoTekLIBC/logstrict.h>
@@ -214,4 +215,9 @@
 
     /*
+     * Free the SPM inherit data.
+     */
+    __libc_spmInheritFree();
+
+    /*
      * Install exception handler.
      */
@@ -442,5 +448,6 @@
 {
     __asm__ ("cld");              /* Don't trust */
-LIBCLOG_MSG2("!!! num %08lx flags %08lx nested %p whatever %p\n", report->ExceptionNum, report->fHandlerFlags, report->NestedExceptionReportRecord, whatever);
+    LIBCLOG_MSG2("!!! num %08lx flags %08lx nested %p whatever %p\n",
+                 report->ExceptionNum, report->fHandlerFlags, (void *)report->NestedExceptionReportRecord, whatever);
     if (report->fHandlerFlags & (EH_UNWINDING | EH_EXIT_UNWIND))
         return XCPT_CONTINUE_SEARCH;
@@ -509,14 +516,2 @@
 
 
-void _sys_get_clock(unsigned long *ms)
-{
-    ULONG val_ms;
-    FS_VAR();
-
-    FS_SAVE_LOAD();
-    DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &val_ms, sizeof (val_ms));
-    FS_RESTORE();
-    *ms = val_ms;
-}
-
-
Index: trunk/src/emx/src/lib/sys/__initdll.c
===================================================================
--- trunk/src/emx/src/lib/sys/__initdll.c	(revision 1460)
+++ trunk/src/emx/src/lib/sys/__initdll.c	(revision 1461)
@@ -17,4 +17,5 @@
 #include "libc-alias.h"
 #define INCL_DOS
+#define INCL_FSMACROS
 #include <os2emx.h>
 #define _osmajor __osminor
@@ -40,4 +41,5 @@
 #pragma weak __init_largefileio
 
+
 /*******************************************************************************
 *   Structures and Typedefs                                                    *
@@ -83,4 +85,5 @@
     PPIB                ppib;
     __LIBC_PSPMPROCESS  pSelf;
+
     static int fInitialized = 0;
 
@@ -177,5 +180,5 @@
      * Init file handles.
      */
-    rc = __libc_fhInit(pSelf->pInherit ? pSelf->pInherit->pFHBundles : NULL);
+    rc = __libc_fhInit();
     if (rc)
     {
@@ -190,4 +193,21 @@
     return 0;
 }
+
+
+/**
+ * Get the current MS timestamp.
+ * @param   pms     Where to store the current timestamp.
+ */
+void _sys_get_clock(unsigned long *pms)
+{
+    ULONG val_ms;
+    FS_VAR();
+
+    FS_SAVE_LOAD();
+    DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &val_ms, sizeof(val_ms));
+    FS_RESTORE();
+    *pms = val_ms;
+}
+
 
 
Index: trunk/src/emx/src/lib/sys/__spawnve.c
===================================================================
--- trunk/src/emx/src/lib/sys/__spawnve.c	(revision 1460)
+++ trunk/src/emx/src/lib/sys/__spawnve.c	(revision 1461)
@@ -7,4 +7,6 @@
 #include <errno.h>
 #include <alloca.h>
+#include <386/builtin.h>
+#include <sys/fmutex.h>
 #define INCL_DOSPROCESS
 #define INCL_FSMACROS
@@ -192,4 +194,6 @@
   *arg_ptr++ = '\0';
   *arg_ptr++ = '\0';
+
+  _fmutex_request(&__libc_gmtxExec, 0);
 
   /*
@@ -218,4 +222,5 @@
               if (arg_buf != NULL)
                   _tfree (arg_buf);
+              _fmutex_release(&__libc_gmtxExec);
 
               /* exit depends on the mode. */
@@ -246,4 +251,5 @@
   if (arg_buf != NULL)
     _tfree (arg_buf);
+  _fmutex_release(&__libc_gmtxExec);
   return -1;
 }
Index: trunk/src/emx/src/lib/sys/filehandles.c
===================================================================
--- trunk/src/emx/src/lib/sys/filehandles.c	(revision 1460)
+++ trunk/src/emx/src/lib/sys/filehandles.c	(revision 1461)
@@ -41,4 +41,5 @@
 #include "libc-alias.h"
 #include <malloc.h>
+#include <string.h>
 #include <sys/fcntl.h>
 #include <errno.h>
@@ -95,12 +96,12 @@
  * @returns 0 on success.
  * @returns -1 on failure.
- * @param   pInherit    Pointer to inherited filehandle data.
- */
-int __libc_fhInit(__LIBC_PSPMINHFHBHDR  pInherit)
-{
-    ULONG   cMaxFHs = 0;
-    LONG    lDeltaFHs = 0;
-    int     rc;
-    int     i;
+ */
+int __libc_fhInit(void)
+{
+    __LIBC_PSPMINHERIT  pInherit;
+    ULONG               cMaxFHs = 0;
+    LONG                lDeltaFHs = 0;
+    int                 rc;
+    int                 i;
 
     /*
@@ -136,6 +137,9 @@
     gcPreAllocatedAvail = sizeof(gaPreAllocated) / sizeof(gaPreAllocated[0]);
 
-
-    if (!pInherit)
+    /*
+     * Check if we inherited flags and stuff from parent.
+     */
+    pInherit = __libc_spmInheritRequest();
+    if (!pInherit || pInherit->pFHBundles)
     {
         /*
@@ -165,5 +169,5 @@
             void                   *pv;
         } u;
-        u.pHdr = pInherit;
+        u.pHdr = pInherit->pFHBundles;
         while (u.pHdr->uchType != __LIBC_SPM_INH_FHB_TYPE_END)
         {
@@ -179,4 +183,5 @@
                         {
                             LIBC_ASSERTM_FAILED("Failed to allocated inherited file handle! iFH=%d\n", iFH);
+                            __libc_spmInheritRelease();
                             return -1;
                         }
@@ -192,4 +197,5 @@
                             LIBC_ASSERTM_FAILED("Failed to allocated inherited socket (4.4) handle! iFH=%d iSocket=%d\n",
                                                 iFH, u.pSockets->aHandles[i].usSocket);
+                            __libc_spmInheritRelease();
                             return -1;
                         }
@@ -205,4 +211,5 @@
                             LIBC_ASSERTM_FAILED("Failed to allocated inherited socket (4.3) handle! iFH=%d iSocket=%d\n",
                                                 iFH, u.pSockets->aHandles[i].usSocket);
+                            __libc_spmInheritRelease();
                             return -1;
                         }
@@ -224,4 +231,5 @@
             }
         }
+        __libc_spmInheritRelease();
     }
 
Index: trunk/src/emx/src/lib/sys/sharedpm.c
===================================================================
--- trunk/src/emx/src/lib/sys/sharedpm.c	(revision 1460)
+++ trunk/src/emx/src/lib/sys/sharedpm.c	(revision 1461)
@@ -113,4 +113,5 @@
 static VOID APIENTRY spmExitList(ULONG ulReason);
 static void spmZombieOrFree(__LIBC_PSPMPROCESS pProcess);
+static unsigned spmTimestamp(void);
 static __LIBC_PSPMPROCESS spmRegisterSelf(pid_t pid, pid_t pidParent);
 static __LIBC_PSPMPROCESS spmAllocProcess(void);
@@ -121,5 +122,4 @@
 static ULONG _System spmXcptHandler(PEXCEPTIONREPORTRECORD pRepRec, PEXCEPTIONREGISTRATIONRECORD pRegRec, PCONTEXTRECORD pCtx, PVOID pvWhatever);
 static int  spmCheck(int fBreakpoint, int fVerbose);
-
 
 
@@ -296,4 +296,92 @@
 
 /**
+ * Gets the inherit data associated with the current process.
+ * This call prevents it from being release by underrun handling.
+ *
+ * @returns Pointer to inherit data.
+ *          The caller must call __libc_spmInheritRelease() when done.
+ * @returns NULL and errno if no inherit data.
+ */
+__LIBC_PSPMINHERIT  __libc_spmInheritRequest(void)
+{
+    LIBCLOG_ENTER("\n");
+    __LIBC_PSPMINHERIT      pRet = NULL;
+    __LIBC_SPMXCPTREGREC    RegRec;
+    if (!spmRequestMutex(&RegRec))
+    {
+        if ((pRet = gpSPMSelf->pInherit) != NULL)
+            gpSPMSelf->pInheritLocked = (void *)__atomic_xchg((unsigned *)(void *)&gpSPMSelf->pInherit, 0);
+        else if (gpSPMSelf->pInheritLocked)
+        {
+            errno = EBUSY;
+            LIBC_ASSERTM_FAILED("Already locked!\n");
+        }
+        else
+            errno = 0;
+        spmReleaseMutex(&RegRec);
+    }
+
+    LIBCLOG_RETURN_P(pRet);
+}
+
+
+/**
+ * Releases the inherit data locked by the __libc_spmInheritRequest() call.
+ *
+ * @returns 0 on success.
+ * @returns -1 and errno on failure.
+ */
+int  __libc_spmInheritRelease(void)
+{
+    LIBCLOG_ENTER("\n");
+    __LIBC_SPMXCPTREGREC    RegRec;
+    int rc = spmRequestMutex(&RegRec);
+    if (!rc)
+    {
+        gpSPMSelf->pInheritLocked = (void *)__atomic_xchg((unsigned *)(void *)&gpSPMSelf->pInherit, (unsigned)gpSPMSelf->pInheritLocked);
+        spmReleaseMutex(&RegRec);
+    }
+    else
+    {
+        errno = EINVAL;
+        rc = -1;
+        LIBC_ASSERTM_FAILED("Not initialized!\n");
+    }
+
+    LIBCLOG_RETURN_INT(rc);
+}
+
+
+/**
+ * Frees the inherit data of this process.
+ * This is called when the executable is initialized.
+ */
+void  __libc_spmInheritFree(void)
+{
+    LIBCLOG_ENTER("\n");
+    if (gpSPMSelf && (gpSPMSelf->pInherit || gpSPMSelf->pInheritLocked))
+    {
+        __LIBC_SPMXCPTREGREC    RegRec;
+        if (!spmRequestMutex(&RegRec))
+        {
+            if (gpSPMSelf->pInherit)
+            {
+                int rc = spmFree(gpSPMSelf->pInherit);
+                LIBC_ASSERTM(!rc, "Failed to free inherit memory %p, errno=%d.\n",
+                             (void *)gpSPMSelf->pInherit, errno);
+                __atomic_xchg((unsigned *)(void *)&gpSPMSelf->pInherit, 0);
+                rc = rc;
+            }
+            LIBC_ASSERTM(!gpSPMSelf->pInheritLocked, "Trying to free a locked inherit struct!\n");
+
+            spmReleaseMutex(&RegRec);
+        }
+    }
+    LIBCLOG_RETURN_VOID();
+}
+
+
+
+/**
  * Create an embryo related to the current process.
  *
@@ -325,4 +413,31 @@
 
     /*
+     * Reap old embryos.
+     */
+    pProcess = gpSPMHdr->apHeads[__LIBC_PROCSTATE_EMBRYO];
+    if (pProcess)
+    {
+        unsigned uTimestamp = spmTimestamp();
+        do
+        {
+            SPM_ASSERT_PTR_NULL(pProcess);
+            SPM_ASSERT_PTR_NULL(pProcess->pPrev);
+            SPM_ASSERT_PTR_NULL(pProcess->pNext);
+            if (    pProcess->pidParent == pidParent
+                &&  pProcess->cReferences == 0
+                &&  uTimestamp - pProcess->uTimestamp >= 1*60*1000)
+            {
+                __LIBC_PSPMPROCESS      pProcessNext = pProcess->pNext;
+                spmFreeProcess(pProcess);
+                pProcess = pProcessNext;
+                continue;
+            }
+
+            /* next */
+            pProcess = pProcess->pNext;
+        } while (pProcess);
+    }
+
+    /*
      * Create a new process block.
      */
@@ -333,10 +448,11 @@
          * Initialize the new process block.
          */
-        pProcess->uVersion   = SPM_VERSION;
-        pProcess->cReferences = 1;
-        pProcess->pid        = -1;
-        pProcess->pidParent  = pidParent;
-        pProcess->enmState   = __LIBC_PROCSTATE_EMBRYO;
-        pProcess->cPoolPointers = 1; /** @todo define for this! */
+        pProcess->uVersion      = SPM_VERSION;
+        pProcess->cReferences   = 1;
+        pProcess->pid           = -1;
+        pProcess->pidParent     = pidParent;
+        pProcess->enmState      = __LIBC_PROCSTATE_EMBRYO;
+        pProcess->uTimestamp    = spmTimestamp();
+        pProcess->cPoolPointers = 2; /** @todo define for this! */
 
         /* link into list. */
@@ -488,6 +604,8 @@
     /*
      * Free the process.
-     */
-    if (pProcess->cReferences == 0)
+     * Note that we do not free embryos. We'll reap them at other places
+     * if they don't become alive.
+     */
+    if (pProcess->cReferences == 0 && pProcess->enmState != __LIBC_PROCSTATE_EMBRYO)
         spmFreeProcess(pProcess);
 
@@ -1168,4 +1286,11 @@
     else if (pProcess->enmState != __LIBC_PROCSTATE_ZOMBIE)
     {
+        /* free data a zombie won't be needing. */
+        if (pProcess->pInherit)
+        {
+            spmFree(pProcess->pInherit);
+            pProcess->pInherit = NULL;
+        }
+
         /* unlink. */
         if (pProcess->pNext)
@@ -1185,4 +1310,24 @@
     }
     /* else already zombie */
+}
+
+
+/**
+ * Gets the current timestamp.
+ *
+ * @returns The current timestamp.
+ */
+static unsigned spmTimestamp(void)
+{
+    ULONG   ul;
+    int     rc;
+    FS_VAR();
+    FS_SAVE_LOAD();
+    ul = 0;
+    rc = DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &ul, sizeof(ul));
+    LIBC_ASSERTM(!rc, "DosQuerySysInfo failed rc=%d\n", rc);
+    FS_RESTORE();
+    rc = rc;
+    return (unsigned)ul;
 }
 
@@ -1298,10 +1443,11 @@
          * Initialize the new process block.
          */
-        pProcess->uVersion   = SPM_VERSION;
-        pProcess->cReferences = 1;
-        pProcess->pid        = pid;
-        pProcess->pidParent  = pidParent;
-        pProcess->enmState   = __LIBC_PROCSTATE_ALIVE;
-        pProcess->cPoolPointers = 1; /** @todo define for this! */
+        pProcess->uVersion      = SPM_VERSION;
+        pProcess->cReferences   = 1;
+        pProcess->pid           = pid;
+        pProcess->pidParent     = pidParent;
+        pProcess->enmState      = __LIBC_PROCSTATE_ALIVE;
+        pProcess->uTimestamp    = spmTimestamp();
+        pProcess->cPoolPointers = 2; /** @todo define for this! */
 
         /* link into list. */
@@ -1444,4 +1590,31 @@
     {
         __LIBC_PSPMPROCESS  pProcess;
+
+        /*
+         * Free embryos which are more than 15 seconds old.
+         */
+        pProcess = gpSPMHdr->apHeads[__LIBC_PROCSTATE_EMBRYO];
+        if (pProcess)
+        {
+            unsigned    uTimestamp = spmTimestamp();
+            do
+            {
+                SPM_ASSERT_PTR_NULL(pProcess);
+                SPM_ASSERT_PTR_NULL(pProcess->pNext);
+                SPM_ASSERT_PTR_NULL(pProcess->pPrev);
+                if (    pProcess->cReferences == 0
+                    &&  uTimestamp - pProcess->uTimestamp >= 15*1000)
+                {
+                    __LIBC_PSPMPROCESS      pProcessNext = pProcess->pNext;
+                    spmFreeProcess(pProcess);
+                    pProcess = pProcessNext;
+                    continue;
+                }
+
+                /* next */
+                pProcess = pProcess->pNext;
+            } while (pProcess);
+        }
+
         /*
          * Free up free processes.
@@ -1449,4 +1622,8 @@
         while ((pProcess = gpSPMHdr->apHeads[__LIBC_PROCSTATE_FREE]) != NULL)
         {
+            SPM_ASSERT_PTR_NULL(pProcess);
+            SPM_ASSERT_PTR_NULL(pProcess->pNext);
+            SPM_ASSERT_PTR_NULL(pProcess->pPrev);
+            gpSPMHdr->apHeads[__LIBC_PROCSTATE_FREE] = pProcess->pNext;
             if (pProcess->pNext)
                 pProcess->pNext->pPrev = NULL;
@@ -1458,18 +1635,17 @@
 
         /*
-         * Free up inherit data.
+         * Free up inherit data of processes in the alive list.
          */
         for (pProcess = gpSPMHdr->apHeads[__LIBC_PROCSTATE_ALIVE]; pProcess; pProcess = pProcess->pNext)
+        {
+            SPM_ASSERT_PTR_NULL(pProcess);
+            SPM_ASSERT_PTR_NULL(pProcess->pNext);
+            SPM_ASSERT_PTR_NULL(pProcess->pPrev);
             if (pProcess->pInherit)
             {
-                void *pv = pProcess->pInherit;
-                pProcess->pInherit = NULL;
+                void *pv = (void *)__atomic_xchg((unsigned *)(void *)&gpSPMSelf->pInherit, 0);
                 spmFree(pv);
             }
-
-        /*
-         * Free embryos which are more than a minutte old.
-         */
-        /** @todo */
+        }
 
         /*
@@ -1708,5 +1884,5 @@
         SPM_ASSERT_PTR_NULL(pLeft->core.pPrev);
 
-        if (pLeft == pFree->core.pPrev)
+        if ((__LIBC_PSPMPOOLCHUNK)pLeft == pFree->core.pPrev)
         {   /* merge with left free chunk. */
             pLeft->core.pNext = pFree->core.pNext;
@@ -1733,5 +1909,5 @@
 
     /* Check if we can merge with right hand free chunk. */
-    if (pRight && pRight == pFree->core.pNext)
+    if (pRight && (__LIBC_PSPMPOOLCHUNK)pRight == pFree->core.pNext)
     {   /* merge with right free chunk. */
         pFree->core.pNext = pRight->core.pNext;
Index: trunk/src/emx/src/lib/sys/syscalls.h
===================================================================
--- trunk/src/emx/src/lib/sys/syscalls.h	(revision 1460)
+++ trunk/src/emx/src/lib/sys/syscalls.h	(revision 1461)
@@ -166,5 +166,5 @@
 extern int              _sys_init_environ(const char *pszEnv);
 extern void             _sys_init_largefileio(void);
-extern int              __libc_fhInit(__LIBC_PSPMINHFHBHDR  pInherit);
+extern int              __libc_fhInit(void);
 /** @} */
 
