Index: trunk/src/emx/Makefile
===================================================================
--- trunk/src/emx/Makefile	(revision 809)
+++ trunk/src/emx/Makefile	(revision 810)
@@ -103,5 +103,5 @@
 LD = gcc
 # Linker flags
-LDFLAGS     = $(LDFLAGS.$(MODE)) $(LDFLAGS.KIND) -Zmap -Zstack 1024 $(LIBS)
+LDFLAGS     = $(LDFLAGS.$(MODE)) $(LDFLAGS.KIND) -Zmap -Zstack 1024 -Zhigh-mem $(LIBS)
 LDFLAGS.DLL = $(LDFLAGS) -Zdll
 # Linker flags for different build modes
Index: trunk/src/emx/include/emx/umalloc.h
===================================================================
--- trunk/src/emx/include/emx/umalloc.h	(revision 809)
+++ trunk/src/emx/include/emx/umalloc.h	(revision 810)
@@ -7,4 +7,12 @@
 extern "C" {
 #endif
+
+/* include all we need here to make life easier. */
+#include <stddef.h>
+#include <umalloc.h>
+#include <sys/builtin.h>
+#include <sys/fmutex.h>
+#include <sys/rmutex.h>
+#include <sys/uflags.h>
 
 /* =========================== Introduction =========================== */
@@ -221,5 +229,5 @@
 
 #define _UM_TILE_OK(p,s)      (_UM_TILE_ALIGNED ((p), (s)) \
-                               && _UM_TILE_TILED ((p), (s))) 
+                               && _UM_TILE_TILED ((p), (s)))
 
 /* Compute the smallest number X such that P will be aligned on a A
@@ -603,7 +611,9 @@
 
 /* Note that _um_regular_heap is declared in <umalloc.h>.
-   _um_tiled_heap isn't, so we declare it here. */
+   the others aren't, so we declare them here. */
 
 extern Heap_t _um_tiled_heap;
+extern Heap_t _um_high_heap;
+extern Heap_t _um_low_heap;
 
 
@@ -710,6 +720,6 @@
 int _um_find_bucket (size_t);
 void _um_free_maybe_lock (void *, int);
-void _um_init_default_regular_heap (void);
-void _um_init_default_tiled_heap (void);
+Heap_t _um_init_default_regular_heap (void);
+Heap_t _um_init_default_tiled_heap (void);
 void *_um_lump_alloc (Heap_t, size_t, size_t, unsigned);
 void _um_lump_coalesce_free (Heap_t, struct _um_lump *, struct _um_seg *,
@@ -725,4 +735,38 @@
 int _um_walk_no_lock (Heap_t, _um_callback2 *, void *);
 
+
+/** @group Low Memory Heap Routines.
+ * Intended for internal LIBC use. First call to any of these routines
+ * will initialize the heap.
+ * @{ */
+void *  _lmalloc(size_t);
+void *  _lcalloc(size_t, size_t);
+void *  _lrealloc(void *, size_t);
+Heap_t  _linitheap(void);
+/** @} */
+
+/** @group High Memory Heap Routines.
+ * Intended for internal LIBC use. First call to any of these routines
+ * will initialize the heap.
+ * @{ */
+void *  _hmalloc(size_t);
+void *  _hcalloc(size_t, size_t);
+void *  _hrealloc(void *, size_t);
+Heap_t  _hinitheap(void);
+void *  __libc_HimemDefaultAlloc(Heap_t Heap, size_t *pcb, int *pfClean);
+void    __libc_HimemDefaultRelease(Heap_t Heap, void *pv, size_t cb);
+int     __libc_HasHighMem(void);
+/** @} */
+
+
+/** @group Default Heap Voting.
+ * @{ */
+void    __libc_HeapVote(int fDefaultHeapInHighMem);
+void    __libc_HeapEndVoting(void);
+int     __libc_HeapGetResult(void);
+/** @} */
+
+
+
 /* Inline functions. */
 
@@ -763,10 +807,10 @@
 {
   /* Use the 'syscall' write for safest possible path. */
-  extern int __write (int handle, const void *buf, size_t nbytes); 
+  extern int __write (int handle, const void *buf, size_t nbytes);
   __write (2, "\r\n!_um_abort!", 13);
   if (pszmsg)
     {
       const char *psz = pszmsg;
-      while (*psz) 
+      while (*psz)
         psz++;
       __write (2, " ", 1);
Index: trunk/src/emx/include/os2safe.h
===================================================================
--- trunk/src/emx/include/os2safe.h	(revision 810)
+++ trunk/src/emx/include/os2safe.h	(revision 810)
@@ -0,0 +1,44 @@
+/* os2safe.h,v 1.1 2003/10/06 00:54:20 bird Exp */
+/** @file
+ *
+ * OS/2 API High Memory Wrappers.
+ * You include this file before os2.h and link with -los2safe.
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+#ifndef __os2safe_h__
+#define __os2safe_h__
+
+#if defined(_OS2_H) || defined(_OS2EMX_H) || defined(__OS2_H__) || defined(OS2_INCLUDED)
+#warning "os2safe.h must be included _before_ os2.h!"
+#endif
+
+#define DosForceDelete          SafeDosForceDelete
+#define DosQueryHType           SafeDosQueryHType
+#define DosCreatePipe           SafeDosCreatePipe
+#define DosQueryNPHState        SafeDosQueryNPHState
+#define DosWaitNPipe            SafeDosWaitNPipe
+#define DosSetFilePtr           SafeDosSetFilePtr
+#define DosSetFilePtrL          SafeDosSetFilePtrL
+#define DosDupHandle            SafeDosDupHandle
+#define DosOpenL                SafeDosOpenL
+#define DosQueryFHState         SafeDosQueryFHState
+#define DosSetDateTime          SafeDosSetDateTime
+
+#endif
Index: trunk/src/emx/include/stdlib.h
===================================================================
--- trunk/src/emx/include/stdlib.h	(revision 809)
+++ trunk/src/emx/include/stdlib.h	(revision 810)
@@ -180,5 +180,5 @@
  */
 #if __POSIX_VISIBLE /* >= ??? */
-/* int	 posix_memalign(void **, size_t, size_t); (ADV) */
+int	 posix_memalign(void **, size_t, size_t); /* bird: we implement this. */
 /** @todo int	 rand_r(unsigned *);	*/		/* (TSF) */
 int	 setenv(const char *, const char *, int);
Index: trunk/src/emx/include/umalloc.h
===================================================================
--- trunk/src/emx/include/umalloc.h	(revision 809)
+++ trunk/src/emx/include/umalloc.h	(revision 810)
@@ -47,4 +47,5 @@
 #define _HEAP_TILED     0x02
 #define _HEAP_SHARED    0x04
+#define _HEAP_HIGHMEM   0x08 /* advisory flag */
 
 #define _BLOCK_CLEAN    1
@@ -95,5 +96,4 @@
 void *_utmalloc (Heap_t, size_t);
 
-
 #if defined (__cplusplus)
 }
Index: trunk/src/emx/src/lib/alias/alias.smak
===================================================================
--- trunk/src/emx/src/lib/alias/alias.smak	(revision 809)
+++ trunk/src/emx/src/lib/alias/alias.smak	(revision 810)
@@ -10,5 +10,5 @@
 .TKIND	:= aout
 .INSDIR := lib/
-.TARGET := c_alias.a
+.TARGET := libc_alias.a
 include common.smak
 
@@ -22,21 +22,32 @@
 # For every aliased function create a .o file containing the alias
 # and add it to the target library.
-$.$(.TARG): $.stmp-libc-std
+##$.$(.TARG): $.stmp-libc-std
+## Depending on the timestamp kind of sucks, now we depend on the
+## header, which is better but will require libc to be build first.
+$.$(.TARG): $.libc-std.h
 	$(call RM,$@)
-	@$(call DO.STDALIAS,_strcasecmp,__std_stricmp,$.strcasecmp.o)
-	@$(call DO.STDALIAS,_strncasecmp,__std_strnicmp,$.strncasecmp.o)
-	@$(call DO.STDALIAS,_itoa,__std_ltoa,$.itoa.o)
-	@$(call DO.STDALIAS,__itoa,__std_ltoa,$._itoa.o)
-	@$(call DO.STDALIAS,__Exit,__exit,$.__Exit.o)
-	@$(foreach x,$(ALIAS.FUNCS),\
-	  $(call DO.STDALIAS,_$x,__std_$x,$.$x.o)$(NL))
-	@$(foreach x,$(ALIAS._FUNCS),\
-	  $(call DO.STDALIAS,__$x,__std_$x,$._$x.o)$(NL))
-	$(AR) $(ARFLAGS) $@ $(addprefix $.,\
-	  strcasecmp.o strncasecmp.o itoa.o _itoa.o __Exit.o \
-	  $(addsuffix .o,$(ALIAS.FUNCS) $(addprefix _,$(ALIAS._FUNCS))))
-	@$(call RM,$(addprefix $., \
-	  strcasecmp.o strncasecmp.o itoa.o _itoa.o __Exit.o \
-	  $(addsuffix .o,$(ALIAS.FUNCS) $(addprefix _,$(ALIAS._FUNCS)))))
+	$(call MKDIR,$.aliases)
+	$(call RM,$.aliases/*.o)
+	$(call RM,$.aliases/*.s)
+	@$(call DO.STDALIAS,_strcasecmp,__std_stricmp,$.aliases/strcasecmp.o)
+	@$(call DO.STDALIAS,_strncasecmp,__std_strnicmp,$.aliases/strncasecmp.o)
+	@$(call DO.STDALIAS,_itoa,__std_ltoa,$.aliases/itoa.o)
+	@$(call DO.STDALIAS,__itoa,__std_ltoa,$.aliases/_itoa.o)
+	@$(call DO.STDALIAS,__Exit,__exit,$.aliases/__Exit.o)
+	for i in $(ALIAS.FUNCS); do \
+		echo "Aliasing _$$i to __std_$$i ..."; \
+        echo ".stabs \"_$$i\",11,0,0,0;.stabs \"__std_$$i\",1,0,0,0;" > $.aliases/_$$i.s; \
+        if as -o $.aliases/_$$i.o $.aliases/_$$i.s; then \
+		else false; \
+		fi \
+	done
+	for i in $(ALIAS._FUNCS); do \
+		echo "Aliasing __$$i to __std_$$i ..."; \
+		echo ".stabs \"__$$i\",11,0,0,0;.stabs \"__std_$$i\",1,0,0,0;" > $.aliases/__$$i.s; \
+		if as -o $.aliases/__$$i.o $.aliases/__$$i.s; then \
+		else false; \
+		fi \
+	done
+	$(AR) $(ARFLAGS) $@ $.aliases/*.o
 
 include mkomflib.smak
Index: trunk/src/emx/src/lib/app/app.smak
===================================================================
--- trunk/src/emx/src/lib/app/app.smak	(revision 809)
+++ trunk/src/emx/src/lib/app/app.smak	(revision 810)
@@ -7,5 +7,5 @@
 
 .TKIND	:= aout
-.TARGET	:= c_app.a
+.TARGET	:= libc_app.a
 .TSRC	:= $(wildcard src/lib/app/*.c)
 .TCF	:= -I$.
@@ -20,4 +20,4 @@
 
 .TKIND	:= aout prof
-.TARGET	:= c_app_p.a
+.TARGET	:= libc_app_p.a
 include mklib.smak
Index: trunk/src/emx/src/lib/io/eadread.c
===================================================================
--- trunk/src/emx/src/lib/io/eadread.c	(revision 809)
+++ trunk/src/emx/src/lib/io/eadread.c	(revision 810)
@@ -11,4 +11,5 @@
 #include <errno.h>
 #include <sys/ead.h>
+#include <emx/umalloc.h>
 #include "ea.h"
 
@@ -147,5 +148,7 @@
     {
       reftype = ENUMEA_REFTYPE_PATH;
-      fileref = path;
+      i = strlen(path) + 1;
+      fileref = alloca(i);
+      memcpy(fileref, path, i);
     }
   else
@@ -162,5 +165,5 @@
         {
           dena_buf_size += 0x20000; /* DosEnumAttribute is broken */
-          dena_buf = realloc (dena_buf, dena_buf_size);
+          dena_buf = _lrealloc (dena_buf, dena_buf_size);
           if (dena_buf == NULL)
             {
Index: trunk/src/emx/src/lib/libc.def
===================================================================
--- trunk/src/emx/src/lib/libc.def	(revision 809)
+++ trunk/src/emx/src/lib/libc.def	(revision 810)
@@ -43,5 +43,5 @@
     "__sys_pid" @23
     "__sys_ppid" @24
-    "__sys_private_heap" @25
+    "__um_high_heap" @25
     "__sys_thread_table" @26
     "__sys_top_heap_obj" @27
@@ -72,9 +72,8 @@
     "___locale_lconv" @52
     "___locale_time" @53
-    "__sys_virtual_address_limit" @54
-    "___pfnDosOpenL" @55
-    "___pfnDosSetFileLocksL" @56
-    "___pfnDosSetFilePtrL" @57
-    "___pfnDosSetFileSizeL" @58
+    "__um_low_heap" @54
+    "__rand48_add" @55
+    "__rand48_mult" @56
+    "__rand48_seed" @57
 
 ; code
@@ -89,6 +88,6 @@
     "__init1_fdinit" @108
     "__init1_tmp" @109
-    "___init_environ" @110
-    "___init_ret" @111
+    "__std_posix_memalign" @110
+    "__lrealloc" @111
     "__init_streams" @112
     "___initthread" @113
@@ -812,5 +811,5 @@
     "__std_unsetenv" @831
     "__std_lockf" @832
-    "___init_largefileio" @833
+    "__lmalloc" @833
     "__std_fseeko" @834
     "__std_ftello" @835
@@ -835,14 +834,17 @@
     "__dorand48" @854
     "__std_srand48" @855
-    "__rand48_add" @856
-    "__rand48_mult" @857
-    "__rand48_seed" @858
-    "__std_drand48" @859
-    "__std_erand48" @860
-    "__std_jrand48" @861
-    "__std_lcong48" @862
-    "__std_lrand48" @863
-    "__std_mrand48" @864
-    "__std_nrand48" @865
-    "__std_seed48" @866
-    "__std_qsort_r" @867
+    "__std_drand48" @856
+    "__std_erand48" @857
+    "__std_jrand48" @858
+    "__std_lcong48" @859
+    "__std_lrand48" @860
+    "__std_mrand48" @861
+    "__std_nrand48" @862
+    "__std_seed48" @863
+    "__std_qsort_r" @864
+    "__hcalloc" @865
+    "__hinitheap" @866
+    "__hmalloc" @867
+    "__hrealloc" @868
+    "__lcalloc" @869
+    "__linitheap" @870
Index: trunk/src/emx/src/lib/libc.smak
===================================================================
--- trunk/src/emx/src/lib/libc.smak	(revision 809)
+++ trunk/src/emx/src/lib/libc.smak	(revision 810)
@@ -25,5 +25,5 @@
 .MDESC	:= The C library
 
-.TARGET	:= c_p.a
+.TARGET	:= libc_p.a
 .TKIND	:= aout prof
 .TSRC	:= $(libc.TSRC.$(CPU)) $(libc.TSRC)
@@ -34,6 +34,6 @@
 include mklib.smak
 
-# Build c.a last since LIBC.DLL needs .OBJS from c.a
-.TARGET	:= c.a
+# Build libc.a last since LIBC.DLL needs .OBJS from libc.a
+.TARGET	:= libc.a
 .TKIND	:= aout
 .TKEEP	:= 1
@@ -49,9 +49,9 @@
 LIBC.STUBARG	:= $(if $(LIBC.STUB),-Zlinker -STUB:$(LIBC.STUB))
 LIBC.DLL        := $.omf/libc$(VH)$(VM).dll
-LIBC.IMPLIB     := $.omf/c_dll.lib $.aout/c_dll.a
+LIBC.IMPLIB     := $.omf/libc_dll.lib $.aout/libc_dll.a
 LIBC.DEF        := $.omf/libc.def
-LIBC.OBJS       := $.omf/src/lib/startup/386/dll0.obj $.omf/src/lib/startup/dllinit.obj
-LIBC.LIBS       := $.omf/c.lib $.omf/c_app.lib
-LIBC.DEPS       := $(LIBC.STUB) $.omf/c_alias.lib
+LIBC.OBJS       := $.omf/src/lib/startup/dll0hi.obj $.omf/src/lib/startup/dllinit.obj
+LIBC.LIBS       := $.omf/libc.lib $.omf/libc_app.lib
+LIBC.DEPS       := $(LIBC.STUB) $.omf/libc_alias.lib
 LIBC.DLL.OBJS   :=
 LIBC.DIRS       := $(sort $(dir $(LIBC.OBJS) $(LIBC.DEPS) $(LIBC.DLL.OBJS)))
@@ -59,6 +59,6 @@
 LIBC.PRF.DLL	:= $(LIBC.DLL:.dll=.prf)
 LIBC.PRF.DEF    := $.omf/libc.prf.def
-LIBC.PRF.OBJS   := $.omf/src/lib/startup/386/dll0.obj $.omf-prof/src/lib/startup/dllinit.obj
-LIBC.PRF.LIBS   := $.omf-prof/c_p.lib $.omf-prof/c_app_p.lib
+LIBC.PRF.OBJS   := $.omf/src/lib/startup/dll0hi.obj $.omf-prof/src/lib/startup/dllinit.obj
+LIBC.PRF.LIBS   := $.omf-prof/libc_p.lib $.omf-prof/libc_app_p.lib
 LIBC.PRF.DEPS   := $(LIBC.DEPS)
 LIBC.PRF.DIRS   := $(sort $(dir $(LIBC.PRF.OBJS) $(LIBC.PRF.DEPS)))
@@ -95,4 +95,6 @@
 	@$(call FECHO,$@,EXPORTS)
 	$(call DO.EMXEXP,$(filter %.lib,$^),$@)
+	sed -e "/\"___pfn/d" -e "/\"__sys_/d" -e "/\"___libc_/d" $@ > $@.tmp
+	mv -f $@.tmp $@
 	krx.exe src/lib/dlllegacy.cmd -e "_DLL_InitTerm" $@ src/lib/libc.def
 
@@ -114,5 +116,5 @@
 	echo $@		
 
-# LIBC .def file (two steps).
+# LIBC.PREF .def file
 $(LIBC.PRF.DEF): $(LIBC.DEF)
 	$(call RM,$@)
@@ -134,7 +136,7 @@
 	echo $@		
 
-# LIBC .def file (two steps)
+# LIBC.ELH .def file
 # Man! This sucks! Isn't there support for inline files (<<\nfile\n<<) in GNU MAKE?
-# Even M$/IBM nmake	have that.
+# Even M$/IBM nmake	have that. ;-)
 # And no, I couldn't care less about performance with this type of DLL.
 $(LIBC.ELH.DEF): $(LIBC.DEF) src/lib/libc.smak
@@ -213,5 +215,5 @@
 .PHONY: libc-dll
 all: libc-dll
-libc-dll: emxbind emxexp app alias libc os2 \
+libc-dll: emxbind emxexp app alias libc os2 os2@omf \
 			$(LIBC.DIRS) $(LIBC.DLL) $(LIBC.IMPLIB) \
 			$(LIBC.PRF.DIRS) $(LIBC.PRF.DLL) \
@@ -244,6 +246,6 @@
 
 # How libc-std.h can be auto-generated.
-# Unfortunately, we cannot use c.a to find out all _std_ names since
-# c.a itself depends on this header file. Thus we have to scan all source
+# Unfortunately, we cannot use libc.a to find out all _std_ names since
+# libc.a itself depends on this header file. Thus we have to scan all source
 # files for _STD() macros invocations. Fortunately, gawk rulez forever thus
 # this happens in just a fraction of second.
Index: trunk/src/emx/src/lib/malloc/_hcalloc.c
===================================================================
--- trunk/src/emx/src/lib/malloc/_hcalloc.c	(revision 810)
+++ trunk/src/emx/src/lib/malloc/_hcalloc.c	(revision 810)
@@ -0,0 +1,51 @@
+/* $Id$ */
+/** @file
+ *
+ * High Memory Heap - calloc().
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include "libc-alias.h"
+#include <umalloc.h>
+#include <emx/umalloc.h>
+#include <emx/umalloc.h>
+
+
+/**
+ * Allocate a memory block from the high memory heap.
+ *
+ * @returns Pointer to zero filled block of cItems*cbItem bytes.
+ * @returns NULL on failure.
+ * @param   cItems  Number of items to allocate.
+ * @param   cbItem  Size of one item.
+ * @remark  If the system doesn't have available high memory or doesn't support
+ *          high memory the low memory heap is used.
+ */
+void *_hcalloc(size_t cItems, size_t cbItem)
+{
+    if (!_um_high_heap)
+        if (!_hinitheap())
+            return NULL;
+    return _ucalloc(_um_high_heap, cItems, cbItem);
+}
+
Index: trunk/src/emx/src/lib/malloc/_heapvoting.c
===================================================================
--- trunk/src/emx/src/lib/malloc/_heapvoting.c	(revision 810)
+++ trunk/src/emx/src/lib/malloc/_heapvoting.c	(revision 810)
@@ -0,0 +1,85 @@
+/* $Id$ */
+/** @file
+ *
+ * Voting on default heap in High or Low memory.
+ *
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include <emx/umalloc.h>
+
+
+/*******************************************************************************
+*   Global Variables                                                           *
+*******************************************************************************/
+/** The voting result. */
+static enum { enmHigh = 0, enmLow = 1, enmResultLow = 2, enmResultHigh = 4 }
+    enmResult = enmHigh;
+
+
+/**
+ * Place a vote for which heap to use as default.
+ *
+ * @param   fDefaultHeapInHighMem
+ */
+void    __libc_HeapVote(int fDefaultHeapInHighMem)
+{
+    if (enmResult < enmResultLow)
+    {
+        if (!fDefaultHeapInHighMem)
+            enmResult = enmLow;
+    }
+#ifdef DEBUG
+    else { __asm__ (" int $3"); }
+#endif
+}
+
+
+/**
+ * End the voting.
+ */
+void    __libc_HeapEndVoting(void)
+{
+    if (enmResult < enmResultLow)
+        enmResult = (enmResult == enmHigh) ? enmResultHigh : enmResultLow;
+#ifdef DEBUG
+    else { __asm__ (" int $3"); }
+#endif
+}
+
+
+/**
+ * Asks what the result of the voting were.
+ *
+ * @returns 0 if to use the low memory heap.
+ * @returns 1 if to use the high memory heap.
+ * @returns -1 if the voting isn't finished yet.
+ */
+int     __libc_HeapGetResult(void)
+{
+    if (enmResult < enmResultLow)
+        return -1;
+    return (enmResult == enmResultHigh);
+}
+
Index: trunk/src/emx/src/lib/malloc/_hinitheap.c
===================================================================
--- trunk/src/emx/src/lib/malloc/_hinitheap.c	(revision 810)
+++ trunk/src/emx/src/lib/malloc/_hinitheap.c	(revision 810)
@@ -0,0 +1,121 @@
+/* $Id$ */
+/** @file
+ *
+ * High Memory Heap - init.
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+
+ */
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include "libc-alias.h"
+#include <stdlib.h>
+#include <emx/umalloc.h>
+#include <sys/smutex.h>
+
+/*******************************************************************************
+*   Global Variables                                                           *
+*******************************************************************************/
+/** Handle to the High Memory Heap.
+ * This is NULL till _hinitheap() is called.
+ * It may be equal to _um_low_heap if there isn't any high memory on the machine.
+ */
+Heap_t _um_high_heap;
+
+
+/**
+ * Initializes the heap which resides in high memory.
+ *
+ * If we do not support high memory a we'll init and use the low memory heap.
+ *
+ * @returns _um_high_heap on success.
+ * @returns don't return on failure.
+ */
+Heap_t   _hinitheap(void)
+{
+    /* only one init at a time. */
+    static _smutex  lock;
+    void *          pvInitial;
+    size_t          cbInitial;
+    int             fClean;
+    Heap_t          Heap;
+
+
+    /*
+     * Request sem and check if we it's already initialized.
+     */
+    _smutex_request(&lock);
+    Heap = _um_high_heap;
+    if (Heap)
+    {
+        _smutex_release(&lock);
+        return Heap;
+    }
+
+    /*
+     * Highmemory support?
+     */
+    if (!__libc_HasHighMem())
+    {
+        _um_high_heap = Heap = _linitheap();
+        _smutex_release(&lock);
+        return Heap;
+    }
+
+    /*
+     * Allocate the initial heap block.
+     */
+    cbInitial = 4*1024*1024;
+    fClean = _BLOCK_CLEAN;
+    pvInitial = __libc_HimemDefaultAlloc(NULL, &cbInitial, &fClean);
+    if (!pvInitial)
+    {
+        abort();
+        return NULL;
+    }
+
+    /*
+     * Create and open the heap.
+     */
+    Heap = _ucreate2(pvInitial, cbInitial, fClean,
+                     _HEAP_REGULAR | _HEAP_HIGHMEM,
+                     __libc_HimemDefaultAlloc, __libc_HimemDefaultRelease,
+                     NULL, NULL);
+    if (Heap == NULL)
+    {
+        abort();
+        return NULL;
+    }
+    if (_uopen(Heap) != 0)
+    {
+        abort();
+        return NULL;
+    }
+
+    /*
+     * Set the global low heap handle release mutex and be gone.
+     */
+    _um_high_heap = Heap;
+    _smutex_release(&lock);
+
+    return Heap;
+}
+
Index: trunk/src/emx/src/lib/malloc/_hmalloc.c
===================================================================
--- trunk/src/emx/src/lib/malloc/_hmalloc.c	(revision 810)
+++ trunk/src/emx/src/lib/malloc/_hmalloc.c	(revision 810)
@@ -0,0 +1,50 @@
+/* $Id$ */
+/** @file
+ *
+ * High Memory Heap - malloc().
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include "libc-alias.h"
+#include <umalloc.h>
+#include <emx/umalloc.h>
+#include <emx/umalloc.h>
+
+
+/**
+ * Allocate a memory block from the high memory heap.
+ *
+ * @returns Pointer to block of cb bytes.
+ * @returns NULL on failure.
+ * @param   cb  Number of bytes to allocate.
+ * @remark  If the system doesn't have available high memory or doesn't support
+ *          high memory the low memory heap is used.
+ */
+void *_hmalloc(size_t cb)
+{
+    if (!_um_high_heap)
+        if (!_hinitheap())
+            return NULL;
+    return _umalloc(_um_high_heap, cb);
+}
+
Index: trunk/src/emx/src/lib/malloc/_hrealloc.c
===================================================================
--- trunk/src/emx/src/lib/malloc/_hrealloc.c	(revision 810)
+++ trunk/src/emx/src/lib/malloc/_hrealloc.c	(revision 810)
@@ -0,0 +1,53 @@
+/* $Id$ */
+/** @file
+ *
+ * High Memory Heap - realloc().
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include "libc-alias.h"
+#include <umalloc.h>
+#include <emx/umalloc.h>
+#include <emx/umalloc.h>
+
+
+/**
+ * Rellocate a memory block from the high memory heap.
+ *
+ * @returns Pointer to reallocated block on success.
+ * @returns NULL if cbNew, pv is freed.
+ * @returns NULL on failure (cbNew != 0), pv not touched.
+ * @param   pv      Pointer to the memory block to allocate.
+ *                  If NULL the function behaves like _lmalloc().
+ * @param   cbNew   The new block size.
+ *                  If Zero the function behaves like free().
+ * @remark  If the system doesn't have available high memory or doesn't support
+ *          high memory the low memory heap is used.
+ */
+void *_hrealloc(void * pv, size_t cbNew)
+{
+    if (!pv)
+      return _hmalloc(cbNew);
+    return _um_realloc(pv, cbNew, cbNew < 32 ? 4 : 16, 0);
+}
+
Index: trunk/src/emx/src/lib/malloc/_lcalloc.c
===================================================================
--- trunk/src/emx/src/lib/malloc/_lcalloc.c	(revision 810)
+++ trunk/src/emx/src/lib/malloc/_lcalloc.c	(revision 810)
@@ -0,0 +1,50 @@
+/* $Id$ */
+/** @file
+ *
+ * Low Memory Heap - calloc().
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include "libc-alias.h"
+#include <umalloc.h>
+#include <emx/umalloc.h>
+#include <emx/umalloc.h>
+
+
+/**
+ * Allocate a memory block from the low memory heap.
+ *
+ * @returns Pointer to zero filled block of cItems*cbItem bytes.
+ * @returns NULL on failure.
+ * @param   cItems  Number of items to allocate.
+ * @param   cbItem  Size of one item.
+ */
+void *_lcalloc(size_t cItems, size_t cbItem)
+{
+    if (!_um_low_heap)
+        if (!_linitheap())
+            return NULL;
+    return _ucalloc(_um_low_heap, cItems, cbItem);
+}
+
Index: trunk/src/emx/src/lib/malloc/_linitheap.c
===================================================================
--- trunk/src/emx/src/lib/malloc/_linitheap.c	(revision 810)
+++ trunk/src/emx/src/lib/malloc/_linitheap.c	(revision 810)
@@ -0,0 +1,106 @@
+/* $Id$ */
+/** @file
+ *
+ * Low Memory Heap - init.
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+
+ */
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include "libc-alias.h"
+#include <stdlib.h>
+#include <emx/umalloc.h>
+#include <sys/smutex.h>
+
+
+/*******************************************************************************
+*   Global Variables                                                           *
+*******************************************************************************/
+/** Handle to the Low Memory Heap.
+ * This is NULL till _linitheap() is called.
+ */
+Heap_t _um_low_heap;
+
+
+/**
+ * Initializes the heap which resides in low memory.
+ *
+ * @returns _um_low_heap on success.
+ * @returns doens't return on failure.
+ */
+Heap_t   _linitheap(void)
+{
+    /* only one init at a time. */
+    static _smutex  lock;
+    void *          pvInitial;
+    Heap_t          Heap;
+
+
+    /*
+     * Request sem and check if we it's already initialized.
+     */
+    _smutex_request(&lock);
+    Heap = _um_low_heap;
+    if (Heap)
+    {
+        _smutex_release(&lock);
+        return Heap;
+    }
+
+    /*
+     * Initialize the sbrk model and allocate the initial heap block.
+     */
+    _uflags(_UF_SBRK_MODEL, _UF_SBRK_ARBITRARY);
+    pvInitial = sbrk(_INITIAL_DEFAULT_HEAP_SIZE);
+    if (pvInitial == (void *)-1)
+    {
+        abort();
+        return NULL;
+    }
+
+    /*
+     * Create and open the heap.
+     */
+    Heap = _ucreate2(pvInitial, _INITIAL_DEFAULT_HEAP_SIZE, !_BLOCK_CLEAN,
+                     _HEAP_REGULAR,
+                     _um_default_alloc,  _um_default_release,
+                     _um_default_expand, _um_default_shrink);
+    if (Heap == NULL)
+    {
+        abort();
+        return NULL;
+    }
+    if (_uopen(Heap) != 0)
+    {
+        abort();
+        return NULL;
+    }
+
+    /*
+     * Set the global low heap handle release mutex and be gone.
+     */
+    _um_low_heap = Heap;
+    _smutex_release(&lock);
+
+    return Heap;
+}
+
Index: trunk/src/emx/src/lib/malloc/_lmalloc.c
===================================================================
--- trunk/src/emx/src/lib/malloc/_lmalloc.c	(revision 810)
+++ trunk/src/emx/src/lib/malloc/_lmalloc.c	(revision 810)
@@ -0,0 +1,48 @@
+/* $Id$ */
+/** @file
+ *
+ * Low Memory Heap - malloc().
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include "libc-alias.h"
+#include <umalloc.h>
+#include <emx/umalloc.h>
+#include <emx/umalloc.h>
+
+
+/**
+ * Allocate a memory block from the low memory heap.
+ *
+ * @returns Pointer to block of cb bytes.
+ * @returns NULL on failure.
+ * @param   cb  Number of bytes to allocate.
+ */
+void *_lmalloc(size_t cb)
+{
+    if (!_um_low_heap)
+        if (!_linitheap())
+            return NULL;
+    return _umalloc(_um_low_heap, cb);
+}
+
Index: trunk/src/emx/src/lib/malloc/_lrealloc.c
===================================================================
--- trunk/src/emx/src/lib/malloc/_lrealloc.c	(revision 810)
+++ trunk/src/emx/src/lib/malloc/_lrealloc.c	(revision 810)
@@ -0,0 +1,52 @@
+/* $Id$ */
+/** @file
+ *
+ * Low Memory Heap - realloc().
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include "libc-alias.h"
+#include <umalloc.h>
+#include <emx/umalloc.h>
+#include <emx/umalloc.h>
+
+
+/**
+ * Rellocate a memory block from the low memory heap.
+ *
+ * @returns Pointer to reallocated block on success.
+ * @returns NULL if cbNew, pv is freed.
+ * @returns NULL on failure (cbNew != 0), pv not touched.
+ * @param   pv      Pointer to the memory block to allocate.
+ *                  If NULL the function behaves like _lmalloc().
+ * @param   cbNew   The new block size.
+ *                  If Zero the function behaves like free().
+ */
+void *_lrealloc(void * pv, size_t cbNew)
+{
+    if (!pv)
+      return _lmalloc(cbNew);
+    return _um_realloc(pv, cbNew, cbNew < 32 ? 4 : 16, 0);
+}
+
+
Index: trunk/src/emx/src/lib/malloc/heapchk.c
===================================================================
--- trunk/src/emx/src/lib/malloc/heapchk.c	(revision 809)
+++ trunk/src/emx/src/lib/malloc/heapchk.c	(revision 810)
@@ -15,16 +15,18 @@
   _UM_MT_DECL
   int rc1, rc2;
+  Heap_t    heap_reg = _UM_DEFAULT_REGULAR_HEAP;
+  Heap_t    heap_tiled = _UM_DEFAULT_TILED_HEAP;
 
   /* Initialize the heap pointers, in case _heapchk() is called by a
      new thread before malloc(). */
 
-  if (_UM_DEFAULT_REGULAR_HEAP == NULL)
-    _um_init_default_regular_heap ();
-  if (_UM_DEFAULT_TILED_HEAP == NULL)
-    _um_init_default_tiled_heap ();
+  if (heap_reg == NULL)
+    heap_reg = _um_init_default_regular_heap ();
+  if (heap_tiled == NULL)
+    heap_tiled = _um_init_default_tiled_heap ();
 
   /* First check the regular heap. */
 
-  rc1 = _uheapchk (_UM_DEFAULT_REGULAR_HEAP);
+  rc1 = _uheapchk (heap_reg);
   if (rc1 != _HEAPOK && rc1 != _HEAPEMPTY)
     return rc1;
@@ -40,5 +42,5 @@
      heaps is non-empty. */
 
-  rc2 = _uheapchk (_UM_DEFAULT_TILED_HEAP);
+  rc2 = _uheapchk (heap_tiled);
   if (rc2 == _HEAPEMPTY)
     return rc1;
Index: trunk/src/emx/src/lib/malloc/heapmin.c
===================================================================
--- trunk/src/emx/src/lib/malloc/heapmin.c	(revision 809)
+++ trunk/src/emx/src/lib/malloc/heapmin.c	(revision 810)
@@ -14,7 +14,8 @@
 {
   _UM_MT_DECL
+  Heap_t    heap_reg = _UM_DEFAULT_REGULAR_HEAP;
 
-  if (_UM_DEFAULT_REGULAR_HEAP == NULL)
-    _um_init_default_regular_heap ();
-  return _uheapmin (_UM_DEFAULT_REGULAR_HEAP);
+  if (heap_reg == NULL)
+    heap_reg = _um_init_default_regular_heap ();
+  return _uheapmin (heap_reg);
 }
Index: trunk/src/emx/src/lib/malloc/heapwalk.c
===================================================================
--- trunk/src/emx/src/lib/malloc/heapwalk.c	(revision 809)
+++ trunk/src/emx/src/lib/malloc/heapwalk.c	(revision 810)
@@ -2,10 +2,5 @@
 
 #include "libc-alias.h"
-#include <stdlib.h>
-#include <stddef.h>
 #include <umalloc.h>
-#include <sys/builtin.h>        /* For <sys/fmutex.h> */
-#include <sys/fmutex.h>         /* For <sys/rmutex.h> */
-#include <sys/rmutex.h>
 #include <emx/umalloc.h>
 #include <emx/thread.h>
@@ -14,17 +9,19 @@
 {
   _UM_MT_DECL
-  int rc;
+  Heap_t    heap_reg = _UM_DEFAULT_REGULAR_HEAP;
+  Heap_t    heap_tiled = _UM_DEFAULT_TILED_HEAP;
+  int       rc;
 
   /* Initialize the heap pointers, in case _heap_walk() is called by a
      new thread before malloc(). */
 
-  if (_UM_DEFAULT_REGULAR_HEAP == NULL)
-    _um_init_default_regular_heap ();
-  if (_UM_DEFAULT_TILED_HEAP == NULL)
-    _um_init_default_tiled_heap ();
+  if (heap_reg == NULL)
+    heap_reg = _um_init_default_regular_heap ();
+  if (heap_tiled == NULL)
+    heap_tiled = _um_init_default_tiled_heap ();
 
   /* First walk through the regular heap. */
 
-  rc = _uheap_walk (_UM_DEFAULT_REGULAR_HEAP, callback);
+  rc = _uheap_walk (heap_reg, callback);
   if (rc != 0)
     return rc;
@@ -33,10 +30,9 @@
      heap, return the regular heap's status. */
 
-  if (_UM_DEFAULT_REGULAR_HEAP == _UM_DEFAULT_TILED_HEAP
-      || _UM_DEFAULT_TILED_HEAP == NULL)
+  if (heap_reg == heap_tiled || heap_tiled == NULL)
     return rc;
 
   /* Walk through the tiled heap. */
 
-  return _uheap_walk (_UM_DEFAULT_TILED_HEAP, callback);
+  return _uheap_walk (heap_tiled, callback);
 }
Index: trunk/src/emx/src/lib/malloc/initr.c
===================================================================
--- trunk/src/emx/src/lib/malloc/initr.c	(revision 809)
+++ trunk/src/emx/src/lib/malloc/initr.c	(revision 810)
@@ -2,55 +2,78 @@
 
 #include "libc-alias.h"
-#include <stdlib.h>
-#include <stddef.h>
 #include <umalloc.h>
-#include <sys/builtin.h>        /* For <sys/fmutex.h> */
-#include <sys/fmutex.h>         /* For <sys/rmutex.h> */
-#include <sys/rmutex.h>
+#include <emx/umalloc.h>
 #include <sys/smutex.h>
-#include <sys/uflags.h>
-#include <emx/umalloc.h>
 #include <emx/thread.h>
 
-/* This is the default regular heap. */
-
+/** This is the default regular heap. */
 Heap_t _um_regular_heap;
 
+/**
+ * Sets the default regular heap for the current thread and perhaps
+ * even the system.
+ *
+ * Now because of the voting procedure we do not set the _um_regular_heap nor
+ * the per thread variable until the voting is completed. There for make sure
+ * to use the returned value not the one in the per thread or system variables!
+ *
+ * @returns Default heap for the thread.
+ */
+Heap_t _um_init_default_regular_heap(void)
+{
+    _UM_MT_DECL
+    static _smutex  lock;
+    Heap_t          heap_reg = _UM_DEFAULT_REGULAR_HEAP;
 
-void _um_init_default_regular_heap (void)
-{
-  _UM_MT_DECL
-  void *memory;
-  Heap_t h;
-  static _smutex lock;
+    /*
+     * Is there actually anything left to be done?
+     */
+    if (!heap_reg)
+    {
+        int     vote = __libc_HeapGetResult();
+        if (vote >= 0)
+        {
+            /*
+             * Is system wide default heap initiated?
+             */
+            _smutex_request(&lock);
+            heap_reg = _um_regular_heap;
+            if (!heap_reg)
+            {
+                if (vote)
+                {
+                    /*
+                     * Use high memory heap.
+                     */
+                    _um_regular_heap = heap_reg = _hinitheap();
+                }
+                else
+                {
+                    /*
+                     * Use low memory heap.
+                     */
+                    _um_regular_heap = heap_reg = _linitheap();
+                }
+            }
+            _smutex_release(&lock);
 
-  _smutex_request (&lock);
-
-  /* Create the regular heap if it hasn't been created by another
-     thread between the check of _UM_DEFAULT_REGULAR_HEAP by our
-     caller and obtaining the semaphore. */
-
-  if (_UM_DEFAULT_REGULAR_HEAP == NULL)
-    {
-      if (_um_regular_heap == NULL)
+            /*
+             * Set the per thread default.
+             */
+            _UM_DEFAULT_REGULAR_HEAP = heap_reg;
+        }
+        else
         {
-          _uflags (_UF_SBRK_MODEL, _UF_SBRK_ARBITRARY);
-          memory = sbrk (_INITIAL_DEFAULT_HEAP_SIZE);
-          if (memory == (void *)-1)
-            abort ();
-          h = _ucreate2 (memory, _INITIAL_DEFAULT_HEAP_SIZE,
-                         !_BLOCK_CLEAN, _HEAP_REGULAR,
-                         _um_default_alloc, _um_default_release,
-                         _um_default_expand, _um_default_shrink);
-          if (h == NULL)
-            abort ();
-          if (_uopen (h) != 0)
-            abort ();
-          _um_regular_heap = h;
+            /*
+             * The voting is not yet over, so we must return the low heap.
+             * We do not set either the per thread or system defaults!
+             */
+            heap_reg = _um_low_heap;
+            if (!heap_reg)
+                heap_reg = _linitheap();
         }
-
-      _UM_DEFAULT_REGULAR_HEAP = _um_regular_heap;
     }
 
-  _smutex_release (&lock);
+    return heap_reg;
 }
+
Index: trunk/src/emx/src/lib/malloc/initt.c
===================================================================
--- trunk/src/emx/src/lib/malloc/initt.c	(revision 809)
+++ trunk/src/emx/src/lib/malloc/initt.c	(revision 810)
@@ -2,44 +2,46 @@
 
 #include "libc-alias.h"
-#include <stdlib.h>
-#include <stddef.h>
-#include <umalloc.h>
-#include <sys/builtin.h>        /* For <sys/fmutex.h> */
-#include <sys/fmutex.h>         /* For <sys/rmutex.h> */
-#include <sys/rmutex.h>
+#include <emx/umalloc.h>
 #include <sys/smutex.h>
-#include <sys/uflags.h>
-#include <emx/umalloc.h>
 #include <emx/thread.h>
 
-/* This is the default tiled heap. */
-
+/** This is the default tiled heap. */
 Heap_t _um_tiled_heap = NULL;
 
+/**
+ * Initialize the default tiled heap for the current thread.
+ *
+ * Sets _um_tiled_heap to _um_low_heap if zero. The per thread
+ * default tiled heap is set to _um_tiled_heap.
+ *
+ * @returns Heap handle on success.
+ */
+Heap_t _um_init_default_tiled_heap(void)
+{
+    _UM_MT_DECL
+    Heap_t          heap_tiled;
+    static _smutex  lock;
 
-void _um_init_default_tiled_heap (void)
-{
-  _UM_MT_DECL
-  static _smutex lock;
-
-  _smutex_request (&lock);
-
-  /* Create the tiled heap if it hasn't been created by another thread
-     between the check of _UM_DEFAULT_TILED_HEAP by our caller and
-     obtaining the semaphore. */
-
-  if (_UM_DEFAULT_TILED_HEAP == NULL)
+    /*
+     * Create the tiled heap if it hasn't been created by another thread
+     * between the check of _UM_DEFAULT_TILED_HEAP by our caller and
+     * obtaining the semaphore.
+     */
+    heap_tiled = _UM_DEFAULT_TILED_HEAP;
+    if (heap_tiled == NULL)
     {
-      if (_um_tiled_heap == NULL)
+        _smutex_request(&lock);
+        if (_um_tiled_heap == NULL)
         {
-          /* Use the regular heap also as tiled heap. */
-          _um_init_default_regular_heap ();
-          _um_tiled_heap = _um_regular_heap;
+            /* Use the low heap also as tiled heap. */
+            _linitheap();
+            _um_tiled_heap = _um_low_heap;
         }
 
-
-      _UM_DEFAULT_TILED_HEAP = _um_tiled_heap;
+        _UM_DEFAULT_TILED_HEAP = heap_tiled = _um_tiled_heap;
+        _smutex_release(&lock);
     }
 
-  _smutex_release (&lock);
+    return heap_tiled;
 }
+
Index: trunk/src/emx/src/lib/malloc/malloc.c
===================================================================
--- trunk/src/emx/src/lib/malloc/malloc.c	(revision 809)
+++ trunk/src/emx/src/lib/malloc/malloc.c	(revision 810)
@@ -14,7 +14,8 @@
 {
   _UM_MT_DECL
+  Heap_t    heap_reg = _UM_DEFAULT_REGULAR_HEAP;
 
-  if (_UM_DEFAULT_REGULAR_HEAP == NULL)
-    _um_init_default_regular_heap ();
-  return _umalloc (_UM_DEFAULT_REGULAR_HEAP, size);
+  if (heap_reg == NULL)
+    heap_reg = _um_init_default_regular_heap ();
+  return _umalloc (heap_reg, size);
 }
Index: trunk/src/emx/src/lib/malloc/posix_memalign.c
===================================================================
--- trunk/src/emx/src/lib/malloc/posix_memalign.c	(revision 810)
+++ trunk/src/emx/src/lib/malloc/posix_memalign.c	(revision 810)
@@ -0,0 +1,81 @@
+/* $Id$ */
+/** @file
+ *
+ * posix_memalign() implementation.
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include "libc-alias.h"
+#include <stdlib.h>
+#include <stddef.h>
+#include <umalloc.h>
+#include <emx/umalloc.h>
+#include <emx/thread.h>
+#include <assert.h>
+
+/**
+ * Aligned allocation.
+ * @returns 0 on success.
+ * @returns -1 on failure. errno set.
+ * @param   memptr      Where to store the pointer to the allocated memory.
+ * @param   alignment   How to align the memory. Must be power of two.
+ * @param   size        Number of bytes to allocate.
+ * @todo    Split this into a _umalloc_aligned() worker perhaps.
+ */
+int _STD(posix_memalign)(void **memptr, size_t alignment, size_t size)
+{
+    _UM_MT_DECL
+    void *      pv;
+    unsigned    flags;
+    Heap_t      Heap = _UM_DEFAULT_REGULAR_HEAP;
+
+    /*
+     * Input values.
+     */
+    *memptr = NULL;                     /* touch it so we crash here. */
+    /** @todo verify that alignment is a power of 2 */
+
+    /*
+     * Get, optionally initialize, and assert the validity of the heap.
+     */
+    if (Heap == NULL)
+        Heap = _um_init_default_regular_heap();
+
+    assert(Heap->magic == _UM_MAGIC_HEAP);
+    if (Heap->magic != _UM_MAGIC_HEAP)
+      return NULL;
+
+    /*
+     * Do the allocation.
+     */
+    _um_heap_lock(Heap);
+    flags = 0;
+    if (Heap->type & _HEAP_TILED)
+        flags |= _UMFI_TILED;
+    pv = _um_alloc_no_lock(Heap, size, alignment, flags);
+    _um_heap_unlock(Heap);
+
+    /*
+     * Store the result and return.
+     */
+    *memptr = pv;
+    return pv ? 0 : -1;
+}
+
Index: trunk/src/emx/src/lib/malloc/realloc.c
===================================================================
--- trunk/src/emx/src/lib/malloc/realloc.c	(revision 809)
+++ trunk/src/emx/src/lib/malloc/realloc.c	(revision 810)
@@ -15,4 +15,4 @@
     return malloc (new_size);
   else
-    return _um_realloc (block, new_size, 4, 0);
+    return _um_realloc (block, new_size, new_size < 32 ? 4 : 16, 0);
 }
Index: trunk/src/emx/src/lib/malloc/ucalloc.c
===================================================================
--- trunk/src/emx/src/lib/malloc/ucalloc.c	(revision 809)
+++ trunk/src/emx/src/lib/malloc/ucalloc.c	(revision 810)
@@ -18,4 +18,5 @@
   void *block;
   unsigned flags;
+  unsigned align;
 
   assert (h->magic == _UM_MAGIC_HEAP);
@@ -27,9 +28,11 @@
     return NULL;
 
+  align = (size < 32 ? 4 : 16);
+
   _um_heap_lock (h);
   flags = _UMFI_ZERO;
   if (h->type & _HEAP_TILED)
     flags |= _UMFI_TILED;
-  block = _um_alloc_no_lock (h, bytes, 4, flags);
+  block = _um_alloc_no_lock (h, bytes, align, flags);
   _um_heap_unlock (h);
   return block;
Index: trunk/src/emx/src/lib/malloc/ucreate2.c
===================================================================
--- trunk/src/emx/src/lib/malloc/ucreate2.c	(revision 809)
+++ trunk/src/emx/src/lib/malloc/ucreate2.c	(revision 810)
@@ -22,12 +22,16 @@
 
   /* Check the TYPE argument.  It must not contain any bits but
-     _HEAP_REGULAR, _HEAP_TILED, and _HEAP_SHARED.  Exactly one of
-     _HEAP_REGULAR and _HEAP_TILED must be set. */
+     _HEAP_REGULAR, _HEAP_TILED, _HEAP_SHARED, and _HEAP_HIGHMEM.
+     Exactly one of _HEAP_REGULAR and _HEAP_TILED must be set.
+     _HEAP_HIGHMEM and _HEAP_TILED are mutaly exclusive. */
 
-  if (type & ~(_HEAP_REGULAR|_HEAP_TILED|_HEAP_SHARED))
+  if (type & ~(_HEAP_REGULAR|_HEAP_TILED|_HEAP_SHARED|_HEAP_HIGHMEM))
     return NULL;
   t = type & (_HEAP_REGULAR|_HEAP_TILED);
   if (t != _HEAP_REGULAR && t != _HEAP_TILED)
       return NULL;
+  if ((type & (_HEAP_HIGHMEM|_HEAP_TILED)) == (_HEAP_HIGHMEM|_HEAP_TILED))
+      return NULL;
+
 
   /* Check the SIZE argument. */
Index: trunk/src/emx/src/lib/malloc/umalloc.c
===================================================================
--- trunk/src/emx/src/lib/malloc/umalloc.c	(revision 809)
+++ trunk/src/emx/src/lib/malloc/umalloc.c	(revision 810)
@@ -15,13 +15,15 @@
   void *block;
   unsigned flags;
+  unsigned align = (size < 32 ? 4 : 16);
 
   assert (h->magic == _UM_MAGIC_HEAP);
   if (h->magic != _UM_MAGIC_HEAP)
     return NULL;
+
   _um_heap_lock (h);
   flags = 0;
   if (h->type & _HEAP_TILED)
     flags |= _UMFI_TILED;
-  block = _um_alloc_no_lock (h, size, 4, flags);
+  block = _um_alloc_no_lock (h, size, align, flags);
   _um_heap_unlock (h);
   return block;
Index: trunk/src/emx/src/lib/malloc/utcalloc.c
===================================================================
--- trunk/src/emx/src/lib/malloc/utcalloc.c	(revision 809)
+++ trunk/src/emx/src/lib/malloc/utcalloc.c	(revision 810)
@@ -19,4 +19,6 @@
   if (h->magic != _UM_MAGIC_HEAP)
     return NULL;
+  if (h->type & _HEAP_HIGHMEM)
+    return NULL;
 
   bytes = count * size;
Index: trunk/src/emx/src/lib/malloc/utmalloc.c
===================================================================
--- trunk/src/emx/src/lib/malloc/utmalloc.c	(revision 809)
+++ trunk/src/emx/src/lib/malloc/utmalloc.c	(revision 810)
@@ -18,4 +18,6 @@
   if (h->magic != _UM_MAGIC_HEAP)
     return NULL;
+  if (h->type & _HEAP_HIGHMEM)
+    return NULL;
   _um_heap_lock (h);
   block = _um_alloc_no_lock (h, size, 4, _UMFI_TILED);
Index: trunk/src/emx/src/lib/misc/dirent.c
===================================================================
--- trunk/src/emx/src/lib/misc/dirent.c	(revision 809)
+++ trunk/src/emx/src/lib/misc/dirent.c	(revision 810)
@@ -11,4 +11,5 @@
 #include <emx/io.h>
 #include <emx/syscalls.h>
+#include <emx/umalloc.h>
 
 
@@ -115,5 +116,5 @@
          */
         cch = strlen(psz) + 1;
-        dp = malloc(sizeof(struct _dircontents) + cch);
+        dp = _hmalloc(sizeof(struct _dircontents) + cch);
         if (dp == NULL)
         {
Index: trunk/src/emx/src/lib/misc/getopt.c
===================================================================
--- trunk/src/emx/src/lib/misc/getopt.c	(revision 809)
+++ trunk/src/emx/src/lib/misc/getopt.c	(revision 810)
@@ -6,4 +6,5 @@
 #include <string.h>
 #include <emx/getopt.h>
+#include <emx/umalloc.h>
 
 char *optarg          = NULL;
@@ -47,6 +48,6 @@
       if (optmode == GETOPT_ANY)
         {
-          options = (char **)malloc (argc * sizeof (char *));
-          non_options = (char **)malloc (argc * sizeof (char *));
+          options = (char **)_hmalloc (argc * sizeof (char *));
+          non_options = (char **)_hmalloc (argc * sizeof (char *));
           if (options == NULL || non_options == NULL)
             {
Index: trunk/src/emx/src/lib/os2_386/highmem.txt
===================================================================
--- trunk/src/emx/src/lib/os2_386/highmem.txt	(revision 810)
+++ trunk/src/emx/src/lib/os2_386/highmem.txt	(revision 810)
@@ -0,0 +1,140 @@
+/** $Id$ */
+
+Private notes about highmemory support in LIBC.
+
+LIBC and most others assume stack to be in low memory.
+LIBC have two strategies of ensuring that buffers for API usage is thunked
+correctly:
+    1) Manualy ensuring it where the API is called.
+    2) API wrappers, 'Safe'-prefixed wrappers. This means the we must
+       include the wrapper header and link with the wrapper lib.
+
+
+This is the list of Dos APIs which officially support high memory in Aurora
+and later kernels:
+    DosAcknowledgeSignalException
+    DosAddMuxWaitSem
+    DosCloseEventSem
+    DosCloseMutexSem
+    DosCloseMuxWaitSem
+    DosCopy
+    DosCreateDir
+    DosCreateEventSem
+    DosCreateMutexSem
+    DosCreateMuxWaitSem
+    DosCreateNPipe
+    DosCreateQueue
+    DosCreateThread2
+    DosDelete
+    DosDeleteDir
+    DosDeleteMuxWaitSem
+    DosEnterMustComplete
+    DosExecPgm
+    DosExitMustComplete
+    DosFindFirst
+    DosFindNext
+    DosFreeMem
+    DosGetNamedSharedMem
+    DosGiveSharedMem
+    DosLoadModule
+    DosMove
+    DosOpen
+    DosOpenEventSem
+    DosOpenMutexSem
+    DosOpenMutexWaitSem
+    DosPhysicalDisk
+    DosPostEventSem
+    DosQueryCurrentDir
+    DosQueryCurrentDisk
+    DosQueryEventSem
+    DosQueryFSAttach
+    DosQueryFSInfo
+    DosQueryFileInfo
+    DosQueryMem
+    DosQueryModuleHandle
+    DosQueryModuleName
+    DosQueryMutexSem
+    DosQueryMuxWaitSem
+    DosQueryNPHState
+    DosQueryPageUsage
+    DosQueryPathInfo
+    DosRaiseException
+    DosRead
+    DosReadQueue
+    DosReleaseMutexSem
+    DosRequestMutexSem
+    DosResetEventSem
+    DosScanEnv
+    DosSearchPath
+    DosSendSignalException
+    DosSetCurrentDir
+    DosSetExceptionHandler
+    DosSetFileInfo
+    DosSetFileLocks
+    DosSetMem
+    DosSetPathInfo
+    DosSetRelMaxFH
+    DosSetSignalExceptionFocus
+    DosSubAllocMem
+    DosSubFreeMem
+    DosSubSetMem
+    DosSubUnsetMem
+    DosUnsetExceptionHandler
+    DosUnwindException
+    DosWaitEventSem
+    DosWaitMuxWaitSem
+    DosWrite
+
+Note that devices (like /DEV/CON) doesn't like high memory.
+Also note that DosOpenL doesn't support high memory even if DosOpen does.
+
+
+One should be supicious of any APIs which deals with memory and isn't
+listed above. However we find that the following APIs seems to be safe:
+    DosGetDateTime
+    DosSetFilePtr
+    DosSetFilePtrL
+    DosQueryProcAddr
+
+
+
+Regarding the other APIs there are no guarantees. Some sources claim the Win*
+and Gpi* to be pretty safe. Regarding the Uni* api we have to try it. TCP/IP
+APIs are know to not accept high memory.
+
+LIBC is currently using some APIs which may (in theory) cause trouble.
+For the Dos API:
+   doscalls.110 (DosForceDelete)    - verified, made wrapper.   LIBC uses wrapper.
+   doscalls.224 (DosQueryHType)     - verified, made wrapper.   LIBC uses stack.
+   doscalls.239 (DosCreatePipe)     - verified, made wrapper.   LIBC uses wrapper.
+   doscalls.245 (DosQueryNPHState)  - ???, made wrapper.        LIBC uses stack.
+   doscalls.253 (DosWaitNPipe)      - verified, made wrapper    LIBC uses static data.
+   doscalls.256 (DosSetFilePtr)     - seems safe, made wrapper. LIBC uses stack.
+   doscalls.260 (DosDupHandle)      - verified, made wrapper.   LIBC uses stack.
+   doscalls.xxx (DosOpenL)          - verified, made wrapper.   LIBC uses stack.
+   doscalls.276 (DosQueryFHState)   - verified, made wrapper.   LIBC uses stack.
+   doscalls.280 (DosWaitChild)      - ???, made wrapper.        LIBC uses stack.
+   doscalls.291 (DosQueryCp)        - ???.                      LIBC uses stack.
+   doscalls.292 (DosSetDateTime)    - verified, made wrapper.   LIBC uses stack.
+   doscalls.311 (DosCreateThread)   - ???.                      LIBC uses stack.
+   doscalls.321 (DosQueryProcAddr)  - seems safe                LIBC uses static data.
+   doscalls.348 (DosQuerySysInfo)   - seems safe                LIBC uses static data.
+   doscalls.372 (DosEnumAttribute)  - ???.                      LIBC uses stack.
+   nls.5        (DosQueryCtryInfo)  - ???.                      LIBC uses stack.
+
+For the Uni API:
+   libuni.20 (UniCreateLocaleObject)
+   libuni.29 (UniQueryLocaleInfo)
+   libuni.30 (UniQueryLocaleItem)
+   libuni.35 (UniStrcoll)
+   libuni.40 (UniStrlen)
+   libuni.42 (UniStrncmp)
+   libuni.53 (UniStrxfrm)
+   libuni.67 (UniMapCtryToLocale)
+   uconv.1 (UniCreateUconvObject)
+   uconv.10 (UniMapCpToUcsCp)
+   uconv.2 (UniUconvToUcs)
+   uconv.3 (UniUconvFromUcs)
+   uconv.7 (UniQueryUconvObject)
+
+Until proven elsewise we'll assume the Uni API to be safe.
Index: trunk/src/emx/src/lib/os2_386/os2.smak
===================================================================
--- trunk/src/emx/src/lib/os2_386/os2.smak	(revision 809)
+++ trunk/src/emx/src/lib/os2_386/os2.smak	(revision 810)
@@ -6,8 +6,8 @@
 .INSDIR := lib/
 
-.TARGET := os2.a
+.TARGET := libos2.a
 .TKIND	:= aout
 .TSRC.386 := $(wildcard src/lib/os2_386/*.s)
-.TSRC	:= $(.TSRC.$(CPU)) $(wildcard src/lib/os2_386/*.c)
+.TSRC	:= $(.TSRC.$(CPU)) $(wildcard src/lib/os2_386/*.c) $(wildcard src/lib/os2_386/safe/*.c)
 .TCF	:= -Wno-unused -s
 .IMPS	:= $(wildcard src/lib/os2_386/*.imp)
@@ -15,6 +15,7 @@
 include mkimplib.smak
 
-.TARGET := os2_p.a
+.TARGET := libos2_p.a
 .TKIND	:= aout prof
 .TCF	:= -Wno-unused
 include mkimplib.smak
+
Index: trunk/src/emx/src/lib/os2_386/safe/SafeDosCreatePipe.c
===================================================================
--- trunk/src/emx/src/lib/os2_386/safe/SafeDosCreatePipe.c	(revision 810)
+++ trunk/src/emx/src/lib/os2_386/safe/SafeDosCreatePipe.c	(revision 810)
@@ -0,0 +1,56 @@
+/* $Id$ */
+/** @file
+ *
+ * SafeDosCreatePipe()
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#define INCL_BASE
+#include <os2.h>
+
+
+ULONG APIENTRY SafeDosCreatePipe(PHFILE phfReadHandle, PHFILE phfWriteHandle, ULONG ulPipeSize)
+{
+    ULONG   rc;
+    HFILE   h1, h2;
+    PHFILE  ph1 = NULL;
+    PHFILE  ph2 = NULL;
+
+    if (phfReadHandle)
+    {
+        h1 = *phfReadHandle;
+        ph1 = &h1;
+    }
+    if (phfWriteHandle)
+    {
+        h2 = *phfWriteHandle;
+        ph2 = &h2;
+    }
+
+    rc = DosCreatePipe(ph1, ph2, ulPipeSize);
+
+    if (phfReadHandle)
+        *phfReadHandle = h1;
+    if (phfWriteHandle)
+        *phfWriteHandle = h2;
+
+    return rc;
+}
+
Index: trunk/src/emx/src/lib/os2_386/safe/SafeDosDupHandle.c
===================================================================
--- trunk/src/emx/src/lib/os2_386/safe/SafeDosDupHandle.c	(revision 810)
+++ trunk/src/emx/src/lib/os2_386/safe/SafeDosDupHandle.c	(revision 810)
@@ -0,0 +1,48 @@
+/* $Id$ */
+/** @file
+ *
+ * SafeDosDupHandle()
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#define INCL_BASE
+#include <os2.h>
+
+
+ULONG APIENTRY SafeDosDupHandle(HFILE hFile, PHFILE phFile)
+{
+    ULONG rc;
+    HFILE   hf1;
+    PHFILE  phf1;
+
+    if (phFile)
+    {
+        hf1 = *phFile;
+        phf1 = &hf1;
+    }
+
+    rc = DosDupHandle(hFile, phf1);
+
+    if (phFile)
+        *phFile = hf1;
+
+    return rc;
+}
+
Index: trunk/src/emx/src/lib/os2_386/safe/SafeDosForceDelete.c
===================================================================
--- trunk/src/emx/src/lib/os2_386/safe/SafeDosForceDelete.c	(revision 810)
+++ trunk/src/emx/src/lib/os2_386/safe/SafeDosForceDelete.c	(revision 810)
@@ -0,0 +1,38 @@
+/* $Id$ */
+/** @file
+ *
+ * SafeDosForceDelete()
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#define INCL_BASE
+#include <os2.h>
+#include "safe.h"
+
+ULONG APIENTRY SafeDosForceDelete(PCSZ pszFileName)
+{
+    ULONG   rc;
+    SAFE_PCSZ(pszFileName);
+    rc = DosForceDelete(SAFE_PCSZ_USE(pszFileName));
+    SAFE_PCSZ_DONE(pszFileName);
+    SAFE_DOS_FAILURE();
+    return rc;
+}
+
Index: trunk/src/emx/src/lib/os2_386/safe/SafeDosOpenL.c
===================================================================
--- trunk/src/emx/src/lib/os2_386/safe/SafeDosOpenL.c	(revision 810)
+++ trunk/src/emx/src/lib/os2_386/safe/SafeDosOpenL.c	(revision 810)
@@ -0,0 +1,63 @@
+/* $Id$ */
+/** @file
+ *
+ * SafeDosOpenL()
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#define INCL_BASE
+#include <os2.h>
+#include "safe.h"
+
+ULONG APIENTRY SafeDosOpenL(PCSZ pszFileName, PHFILE phFile, PULONG pulAction,
+    LONGLONG llFileSize, ULONG ulAttribute, ULONG ulOpenFlags, ULONG ulOpenMode,
+    PEAOP2 pEABuf)
+{
+    /** @todo pEABuf */
+    ULONG   rc, ul1;
+    PULONG  pul1 = NULL;
+    HFILE   hf1;
+    PHFILE  phf1 = NULL;
+    SAFE_PCSZ(pszFileName);
+
+    if (phFile)
+    {
+        hf1 = *phFile;
+        phf1 = &hf1;
+    }
+    if (pulAction)
+    {
+        ul1 = *pulAction;
+        pul1 = &ul1;
+    }
+
+    rc = DosOpenL(SAFE_PCSZ_USE(pszFileName), phf1, pul1, llFileSize, ulAttribute,
+                  ulOpenFlags, ulOpenMode, pEABuf);
+
+    if (phFile)
+        *phFile = hf1;
+    if (pulAction)
+        *pulAction = ul1;
+
+    SAFE_PCSZ_DONE(pszFileName);
+    SAFE_DOS_FAILURE();
+    return rc;
+}
+
Index: trunk/src/emx/src/lib/os2_386/safe/SafeDosQueryFHState.c
===================================================================
--- trunk/src/emx/src/lib/os2_386/safe/SafeDosQueryFHState.c	(revision 810)
+++ trunk/src/emx/src/lib/os2_386/safe/SafeDosQueryFHState.c	(revision 810)
@@ -0,0 +1,47 @@
+/* $Id$ */
+/** @file
+ *
+ * SafeDosQueryFHState()
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#define INCL_BASE
+#include <os2.h>
+
+
+ULONG APIENTRY SafeDosQueryFHState(HFILE hFile, PULONG pulMode)
+{
+    ULONG   rc, ul1;
+    PULONG  pul1 = NULL;
+
+    if (pulMode)
+    {
+        ul1 = *pulMode;
+        pul1 = &ul1;
+    }
+
+    rc = DosQueryFHState(hFile, pul1);
+
+    if (pulMode)
+        *pulMode = ul1;
+
+    return rc;
+}
+
Index: trunk/src/emx/src/lib/os2_386/safe/SafeDosQueryHType.c
===================================================================
--- trunk/src/emx/src/lib/os2_386/safe/SafeDosQueryHType.c	(revision 810)
+++ trunk/src/emx/src/lib/os2_386/safe/SafeDosQueryHType.c	(revision 810)
@@ -0,0 +1,55 @@
+/* $Id$ */
+/** @file
+ *
+ * SafeDosQueryHType
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#define INCL_BASE
+#include <os2.h>
+
+
+ULONG APIENTRY SafeDosQueryHType(HFILE hFile, PULONG pulType, PULONG pulAttr)
+{
+    APIRET  rc;
+    ULONG   ul1, ul2;
+    PULONG  pul1 = NULL;
+    PULONG  pul2 = NULL;
+
+    if (pulType)
+    {
+        ul1 = *pulType;
+        pul1 = &ul1;
+    }
+    if (pulAttr)
+    {
+        ul2 = *pulAttr;
+        pul2 = &ul2;
+    }
+
+    rc = DosQueryHType(hFile, pul1, pul2);
+
+    if (pulType)
+        *pulType = ul1;
+    if (pulAttr)
+        *pulAttr = ul2;
+    return rc;
+}
+
Index: trunk/src/emx/src/lib/os2_386/safe/SafeDosQueryNPHState.c
===================================================================
--- trunk/src/emx/src/lib/os2_386/safe/SafeDosQueryNPHState.c	(revision 810)
+++ trunk/src/emx/src/lib/os2_386/safe/SafeDosQueryNPHState.c	(revision 810)
@@ -0,0 +1,47 @@
+/* $Id$ */
+/** @file
+ *
+ * SafeDosQueryNPHState()
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#define INCL_BASE
+#include <os2.h>
+
+
+ULONG APIENTRY SafeDosQueryNPHState(HPIPE hpipe, PULONG pulState)
+{
+    ULONG   ul1, rc;
+    PULONG  pul1 = NULL;
+
+    if (pulState)
+    {
+        ul1 = *pulState;
+        pul1 = &ul1;
+    }
+
+    rc = DosQueryNPHState(hpipe, pul1);
+
+    if (pulState)
+        *pulState = ul1;
+
+    return rc;
+}
+
Index: trunk/src/emx/src/lib/os2_386/safe/SafeDosSetDateTime.c
===================================================================
--- trunk/src/emx/src/lib/os2_386/safe/SafeDosSetDateTime.c	(revision 810)
+++ trunk/src/emx/src/lib/os2_386/safe/SafeDosSetDateTime.c	(revision 810)
@@ -0,0 +1,46 @@
+/* $Id$ */
+/** @file
+ *
+ * SafeDosSetDateTime().
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#define INCL_BASE
+#include <os2.h>
+
+
+
+ULONG APIENTRY SafeDosSetDateTime(__const__ DATETIME *pdt)
+{
+    ULONG       rc;
+    DATETIME    dt1;
+    PDATETIME   pdt1 = NULL;
+
+    if (pdt)
+    {
+        dt1 = *pdt;
+        pdt1 = &dt1;
+    }
+
+    rc = DosSetDateTime(pdt1);
+
+    return rc;
+}
+
Index: trunk/src/emx/src/lib/os2_386/safe/SafeDosSetFilePtr.c
===================================================================
--- trunk/src/emx/src/lib/os2_386/safe/SafeDosSetFilePtr.c	(revision 810)
+++ trunk/src/emx/src/lib/os2_386/safe/SafeDosSetFilePtr.c	(revision 810)
@@ -0,0 +1,47 @@
+/* $Id$ */
+/** @file
+ *
+ * SafeDosSetFilePtr()
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#define INCL_BASE
+#include <os2.h>
+
+
+ULONG APIENTRY SafeDosSetFilePtr(HFILE hFile, LONG lOffset, ULONG ulOrigin, PULONG pulPos)
+{
+    ULONG rc, ul1;
+    PULONG pul1 = NULL;
+
+    if (pulPos)
+    {
+        ul1 = *pulPos;
+        pul1 = &ul1;
+    }
+
+    rc = DosSetFilePtr(hFile, lOffset, ulOrigin, pul1);
+
+    if (pulPos)
+        *pulPos = ul1;
+
+    return rc;
+}
+
Index: trunk/src/emx/src/lib/os2_386/safe/SafeDosSetFilePtrL.c
===================================================================
--- trunk/src/emx/src/lib/os2_386/safe/SafeDosSetFilePtrL.c	(revision 810)
+++ trunk/src/emx/src/lib/os2_386/safe/SafeDosSetFilePtrL.c	(revision 810)
@@ -0,0 +1,48 @@
+/* $Id$ */
+/** @file
+ *
+ * SafeDosSetFilePtr()
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#define INCL_BASE
+#include <os2.h>
+
+
+ULONG APIENTRY SafeDosSetFilePtrL(HFILE hFile, LONGLONG llOffset, ULONG ulOrigin, PLONGLONG pllPos)
+{
+    ULONG rc;
+    LONGLONG ll1;
+    PLONGLONG pll1 = NULL;
+
+    if (pllPos)
+    {
+        ll1 = *pllPos;
+        pll1 = &ll1;
+    }
+
+    rc = DosSetFilePtr(hFile, llOffset, ulOrigin, pll1);
+
+    if (pllPos)
+        *pllPos = ll1;
+
+    return rc;
+}
+
Index: trunk/src/emx/src/lib/os2_386/safe/SafeDosWaitChild.c
===================================================================
--- trunk/src/emx/src/lib/os2_386/safe/SafeDosWaitChild.c	(revision 810)
+++ trunk/src/emx/src/lib/os2_386/safe/SafeDosWaitChild.c	(revision 810)
@@ -0,0 +1,57 @@
+/* $Id$ */
+/** @file
+ *
+ * SafeDosWaitChild()
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#define INCL_BASE
+#include <os2.h>
+
+
+ULONG APIENTRY SafeDosWaitChild(ULONG ulAction, ULONG ulWait, PRESULTCODES pReturnCodes, PPID ppidOut, PID pidIn)
+{
+    ULONG           rc;
+    RESULTCODES     res;
+    PRESULTCODES    pres = NULL;
+    PID             pid;
+    PPID            ppid = NULL;
+
+    if (pReturnCodes)
+    {
+        res = *pReturnCodes;
+        pres = &res;
+    }
+    if (ppidOut)
+    {
+        pid = *ppidOut;
+        ppid = &pid;
+    }
+
+    rc = DosWaitChild(ulAction, ulWait, pres, ppid, pidIn);
+
+    if (pReturnCodes)
+        *pReturnCodes = res;
+    if (ppidOut)
+        *ppidOut = pid;
+
+    return rc;
+}
+
Index: trunk/src/emx/src/lib/os2_386/safe/SafeDosWaitNPipe.c
===================================================================
--- trunk/src/emx/src/lib/os2_386/safe/SafeDosWaitNPipe.c	(revision 810)
+++ trunk/src/emx/src/lib/os2_386/safe/SafeDosWaitNPipe.c	(revision 810)
@@ -0,0 +1,37 @@
+/* $Id$ */
+/** @file
+ *
+ * SafeDosWaitNPipe()
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#define INCL_BASE
+#include <os2.h>
+#include "safe.h"
+
+ULONG APIENTRY SafeDosWaitNPipe(PCSZ pszName, ULONG ulTimeout)
+{
+    APIRET rc;
+    SAFE_PCSZ(pszName);
+    rc = DosWaitNPipe(SAFE_PCSZ_USE(pszName), ulTimeout);
+    SAFE_PCSZ_DONE(pszName);
+    SAFE_DOS_FAILURE();
+    return rc;
+}
Index: trunk/src/emx/src/lib/os2_386/safe/safe.h
===================================================================
--- trunk/src/emx/src/lib/os2_386/safe/safe.h	(revision 810)
+++ trunk/src/emx/src/lib/os2_386/safe/safe.h	(revision 810)
@@ -0,0 +1,69 @@
+/* $Id$ */
+/** @file
+ *
+ * Macros, prototypes and inline helpers.
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+#ifndef __safe_h__
+#define __safe_h__
+
+
+#include <stdlib.h>
+#include <string.h>
+void *  _lmalloc(unsigned);
+
+/** Check if ptr is in high memory or not. */
+#define SAFE_IS_HIGH(ptr)   ((unsigned)(ptr) >= 512*1024*1024)
+
+
+
+/** Wrap a const string. */
+#define SAFE_PCSZ(arg) \
+    char * arg##_safe = (char*)arg;                 \
+    if (SAFE_IS_HIGH(arg))                          \
+    {                                               \
+        int cch = strlen(arg) + 1;                  \
+        arg##_safe = _lmalloc(cch);                 \
+        if (!arg##_safe) goto safe_failure;         \
+        memcpy(arg##_safe, (arg), cch);             \
+    }                                               \
+        {
+
+
+/** Use the const string. */
+#define SAFE_PCSZ_USE(arg) arg##_safe
+
+/** Cleanup a const string. */
+#define SAFE_PCSZ_DONE(arg) \
+        }                                           \
+    if (arg##_safe != (char*)arg) free(arg##_safe)
+
+
+/** Generic failure label for Dos API wappers.
+ * It'll just return out of memory error. */
+#define SAFE_DOS_FAILURE() \
+    if (0)                                          \
+    {                                               \
+        safe_failure:                               \
+            rc = 8;                                 \
+    }
+
+
+#endif
Index: trunk/src/emx/src/lib/startup/386/crt0.s
===================================================================
--- trunk/src/emx/src/lib/startup/386/crt0.s	(revision 809)
+++ trunk/src/emx/src/lib/startup/386/crt0.s	(revision 810)
@@ -38,4 +38,9 @@
 
 __text:
+#if defined (HIGHMEM)
+    pushl    $1     /* vote for high mem for default stack */
+#else
+    pushl    $0     /* veto agains high mem for default stack */
+#endif
 	call    ___init_app
     /* esp points to main() call frame. */
Index: trunk/src/emx/src/lib/startup/386/dll0.s
===================================================================
--- trunk/src/emx/src/lib/startup/386/dll0.s	(revision 809)
+++ trunk/src/emx/src/lib/startup/386/dll0.s	(revision 810)
@@ -36,11 +36,36 @@
 
 __text:
-/** @todo ___init_dll shouldn't be called, only _DLL_InitTerm. */
+    cmpl    $0, 8(%esp)
+    jz      do_common_init
+    jmp     do_initterm
+
+    /*
+     * Nonstandard: we're doing some early initializations.
+     */
+do_common_init:
+#if defined (HIGHMEM)
+    pushl    $1     /* vote for high mem for default stack */
+#else
+    pushl    $0     /* veto against high mem for default stack */
+#endif
 	call    ___init_dll
+    add     $4, %esp
+    orl     %eax, %eax
+    jz      do_initterm
+    /*
+     * __init_dll() failed - fail the dll loading.
+     */
+    xorl    %eax, %eax
+    ret
+
+    /*
+     * Standard initialization.
+     */
+do_initterm:
 	cld
     jmp     _DLL_InitTerm
 
+
 	.data
-
 __data:
 	.long	0xba0bab	// Magic number (error detection)
Index: trunk/src/emx/src/lib/startup/startup.c
===================================================================
--- trunk/src/emx/src/lib/startup/startup.c	(revision 809)
+++ trunk/src/emx/src/lib/startup/startup.c	(revision 810)
@@ -111,11 +111,12 @@
  * LIBCxy.DLL:
  *      - 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 _sys_pid and _sys_ppid globals.
- *          - __init_dll creates _sys_heap_fmutex.
- *          - __init_dll allocates and initialized the _sys_private_heap heap, which is
- *            operated by DosSubSetMem() and it's friends.
+ *          - __init_dll creates _sys_heap_fmutex and _sys_gmtxHimem.
  *          - __init_dll then initializes _sys_thread_table and calls __newthread() in
  *            sys/__newthread.c to create the thread 1 entry.
+ *              - __newthread() will call __sys_newthread() which inits the high memory
+ *                heap (or low if no high mem) when calling _hmalloc().
  *          - __init_dll calls __init_environ() which initializes environ and _org_environ.
  *          - __init_dll then intializes _sys_clock0_ms with the current MS count.
@@ -130,5 +131,6 @@
  * Your.DLL:
  *      - dll0.s gets control and calls __init_dll() in sys/__initdll.c
- *          - __init_dll returns at once since already done during LIBCxy.DLL init.
+ *          - __init_dll calls __libc_HeapVote() to do the heap voting.
+ *          - __init_dll then returns since already done during LIBCxy.DLL init.
  *      - dll0.s calls _DLL_InitTerm in startup/dllinit.c.
  *          - _DLL_InitTerm calls _CRT_init() in startup/startup.c to initialize the CRT.
@@ -141,5 +143,7 @@
  *      - crt0.s gets control and calls ___init_app in sys/386/appinit.s which forwards
  *        the call to __init() in sys/__init.c.
- *          - __init() calls __init_dll() which returns at once because of LIBCxy.DLL init.
+ *          - __init() calls __init_dll() to do common initiation.
+ *              - __init_dll calls __libc_HeapVote() to do the heap voting.
+ *              - __init_dll then returns since already done during LIBCxy.DLL init.
  *          - __init() parse the commandline to figure out how much stack to use for array
  *            and the argument copy.
Index: trunk/src/emx/src/lib/startup/startup.smak
===================================================================
--- trunk/src/emx/src/lib/startup/startup.smak	(revision 809)
+++ trunk/src/emx/src/lib/startup/startup.smak	(revision 810)
@@ -9,7 +9,7 @@
 include common.smak
 
-.OBJS += $(addprefix $.$(.TKIND.DIR)src/lib/startup/,mcrt0.o gcrt0.o) \
+.OBJS += $(addprefix $.$(.TKIND.DIR)src/lib/startup/,mcrt0.o gcrt0.o crt0hi.o dll0hi.o) \
   $(addprefix $.omf/src/lib/startup/,mcrt0.obj gcrt0.obj \
-  $(CPU)/crt0.obj $(CPU)/dll0.obj)
+  $(CPU)/crt0.obj $(CPU)/dll0.obj crt0hi.obj dll0hi.obj)
 .DIRS := $(sort $(dir $(.OBJS)))
 TARGDIRS += $(.DIRS)
@@ -21,4 +21,10 @@
 	$(call CP,$^,$(dir $@))
 
+$.aout/src/lib/startup/crt0hi.o: src/lib/startup/386/crt0.s
+	$(call DO.COMPILE.s, -DHIGHMEM)
+	
+$.aout/src/lib/startup/dll0hi.o: src/lib/startup/386/dll0.s
+	$(call DO.COMPILE.s, -DHIGHMEM)
+				
 $.aout/src/lib/startup/mcrt0.o: src/lib/startup/386/crt0.s
 	$(call DO.COMPILE.s, -DMCRT0)
@@ -30,5 +36,5 @@
 	$(call RM,tmp1.o tmp2.o)
 
-# This rule doesnt work if the aout/src/lib/startup/ directory does not
+# This rule doesn't work if the aout/src/lib/startup/ directory does not
 # exist when make is started, and is ignored because of this (shit!)
 #$.omf/src/lib/startup/%.obj: $.aout/src/lib/startup/%.o
@@ -40,4 +46,8 @@
 $.omf/src/lib/startup/gcrt0.obj: $.aout/src/lib/startup/gcrt0.o
 	$(call DO.EMXOMF,-m__text)
+$.omf/src/lib/startup/dll0hi.obj: $.aout/src/lib/startup/dll0hi.o
+	$(call DO.EMXOMF,-m__text)
+$.omf/src/lib/startup/crt0hi.obj: $.aout/src/lib/startup/crt0hi.o
+	$(call DO.EMXOMF,-m__text)
 $.omf/src/lib/startup/386/dll0.obj: $.aout/src/lib/startup/386/dll0.o
 	$(call DO.EMXOMF,-m__text)
Index: trunk/src/emx/src/lib/sys/386/__init_environ.s
===================================================================
--- trunk/src/emx/src/lib/sys/386/__init_environ.s	(revision 809)
+++ trunk/src/emx/src/lib/sys/386/__init_environ.s	(revision 810)
@@ -36,6 +36,6 @@
  *
  */
-    .globl ___init_environ
-___init_environ:
+    .globl __sys_init_environ
+__sys_init_environ:
     pushl   %ebp
     movl    %esp, %ebp
@@ -68,12 +68,11 @@
     movl    %esi, %ecx
     subl    %esp, %ecx
-    / DosSubAllocMem(_sys_private_heap, &_org_environ, size);
+    / _org_environ = _hmalloc(size);
     pushl   %ecx
-    pushl   $__org_environ
-    pushl   __sys_private_heap
-    call    DosSubAllocMem
-    addl    $12, %esp
+    call    __hmalloc
+    addl    $4, %esp
     orl     %eax, %eax
-    jnz     env_ret
+    jz      env_ret
+    mov     %eax, __org_environ
 
     /*
Index: trunk/src/emx/src/lib/sys/386/appinit.s
===================================================================
--- trunk/src/emx/src/lib/sys/386/appinit.s	(revision 809)
+++ trunk/src/emx/src/lib/sys/386/appinit.s	(revision 810)
@@ -2,5 +2,5 @@
 
 	.globl  ___init_app
-	.globl  ___init_ret
+	.globl  __sys_init_ret
 
 	.data
@@ -16,5 +16,5 @@
 	hlt
 
-___init_ret:
+__sys_init_ret:
 	movl    4(%esp), %esp
 	jmp     *L_ret
Index: trunk/src/emx/src/lib/sys/386/systhrea.s
===================================================================
--- trunk/src/emx/src/lib/sys/386/systhrea.s	(revision 809)
+++ trunk/src/emx/src/lib/sys/386/systhrea.s	(revision 810)
@@ -8,8 +8,13 @@
 
 __sys_thread:
+        /** @todo change this to use a TLS variable */
+        movl    %fs, %ecx
+        movl    $DosTIB, %eax
+        movl    %eax, %fs
         fs
         movl    12, %eax                /* ptib2 */
         movl    0(%eax), %edx           /* TID */
         movl    __sys_thread_table(,%edx,4), %eax
+        movl    %ecx, %fs
         testl   %eax, %eax
         jz      1f
@@ -21,5 +26,5 @@
         pushl   %edx                    /* tid */
         call    ___sys_newthread
-        addl    $4, %esp
+        addl    $8, %esp
         popl    %edx
         movl    __sys_thread_table(,%edx,4), %eax
Index: trunk/src/emx/src/lib/sys/__endthread.c
===================================================================
--- trunk/src/emx/src/lib/sys/__endthread.c	(revision 809)
+++ trunk/src/emx/src/lib/sys/__endthread.c	(revision 810)
@@ -2,4 +2,5 @@
 
 #include "libc-alias.h"
+#include <stdlib.h>
 #define INCL_DOS
 #define INCL_FSMACROS
@@ -11,17 +12,17 @@
 {
   thread_data *tp;
-  FS_VAR();
 
   if (tid < MAX_THREADS && _sys_thread_table[tid] != NULL)
     {
       tp = _sys_thread_table[tid];
-      FS_SAVE_LOAD();
       if (tp->fd.hdir != HDIR_CREATE)
         {
+          FS_VAR();
+          FS_SAVE_LOAD();
           DosFindClose (tp->fd.hdir);
+          FS_RESTORE();
           tp->fd.hdir = HDIR_CREATE;
         }
-      DosSubFreeMem (_sys_private_heap, tp, sizeof (thread_data));
-      FS_RESTORE();
+      free (tp);
       _sys_thread_table[tid] = NULL;
     }
Index: trunk/src/emx/src/lib/sys/__init.c
===================================================================
--- trunk/src/emx/src/lib/sys/__init.c	(revision 809)
+++ trunk/src/emx/src/lib/sys/__init.c	(revision 810)
@@ -10,4 +10,8 @@
 */
 
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
 #include "libc-alias.h"
 #define INCL_DOS
@@ -21,17 +25,27 @@
 #include <alloca.h>
 
+
+/* All globals is to be defined in this object file. */
 #define EXTERN
 #define INIT(x) = x
-
 #include "syscalls.h"
 
 
-extern int __init_dll(void);
-extern void volatile __init_ret(void *stack);
+/*******************************************************************************
+*   Internal Functions                                                         *
+*******************************************************************************/
 static int parse_args(const char *src, char **argv, char *pool);
 
+
+/*******************************************************************************
+*   Global Variables                                                           *
+*******************************************************************************/
 /** argument count found by parse_args(). */
 static int argc;
 
+
+/*******************************************************************************
+*   Defined Constants And Macros                                               *
+*******************************************************************************/
 /** Helper macros for parse args
  * @{ */
@@ -128,7 +142,12 @@
  * magic done in sys/386/appinit.s. The top of the returned stack have a layout
  * as seen in struct stackframe below - start of struct is main() callframe.
+ * @param   fDefaultHeapInHighMem   If set the application is open to put the default
+ *                                  heap in high memory.
+ *                                  If clear the application veto against putting the
+ *                                  default heap in high memory.
+ *                                  Passed on to __init_dll().
  * @ingroup startup
  */
-void __init(void)
+void __init(int fDefaultHeapInHighMem)
 {
     /** top of stack unpon 'return' from this function. */
@@ -155,7 +174,11 @@
     /*
      * Do the common initialization in case we're linked statically.
+     * Then end the heap voting.
      */
-    if (__init_dll())
+    if (__init_dll(fDefaultHeapInHighMem))
         goto failure;
+
+    __libc_HeapEndVoting();
+
 
     /*
@@ -200,5 +223,5 @@
 
     /* Return to the program. */
-    __init_ret(pStackFrame);
+    _sys_init_ret(pStackFrame);
 
 failure:
Index: trunk/src/emx/src/lib/sys/__initdll.c
===================================================================
--- trunk/src/emx/src/lib/sys/__initdll.c	(revision 809)
+++ trunk/src/emx/src/lib/sys/__initdll.c	(revision 810)
@@ -32,4 +32,8 @@
 #include "syscalls.h"
 
+/* Make this function an weak external. */
+#pragma weak __init_largefileio
+
+
 /*******************************************************************************
 *   Global Variables                                                           *
@@ -39,16 +43,9 @@
 
 
-/*******************************************************************************
-*   External Functions                                                         *
-*******************************************************************************/
-extern int __init_environ(const char *pszEnv);
-extern void __init_largefileio(void) __attribute__((weak));
-
-
 /**
  * Common init code for crt0 and dll0.
  * This should perhaps be a part of _CRT_init.
  */
-int __init_dll(void)
+int __init_dll(int fDefaultHeapInHighMem)
 {
     ULONG   aul[2];
@@ -60,5 +57,10 @@
 
     /*
-     * Only called once.
+     * Heap voting.
+     */
+    __libc_HeapVote(fDefaultHeapInHighMem);
+
+    /*
+     * The rest must only be executed once.
      */
     if (initialized)
@@ -76,8 +78,8 @@
      * Check for high memory (>512MB) support.
      */
-    _sys_virtual_address_limit = 0;
+    _sys_gcbVirtualAddressLimit = 0;
     if (    !DosQuerySysInfo(QSV_VIRTUALADDRESSLIMIT, QSV_VIRTUALADDRESSLIMIT, &aul[0], sizeof(aul[0]))
         &&  aul[0] > 512)
-        _sys_virtual_address_limit = aul[0] * 1024*1024;
+        _sys_gcbVirtualAddressLimit = aul[0] * 1024*1024;
 
     /*
@@ -94,25 +96,9 @@
 
     /*
-     * Initialize the heap.  Here, we only create the semaphore
-     * (while having only one thread).  The heap will be created by __sbrk().
+     * Initialize the heap semaphores.
      */
     if (_fmutex_create(&_sys_heap_fmutex, 0) != 0)
         return -1;
-
-    /*
-     * LIBC Private heap, used for org_environ and per thread data.
-     * Let's try put it in high memory...
-     */
-    /** @todo Redo this private heap stuff. */
-    rc = DosAllocMem(&_sys_private_heap, SYS_PRIVATE_HEAP_SIZE,
-                     _sys_virtual_address_limit
-                        ? PAG_READ | PAG_WRITE | OBJ_ANY
-                        : PAG_READ | PAG_WRITE);
-    if (rc != 0)
-        return -1;
-    rc = DosSubSetMem(_sys_private_heap,
-                      DOSSUB_INIT | DOSSUB_SPARSE_OBJ | DOSSUB_SERIALIZE,
-                      SYS_PRIVATE_HEAP_SIZE);
-    if (rc != 0)
+    if (_fmutex_create(&_sys_gmtxHimem, 0) != 0)
         return -1;
 
@@ -128,5 +114,5 @@
      * Setup environment (org_environ and _STD(environ))
      */
-    rc = __init_environ(ppib->pib_pchenv);
+    rc = _sys_init_environ(ppib->pib_pchenv);
     if (rc)
         return -1;
@@ -137,6 +123,6 @@
      * large file suppoort enabled.
      */
-    if (__init_largefileio)
-        __init_largefileio();
+    if (_sys_init_largefileio)
+        _sys_init_largefileio();
 
     /*
Index: trunk/src/emx/src/lib/sys/__newthread.c
===================================================================
--- trunk/src/emx/src/lib/sys/__newthread.c	(revision 809)
+++ trunk/src/emx/src/lib/sys/__newthread.c	(revision 810)
@@ -2,9 +2,8 @@
 
 #include "libc-alias.h"
+#include <os2emx.h>
 #include <errno.h>
-#define INCL_DOS
-#define INCL_FSMACROS
-#include <os2emx.h>
 #include <emx/syscalls.h>
+#include <emx/umalloc.h>
 #include "syscalls.h"
 
@@ -13,7 +12,5 @@
 int __sys_newthread (int tid, int *errnop)
 {
-  ULONG rc;
   void *data;
-  FS_VAR();
 
   if (tid >= MAX_THREADS)
@@ -23,10 +20,8 @@
       return -1;
     }
-  FS_SAVE_LOAD();
-  rc = DosSubAllocMem (_sys_private_heap, &data, sizeof (thread_data));
-  FS_RESTORE();
-  if (rc != 0)
+  data = _hmalloc (sizeof (thread_data));
+  if (!data)
     {
-      _sys_set_errno (rc);
+      errno = ENOMEM;
       return -1;
     }
Index: trunk/src/emx/src/lib/sys/__open.c
===================================================================
--- trunk/src/emx/src/lib/sys/__open.c	(revision 809)
+++ trunk/src/emx/src/lib/sys/__open.c	(revision 810)
@@ -91,5 +91,13 @@
     {
         LONGLONG cbInitialTmp = cbInitial;
-        rc = __pfnDosOpenL(pszFile, &hFile, &ulAction, cbInitialTmp, flAttr, flOpenFlags, flOpenMode, NULL);
+        int     cch = strlen(pszFile);
+        char *  pszFile_safe = alloca(cch + 1);
+        if (pszFile_safe)
+        {
+            strcpy(pszFile_safe, pszFile);
+            rc = __pfnDosOpenL(pszFile_safe, &hFile, &ulAction, cbInitialTmp, flAttr, flOpenFlags, flOpenMode, NULL);
+        }
+        else
+            rc = ERROR_NOT_ENOUGH_MEMORY;
     }
     else
Index: trunk/src/emx/src/lib/sys/__pipe.c
===================================================================
--- trunk/src/emx/src/lib/sys/__pipe.c	(revision 809)
+++ trunk/src/emx/src/lib/sys/__pipe.c	(revision 810)
@@ -4,4 +4,5 @@
 #define INCL_DOSQUEUES
 #define INCL_FSMACROS
+#include <os2safe.h>
 #include <os2emx.h>
 #include <emx/syscalls.h>
Index: trunk/src/emx/src/lib/sys/__read.c
===================================================================
--- trunk/src/emx/src/lib/sys/__read.c	(revision 809)
+++ trunk/src/emx/src/lib/sys/__read.c	(revision 810)
@@ -3,5 +3,9 @@
 #include "libc-alias.h"
 #define INCL_FSMACROS
+#define INCL_ERRORS
 #include <os2emx.h>
+#include <stdlib.h>
+#include <memory.h>
+#include <emx/umalloc.h>
 #include <emx/syscalls.h>
 #include "syscalls.h"
@@ -11,9 +15,35 @@
   ULONG rc;
   ULONG n;
+  void *pvBuf_safe = NULL;
   FS_VAR();
 
+  /*
+   * Devices doesn't like getting high addresses.
+   */
+  if ((unsigned)buf >= 512*1024*1024)
+  {
+    ULONG   ulType = 0;
+    ULONG   ulAttr = 0;
+    FS_SAVE_LOAD();
+    rc = DosQueryHType(handle, &ulType, &ulAttr);
+    FS_RESTORE();
+
+    if (!rc && (ulType & 0xf) == HANDTYPE_DEVICE)
+      {
+        pvBuf_safe = _lmalloc(nbyte);
+        if (!pvBuf_safe)
+            return ERROR_NOT_ENOUGH_MEMORY;
+        memcpy(pvBuf_safe, buf, nbyte);
+      }
+  }
+
   FS_SAVE_LOAD();
-  rc = DosRead (handle, buf, nbyte, &n);
+  rc = DosRead (handle, pvBuf_safe ? pvBuf_safe : buf, nbyte, &n);
   FS_RESTORE();
+  if (pvBuf_safe)
+    {
+      memcpy(buf, pvBuf_safe, nbyte);
+      free(pvBuf_safe);
+    }
   if (rc == 0)
     return n;
Index: trunk/src/emx/src/lib/sys/__write.c
===================================================================
--- trunk/src/emx/src/lib/sys/__write.c	(revision 809)
+++ trunk/src/emx/src/lib/sys/__write.c	(revision 810)
@@ -3,6 +3,10 @@
 #include "libc-alias.h"
 #define INCL_FSMACROS
+#define INCL_ERRORS
 #include <os2emx.h>
+#include <memory.h>
+#include <stdlib.h>
 #include <emx/syscalls.h>
+#include <emx/umalloc.h>
 #include "syscalls.h"
 
@@ -11,9 +15,44 @@
   ULONG rc;
   ULONG n;
+  void *pvBuf_safe = NULL;
   FS_VAR();
+
+  /*
+   * Devices doesn't like getting high addresses.
+   */
+  if ((unsigned)buf >= 512*1024*1024)
+  {
+    ULONG   ulType = 0;
+    ULONG   ulAttr = 0;
+    FS_SAVE_LOAD();
+    rc = DosQueryHType(handle, &ulType, &ulAttr);
+    FS_RESTORE();
+
+    if (!rc && (ulType & 0xf) == HANDTYPE_DEVICE)
+      {
+        if (nbyte > 256)
+          { /* use heap for large buffers */
+            pvBuf_safe = _lmalloc(nbyte);
+            if (!pvBuf_safe)
+                return ERROR_NOT_ENOUGH_MEMORY;
+            memcpy(pvBuf_safe, buf, nbyte);
+            buf = pvBuf_safe;
+          }
+        else
+          { /* use stack for small buffers */
+            pvBuf_safe = alloca(nbyte);
+            memcpy(pvBuf_safe, buf, nbyte);
+            buf = pvBuf_safe;
+            pvBuf_safe = NULL;
+          }
+      }
+  }
 
   FS_SAVE_LOAD();
   rc = DosWrite (handle, buf, nbyte, &n);
   FS_RESTORE();
+
+  if (pvBuf_safe)
+      free(pvBuf_safe);
   if (rc == 0)
     return n;
Index: trunk/src/emx/src/lib/sys/heaphigh.c
===================================================================
--- trunk/src/emx/src/lib/sys/heaphigh.c	(revision 810)
+++ trunk/src/emx/src/lib/sys/heaphigh.c	(revision 810)
@@ -0,0 +1,189 @@
+/* $Id$ */
+/** @file
+ *
+ * LIBC Base Functions for high memory heap.
+ * Note. High memory heap does not mess around with sbrk().
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#define INCL_DOSMEMMGR
+#define INCL_ERRORS
+#include <os2emx.h>
+#include <emx/umalloc.h>
+#include "syscalls.h"
+
+
+/*******************************************************************************
+*   Structures and Typedefs                                                    *
+*******************************************************************************/
+/** One chunk of memory
+ * This structure is located at the very start of the chunk.
+ */
+typedef struct _HighChunk
+{
+    /** Magic / padding the struct to 16 bytes. */
+    char                szMagic[8];
+    /** Pointer to the next one. */
+    struct _HighChunk  *pNext;
+    /** Size of the chunk. */
+    size_t              cb;
+} HIGHCHUNK, *PHIGHCHUNK;
+
+
+/*******************************************************************************
+*   Global Variables                                                           *
+*******************************************************************************/
+/** List of chuncks. Protected by _sys_gmtxHimem. */
+static PHIGHCHUNK   pHimemHead;
+
+
+
+/**
+ * Heap callback function for allocating high memory.
+ *
+ * @returns Pointer to the allocated memory on success.
+ * @returns NULL on failure.
+ * @param   Heap        Heap in question.
+ * @param   pcb         Input the requested block size.
+ *                      Output the amount of memory actually allocated.
+ * @param   pfClean     On output this will tell the call if the memory
+ *                      pointed to by the returned address is clean
+ *                      (i.e zeroed) or not.
+ */
+void *__libc_HimemDefaultAlloc(Heap_t Heap, size_t *pcb, int *pfClean)
+{
+    size_t      cbAlloc;
+    int         rc;
+    PHIGHCHUNK  pChunk;
+
+    /*
+     * Allocate a (rather big) memory block, there is generally speaking
+     * more than enough high memory to allocate from. So, we'll align the
+     * chunks on a rather high limit, 4MB to save kernel calls and list
+     * elements.
+     */
+    cbAlloc = *pcb + sizeof(HIGHCHUNK);
+    cbAlloc = (cbAlloc + (4*1024*1024 - 1)) & ~(4*1024*1024 - 1);
+
+    rc = DosAllocMem((PPVOID)&pChunk, cbAlloc, PAG_READ | PAG_WRITE | PAG_COMMIT | OBJ_ANY);
+    if (rc == ERROR_NOT_ENOUGH_MEMORY)
+    {   /*
+         * Retry with page alignment instead of 4MB.
+         */
+        cbAlloc = *pcb + sizeof(HIGHCHUNK);
+        cbAlloc = (cbAlloc + (0x1000 - 1)) & ~(0x1000 - 1);
+        rc = DosAllocMem((PPVOID)&pChunk, cbAlloc, PAG_READ | PAG_WRITE | PAG_COMMIT | OBJ_ANY);
+    }
+
+    if (rc)
+        return NULL;
+
+    /*
+     * We've got a block. Now it's gotta go into the list.
+     */
+    memcpy(pChunk->szMagic, "HiChunk", sizeof(pChunk->szMagic));
+    pChunk->cb = cbAlloc;
+    if (_fmutex_request(&_sys_gmtxHimem, _FMR_IGNINT) != 0)
+    {
+        DosFreeMem(pChunk);
+        return NULL;
+    }
+    pChunk->pNext = pHimemHead;
+    pHimemHead = pChunk;
+    _fmutex_release(&_sys_gmtxHimem);
+
+
+    /*
+     * Set the output values and return.
+     */
+    *pfClean = _BLOCK_CLEAN;
+    *pcb = cbAlloc - sizeof(HIGHCHUNK);
+    return &pChunk[1];
+}
+
+
+/**
+ * Heap callback function for releaseing high memory.
+ *
+ * @param   Heap    Heap in question.
+ * @param   pv      Pointer to block.
+ * @param   cb      Size of block.
+ */
+void __libc_HimemDefaultRelease(Heap_t Heap, void *pv, size_t cb)
+{
+    int         rc;
+    PHIGHCHUNK  pChunk;
+    PHIGHCHUNK  pPrevChunk;
+
+    /*
+     * Find and unlink the chunk.
+     */
+    if (_fmutex_request(&_sys_gmtxHimem, _FMR_IGNINT) != 0)
+        return;
+    for (pChunk = pHimemHead, pPrevChunk; pChunk; pPrevChunk = pChunk, pChunk = pChunk->pNext)
+        if (&pChunk[1] == pv)
+        {
+            if (pPrevChunk)
+                pPrevChunk->pNext = pChunk->pNext;
+            else
+                pHimemHead = pChunk->pNext;
+            break;
+        }
+    _fmutex_release(&_sys_gmtxHimem);
+
+    /*
+     * Precautions and assertions.
+     */
+    if (!pChunk || cb + sizeof(HIGHCHUNK) != pChunk->cb)
+    {
+        #ifdef DEBUG
+        __asm__("int $3");
+        #endif
+        return;
+    }
+
+    /*
+     * Free it.
+     */
+    rc = DosFreeMem(pChunk);
+    if (rc)
+    {
+        #ifdef DEBUG
+        __asm__("int $3");
+        #endif
+    }
+}
+
+
+/**
+ * Query if the system have support for high memory.
+ *
+ * @returns 1 if the system have more than 512MB of user address space.
+ * @returns 0 if the system only have 512MB of user address space.
+ */
+int     __libc_HasHighMem(void)
+{
+    return _sys_gcbVirtualAddressLimit > 512*1024*1024;
+}
+
Index: trunk/src/emx/src/lib/sys/largefileio.c
===================================================================
--- trunk/src/emx/src/lib/sys/largefileio.c	(revision 809)
+++ trunk/src/emx/src/lib/sys/largefileio.c	(revision 810)
@@ -37,4 +37,5 @@
 #define INCL_BASE
 #include <os2.h>
+#include "syscalls.h"
 
 
@@ -62,5 +63,5 @@
  * @author  knut st. osmundsen <bird-srcspam@anduin.net>
  */
-void __init_largefileio(void)
+void _sys_init_largefileio(void)
 {
     HMODULE     hmod = NULLHANDLE;
Index: trunk/src/emx/src/lib/sys/remove.c
===================================================================
--- trunk/src/emx/src/lib/sys/remove.c	(revision 809)
+++ trunk/src/emx/src/lib/sys/remove.c	(revision 810)
@@ -5,4 +5,5 @@
 #define INCL_FSMACROS
 #define INCL_DOSMISC
+#include <os2safe.h>
 #include <os2emx.h>
 #include <emx/syscalls.h>
Index: trunk/src/emx/src/lib/sys/syscalls.h
===================================================================
--- trunk/src/emx/src/lib/sys/syscalls.h	(revision 809)
+++ trunk/src/emx/src/lib/sys/syscalls.h	(revision 810)
@@ -54,6 +54,8 @@
  * address space size in bytes.
  *
- * Initiated by __init_dll(). */
-EXTERN unsigned long _sys_virtual_address_limit;
+ * Initiated by __init_dll().
+ */
+EXTERN unsigned long    _sys_gcbVirtualAddressLimit;
+
 
 /* The top heap object.  This points into _sys_heap_objs[] or is NULL.
@@ -65,14 +67,14 @@
    objects are managed in LIFO fashion. */
 
-EXTERN struct heap_obj _sys_heap_objs[MAX_HEAP_OBJS];
+EXTERN struct heap_obj  _sys_heap_objs[MAX_HEAP_OBJS];
 
 /* This is the number of heap objects. */
 
-EXTERN unsigned _sys_heap_obj_count;
+EXTERN unsigned         _sys_heap_obj_count;
 
 /* This variable can be initialized by the application to control the
    size of the heap object(s). */
 
-extern unsigned _sys_heap_size;
+extern unsigned         _sys_heap_size;
 
 
@@ -158,9 +160,4 @@
 #define MAX_THREADS 1024
 
-/* This mutex semaphore protects the heap. */
-#ifdef _FMC_SHARED
-EXTERN _fmutex _sys_heap_fmutex;
-#endif
-EXTERN void *_sys_private_heap INIT (NULL);
 EXTERN thread_data *_sys_thread_table[MAX_THREADS];
 
@@ -172,4 +169,7 @@
 void _sys_set_errno (unsigned long rc);
 void _sys_get_clock (unsigned long *ms);
+
+/** @group Heap stuff.
+ * @{ */
 ULONG _sys_expand_heap_obj_by (ULONG incr);
 ULONG _sys_expand_heap_by (ULONG incr, ULONG sbrk_model);
@@ -177,3 +177,18 @@
 ULONG _sys_shrink_heap_by (ULONG decr, ULONG sbrk_model);
 ULONG _sys_shrink_heap_obj_by (ULONG decr);
+#ifdef _FMC_SHARED
+/** This mutex semaphore protects the heap. */
+EXTERN _fmutex          _sys_heap_fmutex;
+/** Mutex semaphore protecting the list of high memory big blocks. */
+EXTERN _fmutex          _sys_gmtxHimem;
+#endif
+/** @} */
 
+
+/** @group Init functions
+ * @{ */
+extern int              __init_dll(int fDefaultHeapInHighMem);
+extern void volatile    _sys_init_ret(void *stack);
+extern int              _sys_init_environ(const char *pszEnv);
+extern void             _sys_init_largefileio(void);
+/** @} */
Index: trunk/src/emx/src/libos2/highmem.txt
===================================================================
--- trunk/src/emx/src/libos2/highmem.txt	(revision 810)
+++ trunk/src/emx/src/libos2/highmem.txt	(revision 810)
@@ -0,0 +1,140 @@
+/** $Id$ */
+
+Private notes about highmemory support in LIBC.
+
+LIBC and most others assume stack to be in low memory.
+LIBC have two strategies of ensuring that buffers for API usage is thunked
+correctly:
+    1) Manualy ensuring it where the API is called.
+    2) API wrappers, 'Safe'-prefixed wrappers. This means the we must
+       include the wrapper header and link with the wrapper lib.
+
+
+This is the list of Dos APIs which officially support high memory in Aurora
+and later kernels:
+    DosAcknowledgeSignalException
+    DosAddMuxWaitSem
+    DosCloseEventSem
+    DosCloseMutexSem
+    DosCloseMuxWaitSem
+    DosCopy
+    DosCreateDir
+    DosCreateEventSem
+    DosCreateMutexSem
+    DosCreateMuxWaitSem
+    DosCreateNPipe
+    DosCreateQueue
+    DosCreateThread2
+    DosDelete
+    DosDeleteDir
+    DosDeleteMuxWaitSem
+    DosEnterMustComplete
+    DosExecPgm
+    DosExitMustComplete
+    DosFindFirst
+    DosFindNext
+    DosFreeMem
+    DosGetNamedSharedMem
+    DosGiveSharedMem
+    DosLoadModule
+    DosMove
+    DosOpen
+    DosOpenEventSem
+    DosOpenMutexSem
+    DosOpenMutexWaitSem
+    DosPhysicalDisk
+    DosPostEventSem
+    DosQueryCurrentDir
+    DosQueryCurrentDisk
+    DosQueryEventSem
+    DosQueryFSAttach
+    DosQueryFSInfo
+    DosQueryFileInfo
+    DosQueryMem
+    DosQueryModuleHandle
+    DosQueryModuleName
+    DosQueryMutexSem
+    DosQueryMuxWaitSem
+    DosQueryNPHState
+    DosQueryPageUsage
+    DosQueryPathInfo
+    DosRaiseException
+    DosRead
+    DosReadQueue
+    DosReleaseMutexSem
+    DosRequestMutexSem
+    DosResetEventSem
+    DosScanEnv
+    DosSearchPath
+    DosSendSignalException
+    DosSetCurrentDir
+    DosSetExceptionHandler
+    DosSetFileInfo
+    DosSetFileLocks
+    DosSetMem
+    DosSetPathInfo
+    DosSetRelMaxFH
+    DosSetSignalExceptionFocus
+    DosSubAllocMem
+    DosSubFreeMem
+    DosSubSetMem
+    DosSubUnsetMem
+    DosUnsetExceptionHandler
+    DosUnwindException
+    DosWaitEventSem
+    DosWaitMuxWaitSem
+    DosWrite
+
+Note that devices (like /DEV/CON) doesn't like high memory.
+Also note that DosOpenL doesn't support high memory even if DosOpen does.
+
+
+One should be supicious of any APIs which deals with memory and isn't
+listed above. However we find that the following APIs seems to be safe:
+    DosGetDateTime
+    DosSetFilePtr
+    DosSetFilePtrL
+    DosQueryProcAddr
+
+
+
+Regarding the other APIs there are no guarantees. Some sources claim the Win*
+and Gpi* to be pretty safe. Regarding the Uni* api we have to try it. TCP/IP
+APIs are know to not accept high memory.
+
+LIBC is currently using some APIs which may (in theory) cause trouble.
+For the Dos API:
+   doscalls.110 (DosForceDelete)    - verified, made wrapper.   LIBC uses wrapper.
+   doscalls.224 (DosQueryHType)     - verified, made wrapper.   LIBC uses stack.
+   doscalls.239 (DosCreatePipe)     - verified, made wrapper.   LIBC uses wrapper.
+   doscalls.245 (DosQueryNPHState)  - ???, made wrapper.        LIBC uses stack.
+   doscalls.253 (DosWaitNPipe)      - verified, made wrapper    LIBC uses static data.
+   doscalls.256 (DosSetFilePtr)     - seems safe, made wrapper. LIBC uses stack.
+   doscalls.260 (DosDupHandle)      - verified, made wrapper.   LIBC uses stack.
+   doscalls.xxx (DosOpenL)          - verified, made wrapper.   LIBC uses stack.
+   doscalls.276 (DosQueryFHState)   - verified, made wrapper.   LIBC uses stack.
+   doscalls.280 (DosWaitChild)      - ???, made wrapper.        LIBC uses stack.
+   doscalls.291 (DosQueryCp)        - ???.                      LIBC uses stack.
+   doscalls.292 (DosSetDateTime)    - verified, made wrapper.   LIBC uses stack.
+   doscalls.311 (DosCreateThread)   - ???.                      LIBC uses stack.
+   doscalls.321 (DosQueryProcAddr)  - seems safe                LIBC uses static data.
+   doscalls.348 (DosQuerySysInfo)   - seems safe                LIBC uses static data.
+   doscalls.372 (DosEnumAttribute)  - ???.                      LIBC uses stack.
+   nls.5        (DosQueryCtryInfo)  - ???.                      LIBC uses stack.
+
+For the Uni API:
+   libuni.20 (UniCreateLocaleObject)
+   libuni.29 (UniQueryLocaleInfo)
+   libuni.30 (UniQueryLocaleItem)
+   libuni.35 (UniStrcoll)
+   libuni.40 (UniStrlen)
+   libuni.42 (UniStrncmp)
+   libuni.53 (UniStrxfrm)
+   libuni.67 (UniMapCtryToLocale)
+   uconv.1 (UniCreateUconvObject)
+   uconv.10 (UniMapCpToUcsCp)
+   uconv.2 (UniUconvToUcs)
+   uconv.3 (UniUconvFromUcs)
+   uconv.7 (UniQueryUconvObject)
+
+Until proven elsewise we'll assume the Uni API to be safe.
Index: trunk/src/emx/src/libos2/os2.smak
===================================================================
--- trunk/src/emx/src/libos2/os2.smak	(revision 809)
+++ trunk/src/emx/src/libos2/os2.smak	(revision 810)
@@ -6,8 +6,8 @@
 .INSDIR := lib/
 
-.TARGET := os2.a
+.TARGET := libos2.a
 .TKIND	:= aout
 .TSRC.386 := $(wildcard src/lib/os2_386/*.s)
-.TSRC	:= $(.TSRC.$(CPU)) $(wildcard src/lib/os2_386/*.c)
+.TSRC	:= $(.TSRC.$(CPU)) $(wildcard src/lib/os2_386/*.c) $(wildcard src/lib/os2_386/safe/*.c)
 .TCF	:= -Wno-unused -s
 .IMPS	:= $(wildcard src/lib/os2_386/*.imp)
@@ -15,6 +15,7 @@
 include mkimplib.smak
 
-.TARGET := os2_p.a
+.TARGET := libos2_p.a
 .TKIND	:= aout prof
 .TCF	:= -Wno-unused
 include mkimplib.smak
+
Index: trunk/src/emx/src/libos2/safe/SafeDosCreatePipe.c
===================================================================
--- trunk/src/emx/src/libos2/safe/SafeDosCreatePipe.c	(revision 810)
+++ trunk/src/emx/src/libos2/safe/SafeDosCreatePipe.c	(revision 810)
@@ -0,0 +1,56 @@
+/* $Id$ */
+/** @file
+ *
+ * SafeDosCreatePipe()
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#define INCL_BASE
+#include <os2.h>
+
+
+ULONG APIENTRY SafeDosCreatePipe(PHFILE phfReadHandle, PHFILE phfWriteHandle, ULONG ulPipeSize)
+{
+    ULONG   rc;
+    HFILE   h1, h2;
+    PHFILE  ph1 = NULL;
+    PHFILE  ph2 = NULL;
+
+    if (phfReadHandle)
+    {
+        h1 = *phfReadHandle;
+        ph1 = &h1;
+    }
+    if (phfWriteHandle)
+    {
+        h2 = *phfWriteHandle;
+        ph2 = &h2;
+    }
+
+    rc = DosCreatePipe(ph1, ph2, ulPipeSize);
+
+    if (phfReadHandle)
+        *phfReadHandle = h1;
+    if (phfWriteHandle)
+        *phfWriteHandle = h2;
+
+    return rc;
+}
+
Index: trunk/src/emx/src/libos2/safe/SafeDosDupHandle.c
===================================================================
--- trunk/src/emx/src/libos2/safe/SafeDosDupHandle.c	(revision 810)
+++ trunk/src/emx/src/libos2/safe/SafeDosDupHandle.c	(revision 810)
@@ -0,0 +1,48 @@
+/* $Id$ */
+/** @file
+ *
+ * SafeDosDupHandle()
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#define INCL_BASE
+#include <os2.h>
+
+
+ULONG APIENTRY SafeDosDupHandle(HFILE hFile, PHFILE phFile)
+{
+    ULONG rc;
+    HFILE   hf1;
+    PHFILE  phf1;
+
+    if (phFile)
+    {
+        hf1 = *phFile;
+        phf1 = &hf1;
+    }
+
+    rc = DosDupHandle(hFile, phf1);
+
+    if (phFile)
+        *phFile = hf1;
+
+    return rc;
+}
+
Index: trunk/src/emx/src/libos2/safe/SafeDosForceDelete.c
===================================================================
--- trunk/src/emx/src/libos2/safe/SafeDosForceDelete.c	(revision 810)
+++ trunk/src/emx/src/libos2/safe/SafeDosForceDelete.c	(revision 810)
@@ -0,0 +1,38 @@
+/* $Id$ */
+/** @file
+ *
+ * SafeDosForceDelete()
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#define INCL_BASE
+#include <os2.h>
+#include "safe.h"
+
+ULONG APIENTRY SafeDosForceDelete(PCSZ pszFileName)
+{
+    ULONG   rc;
+    SAFE_PCSZ(pszFileName);
+    rc = DosForceDelete(SAFE_PCSZ_USE(pszFileName));
+    SAFE_PCSZ_DONE(pszFileName);
+    SAFE_DOS_FAILURE();
+    return rc;
+}
+
Index: trunk/src/emx/src/libos2/safe/SafeDosOpenL.c
===================================================================
--- trunk/src/emx/src/libos2/safe/SafeDosOpenL.c	(revision 810)
+++ trunk/src/emx/src/libos2/safe/SafeDosOpenL.c	(revision 810)
@@ -0,0 +1,63 @@
+/* $Id$ */
+/** @file
+ *
+ * SafeDosOpenL()
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#define INCL_BASE
+#include <os2.h>
+#include "safe.h"
+
+ULONG APIENTRY SafeDosOpenL(PCSZ pszFileName, PHFILE phFile, PULONG pulAction,
+    LONGLONG llFileSize, ULONG ulAttribute, ULONG ulOpenFlags, ULONG ulOpenMode,
+    PEAOP2 pEABuf)
+{
+    /** @todo pEABuf */
+    ULONG   rc, ul1;
+    PULONG  pul1 = NULL;
+    HFILE   hf1;
+    PHFILE  phf1 = NULL;
+    SAFE_PCSZ(pszFileName);
+
+    if (phFile)
+    {
+        hf1 = *phFile;
+        phf1 = &hf1;
+    }
+    if (pulAction)
+    {
+        ul1 = *pulAction;
+        pul1 = &ul1;
+    }
+
+    rc = DosOpenL(SAFE_PCSZ_USE(pszFileName), phf1, pul1, llFileSize, ulAttribute,
+                  ulOpenFlags, ulOpenMode, pEABuf);
+
+    if (phFile)
+        *phFile = hf1;
+    if (pulAction)
+        *pulAction = ul1;
+
+    SAFE_PCSZ_DONE(pszFileName);
+    SAFE_DOS_FAILURE();
+    return rc;
+}
+
Index: trunk/src/emx/src/libos2/safe/SafeDosQueryFHState.c
===================================================================
--- trunk/src/emx/src/libos2/safe/SafeDosQueryFHState.c	(revision 810)
+++ trunk/src/emx/src/libos2/safe/SafeDosQueryFHState.c	(revision 810)
@@ -0,0 +1,47 @@
+/* $Id$ */
+/** @file
+ *
+ * SafeDosQueryFHState()
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#define INCL_BASE
+#include <os2.h>
+
+
+ULONG APIENTRY SafeDosQueryFHState(HFILE hFile, PULONG pulMode)
+{
+    ULONG   rc, ul1;
+    PULONG  pul1 = NULL;
+
+    if (pulMode)
+    {
+        ul1 = *pulMode;
+        pul1 = &ul1;
+    }
+
+    rc = DosQueryFHState(hFile, pul1);
+
+    if (pulMode)
+        *pulMode = ul1;
+
+    return rc;
+}
+
Index: trunk/src/emx/src/libos2/safe/SafeDosQueryHType.c
===================================================================
--- trunk/src/emx/src/libos2/safe/SafeDosQueryHType.c	(revision 810)
+++ trunk/src/emx/src/libos2/safe/SafeDosQueryHType.c	(revision 810)
@@ -0,0 +1,55 @@
+/* $Id$ */
+/** @file
+ *
+ * SafeDosQueryHType
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#define INCL_BASE
+#include <os2.h>
+
+
+ULONG APIENTRY SafeDosQueryHType(HFILE hFile, PULONG pulType, PULONG pulAttr)
+{
+    APIRET  rc;
+    ULONG   ul1, ul2;
+    PULONG  pul1 = NULL;
+    PULONG  pul2 = NULL;
+
+    if (pulType)
+    {
+        ul1 = *pulType;
+        pul1 = &ul1;
+    }
+    if (pulAttr)
+    {
+        ul2 = *pulAttr;
+        pul2 = &ul2;
+    }
+
+    rc = DosQueryHType(hFile, pul1, pul2);
+
+    if (pulType)
+        *pulType = ul1;
+    if (pulAttr)
+        *pulAttr = ul2;
+    return rc;
+}
+
Index: trunk/src/emx/src/libos2/safe/SafeDosQueryNPHState.c
===================================================================
--- trunk/src/emx/src/libos2/safe/SafeDosQueryNPHState.c	(revision 810)
+++ trunk/src/emx/src/libos2/safe/SafeDosQueryNPHState.c	(revision 810)
@@ -0,0 +1,47 @@
+/* $Id$ */
+/** @file
+ *
+ * SafeDosQueryNPHState()
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#define INCL_BASE
+#include <os2.h>
+
+
+ULONG APIENTRY SafeDosQueryNPHState(HPIPE hpipe, PULONG pulState)
+{
+    ULONG   ul1, rc;
+    PULONG  pul1 = NULL;
+
+    if (pulState)
+    {
+        ul1 = *pulState;
+        pul1 = &ul1;
+    }
+
+    rc = DosQueryNPHState(hpipe, pul1);
+
+    if (pulState)
+        *pulState = ul1;
+
+    return rc;
+}
+
Index: trunk/src/emx/src/libos2/safe/SafeDosSetDateTime.c
===================================================================
--- trunk/src/emx/src/libos2/safe/SafeDosSetDateTime.c	(revision 810)
+++ trunk/src/emx/src/libos2/safe/SafeDosSetDateTime.c	(revision 810)
@@ -0,0 +1,46 @@
+/* $Id$ */
+/** @file
+ *
+ * SafeDosSetDateTime().
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#define INCL_BASE
+#include <os2.h>
+
+
+
+ULONG APIENTRY SafeDosSetDateTime(__const__ DATETIME *pdt)
+{
+    ULONG       rc;
+    DATETIME    dt1;
+    PDATETIME   pdt1 = NULL;
+
+    if (pdt)
+    {
+        dt1 = *pdt;
+        pdt1 = &dt1;
+    }
+
+    rc = DosSetDateTime(pdt1);
+
+    return rc;
+}
+
Index: trunk/src/emx/src/libos2/safe/SafeDosSetFilePtr.c
===================================================================
--- trunk/src/emx/src/libos2/safe/SafeDosSetFilePtr.c	(revision 810)
+++ trunk/src/emx/src/libos2/safe/SafeDosSetFilePtr.c	(revision 810)
@@ -0,0 +1,47 @@
+/* $Id$ */
+/** @file
+ *
+ * SafeDosSetFilePtr()
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#define INCL_BASE
+#include <os2.h>
+
+
+ULONG APIENTRY SafeDosSetFilePtr(HFILE hFile, LONG lOffset, ULONG ulOrigin, PULONG pulPos)
+{
+    ULONG rc, ul1;
+    PULONG pul1 = NULL;
+
+    if (pulPos)
+    {
+        ul1 = *pulPos;
+        pul1 = &ul1;
+    }
+
+    rc = DosSetFilePtr(hFile, lOffset, ulOrigin, pul1);
+
+    if (pulPos)
+        *pulPos = ul1;
+
+    return rc;
+}
+
Index: trunk/src/emx/src/libos2/safe/SafeDosSetFilePtrL.c
===================================================================
--- trunk/src/emx/src/libos2/safe/SafeDosSetFilePtrL.c	(revision 810)
+++ trunk/src/emx/src/libos2/safe/SafeDosSetFilePtrL.c	(revision 810)
@@ -0,0 +1,48 @@
+/* $Id$ */
+/** @file
+ *
+ * SafeDosSetFilePtr()
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#define INCL_BASE
+#include <os2.h>
+
+
+ULONG APIENTRY SafeDosSetFilePtrL(HFILE hFile, LONGLONG llOffset, ULONG ulOrigin, PLONGLONG pllPos)
+{
+    ULONG rc;
+    LONGLONG ll1;
+    PLONGLONG pll1 = NULL;
+
+    if (pllPos)
+    {
+        ll1 = *pllPos;
+        pll1 = &ll1;
+    }
+
+    rc = DosSetFilePtr(hFile, llOffset, ulOrigin, pll1);
+
+    if (pllPos)
+        *pllPos = ll1;
+
+    return rc;
+}
+
Index: trunk/src/emx/src/libos2/safe/SafeDosWaitChild.c
===================================================================
--- trunk/src/emx/src/libos2/safe/SafeDosWaitChild.c	(revision 810)
+++ trunk/src/emx/src/libos2/safe/SafeDosWaitChild.c	(revision 810)
@@ -0,0 +1,57 @@
+/* $Id$ */
+/** @file
+ *
+ * SafeDosWaitChild()
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#define INCL_BASE
+#include <os2.h>
+
+
+ULONG APIENTRY SafeDosWaitChild(ULONG ulAction, ULONG ulWait, PRESULTCODES pReturnCodes, PPID ppidOut, PID pidIn)
+{
+    ULONG           rc;
+    RESULTCODES     res;
+    PRESULTCODES    pres = NULL;
+    PID             pid;
+    PPID            ppid = NULL;
+
+    if (pReturnCodes)
+    {
+        res = *pReturnCodes;
+        pres = &res;
+    }
+    if (ppidOut)
+    {
+        pid = *ppidOut;
+        ppid = &pid;
+    }
+
+    rc = DosWaitChild(ulAction, ulWait, pres, ppid, pidIn);
+
+    if (pReturnCodes)
+        *pReturnCodes = res;
+    if (ppidOut)
+        *ppidOut = pid;
+
+    return rc;
+}
+
Index: trunk/src/emx/src/libos2/safe/SafeDosWaitNPipe.c
===================================================================
--- trunk/src/emx/src/libos2/safe/SafeDosWaitNPipe.c	(revision 810)
+++ trunk/src/emx/src/libos2/safe/SafeDosWaitNPipe.c	(revision 810)
@@ -0,0 +1,37 @@
+/* $Id$ */
+/** @file
+ *
+ * SafeDosWaitNPipe()
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#define INCL_BASE
+#include <os2.h>
+#include "safe.h"
+
+ULONG APIENTRY SafeDosWaitNPipe(PCSZ pszName, ULONG ulTimeout)
+{
+    APIRET rc;
+    SAFE_PCSZ(pszName);
+    rc = DosWaitNPipe(SAFE_PCSZ_USE(pszName), ulTimeout);
+    SAFE_PCSZ_DONE(pszName);
+    SAFE_DOS_FAILURE();
+    return rc;
+}
Index: trunk/src/emx/src/libos2/safe/safe.h
===================================================================
--- trunk/src/emx/src/libos2/safe/safe.h	(revision 810)
+++ trunk/src/emx/src/libos2/safe/safe.h	(revision 810)
@@ -0,0 +1,69 @@
+/* $Id$ */
+/** @file
+ *
+ * Macros, prototypes and inline helpers.
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+#ifndef __safe_h__
+#define __safe_h__
+
+
+#include <stdlib.h>
+#include <string.h>
+void *  _lmalloc(unsigned);
+
+/** Check if ptr is in high memory or not. */
+#define SAFE_IS_HIGH(ptr)   ((unsigned)(ptr) >= 512*1024*1024)
+
+
+
+/** Wrap a const string. */
+#define SAFE_PCSZ(arg) \
+    char * arg##_safe = (char*)arg;                 \
+    if (SAFE_IS_HIGH(arg))                          \
+    {                                               \
+        int cch = strlen(arg) + 1;                  \
+        arg##_safe = _lmalloc(cch);                 \
+        if (!arg##_safe) goto safe_failure;         \
+        memcpy(arg##_safe, (arg), cch);             \
+    }                                               \
+        {
+
+
+/** Use the const string. */
+#define SAFE_PCSZ_USE(arg) arg##_safe
+
+/** Cleanup a const string. */
+#define SAFE_PCSZ_DONE(arg) \
+        }                                           \
+    if (arg##_safe != (char*)arg) free(arg##_safe)
+
+
+/** Generic failure label for Dos API wappers.
+ * It'll just return out of memory error. */
+#define SAFE_DOS_FAILURE() \
+    if (0)                                          \
+    {                                               \
+        safe_failure:                               \
+            rc = 8;                                 \
+    }
+
+
+#endif
Index: trunk/src/gcc/gcc/config/i386/emx.h
===================================================================
--- trunk/src/gcc/gcc/config/i386/emx.h	(revision 809)
+++ trunk/src/gcc/gcc/config/i386/emx.h	(revision 810)
@@ -267,5 +267,5 @@
   "%(cpp_cpu) "								       \
   "%{posix:-D_POSIX_SOURCE} "						       \
-  "%{Zmt*:} "    							       \
+  "%{Zmt*:} %{Zlow-mem:} " 						       \
   "%{pg:-D__GPROF__} "							       \
   "%{mepilogue:-D__EPILOGUE__} "					       \
@@ -315,7 +315,7 @@
 /* Override the default crt0 files.  */
 #define STARTFILE_SPEC							       \
-  "%{Zdll:dll0%O%{Zomf:bj}%s}"						       \
+  "%{Zdll:dll0%{Zhigh-mem:hi}%O%{Zomf:bj}%s}"				       \
   "%{!Zdll:%{pg:gcrt0%O%{Zomf:bj}%s}"					       \
-          "%{!pg:%{pn:gcrt0%O%{Zomf:bj}%s}%{!pn:%{p:mcrt0%O%{Zomf:bj}%s}%{!p:crt0%O%{Zomf:bj}%s}}}"\
+          "%{!pg:%{pn:gcrt0%O%{Zomf:bj}%s}%{!pn:%{p:mcrt0%O%{Zomf:bj}%s}%{!p:crt0%{Zhigh-mem:hi}%O%{Zomf:bj}%s}}}"\
          " %{Zbin-files:binmode%O%{Zomf:bj}%s} %{Zsmall-conv:smallcnv%O%{Zomf:bj}%s}}"
 
@@ -348,5 +348,5 @@
   "%(cpp_cpu) "								       \
   "%{posix:-D_POSIX_SOURCE} "						       \
-  "%{Zmt*:} "    							       \
+  "%{Zmt*:} %{Zlow-mem:} "    						       \
   "%{pg:-D__GPROF__} "							       \
   "%{mepilogue:-D__EPILOGUE__} "					       \
@@ -396,7 +396,7 @@
 /* Override the default crt0 files.  */
 #define STARTFILE_SPEC							       \
-  "%{Zdll:dll0%O%{!Zaout:bj}%s}"					       \
+  "%{Zdll:dll0%{Zhigh-mem:hi}%O%{!Zaout:bj}%s}"					       \
   "%{!Zdll:%{pg:gcrt0%O%{!Zaout:bj}%s}"					       \
-          "%{!pg:%{pn:gcrt0%O%{!Zaout:bj}%s}%{!pn:%{p:mcrt0%O%{!Zaout:bj}%s}%{!p:crt0%O%{!Zaout:bj}%s}}}"\
+          "%{!pg:%{pn:gcrt0%O%{!Zaout:bj}%s}%{!pn:%{p:mcrt0%O%{!Zaout:bj}%s}%{!p:crt0%{Zhigh-mem:hi}%O%{!Zaout:bj}%s}}}"\
          " %{Zbin-files:binmode%O%{!Zaout:bj}%s} %{Zsmall-conv:smallcnv%O%{!Zaout:bj}%s}}"
 
