Index: trunk/src/emx/include/emx/io.h
===================================================================
--- trunk/src/emx/include/emx/io.h	(revision 870)
+++ trunk/src/emx/include/emx/io.h	(revision 871)
@@ -18,25 +18,44 @@
 #endif
 
-/* Low-level i/o */
-
+/** @defgroup   libc_ioflags    Low Level I/O Flags
+ * These low level I/O flags are kept in the fFlags member of the LIBCFH
+ * structure. The O_* flags are defined in sys/fcntl.h, the F_* flags are
+ * internal to LIBC and defined in emx/io.h.
+ * @{
+ */
+/*      O_RDONLY    0x00000000 */
+/*      O_WRONLY    0x00000001 */
+/*      O_RDWR      0x00000002 */
 /*      O_ACCMODE   0x00000003 */
-/*      O_NDELAY    0x00000004 */
+/*      O_NONBLOCK  0x00000004 */
 /*      O_APPEND    0x00000008 */
-/*      O_TEXT      0x00000010 */
-#define F_EOF       0x00000020
-#define F_TERMIO    0x00000040
-#define F_DEV       0x00000080
-/*      O_BINARY    0x00000100 */
+/* emx  O_TEXT      0x00000010 */
+/* emx  O_SIZE      0x00000020 */
+/*      free        0x00000040 */
+/*      O_(F)SYNC   0x00000080 */
+/*      O_SYNC      0x00000080 */
+/* emx  O_BINARY    0x00000100 */
 /*      O_CREAT     0x00000200 */
 /*      O_TRUNC     0x00000400 */
 /*      O_EXCL      0x00000800 */
-/*      O_NOINHERIT 0x00001000 */
-/*      O_SYNC      0x00002000 */
-/*      O_NOCTTY    0x00004000 */
-/*      O_SIZE      0x00008000 */
-#define F_SOCKET    0x10000000
-#define F_PIPE      0x20000000
-#define F_WRCRPEND  0x40000000
-#define F_CRLF      0x80000000
+/* emx  O_NOINHERIT 0x00001000 */
+/*      free        0x00002000 */
+/*      free        0x00004000 */
+/*      O_NOCTTY    0x00008000 */
+#define F_EOF       0x01000000
+#define F_TERMIO    0x02000000
+#define F_WRCRPEND  0x04000000
+#define F_CRLF      0x08000000
+/** Filetype mask. */
+#define F_TYPEMASK  0xf0000000
+/** Type - Regular file. */
+#define F_FILE      0x10000000
+/** Type - Characater device. */
+#define F_DEV       0x20000000
+/** Type - Pipe. */
+#define F_PIPE      0x30000000
+/** Type - Socket. */
+#define F_SOCKET    0x40000000
+/** @} */
 
 /* stdio */
@@ -157,21 +176,7 @@
 };
 
-extern struct streamvec _streamvec_head;
-
-extern int _io_ninherit;
-extern struct fdvec _fdvec_head;
-
-/* This is currently used only in the multi-thread libraries.  We
-   can't use and reallocate a single array because rmutex semaphores
-   cannot be moved. */
-
-struct streamvec2
-{
-  struct _file2 *vec;
-  struct streamvec2 *next;
-  int n;
-};
-
-extern struct streamvec2 _streamvec2_head;
+extern struct streamvec    *_streamvec_head;
+extern int                  _io_ninherit;
+extern struct fdvec         _fdvec_head;
 
 #if defined (_SYS_RMUTEX_H)
@@ -203,10 +208,119 @@
 #endif /* defined (_SYS_RMUTEX_H) */
 
+struct __libc_FileHandle;
+
+/**
+ * File handle Operations.
+ * (for non standard handles (like sockets))
+ */
+typedef struct __libc_FileHandleOperations
+{
+    /** Handle type. */
+    enum
+    {
+        /** Anything which is supported by the OS/2 file API.
+         * (not used at present as those handles doesn't need special ops). */
+        enmFH_File,
+        /** Socket handle. */
+        enmFH_Socket
+    }   enmType;
+
+    /** Close operation.
+     * @returns 0 on success.
+     * @returns OS/2 error code on failure.
+     * @param   pFH         Pointer to the handle structure to operate on.
+     * @param   fh          It's associated filehandle.
+     */
+    int (*pfnClose)(struct __libc_FileHandle *pFH, int fh);
+    /** Read operation.
+     * @returns 0 on success.
+     * @returns OS/2 error code on failure.
+     * @param   pFH         Pointer to the handle structure to operate on.
+     * @param   fh          It's associated filehandle.
+     * @param   pvBuf       Pointer to the buffer to read into.
+     * @param   cbRead      Number of bytes to read.
+     * @param   pcbRead     Where to store the count of bytes actually read.
+     */
+    int (*pfnRead)(struct __libc_FileHandle *pFH, int fh, void *pvBuf, size_t cbRead, size_t *pcbRead);
+    /** Write operation.
+     * @returns 0 on success.
+     * @returns OS/2 error code on failure.
+     * @param   pFH         Pointer to the handle structure to operate on.
+     * @param   fh          It's associated filehandle.
+     * @param   pvBuf       Pointer to the buffer which contains the data to write.
+     * @param   cbWrite     Number of bytes to write.
+     * @param   pcbWritten  Where to store the count of bytes actually written.
+     */
+    int (*pfnWrite)(struct __libc_FileHandle *pFH, int fh, const void *pvBuf, size_t cbWrite, size_t *pcbWritten);
+    /** Duplicate handle operation.
+     * @returns 0 on success, OS/2 error code on failure.
+     * @param   pFH         Pointer to the handle structure to operate on.
+     * @param   fh          It's associated filehandle.
+     * @param   pfhNew      Where to store the duplicate filehandle.
+     *                      The input value describe how the handle is to be
+     *                      duplicated. If it's -1 a new handle is allocated.
+     *                      Any other value will result in that value to be
+     *                      used as handle. Any existing handle with that
+     *                      value will be closed.
+     */
+    int (*pfnDuplicate)(struct __libc_FileHandle *pFH, int fh, int *pfhNew);
+    /** File Control operation.
+     * @returns 0 on success, OS/2 error code on failure.
+     * @param   pFH         Pointer to the handle structure to operate on.
+     * @param   fh          It's associated filehandle.
+     * @param   iIOControl  Which file file control operation to perform.
+     * @param   iArg        Argument which content is specific to each
+     *                      iIOControl operation.
+     * @param   prc         Where to store the value which upon success is
+     *                      returned to the caller.
+     */
+    int (*pfnFileControl)(struct __libc_FileHandle *pFH, int fh, int iIOControl, int iArg, int *prc);
+    /** I/O Control operation.
+     * @returns 0 on success, OS/2 error code on failure.
+     * @param   pFH         Pointer to the handle structure to operate on.
+     * @param   fh          It's associated filehandle.
+     * @param   iIOControl  Which I/O control operation to perform.
+     * @param   iArg        Argument which content is specific to each
+     *                      iIOControl operation.
+     * @param   prc         Where to store the value which upon success is
+     *                      returned to the caller.
+     */
+    int (*pfnIOControl)(struct __libc_FileHandle *pFH, int fh, int iIOControl, int iArg, int *prc);
+
+} LIBCFHOPS, *PLIBCFHOPS/*, const * PCLIBCFHOPS*/;
+
+
+/**
+ * Common part of a per 'file' handle structure.
+ */
+typedef struct __libc_FileHandle
+{
+    /** Handle flags.
+     * Previously represented by _files / *fd_vec->flags.
+     * @remark For thread safety update this atomically. */
+    unsigned int    fFlags;
+
+    /** Lookahead. (whoever uses that?)
+     * Previously represented by _files / *fd_vec->flags.
+     * @remark For thread safety update this atomically. */
+    int             iLookAhead;
+
+    /** Pointer to the operations one can perform on the handle.
+     * Only for special handles not supported by the OS/2 file API. */
+    PLIBCFHOPS      pOps;
+
+} LIBCFH, *PLIBCFH;
+
+int     __libc_FHEnsureHandles(int fh);
+int     __libc_FHAllocate(int fh, unsigned fFlags, int cb, PLIBCFHOPS pOps, PLIBCFH *ppFH, int *pfh);
+int     __libc_FHClose(int fh);
+PLIBCFH __libc_FH(int fh);
+
 
 int _endbuf1 (struct _FILE *);
 void _fbuf (struct _FILE *);
-int *_fd_flags (int);
-int *_fd_init (int);
-int *_fd_lookahead (int);
+#define _fd_flags(a)        please do not use this use this! ##a
+#define _fd_init(a)         please do not use this use this! ##a
+#define _fd_lookahead(a)    please do not use this use this! ##a
 struct _FILE *_openstream (struct _FILE *, __const__ char *, __const__ char *,
     int, int);
Index: trunk/src/emx/include/emx/syscalls.h
===================================================================
--- trunk/src/emx/include/emx/syscalls.h	(revision 870)
+++ trunk/src/emx/include/emx/syscalls.h	(revision 871)
@@ -180,7 +180,8 @@
 int __mkdir (__const__ char *name);
 int __newthread (int tid);
-int __open (__const__ char *name, int flags, off_t size);
+struct __libc_FileHandle;
+int __open (__const__ char *name, int flags, off_t size, unsigned fLibc, struct __libc_FileHandle **pFH);
 int __pause (void);
-int __pipe (int *two_handles, int pipe_size);
+int __pipe(int *two_handles, int pipe_size, struct __libc_FileHandle **ppFHRead, struct __libc_FileHandle **ppFHWrite);
 int __profil (__const__ struct _profil *p);
 int __ptrace (int request, int pid, int addr, int data);
Index: trunk/src/emx/include/stdio.h
===================================================================
--- trunk/src/emx/include/stdio.h	(revision 870)
+++ trunk/src/emx/include/stdio.h	(revision 871)
@@ -197,10 +197,8 @@
 
 __BEGIN_DECLS
-extern FILE _streamv[];
+extern FILE *__stdinp;
+extern FILE *__stdoutp;
+extern FILE *__stderrp;
 __END_DECLS
-
-#define __stdinp    (&_streamv[0])
-#define __stdoutp   (&_streamv[1])
-#define __stderrp   (&_streamv[2])
 
 #endif /* bird: EMX specific FILE stuff ends. */
Index: trunk/src/emx/src/lib/app/iodata.c
===================================================================
--- trunk/src/emx/src/lib/app/iodata.c	(revision 870)
+++ 	(revision )
@@ -1,17 +1,0 @@
-/* iodata.c (emx+gcc) -- Copyright (c) 1990-1996 by Eberhard Mattes */
-
-#include "libc-alias.h"
-#include <fcntl.h>
-#include <emx/io.h>
-
-/* The following variables are used for backward compatibility with
-   existing libraries (-Zcrtdll -lsocket!).  See also io/_fd.c,
-   app/stdio.c, and startup/startup.c. */
-
-int _files[_NFILES];
-int _lookahead[_NFILES];
-const int _nfiles = _NFILES;
-
-struct fdvec _fdvec_head = {_files, _lookahead, NULL, _NFILES};
-
-int _io_ninherit = 40;
Index: trunk/src/emx/src/lib/app/stdio.c
===================================================================
--- trunk/src/emx/src/lib/app/stdio.c	(revision 870)
+++ trunk/src/emx/src/lib/app/stdio.c	(revision 871)
@@ -10,102 +10,123 @@
 #include <emx/startup.h>
 
-/* See app/iodata.c. */
 
-extern int _nfiles;
-extern int _files[];
+/*******************************************************************************
+*   Global Variables                                                           *
+*******************************************************************************/
+/** Preallocated streams
+ * (public since stdin,stdout,stderr references this thru #defines.) */
+static FILE                 gaPreFiles[_NFILES] = {{0}};
 
-_rmutex _streamv_rmutex;        /* See io/_newstre.c */
+/** Vector entry for preallocated streams. */
+static struct streamvec     gPreStreamVec = {&gaPreFiles[0], NULL, _NFILES};
+
+/** More structures for preallocated streams. */
+static struct _file2        gaPreFile2s[_NFILES];
+
+/** The buffer for stdin. */
+static char                 gachStdIn[BUFSIZ];
+
+/** Mutex protecting the stream vector. */
+_rmutex                     _streamv_rmutex;    /* See io/_newstre.c */
+
+/*
+ * (These variables must be initialized as no extended dictionary
+ * entries are built for COMDEF.)
+ */
+
+/** Head of the stream vector. */
+struct streamvec           *_streamvec_head = NULL;
+
+/** Standard input stream pointer. */
+FILE                       *__stdinp = &gaPreFiles[0];
+/** Standard output stream pointer. */
+FILE                       *__stdoutp = &gaPreFiles[1];
+/** Standard error stream pointer. */
+FILE                       *__stderrp = &gaPreFiles[2];
 
 
-/* These variables must be initialized as no extended dictionary
-   entries are built for COMDEF. */
+/**
+ * Initialize the streams -- this function will be called by
+ * _CRT_init() via the __crtinit1__ set vector.
+ */
+void _init_streams(void);
+void _init_streams(void)
+{
+    struct _FILE       *pFile;
+    struct _file2      *pFile2;
+    int                 i;
+    static char         fInited = 0;
 
-FILE _streamv[_NFILES] = {{0}};
+    /*
+     * Paranoia!
+     */
+    if (fInited)
+        return;
+    fInited = 1;
 
-struct streamvec _streamvec_head = {_streamv, NULL, _NFILES};
+    /*
+     * Init the _more and _owner pointers.
+     */
+    pFile   = &gaPreFiles[0];
+    pFile2  = &gaPreFile2s[0];
+    for (i = 0; i < _NFILES; i++, pFile++, pFile2++)
+    {
+        pFile2->owner = pFile; /* obsolete? */
+        pFile->_more = pFile2;
+    }
 
-/* If we don't preallocate the first entry, _CRT_init() will call
-   malloc() which breaks fork() because the heap object of the EXE
-   file won't be used. */
+    /*
+     * Create the mutex protecting the stream list and insert the table.
+     * ASSUME: we're ALONE at this point.
+     */
+    gPreStreamVec.next  = _streamvec_head;
+    _streamvec_head     = &gPreStreamVec;
+    _rmutex_checked_create(&_streamv_rmutex, 0);
 
-static struct _file2 _streamv2[_NFILES];
+    /*
+     * As far as I know there is no reason to initiate a bunch of streams
+     * here as EM used to do. All that is required is the three standard
+     * streams.
+     */
+    for (i = 0; i < 3; i++)
+    {
+        PLIBCFH pFH = __libc_FH(i);
+        if (pFH)
+        {
+            /*
+             * Common init - recall everything is ZERO.
+             */
+            gaPreFiles[i]._flags    |= _IOOPEN;
+            gaPreFiles[i]._handle    = i;
+            gaPreFiles[i]._flush     = _flushstream;
+            if (_setmore(&gaPreFiles[i], 0))
+                abort();
 
-struct streamvec2 _streamvec2_head = {_streamv2, NULL, _NFILES};
+            /*
+             * Specific init.
+             */
+            switch (i)
+            {
+                case 0:
+                    /* stdin is always buffered. */
+                    gaPreFiles[0]._flags    |= _IOREAD | _IOFBF | _IOBUFUSER;
+                    gaPreFiles[0]._ptr       = gachStdIn;
+                    gaPreFiles[0]._buffer    = gachStdIn;
+                    gaPreFiles[0]._buf_size  = BUFSIZ;
+                    break;
 
-/* The buffer for stdin. */
+                case 1:
+                    /* stdout is buffered unless it's connected to a device. */
+                    gaPreFiles[1]._flags |= _IOWRT | _IOBUFNONE
+                        | ((pFH->fFlags & F_TYPEMASK) == F_DEV ? _IONBF : _IOFBF);
+                    break;
 
-static char ibuf[BUFSIZ];
-
-
-/* Initialize the streams -- this function will be called by
-   _CRT_init() via the __crtinit1__ set vector. */
-
-void _init_streams (void);
-void _init_streams (void)
-{
-  int i;
-
-  _rmutex_checked_create (&_streamv_rmutex, 0);
-
-  for (i = 0; i < _nfiles && i < _streamvec_head.n; ++i)
-    {
-      _streamv[i]._flags = 0;
-      /* O_TEXT is set by init_files() for all valid handles. */
-      if (_files[i] != 0)
-        {
-          _streamv[i]._flags |= _IOOPEN;
-          _streamv[i]._ptr = NULL;
-          _streamv[i]._buffer = NULL;
-          _streamv[i]._rcount = 0;
-          _streamv[i]._wcount = 0;
-          _streamv[i]._handle = i;
-          _streamv[i]._buf_size = 0;
-          _streamv[i]._tmpidx = 0;
-          _streamv[i]._pid = 0;
-          _streamv[i]._flush = _flushstream;
-          _streamv[i]._ungetc_count = 0;
-          switch (i)
-            {
-            case 0:
-
-              /* stdin is always buffered. */
-
-              _streamv[0]._flags |= _IOREAD | _IOFBF | _IOBUFUSER;
-              _streamv[0]._ptr = ibuf;
-              _streamv[0]._buffer = ibuf;
-              _streamv[0]._buf_size = BUFSIZ;
-              break;
-
-            case 1:
-
-              /* stdout is buffered unless it's connected to a
-                 device. */
-
-              _streamv[i]._flags |= (_IOWRT | _IOBUFNONE
-                                     | ((_files[i] & F_DEV)
-                                        ? _IONBF : _IOFBF));
-              break;
-
-            case 2:
-
-              /* stderr is always unbuffered. */
-
-              _streamv[i]._flags |= _IOWRT | _IOBUFNONE | _IONBF;
-              break;
-
-            default:
-
-              /* All other streams are buffered unless connected to a
-                 device. */
-
-              _streamv[i]._flags |= (_IORW | _IOBUFNONE
-                                     | ((_files[i] & F_DEV)
-                                        ? _IONBF : _IOFBF));
-              break;
+                case 2:
+                    /* stderr is always unbuffered. */
+                    gaPreFiles[2]._flags |= _IOWRT | _IOBUFNONE | _IONBF;
+                    break;
             }
-          if (_setmore (&_streamv[i], 0) != 0)
-            abort ();
         }
-    }
+    } /* for standard handles. */
 }
 
@@ -116,11 +137,11 @@
    print something.  (ISO 9899-1990 lets this undefined.) */
 
-void _exit_streams (void);
-void _exit_streams (void)
+void _exit_streams(void);
+void _exit_streams(void)
 {
-  flushall ();
-  _rmtmp ();
+    flushall();
+    _rmtmp();
 }
 
-_CRT_INIT1 (_init_streams)
-_CRT_EXIT1 (_exit_streams)
+_CRT_INIT1(_init_streams)
+_CRT_EXIT1(_exit_streams)
Index: trunk/src/emx/src/lib/io/_fbuf.c
===================================================================
--- trunk/src/emx/src/lib/io/_fbuf.c	(revision 870)
+++ trunk/src/emx/src/lib/io/_fbuf.c	(revision 871)
@@ -1,3 +1,4 @@
-/* _fbuf.c (emx+gcc) -- Copyright (c) 1990-1996 by Eberhard Mattes */
+/* _fbuf.c (emx+gcc) -- Copyright (c) 1990-1996 by Eberhard Mattes
+                     -- Copyrithg (c) 2003 by knut st. osmundsen */
 
 #include "libc-alias.h"
@@ -5,4 +6,5 @@
 #include <stdlib.h>
 #include <emx/io.h>
+#include <emx/umalloc.h>
 
 /* Assign a buffer to a stream (which must not have a buffer) */
@@ -13,5 +15,12 @@
     stream->_buffer = NULL;
   else
-    stream->_buffer = malloc (BUFSIZ);
+    {
+      PLIBCFH   pFH = __libc_FH(stream->_handle);
+      if (pFH && (   (pFH->fFlags & F_TYPEMASK) == F_DEV
+                  || (pFH->fFlags & F_TYPEMASK) == F_SOCKET))
+        stream->_buffer = _lmalloc(BUFSIZ);
+      else
+        stream->_buffer = _hmalloc(BUFSIZ);
+    }
   if (stream->_buffer == NULL)
     {
Index: trunk/src/emx/src/lib/io/_fd.c
===================================================================
--- trunk/src/emx/src/lib/io/_fd.c	(revision 870)
+++ trunk/src/emx/src/lib/io/_fd.c	(revision 871)
@@ -1,2 +1,4 @@
+#if 0 /* dead */
+
 /* _fd.c (emx+gcc) -- Copyright (c) 1996 by Eberhard Mattes */
 
@@ -4,66 +6,34 @@
 #include <emx/io.h>
 
-/* See app/iodata.c. */
 
-extern int _nfiles;
-extern int _files[];
-extern int _lookahead[];
-
-/* Return pointer to flags word for the file descriptor HANDLE.
-   Return NULL on error. */
-
-int *_fd_flags (int handle)
+/**
+ * @returns pointer to flags word for the file descriptor HANDLE.
+ * @returns NULL on error.
+ * @deprecated
+ */
+int *_fd_flags(int fh)
 {
-  struct fdvec *p;
-
-  if (handle < 0)
+    PLIBCFH     pFH;
+    pFH = __libc_FH(fh);
+    if (!pFH)
+        return &pFH->fFlags;
     return NULL;
-
-  /* We want this case to be fast.  Note that _fdvec_head.n == _nfiles
-     and _fdvec_head.flags == _files! */
-
-  if (handle < _nfiles)
-    return &_files[handle];
-
-  handle -= _nfiles;
-  p = _fdvec_head.next;
-  while (p != NULL && handle >= p->n)
-    {
-      handle -= p->n;
-      p = p->next;
-    }
-  if (p == NULL)
-    return NULL;
-  return &p->flags[handle];
 }
 
 
-/* Return pointer to lookahead word for the file descriptor HANDLE.
-   Return NULL on error.
+/**
+ * @returns pointer to lookahead word for the file descriptor HANDLE.
+ * @returns NULL on error.
+ * @remark  select() does this inline.
+ * @depricated
+ */
+int *_fd_lookahead(int fh)
+{
+    PLIBCFH     pFH;
+    pFH = __libc_FH(fh);
+    if (!pFH)
+        return &pFH->iLookAhead;
+    return NULL;
+}
 
-   Note: select() does this inline. */
-
-int *_fd_lookahead (int handle)
-{
-  struct fdvec *p;
-
-  if (handle < 0)
-    return NULL;
-
-  /* We want this case to be fast.  Note that _fdvec_head.n == _nfiles
-     and _fdvec_head.lookahead == _lookahead! */
-
-  if (handle < _nfiles)
-    return &_lookahead[handle];
-
-  handle -= _nfiles;
-  p = _fdvec_head.next;
-  while (p != NULL && handle >= p->n)
-    {
-      handle -= p->n;
-      p = p->next;
-    }
-  if (p == NULL)
-    return NULL;
-  return &p->lookahead[handle];
-}
+#endif
Index: trunk/src/emx/src/lib/io/_fdinit.c
===================================================================
--- trunk/src/emx/src/lib/io/_fdinit.c	(revision 870)
+++ trunk/src/emx/src/lib/io/_fdinit.c	(revision 871)
@@ -1,2 +1,3 @@
+#if 0 /* dead */
 /* _fdinit.c (emx+gcc) -- Copyright (c) 1996-1997 by Eberhard Mattes */
 
@@ -119,2 +120,3 @@
   return &p->flags[handle];
 }
+#endif
Index: trunk/src/emx/src/lib/io/_flushst.c
===================================================================
--- trunk/src/emx/src/lib/io/_flushst.c	(revision 870)
+++ trunk/src/emx/src/lib/io/_flushst.c	(revision 871)
@@ -49,7 +49,7 @@
           else                  /* New or flushed buffer */
             {
-              int *pflags = _fd_flags (fh);
+              PLIBCFH   pFH = __libc_FH(fh);
               w = 0;
-              if (pflags != NULL && (*pflags & O_APPEND))
+              if (pFH && (pFH->fFlags & O_APPEND))
                 lseek (fh, 0, SEEK_END);
             }
Index: trunk/src/emx/src/lib/io/_imphand.c
===================================================================
--- trunk/src/emx/src/lib/io/_imphand.c	(revision 870)
+++ trunk/src/emx/src/lib/io/_imphand.c	(revision 871)
@@ -3,50 +3,8 @@
 #include "libc-alias.h"
 #include <io.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/ioctl.h>
-#include <emx/io.h>
 #include <emx/syscalls.h>
-
-extern int _fmode_bin;
 
 int _imphandle (int handle)
 {
-  int fd, rc, ht, *pflags;
-
-  if (handle < 0)
-    {
-      errno = EBADF;
-      return -1;
-    }
-
-  fd = __imphandle (handle);
-  if (fd == -1)
-    return -1;
-  pflags = _fd_init (fd);
-  if (pflags == NULL)
-    {
-      /* `fd' has been relocated and is now out of range. */
-
-      __dup2 (fd, handle);
-      __close (fd);
-      errno = EBADF;
-      return -1;
-    }
-
-  *pflags = O_RDWR;             /* TODO */
-  if (_fmode_bin == 0)
-    *pflags |= O_TEXT;
-  rc = __ioctl1 (fd, 0);
-  if (rc != -1 && (rc & 0x80))
-    *pflags |= F_DEV;
-  rc = __ioctl2 (fd, FGETHTYPE, (int)&ht);
-  if (rc >= 0)
-    {
-      if (HT_ISDEV (ht))
-        *pflags |= F_DEV;
-      if (ht == HT_UPIPE || ht == HT_NPIPE)
-        *pflags |= F_PIPE;
-    }
-  return fd;
+    return __imphandle(handle);
 }
Index: trunk/src/emx/src/lib/io/_isterm.c
===================================================================
--- trunk/src/emx/src/lib/io/_isterm.c	(revision 870)
+++ trunk/src/emx/src/lib/io/_isterm.c	(revision 871)
@@ -3,15 +3,32 @@
 #include "libc-alias.h"
 #include <io.h>
+#include <errno.h>
+#include <emx/io.h>
 #include <emx/syscalls.h>
 
-int _isterm (int handle)
+int _isterm(int handle)
 {
-  int j;
+    PLIBCFH pFH;
 
-  if (!isatty (handle))
-    return 0;
-  j = __ioctl1 (handle, 0);
-  if (j < 0)
-    return 0;
-  return ((j & 0x03) ? 1 : 0);
+    /*
+     * Get filehandle.
+     */
+    pFH = __libc_FH(handle);
+    if (!pFH)
+    {
+        errno = EBADF;
+        return 0;
+    }
+
+    /*
+     * Is it a atty?
+     */
+    if (!isatty(handle))
+        return 0;
+
+    /*
+     * If it's a device we assume is a terminal...
+     * (Hope that's correct interpretation of the __ioctl1() call...)
+     */
+    return (pFH->fFlags & F_TYPEMASK) == F_DEV;
 }
Index: trunk/src/emx/src/lib/io/_newstre.c
===================================================================
--- trunk/src/emx/src/lib/io/_newstre.c	(revision 870)
+++ trunk/src/emx/src/lib/io/_newstre.c	(revision 871)
@@ -1,3 +1,4 @@
-/* _newstre.c (emx+gcc) -- Copyright (c) 1990-1996 by Eberhard Mattes */
+/* _newstre.c (emx+gcc) -- Copyright (c) 1990-1996 by Eberhard Mattes
+                        -- Copyright (c) 2003 by Knut St. Osmundsen */
 
 #include "libc-alias.h"
@@ -7,144 +8,142 @@
 #include <sys/fmutex.h>         /* For <sys/rmutex.h> */
 #include <sys/rmutex.h>
+#include <emx/umalloc.h>
 #include <emx/io.h>
 
 #define INC     32
+#define ALIGN(p, a) (((unsigned long)(p) + (a) - 1) & ~((a) - 1))
 
 FILE *_newstream (void)
 {
-  int i;
-  struct streamvec *sv, *last = NULL;
+    int                 i;
+    struct streamvec   *pSV;
+    struct streamvec   *pSVNew;
 
-  STREAMV_LOCK;
-  for (sv = &_streamvec_head; sv != NULL; sv = sv->next)
+    /*
+     * Search thru the list of streams.
+     */
+    STREAMV_LOCK;
+    for (pSV = _streamvec_head; pSV != NULL; pSV = pSV->next)
     {
-      last = sv;
-      for (i = 0; i < sv->n; ++i)
-        if (!(sv->vec[i]._flags & (_IOOPEN|_IONEW)))
-          {
-            sv->vec[i]._flags = _IONEW;
-
-            /* Initialize new members to support dynamically linked
-               old executables with, say, -lvideo.  See also below. */
-
-            sv->vec[i]._more = 0;
-            sv->vec[i]._mbstate = 0;
-
-            STREAMV_UNLOCK;
-            return &sv->vec[i];
-          }
-    }
-
-  /* Enlarge our tables.  As the entries must not move, we add another
-     segment. */
-
-  sv = malloc (sizeof (*sv));
-  if (sv != NULL)
-    {
-      struct _FILE *fv;
-
-      fv = malloc (INC * sizeof (*fv));
-      if (fv == NULL)
-        free (sv);
-      else
+        for (i = 0; i < pSV->n; ++i)
         {
-          for (i = 0; i < INC; ++i)
-            fv[i]._flags = 0;
-          sv->next = NULL;
-          sv->vec = fv;
-          sv->n = INC;
-
-          /* See above. */
-          fv[0]._flags = _IONEW;
-          fv[0]._more = 0;
-          fv[0]._mbstate = 0;
-
-          last->next = sv;      /* Done as last step, see fflush() */
-
-          STREAMV_UNLOCK;
-          return &fv[0];
-        }
-    }
-
-  STREAMV_UNLOCK;
-  return NULL;
-}
-
-int _setmore (FILE *stream, int lock)
-{
-  int i;
-  struct _file2 *p;
-  struct streamvec2 *sv2, *last = NULL;
-
-  stream->_mbstate = 0;
-  stream->_more = NULL;
-  if (lock)
-    STREAMV_LOCK;
-  p = NULL;
-  for (sv2 = &_streamvec2_head; sv2 != NULL; sv2 = sv2->next)
-    {
-      last = sv2;
-      for (i = 0; i < sv2->n; ++i)
-        if (sv2->vec[i].owner == NULL)
-          {
-            p = &sv2->vec[i];
-            goto super_break;
-          }
-    }
-super_break:
-  if (p == NULL)
-    {
-      sv2 = malloc (sizeof (*sv2));
-      if (sv2 != NULL)
-        {
-          struct _file2 *fv2;
-
-          fv2 = malloc (INC * sizeof (*fv2));
-          if (fv2 == NULL)
-            free (sv2);
-          else
+            if (!(pSV->vec[i]._flags & (_IOOPEN|_IONEW)))
             {
-              for (i = 0; i < INC; ++i)
-                fv2[i].owner = NULL;
-              sv2->next = NULL;
-              sv2->vec = fv2;
-              sv2->n = INC;
-              last->next = sv2;
-              p = &sv2->vec[0];
+                pSV->vec[i]._flags = _IONEW;
+                STREAMV_UNLOCK;
+                return &pSV->vec[i];
             }
         }
     }
-  if (p != NULL)
-    p->owner = stream;
-  if (lock)
     STREAMV_UNLOCK;
-  if (p == NULL || _rmutex_create (&p->rsem, 0) != 0)
+
+    /*
+     * Enlarge our table.
+     * (As the entries must not move, we add another segment.)
+     */
+    pSVNew = _hcalloc(1, sizeof(*pSV) + 15
+                      + INC * sizeof(struct _FILE)
+                      + 15
+                      + INC * sizeof(struct _file2));
+    if (pSVNew)
     {
-      /* Note that stream->_more is NULL. */
+        struct _FILE       *pFile;
+        struct _file2      *pFile2;
 
-      _closestream (stream);
-      if (p != NULL)
-        p->owner = NULL;
-      return -1;
+        /*
+         * Init the structures in the segment.
+         * Remember everything is ZEROed by calloc()!
+         */
+        pSVNew->vec = pFile = (struct _FILE  *)ALIGN(pSVNew + 1, 16);
+        pFile2              = (struct _file2 *)ALIGN(&pFile[INC], 16);
+        pSVNew->vec         = pFile;
+        pSVNew->n           = INC;
+        for (i = 0; i < INC; i++, pFile++, pFile2++)
+        {
+            pFile2->owner = pFile; /* obsolete? */
+            pFile->_more = pFile2;
+        }
+
+        /*
+         * Allocate the first one.
+         */
+        pFile = &pSV->vec[0];
+        pFile->_flags = _IONEW;
+
+        /*
+         * Insert the new chunk.
+         */
+        STREAMV_LOCK;
+        if (_streamvec_head)
+        {
+            for (pSV = _streamvec_head; pSV; pSV = pSV->next)
+                if (!pSV->next)
+                {
+                    pSV->next = pSVNew;
+                    break;
+                }
+        }
+        else
+            /* Someone fopen'ed something before streams were initated. */
+            _streamvec_head = pSVNew;
+        STREAMV_UNLOCK;
+        return pFile;
     }
-  stream->_more = p;
-  return 0;
+
+    return NULL;
 }
 
+/**
+ * This used to set the _more member, but now it only create the mutex and
+ * init _mbstate.
+ *
+ * @returns 0 on success.
+ * @returns -1 on failure
+ * @param   stream  Stream to init.
+ * @param   lock    Ignored.
+ */
+int _setmore(FILE *stream, int lock)
+{
+    /*
+     * Now this isn't so much work any longer, the streams are
+     * allocated with a more buffer by default now.
+     * All we gotta do is init _mbstate and create the mutex.
+     */
+    stream->_mbstate = 0;
+    if (_rmutex_create(&stream->_more->rsem, 0) != 0)
+    {
+        /* free the stream */
+        stream->_flags = 0;
+        lock = lock;
+        return -1;
+    }
+    return 0;
+}
+
+/**
+ * This is used when creating a special stream for instance in vsprintf().
+ *
+ * @param   stream  Special stream.
+ * @param   more    Dummy more block
+ */
 void _setdummymore (FILE *stream, struct _file2 *more)
 {
-  stream->_mbstate = 0;
-  stream->_more = more;
-  more->owner = stream;
-  _rmutex_dummy (&more->rsem);
+    stream->_mbstate = 0;
+    stream->_more = more;
+    more->owner = stream;
+    _rmutex_dummy(&more->rsem);
 }
 
-void _closestream (FILE *stream)
+
+/**
+ * Closes a stream freeing the associated mutex semaphore.
+ *
+ * @param   stream  Stream to close.
+ */
+void _closestream(FILE *stream)
 {
-  if (stream->_more != NULL && stream->_more->owner == stream)
-    {
-      _rmutex_close (&stream->_more->rsem);
-      stream->_more->owner = NULL;
-    }
-  stream->_flags = 0;
+    if (    stream->_more != NULL
+        &&  stream->_more->owner == stream) /* paranoia */
+        _rmutex_close(&stream->_more->rsem);
+    stream->_flags = 0;
 }
Index: trunk/src/emx/src/lib/io/_rmtmp.c
===================================================================
--- trunk/src/emx/src/lib/io/_rmtmp.c	(revision 870)
+++ trunk/src/emx/src/lib/io/_rmtmp.c	(revision 871)
@@ -17,5 +17,5 @@
 
   n = 0;
-  for (sv = &_streamvec_head; sv != NULL; sv = sv->next)
+  for (sv = _streamvec_head; sv != NULL; sv = sv->next)
     for (i = 0; i < sv->n; ++i)
       if ((sv->vec[i]._flags & _IOOPEN) && (sv->vec[i]._flags & _IOTMP)
Index: trunk/src/emx/src/lib/io/_vsopen.c
===================================================================
--- trunk/src/emx/src/lib/io/_vsopen.c	(revision 870)
+++ trunk/src/emx/src/lib/io/_vsopen.c	(revision 871)
@@ -38,11 +38,11 @@
      * 16 - 23  __open flags, _SO_*
      */
-    int     fFlags;
-    int    *pfFlags;
-    int     saved_errno;
-    int     bits;
-    char    chDummy;
-    int     fCtrlZKludge = 0;
-    off_t   cbInitial;
+    int         fFlags;
+    unsigned    fLibc;                  /* LIBC handle flags. */
+    int         saved_errno;
+    char        chDummy;
+    int         fCtrlZKludge = 0;
+    off_t       cbInitial;
+    PLIBCFH     pFH;
 
     /*
@@ -58,13 +58,10 @@
      * Build fFlags.
      */
-    bits = fOpen & (O_ACCMODE|O_NDELAY|O_APPEND);
-    if (fOpen & O_BINARY)
-        /* do nothing */;
-    else if (fOpen & O_TEXT)
-        bits |= O_TEXT;
-    else if (_fmode_bin == 0)          /* neither O_TEXT nor O_BINARY given */
-        bits |= O_TEXT;
+    fLibc = fOpen & (O_ACCMODE|O_NDELAY|O_APPEND|O_SYNC/*|O_DIRECT*/|O_NOINHERIT);
+    if (   !(fOpen & O_BINARY)
+        && ((fOpen & O_TEXT) || !_fmode_bin))
+        fLibc |= O_TEXT;
 
-    if ((bits & O_TEXT) && (fOpen & O_APPEND) && (fOpen & O_ACCMODE) == O_WRONLY)
+    if ((fLibc & O_TEXT) && (fOpen & O_APPEND) && (fOpen & O_ACCMODE) == O_WRONLY)
     {
         /* The caller requests to open a text file for appending in
@@ -113,5 +110,5 @@
      */
     saved_errno = errno;
-    hFile = __open(pszName, fFlags, cbInitial);
+    hFile = __open(pszName, fFlags, cbInitial, fLibc, &pFH);
     if (hFile < 0 && fCtrlZKludge && errno == EACCES)
     {
@@ -120,22 +117,21 @@
         fCtrlZKludge = 0;
         fFlags = (fFlags & ~O_ACCMODE) | (fOpen & O_ACCMODE);
-        hFile = __open(pszName, fFlags, cbInitial);
+        hFile = __open(pszName, fFlags, cbInitial, fLibc, &pFH);
     }
     if (hFile < 0)
         return -1;
+    fLibc = pFH->fFlags;                /* get the updated flags. */
 
     /*
      * Check what we got a handle to.
      */
-    if (__ioctl1(hFile, 0) & 0x80)
-    {
-        bits |= F_DEV;
+    if ((fLibc & F_TYPEMASK) == F_DEV)
         fOpen &= ~O_APPEND;
-    }
 
     /*
      * For text files we shall remove eventual ending Ctrl-Z.
      */
-    if (!(bits & F_DEV) && (bits & O_TEXT))
+    if (    (fLibc & F_TYPEMASK) != F_DEV
+        &&  (fLibc & O_TEXT))
     {
         off_t cbSize;
@@ -163,5 +159,5 @@
         fFlags = (fFlags & ~O_ACCMODE) | (fOpen & O_ACCMODE);
         fFlags &= ~_SO_EXCL;       /* Ignore O_EXCL */
-        hFile = __open(pszName, fFlags, cbInitial);
+        hFile = __open(pszName, fFlags, cbInitial, fLibc & ~F_TYPEMASK, &pFH);
         if (hFile < 0)
             return -1;
@@ -169,20 +165,9 @@
 
     /*
-     * Set file bits.
-     */
-    pfFlags = _fd_init(hFile);
-    if (!pfFlags)
-    {
-        __close(hFile);
-        errno = EMFILE;
-        return -1;
-    }
-    *pfFlags = bits;
-
-    /*
      * When opening a file for appending, move to the end of the file.
      * This is required for passing the file to a child process.
      */
-    if (!(bits & F_DEV) && (bits & O_APPEND))
+    if (    (fLibc & F_TYPEMASK) == F_FILE
+        &&  (fLibc & O_APPEND))
         __lseek(hFile, 0L, SEEK_END);
     errno = saved_errno;
Index: trunk/src/emx/src/lib/io/chsize.c
===================================================================
--- trunk/src/emx/src/lib/io/chsize.c	(revision 870)
+++ trunk/src/emx/src/lib/io/chsize.c	(revision 871)
@@ -10,10 +10,11 @@
 int _STD(chsize) (int handle, off_t length)
 {
+  PLIBCFH   pFH;
   off_t n;
-  off_t i;
-  int j, *pflags;
-  char zeros[4096];
 
-  if ((pflags = _fd_flags (handle)) == NULL || (*pflags & F_DEV))
+  pFH = __libc_FH(handle);
+  if (   !pFH
+      || (pFH->fFlags & F_DEV)
+      || pFH->pOps)
     {
       errno = EBADF;
@@ -27,4 +28,7 @@
   if (n < length)
     {
+      off_t i;
+      int   j;
+      char  zeros[4096];
       memset (zeros, 0, sizeof (zeros));
       if (__lseek (handle, n, SEEK_SET) == -1)
Index: trunk/src/emx/src/lib/io/close.c
===================================================================
--- trunk/src/emx/src/lib/io/close.c	(revision 870)
+++ trunk/src/emx/src/lib/io/close.c	(revision 871)
@@ -1,17 +1,16 @@
-/* close.c (emx+gcc) -- Copyright (c) 1990-1996 by Eberhard Mattes */
+/* close.c (emx+gcc) -- Copyright (c) 1990-1996 by Eberhard Mattes
+                     -- Copyright (c) 2003 by Knut St. Osmunden */
 
 #include "libc-alias.h"
 #include <io.h>
-#include <errno.h>
 #include <emx/io.h>
-#include <emx/syscalls.h>
 
-int _STD(close) (int handle)
+int _STD(close)(int fh)
 {
-  if (_fd_flags (handle) == NULL)
-    {
-      errno = EBADF;
-      return -1;
-    }
-  return __close (handle);
+    int rc;
+    rc = __libc_FHClose(fh);
+    if (!rc)
+        return 0;
+    /* (it sets errno) */
+    return -1;
 }
Index: trunk/src/emx/src/lib/io/dup.c
===================================================================
--- trunk/src/emx/src/lib/io/dup.c	(revision 870)
+++ trunk/src/emx/src/lib/io/dup.c	(revision 871)
@@ -1,32 +1,11 @@
-/* dup.c (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes */
+/* dup.c (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes
+                   -- Copyright (c) 2003 by Knut St. Osmunden */
 
 #include "libc-alias.h"
 #include <io.h>
-#include <errno.h>
-#include <emx/io.h>
 #include <emx/syscalls.h>
 
-int _STD(dup) (int handle)
+int _STD(dup)(int fh)
 {
-  int new, *pflags1, *pflags2, *pla1, *pla2;
-
-  if ((pflags1 = _fd_flags (handle)) == NULL
-   || (pla1 = _fd_lookahead (handle)) == NULL)
-    {
-      errno = EBADF;
-      return -1;
-    }
-  new = __dup (handle);
-  if (new < 0)
-    return new;
-  if ((pflags2 = _fd_init (new)) == NULL
-      || (pla2 = _fd_lookahead (new)) == NULL)
-    {
-      close (new);
-      errno = EMFILE;
-      return -1;
-    }
-  *pflags2 = *pflags1;
-  *pla2 = *pla1;
-  return new;
+    return __dup(fh);
 }
Index: trunk/src/emx/src/lib/io/dup2.c
===================================================================
--- trunk/src/emx/src/lib/io/dup2.c	(revision 870)
+++ trunk/src/emx/src/lib/io/dup2.c	(revision 871)
@@ -1,37 +1,14 @@
-/* dup2.c (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes */
+/* dup2.c (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes
+                    -- Copyright (c) 2003 by Knut St. Osmunden */
 
 #include "libc-alias.h"
 #include <io.h>
-#include <errno.h>
-#include <emx/io.h>
 #include <emx/syscalls.h>
 
-int _STD(dup2) (int handle1, int handle2)
+int _STD(dup2)(int handle1, int handle2)
 {
-  int *pflags1, *pflags2, *pla1, *pla2;
-
-  if ((pflags1 = _fd_flags (handle1)) == NULL
-   || (pla1 = _fd_lookahead (handle1)) == NULL
-   || handle2 < 0)
-    {
-      errno = EBADF;
-      return -1;
-    }
   /* TODO: Block signals */
-  if (__dup2 (handle1, handle2) < 0)
+  if (__dup2(handle1, handle2) < 0)
     return -1;
-
-  if ((pflags2 = _fd_init (handle2)) == NULL
-   || (pla2 = _fd_lookahead (handle2)) == NULL)
-    {
-      /* TODO: Unfortunately, the original HANDLE2, if there was one,
-         is now closed. */
-      close (handle2);
-      errno = EMFILE;
-      return -1;
-    }
-
-  *pflags2 = *pflags1;
-  *pla2 = *pla1;
   return handle2;
 }
Index: trunk/src/emx/src/lib/io/eof.c
===================================================================
--- trunk/src/emx/src/lib/io/eof.c	(revision 870)
+++ trunk/src/emx/src/lib/io/eof.c	(revision 871)
@@ -8,13 +8,17 @@
 int _STD(eof) (int handle)
 {
-  int *pflags;
+  PLIBCFH   pFH;
   off_t cur, len;
 
-  if ((pflags = _fd_flags (handle)) == NULL)
-    {
+  /*
+   * Get filehandle.
+   */
+  pFH = __libc_FH(handle);
+  if (!pFH)
+  {
       errno = EBADF;
       return -1;
-    }
-  if (*pflags & F_EOF)          /* Ctrl-Z reached */
+  }
+  if (pFH->fFlags & F_EOF)          /* Ctrl-Z reached */
     return 1;
   cur = tell (handle);
Index: trunk/src/emx/src/lib/io/fcloseal.c
===================================================================
--- trunk/src/emx/src/lib/io/fcloseal.c	(revision 870)
+++ trunk/src/emx/src/lib/io/fcloseal.c	(revision 871)
@@ -7,16 +7,14 @@
 int _fcloseall (void)
 {
-  int i, n, start;
+  int i, n;
   char ok;
   struct streamvec *sv;
 
   n = 0; ok = 1;
-  for (sv = &_streamvec_head; sv != NULL; sv = sv->next)
+  for (sv = _streamvec_head; sv != NULL; sv = sv->next)
     {
-      if (sv->vec == _streamv)
-        start = 3;              /* Keep stdin, stdout, stderr */
-      else
-        start = 0;
-      for (i = start; i < sv->n; ++i)
+      for (i = sv->vec == stdin ? 3 : 0; /* Keep stdin, stdout, stderr */
+           i < sv->n;
+           ++i)
         if (sv->vec[i]._flags & _IOOPEN)
           {
@@ -26,5 +24,4 @@
               ok = 0;
           }
-      start = 0;
     }
   return (ok ? n : EOF);
Index: trunk/src/emx/src/lib/io/fcntl.c
===================================================================
--- trunk/src/emx/src/lib/io/fcntl.c	(revision 870)
+++ trunk/src/emx/src/lib/io/fcntl.c	(revision 871)
@@ -1,3 +1,4 @@
-/* fcntl.c (emx+gcc) -- Copyright (c) 1992-1998 by Eberhard Mattes */
+/* fcntl.c (emx+gcc) -- Copyright (c) 1992-1998 by Eberhard Mattes
+                     -- Copyright (c) 2003 by Knut St. Osmunden */
 
 #include "libc-alias.h"
@@ -28,4 +29,5 @@
 
   /* TODO: Use sysconf()? */
+  /** @todo Define a max handles or something */
 
   if (handle2 < 0 || handle2 >= _POSIX_OPEN_MAX)
@@ -63,22 +65,23 @@
 {
   va_list va;
-  int ht, arg, *pflags;
+  int arg;
+  PLIBCFH   pFH;
 
-  if ((pflags = _fd_flags (handle)) == NULL)
-    {
+  /*
+   * Get filehandle.
+   */
+  pFH = __libc_FH(handle);
+  if (!pFH)
+  {
       errno = EBADF;
       return -1;
-    }
+  }
+
+  /** @todo Let __fcntl handle the flags. */
+
   switch (request)
     {
     case F_GETFL:
-      /* Check for valid handle.  We don't call __fcntl() because
-         emx.exe does not implement F_GETFL (emx.dll and rsx.exe
-         do). */
-
-      if (__ioctl2 (handle, FGETHTYPE, (int)&ht) != 0)
-        return -1;
-      return *pflags & FLAGS;
-
+      return __fcntl(handle, request, 0);
     case F_SETFL:
       va_start (va, request);
@@ -89,5 +92,5 @@
       if (__fcntl (handle, request, arg) == -1)
         return -1;
-      SETBITS (*pflags, FLAGS, arg);
+      SETBITS (pFH->fFlags, FLAGS, arg);
       return 0;
 
Index: trunk/src/emx/src/lib/io/fdopen.c
===================================================================
--- trunk/src/emx/src/lib/io/fdopen.c	(revision 870)
+++ trunk/src/emx/src/lib/io/fdopen.c	(revision 871)
@@ -19,5 +19,5 @@
   int omode;
 
-  if (_fd_flags (handle) == NULL)
+  if (!__libc_FH(handle))
     {
       errno = EBADF;
Index: trunk/src/emx/src/lib/io/fflush.c
===================================================================
--- trunk/src/emx/src/lib/io/fflush.c	(revision 870)
+++ trunk/src/emx/src/lib/io/fflush.c	(revision 871)
@@ -73,5 +73,5 @@
   if (stream == NULL)
     {
-      for (sv = &_streamvec_head; sv != NULL; sv = sv->next)
+      for (sv = _streamvec_head; sv != NULL; sv = sv->next)
         for (n = 0; n < sv->n; ++n)
           if ((sv->vec[n]._flags & (_IOOPEN|_IOWRT)) == (_IOOPEN|_IOWRT))
Index: trunk/src/emx/src/lib/io/flushall.c
===================================================================
--- trunk/src/emx/src/lib/io/flushall.c	(revision 870)
+++ trunk/src/emx/src/lib/io/flushall.c	(revision 871)
@@ -18,5 +18,5 @@
 
   n = 0;
-  for (sv = &_streamvec_head; sv != NULL; sv = sv->next)
+  for (sv = _streamvec_head; sv != NULL; sv = sv->next)
     for (i = 0; i < sv->n; ++i)
       if ((sv->vec[i]._flags & _IOOPEN) && STREAM_LOCK_NOWAIT (&sv->vec[i]))
Index: trunk/src/emx/src/lib/io/fseek.c
===================================================================
--- trunk/src/emx/src/lib/io/fseek.c	(revision 870)
+++ trunk/src/emx/src/lib/io/fseek.c	(revision 871)
@@ -13,6 +13,7 @@
 int _fseek_nolock (FILE *stream, off_t offset, int origin)
 {
-  off_t cur_pos;
-  int fflush_result, *pflags;
+  off_t     cur_pos;
+  int       fflush_result;
+  PLIBCFH   pFH;
 
   if (!(stream->_flags & _IOOPEN) || origin < 0 || origin > 2
@@ -55,6 +56,6 @@
           origin = SEEK_SET;
         }
-      text_mode = ((pflags = _fd_flags (stream->_handle)) != NULL
-                   && (*pflags & F_CRLF));
+      text_mode = (   (pFH = __libc_FH (stream->_handle)) != NULL
+                   && (pFH->fFlags & F_CRLF));
       n = stream->_ptr - stream->_buffer;
       if (text_mode)
Index: trunk/src/emx/src/lib/io/ftell.c
===================================================================
--- trunk/src/emx/src/lib/io/ftell.c	(revision 870)
+++ trunk/src/emx/src/lib/io/ftell.c	(revision 871)
@@ -13,6 +13,6 @@
 off_t _ftell_nolock (FILE *stream)
 {
-  off_t pos;
-  int * pflags;
+  off_t     pos;
+  PLIBCFH   pFH;
 
   if (stream->_flags & _IOSPECIAL)
@@ -30,6 +30,6 @@
           pos += stream->_ptr - stream->_buffer;
           if (!(stream->_flags & _IOSPECIAL)
-              && (pflags = _fd_flags (stream->_handle)) != NULL
-              && (*pflags & O_TEXT))
+              && (pFH = __libc_FH (stream->_handle)) != NULL
+              && (pFH->fFlags & O_TEXT))
             {
               const char *p;
@@ -58,6 +58,6 @@
       if (!(stream->_flags & _IOSPECIAL)
           && stream->_ungetc_count == 0
-          && (pflags = _fd_flags (stream->_handle)) != NULL
-          && (*pflags & F_CRLF))
+          && (pFH = __libc_FH (stream->_handle)) != NULL
+          && (pFH->fFlags & F_CRLF))
         {
           const char *p;
Index: trunk/src/emx/src/lib/io/ftruncat.c
===================================================================
--- trunk/src/emx/src/lib/io/ftruncat.c	(revision 870)
+++ trunk/src/emx/src/lib/io/ftruncat.c	(revision 871)
@@ -1,3 +1,4 @@
-/* ftruncat.c (emx+gcc) -- Copyright (c) 1990-1996 by Eberhard Mattes */
+/* ftruncat.c (emx+gcc) -- Copyright (c) 1990-1996 by Eberhard Mattes
+                        -- Copyright (c) 2003 by Knut St. Osmunden */
 
 #include "libc-alias.h"
@@ -9,11 +10,21 @@
 int _STD(ftruncate) (int handle, off_t length)
 {
-  int *pflags;
+    PLIBCFH pFH;
 
-  if ((pflags = _fd_flags (handle)) == NULL || (*pflags & F_DEV))
+    /*
+     * Get filehandle.
+     */
+    pFH = __libc_FH(handle);
+    if (!pFH)
     {
-      errno = EBADF;
-      return -1;
+        errno = EBADF;
+        return -1;
     }
-  return __ftruncate (handle, length);
+/** @todo check this api with latest specs - there is a zero fill extension now IIRC. */
+    if ((pFH->fFlags & F_TYPEMASK) != F_FILE)
+    {
+        errno = EBADF;
+        return -1;
+    }
+    return __ftruncate (handle, length);
 }
Index: trunk/src/emx/src/lib/io/ioctl.c
===================================================================
--- trunk/src/emx/src/lib/io/ioctl.c	(revision 870)
+++ trunk/src/emx/src/lib/io/ioctl.c	(revision 871)
@@ -1,3 +1,4 @@
-/* ioctl.c (emx+gcc) -- Copyright (c) 1990-1996 by Eberhard Mattes */
+/* ioctl.c (emx+gcc) -- Copyright (c) 1990-1996 by Eberhard Mattes
+                     -- Copyright (c) 2003 by Knut St. Osmunden */
 
 #include "libc-alias.h"
@@ -19,61 +20,77 @@
 int _STD(ioctl) (int handle, unsigned long request, ...)
 {
-  va_list va;
-  int rc, saved_errno, arg, *int_ptr, *pflags, *pla;
-  const struct termio *tp;
+    va_list     va;
+    PLIBCFH     pFH;
+    int         rc, saved_errno, arg, *int_ptr;
+    const struct termio *tp;
 
-  if ((pflags = _fd_flags (handle)) == NULL)
+    /*
+     * Get filehandle.
+     */
+    pFH = __libc_FH(handle);
+    if (!pFH)
     {
-      errno = EBADF;
-      return -1;
+        errno = EBADF;
+        return -1;
     }
-  saved_errno = errno; errno = 0;
-  va_start (va, request);
-  arg = va_arg (va, int);
-  va_end (va);
-  rc = __ioctl2 (handle, request, arg);
-  if (rc >= 0 && errno == 0)
-    switch (__IOCLW(request))
-      {
-      case __IOCLW(TCSETAF):
-      case __IOCLW(TCSETAW):
-      case __IOCLW(TCSETA):
-        va_start (va, request);
-        tp = va_arg (va, const struct termio *);
-        va_end (va);
-        if (tp->c_lflag & IDEFAULT)
-          *pflags &= ~F_TERMIO;
-        else
-          *pflags |= F_TERMIO;
-        break;
 
-      case __IOCLW(_TCSANOW):
-      case __IOCLW(_TCSADRAIN):
-      case __IOCLW(_TCSAFLUSH):
-        *pflags |= F_TERMIO;
-        break;
+    /*
+     * Make syscall.
+     */
+    saved_errno = errno; errno = 0;
+    va_start (va, request);
+    arg = va_arg(va, int);
+    va_end (va);
+    rc = __ioctl2(handle, request, arg);
 
-      case __IOCLW(FIONREAD):
-        if ((pla = _fd_lookahead (handle)) != NULL && *pla >= 0)
-          {
-            va_start (va, request);
-            int_ptr = va_arg (va, int *);
-            va_end (va);
-            ++(*int_ptr);
-          }
-        break;
+    /*
+     * On success do small touches of our own.
+     */
+    /** @todo fFlags can be handled by the syscall just as well as here..*/
+    if (rc >= 0 && errno == 0)
+    {
+        switch (__IOCLW(request))
+        {
+            case __IOCLW(TCSETAF):
+            case __IOCLW(TCSETAW):
+            case __IOCLW(TCSETA):
+                va_start(va, request);
+                tp = va_arg(va, const struct termio *);
+                va_end(va);
+                if (tp->c_lflag & IDEFAULT)
+                    pFH->fFlags &= ~F_TERMIO;
+                else
+                    pFH->fFlags |= F_TERMIO;
+                break;
 
-      case __IOCLW(FIONBIO):
-        va_start (va, request);
-        int_ptr = va_arg (va, int *);
-        va_end (va);
-        if (*int_ptr)
-          *pflags |= O_NDELAY;
-        else
-          *pflags &= ~O_NDELAY;
-        break;
-      }
-  if (errno == 0)
-    errno = saved_errno;
-  return rc;
+            case __IOCLW(_TCSANOW):
+            case __IOCLW(_TCSADRAIN):
+            case __IOCLW(_TCSAFLUSH):
+                pFH->fFlags |= F_TERMIO;
+                break;
+
+            case __IOCLW(FIONREAD):
+                if (pFH->iLookAhead >= 0)
+                {
+                    va_start(va, request);
+                    int_ptr = va_arg(va, int *);
+                    va_end(va);
+                    ++(*int_ptr);
+                }
+                break;
+
+            case __IOCLW(FIONBIO):
+                va_start(va, request);
+                int_ptr = va_arg(va, int *);
+                va_end(va);
+                if (*int_ptr)
+                    pFH->fFlags |= O_NDELAY;
+                else
+                    pFH->fFlags &= ~O_NDELAY;
+                break;
+        } /* switch */
+    }
+    if (errno == 0)
+        errno = saved_errno;
+    return rc;
 }
Index: trunk/src/emx/src/lib/io/isatty.c
===================================================================
--- trunk/src/emx/src/lib/io/isatty.c	(revision 870)
+++ trunk/src/emx/src/lib/io/isatty.c	(revision 871)
@@ -1,3 +1,4 @@
-/* isatty.c (emx+gcc) -- Copyright (c) 1990-1996 by Eberhard Mattes */
+/* isatty.c (emx+gcc) -- Copyright (c) 1990-1996 by Eberhard Mattes
+                      -- Copyright (c) 2003 by Knut St. Osmunden */
 
 #include "libc-alias.h"
@@ -6,14 +7,18 @@
 #include <emx/io.h>
 
-int _STD(isatty) (int handle)
+int _STD(isatty)(int handle)
 {
-  int *pflags;
+    PLIBCFH pFH;
 
-  if ((pflags = _fd_flags (handle)) == NULL)
+    /*
+     * Get filehandle.
+     */
+    pFH = __libc_FH(handle);
+    if (!pFH)
     {
-      errno = EBADF;
-      return 0;
+        errno = EBADF;
+        return 0;
     }
-  else
-    return ((*pflags & F_DEV) ? 1 : 0);
+
+    return (pFH->fFlags & F_TYPEMASK) == F_DEV;
 }
Index: trunk/src/emx/src/lib/io/lseek.c
===================================================================
--- trunk/src/emx/src/lib/io/lseek.c	(revision 870)
+++ trunk/src/emx/src/lib/io/lseek.c	(revision 871)
@@ -9,43 +9,53 @@
 off_t _STD(lseek) (int handle, off_t offset, int origin)
 {
-  int *pflags, *pla;
-  off_t n, cur;
+    PLIBCFH pFH;
+    off_t   n;
 
-  if ((pflags = _fd_flags (handle)) == NULL
-      || (pla = _fd_lookahead (handle)) == NULL)
+    /*
+     * Get filehandle.
+     */
+    pFH = __libc_FH(handle);
+    if (!pFH)
     {
-      errno = EBADF;
-      return -1;
+        errno = EBADF;
+        return -1;
     }
-  if (origin == SEEK_CUR && (*pla >= 0 || (*pflags & F_EOF)))
-    --offset;
-  if (offset < 0)
+
+    if (    origin == SEEK_CUR
+        && (    pFH->iLookAhead >= 0
+            || (pFH->fFlags & F_EOF)) )
+        --offset;
+#if 0 /* not needed on OS/2 I think... */
+    if (offset < 0)
     {
-      /* DOS doesn't return an error for seek before beginning of file */
-      if (origin == SEEK_SET)
+        off_t   cur;
+        /* DOS doesn't return an error for seek before beginning of file */
+        if (origin == SEEK_SET)
         {
-          errno = EINVAL;
-          return -1;
+            errno = EINVAL;
+            return -1;
         }
-      cur = __lseek (handle, 0, SEEK_CUR);
-      if (cur == -1L)
+        cur = __lseek(handle, 0, SEEK_CUR);
+        if (cur == -1L)
+            return -1;
+        n = __lseek(handle, 0, origin);
+        if (n + offset < 0)
+        {
+            __lseek(handle, cur, SEEK_SET);
+            errno = EINVAL;
+            return -1;
+        }
+        offset += n;
+        origin = SEEK_SET;
+    }
+#endif
+    n = __lseek(handle, offset, origin);
+    if (n == -1)
         return -1;
-      n = __lseek (handle, 0, origin);
-      if (n + offset < 0)
-        {
-          __lseek (handle, cur, SEEK_SET);
-          errno = EINVAL;
-          return -1;
-        }
-      offset += n; origin = SEEK_SET;
-    }
-  n = __lseek (handle, offset, origin);
-  if (n == -1)
-    return -1;
-  else
+    else
     {
-      *pflags &= ~F_EOF;        /* Clear Ctrl-Z flag */
-      *pla = -1;                /* Clear lookahead */
-      return n;
+        pFH->fFlags &= ~F_EOF;          /* Clear Ctrl-Z flag */
+        pFH->iLookAhead = -1;           /* Clear lookahead */
+        return n;
     }
 }
Index: trunk/src/emx/src/lib/io/pipe.c
===================================================================
--- trunk/src/emx/src/lib/io/pipe.c	(revision 870)
+++ trunk/src/emx/src/lib/io/pipe.c	(revision 871)
@@ -9,31 +9,22 @@
 
 extern int _fmode_bin;
-int _pipe_size;
 
-int _STD(pipe) (int *two_handles)
+/** The default pipe size. */
+int     _pipe_size;
+
+int _STD(pipe)(int *two_handles)
 {
-  int *pflags1, *pflags2;
+    PLIBCFH pFHRead, pFHWrite;
 
-  if (__pipe (two_handles, (_pipe_size != 0 ? _pipe_size : 8192)) != 0)
-    return -1;
-  pflags1 = _fd_init (two_handles[0]);
-  if (pflags1 == NULL)
-    pflags2 = NULL;
-  else
-    pflags2 = _fd_init (two_handles[1]);
-  if (pflags2 == NULL)
+    if (__pipe(two_handles, _pipe_size != 0 ? _pipe_size : 8192, &pFHRead, &pFHWrite) != 0)
+        return -1;
+
+    /** @todo move _fmode_bin check to __pipe()? */
+    if (!_fmode_bin)
     {
-      __close (two_handles[0]);
-      __close (two_handles[1]);
-      errno = EMFILE;
-      return -1;
+        pFHRead->fFlags  |= O_TEXT;
+        pFHWrite->fFlags |= O_TEXT;
     }
-  *pflags1 = O_RDONLY | F_PIPE;
-  *pflags2 = O_WRONLY | F_PIPE;
-  if (_fmode_bin == 0)
-    {
-      *pflags1 |= O_TEXT;
-      *pflags2 |= O_TEXT;
-    }
-  return 0;
+
+    return 0;
 }
Index: trunk/src/emx/src/lib/io/popen.c
===================================================================
--- trunk/src/emx/src/lib/io/popen.c	(revision 870)
+++ trunk/src/emx/src/lib/io/popen.c	(revision 871)
@@ -29,5 +29,5 @@
   const char *sh, *base, *opt;
 
-  fcntl (pipe_local, F_SETFD, 1);
+  fcntl (pipe_local, F_SETFD, FD_CLOEXEC);
   org_private = fcntl (handle, F_GETFD, 0);
   if (org_private == -1)
@@ -36,5 +36,6 @@
   if (org_handle == -1)
     return NULL;
-  fcntl (org_handle, F_SETFD, 1);
+  fcntl (org_handle, F_SETFD, FD_CLOEXEC);
+
   i = dup2 (pipe_remote, handle);
   if (i != handle)
@@ -96,7 +97,7 @@
   if (pipe (ph) == -1)
     return NULL;
-  if (fcntl (ph[0], F_SETFD, 1) == -1)
+  if (fcntl (ph[0], F_SETFD, FD_CLOEXEC) == -1)
     return NULL;
-  if (fcntl (ph[1], F_SETFD, 1) == -1)
+  if (fcntl (ph[1], F_SETFD, FD_CLOEXEC) == -1)
     return NULL;
   if (mode[0] == 'r')
Index: trunk/src/emx/src/lib/io/read.c
===================================================================
--- trunk/src/emx/src/lib/io/read.c	(revision 870)
+++ trunk/src/emx/src/lib/io/read.c	(revision 871)
@@ -13,5 +13,5 @@
    unless O_NDELAY is in effect. */
 
-static int read_lookahead (int handle, void *buf, size_t nbyte, int *pla)
+static int read_lookahead (int handle, void *buf, size_t nbyte, PLIBCFH pFH)
 {
   int i, n, la, saved_errno;
@@ -19,5 +19,5 @@
 
   i = 0; dst = buf; saved_errno = errno;
-  if (nbyte > 0 && (la = __lxchg (pla, -1)) != -1)
+  if (nbyte > 0 && (la = __lxchg (&pFH->iLookAhead, -1)) != -1)
     {
       *dst = (char)la;
@@ -40,10 +40,14 @@
 ssize_t _STD(read) (int handle, void *buf, size_t nbyte)
 {
-  int n, *pflags, *pla;
-  size_t j, k;
-  char *dst, c;
+  int       n;
+  PLIBCFH   pFH;
+  size_t    j, k;
+  char     *dst, c;
 
-  if ((pflags = _fd_flags (handle)) == NULL
-      || (pla = _fd_lookahead (handle)) == NULL)
+  /*
+   * Get filehandle.
+   */
+  pFH = __libc_FH(handle);
+  if (!pFH)
     {
       errno = EBADF;
@@ -51,20 +55,21 @@
     }
 
-  *pflags &= ~F_CRLF;           /* No CR/LF pair translated to newline */
-  if (nbyte > 0 && (*pflags & F_EOF))
+  pFH->fFlags &= ~F_CRLF;           /* No CR/LF pair translated to newline */
+  if (nbyte > 0 && (pFH->fFlags & F_EOF))
     return 0;
   dst = buf;
-  n = read_lookahead (handle, dst, nbyte, pla);
+  n = read_lookahead (handle, dst, nbyte, pFH);
   if (n == -1)
     return -1;
-  if ((*pflags & O_TEXT) && !(*pflags & F_TERMIO) && n > 0)
+  if ((pFH->fFlags & O_TEXT) && !(pFH->fFlags & F_TERMIO) && n > 0)
     {
       /* special processing for text mode */
-      if (!(*pflags & (F_PIPE|F_SOCKET|F_DEV)) && dst[n-1] == 0x1a &&
-          eof (handle))
+      if (  (pFH->fFlags & F_TYPEMASK) == F_FILE
+          && dst[n-1] == 0x1a
+          && eof (handle))
         {
           /* remove last Ctrl-Z in text files */
           --n;
-          *pflags |= F_EOF;
+          pFH->fFlags |= F_EOF;
           if (n == 0)
             return 0;
@@ -77,8 +82,8 @@
 
           int saved_errno = errno;
-          j = read_lookahead (handle, &c, 1, pla); /* look ahead */
+          j = read_lookahead (handle, &c, 1, pFH); /* look ahead */
           if (j == -1 && errno == EAGAIN)
             {
-              *pla = '\r';
+              pFH->iLookAhead = '\r';
               return -1;
             }
@@ -87,8 +92,8 @@
             {
               dst[0] = '\n';                  /* yes -> replace with LF */
-              *pflags |= F_CRLF;
+              pFH->fFlags |= F_CRLF;
             }
           else
-            *pla = (unsigned char)c;          /* no -> save the 2nd char */
+            pFH->iLookAhead = (unsigned char)c; /* no -> save the 2nd char */
         }
       else
@@ -104,9 +109,9 @@
                  for F_CRLF logic. */
 
-              *pla = '\r';
+              pFH->iLookAhead = '\r';
               --n;
             }
           if (k != n)
-            *pflags |= F_CRLF;
+            pFH->fFlags |= F_CRLF;
           n = k;
         }
Index: trunk/src/emx/src/lib/io/readv.c
===================================================================
--- trunk/src/emx/src/lib/io/readv.c	(revision 870)
+++ trunk/src/emx/src/lib/io/readv.c	(revision 871)
@@ -13,4 +13,5 @@
 int _STD(readv) (int handle, const struct iovec *iov, int iovcnt)
 {
+/** @todo make readv a syscall so tcpip can do it's own handling. */
   int i, n;
   size_t total, len;
@@ -35,5 +36,5 @@
 
   mp = NULL;
-  if (total <= 0x100000)
+  if (total <= 0x1000)
     buf = alloca (total);
   else
Index: trunk/src/emx/src/lib/io/select.c
===================================================================
--- trunk/src/emx/src/lib/io/select.c	(revision 870)
+++ trunk/src/emx/src/lib/io/select.c	(revision 871)
@@ -13,6 +13,7 @@
                   fd_set *exceptfds, struct timeval *timeout)
 {
-  struct _select args;
-
+/** @todo rewrite select */
+  struct _select args = {0,0,0,0,0};
+#if 0
   args.nfds = nfds;
   args.readfds = readfds;
@@ -68,4 +69,5 @@
         }
     }
+#endif
   return __select (&args);
 }
Index: trunk/src/emx/src/lib/io/setmode.c
===================================================================
--- trunk/src/emx/src/lib/io/setmode.c	(revision 870)
+++ trunk/src/emx/src/lib/io/setmode.c	(revision 871)
@@ -1,3 +1,4 @@
-/* setmode.c (emx+gcc) -- Copyright (c) 1990-1996 by Eberhard Mattes */
+/* setmode.c (emx+gcc) -- Copyright (c) 1990-1996 by Eberhard Mattes
+                       -- Copyright (c) 2003 by Knut St. Osmunden */
 
 #include "libc-alias.h"
@@ -9,21 +10,30 @@
 int _STD(setmode) (int handle, int mode)
 {
-  int old_mode, *pflags;
+    PLIBCFH pFH;
+    int     old_mode;
 
-  if ((pflags = _fd_flags (handle)) == NULL)
+    /*
+     * Get filehandle.
+     */
+    pFH = __libc_FH(handle);
+    if (!pFH)
     {
-      errno = EBADF;
-      return -1;
+        errno = EBADF;
+        return -1;
     }
-  old_mode = ((*pflags & O_TEXT) ? O_TEXT : O_BINARY);
-  if (mode == O_BINARY)
-    *pflags &= ~O_TEXT;
-  else if (mode == O_TEXT)
-    *pflags |= O_TEXT;
-  else
+
+    /*
+     * O_BINARY isn't normally stored in the fFlags member.
+     */
+    old_mode = (pFH->fFlags & O_TEXT) ? O_TEXT : O_BINARY;
+    if (mode == O_BINARY)
+        pFH->fFlags &= ~O_TEXT;
+    else if (mode == O_TEXT)
+        pFH->fFlags = (pFH->fFlags & ~O_BINARY) | O_TEXT; /* paranoia */
+    else
     {
-      errno = EINVAL;
-      return -1;
+        errno = EINVAL;
+        return -1;
     }
-  return old_mode;
+    return old_mode;
 }
Index: trunk/src/emx/src/lib/io/tell.c
===================================================================
--- trunk/src/emx/src/lib/io/tell.c	(revision 870)
+++ trunk/src/emx/src/lib/io/tell.c	(revision 871)
@@ -7,20 +7,20 @@
 #include <emx/syscalls.h>
 
-off_t _STD(tell) (int handle)
+off_t _STD(tell)(int handle)
 {
-  int *pflags, *pla;
-  off_t n;
+    PLIBCFH pFH;
+    off_t   n;
 
-  if ((pflags = _fd_flags (handle)) == NULL
-      || (pla = _fd_lookahead (handle)) == NULL)
+    pFH = __libc_FH(handle);
+    if (!pFH)
     {
-      errno = EBADF;
-      return -1;
+        errno = EBADF;
+        return -1;
     }
-  n = __lseek (handle, 0L, SEEK_CUR);
-  if (n == -1)
+    n = __lseek(handle, 0L, SEEK_CUR);
+    if (n == -1)
+        return n;
+    if (pFH->iLookAhead >= 0 || (pFH->fFlags & F_EOF))
+        --n;
     return n;
-  if (*pla >= 0 || (*pflags & F_EOF))
-    --n;
-  return n;
 }
Index: trunk/src/emx/src/lib/io/tmpnam.c
===================================================================
--- trunk/src/emx/src/lib/io/tmpnam.c	(revision 870)
+++ trunk/src/emx/src/lib/io/tmpnam.c	(revision 871)
@@ -10,8 +10,9 @@
 char *_STD(tmpnam) (char *string)
 {
-  struct _thread *tp = _thread ();
-
   if (string == NULL)
-    string = tp->_th_tmpnam_buf;
+    {
+      struct _thread *tp = _thread ();
+      string = tp->_th_tmpnam_buf;
+    }
   if (_tmpidxnam (string) >= 0)
     return string;
Index: trunk/src/emx/src/lib/io/write.c
===================================================================
--- trunk/src/emx/src/lib/io/write.c	(revision 870)
+++ trunk/src/emx/src/lib/io/write.c	(revision 871)
@@ -35,5 +35,5 @@
    Return -1 on error. */
 
-static int write_text (int handle, const char *src, size_t nbyte, int *pflags)
+static int write_text (int handle, const char *src, size_t nbyte, PLIBCFH pFH)
 {
   int out_cnt, lf_cnt, lf_cnt_1, buf_cnt, n;
@@ -44,5 +44,5 @@
   out_cnt = lf_cnt = lf_cnt_1 = buf_cnt = 0;
   buf_pos = 0; i = 0;
-  if (*pflags & F_WRCRPEND)
+  if (pFH->fFlags & F_WRCRPEND)
     {
       if (*src == '\n')
@@ -60,5 +60,5 @@
              pipe. */
 
-          *pflags &= ~F_WRCRPEND;
+          pFH->fFlags &= ~F_WRCRPEND;
         }
     }
@@ -79,5 +79,5 @@
     }
   if (buf_cnt != 0) WRTBUF;
-  *pflags &= ~F_WRCRPEND;
+  pFH->fFlags &= ~F_WRCRPEND;
   return out_cnt - lf_cnt;
 
@@ -118,6 +118,6 @@
   if (splitp)
     {
-      if (*pflags & (F_DEV|F_SOCKET|F_PIPE))
-        *pflags |= F_WRCRPEND;
+      if ((pFH->fFlags & F_TYPEMASK) != F_FILE)
+        pFH->fFlags |= F_WRCRPEND;
       else
         {
@@ -133,5 +133,5 @@
     }
   else
-    *pflags &= ~F_WRCRPEND;
+    pFH->fFlags &= ~F_WRCRPEND;
   return out_cnt - lf_cnt_1;
 }
@@ -140,19 +140,27 @@
 int _STD(write) (int handle, const void *buf, size_t nbyte)
 {
-  int n, *pflags;
+  PLIBCFH   pFH;
+  int       n;
   const char *src;
 
-  if ((pflags = _fd_flags (handle)) == NULL)
-    {
-      errno = EBADF; return -1;
-    }
-  if ((*pflags & (F_DEV|F_SOCKET|F_PIPE|O_APPEND)) == O_APPEND)
+  /*
+   * Get filehandle
+   */
+  pFH = __libc_FH(handle);
+  if (!pFH)
+  {
+      errno = EBADF;
+      return -1;
+  }
+
+  if ((pFH->fFlags & (F_TYPEMASK | O_APPEND)) == (O_APPEND | F_FILE))
     __lseek (handle, 0, SEEK_END);
   if (nbyte == 0)                 /* Avoid truncation of file */
     return 0;
   src = buf;
-  if ((*pflags & O_TEXT) && ((*pflags & F_WRCRPEND)
-                             || memchr (src, '\n', nbyte) != NULL))
-    n = write_text (handle, src, nbyte, pflags);
+  if (    (pFH->fFlags & O_TEXT)
+       && (   (pFH->fFlags & F_WRCRPEND)
+           || memchr (src, '\n', nbyte) != NULL))
+    n = write_text (handle, src, nbyte, pFH);
   else
     n = __write (handle, src, nbyte);
@@ -174,5 +182,6 @@
          data to be written. */
 
-      if ((*pflags & F_DEV) && *src == CTRL_Z)
+      if (   (pFH->fFlags & F_TYPEMASK) == F_DEV
+          && *src == CTRL_Z)
         return 0;
 
@@ -180,6 +189,8 @@
          EAGAIN. */
 
-      if ((*pflags & (F_DEV|F_SOCKET|F_PIPE))
-          && (*pflags & O_NONBLOCK))
+      if (   (pFH->fFlags & O_NONBLOCK)
+          && (   (pFH->fFlags & F_TYPEMASK) == F_DEV
+              || (pFH->fFlags & F_TYPEMASK) == F_SOCKET /* ???? */
+              || (pFH->fFlags & F_TYPEMASK) == F_PIPE) )
         {
           errno = EAGAIN;
Index: trunk/src/emx/src/lib/io/writev.c
===================================================================
--- trunk/src/emx/src/lib/io/writev.c	(revision 870)
+++ trunk/src/emx/src/lib/io/writev.c	(revision 871)
@@ -13,4 +13,5 @@
 int _STD(writev) (int handle, const struct iovec *iov, int iovcnt)
 {
+/** @todo make syscall for this as we wanna let tcpip handle this it's own way. */
   int i, n;
   size_t total, len;
@@ -35,5 +36,5 @@
 
   mp = NULL;
-  if (total <= 0x100000)
+  if (total <= 0x1000)
     buf = alloca (total);
   else
Index: trunk/src/emx/src/lib/libc.def
===================================================================
--- trunk/src/emx/src/lib/libc.def	(revision 870)
+++ trunk/src/emx/src/lib/libc.def	(revision 871)
@@ -19,831 +19,809 @@
 EXPORTS
 ; data
-    "__std_daylight" @1
-    "__fdvec_head" @2
-    "__files" @3
-    "__fmode_bin" @4
-    "__io_ninherit" @5
-    "__lookahead" @6
-    "__mb_cur_max" @7
-    "__org_environ" @8
-    "__osmajor" @9
-    "__osminor" @10
-    "__pipe_size" @11
-    "__std_environ" @12
-    "__streamv" @13
-    "__streamv_rmutex" @14
-    "__streamvec2_head" @15
-    "__streamvec_head" @16
-    "__sys_clock0_ms" @17
-    "__sys_heap_fmutex" @18
-    "__sys_heap_obj_count" @19
-    "__sys_heap_objs" @20
-    "__sys_heap_size" @21
-    "__sys_ino" @22
-    "__sys_pid" @23
-    "__sys_ppid" @24
-    "__um_high_heap" @25
-    "__sys_thread_table" @26
-    "__sys_top_heap_obj" @27
-    "__sys_uflags" @28
-    "__sys_umask" @29
-    "__sys_xreg" @30
-    "__std_timezone" @31
-    "__tmpidx" @32
-    "__tzi" @33
-    "__std_tzname" @34
-    "__tzset_flag" @35
-    "__um_regular_heap" @36
-    "__um_tiled_heap" @37
-    "_optarg" @38
-    "_opterr" @39
-    "_optind" @40
-    "_optmode" @41
-    "_optopt" @42
-    "_optswchar" @43
-    "__atexit_n" @44
-    "__atexit_v" @45
-    "__thread_tab" @46
-    "___digits" @47
-    "___locale" @48
-    "___locale_C" @49
-    "___locale_collate" @50
-    "___locale_ctype" @51
-    "___locale_lconv" @52
-    "___locale_time" @53
-    "__um_low_heap" @54
-    "__rand48_add" @55
-    "__rand48_mult" @56
-    "__rand48_seed" @57
+    "___digits" @1
+    "___locale" @2
+    "___locale_C" @3
+    "___locale_collate" @4
+    "___locale_ctype" @5
+    "___locale_lconv" @6
+    "___locale_time" @7
+    "___stderrp" @8
+    "___stdinp" @9
+    "___stdoutp" @10
+    "__atexit_n" @11
+    "__atexit_v" @12
+    "__fmode_bin" @13
+    "__mb_cur_max" @14
+    "__org_environ" @15
+    "__osmajor" @16
+    "__osminor" @17
+    "__pipe_size" @18
+    "__rand48_add" @19
+    "__rand48_mult" @20
+    "__rand48_seed" @21
+    "__std_daylight" @22
+    "__std_environ" @23
+    "__std_timezone" @24
+    "__std_tzname" @25
+    "__streamv_rmutex" @26
+    "__streamvec_head" @27
+    "__thread_tab" @28
+    "__tmpidx" @29
+    "__tzi" @30
+    "__tzset_flag" @31
+    "__um_high_heap" @32
+    "__um_low_heap" @33
+    "__um_regular_heap" @34
+    "__um_tiled_heap" @35
+    "_optarg" @36
+    "_opterr" @37
+    "_optind" @38
+    "_optmode" @39
+    "_optopt" @40
+    "_optswchar" @41
+
 
 ; code
-    "__CRT_init" @100
-    "__CRT_term" @101
-    "___init" @102
-    "___init_app" @103
-    "___init_dll" @104
-    "__fd_flags" @105
-    "__fd_init" @106
-    "__fd_lookahead" @107
-    "__init1_fdinit" @108
-    "__init1_tmp" @109
-    "__std_posix_memalign" @110
-    "__lrealloc" @111
-    "__init_streams" @112
-    "___initthread" @113
-    "__emxload_connect" @114
-    "__emxload_disconnect" @115
-    "__emxload_do_connect" @116
-    "__emxload_do_disconnect" @117
-    "__emxload_do_receive" @118
-    "__emxload_do_request" @119
-    "__emxload_do_wait" @120
-    "__emxload_env" @121
-    "__emxload_list_get" @122
-    "__emxload_list_start" @123
-    "__emxload_prog" @124
-    "__emxload_request" @125
-    "__emxload_stop" @126
-    "__emxload_this" @127
-    "__emxload_unload" @128
-    "__sys_init_thread" @129
-    "__HUGE_VAL" @130
-    "__LHUGE_VAL" @131
-    "__abspath" @132
-    "___alloc_thread" @133
-    "__assert" @134
-    "__year_day" @135
-    "__tmalloc" @136
-    "___atod" @137
-    "__std_fprintf" @138
-    "__std_printf" @139
-    "__std_malloc" @140
-    "__std_free" @141
-    "__std_realloc" @142
-    "__std_calloc" @143
-    "__std_strdup" @144
-    "__um_addmem_nolock" @145
-    "__umalloc" @146
-    "__um_alloc_no_lock" @147
-    "__linitheap" @148
-    "__um_crumb_free_maybe_lock" @149
-    "__um_default_alloc" @150
-    "__um_default_expand" @151
-    "__um_default_release" @152
-    "__um_default_shrink" @153
-    "__um_find_bucket" @154
-    "__um_free_maybe_lock" @155
-    "__um_init_default_regular_heap" @156
-    "__um_init_default_tiled_heap" @157
-    "__um_lump_alloc" @158
-    "__um_lump_coalesce_free" @159
-    "__um_lump_free_maybe_lock" @160
-    "__um_lump_link_heap" @161
-    "__um_lump_make_free" @162
-    "__um_lump_unlink_bucket" @163
-    "__um_lump_unlink_heap" @164
-    "__um_realloc" @165
-    "__um_seg_addmem" @166
-    "__um_seg_setmem" @167
-    "__std_strcat" @168
-    "__std_strchr" @169
-    "__std_strcmp" @170
-    "__std_strcoll" @171
-    "__std_strcpy" @172
-    "__std_strcspn" @173
-    "__std_strerror" @174
-    "__std_strftime" @175
-    "__std_stricmp" @176
-    "__std_strlen" @177
-    "__std_strlwr" @178
-    "__std_strncat" @179
-    "__std_strncmp" @180
-    "__std_strncpy" @181
-    "__std_strnicmp" @182
-    "__std_strnset" @183
-    "__std_strpbrk" @184
-    "__std_strptime" @185
-    "__std_strrchr" @186
-    "__std_strrev" @187
-    "__std_strset" @188
-    "__std_strspn" @189
-    "__std_strstr" @190
-    "__std_strtod" @191
-    "__std_strtof" @192
-    "__std_strtok" @193
-    "__std_strtol" @194
-    "__std_strtold" @195
-    "__std_strtoul" @196
-    "__std_strupr" @197
-    "__std_strxfrm" @198
-    "__std_abort" @199
-    "__std_abs" @200
-    "__std_access" @201
-    "__std_acos" @202
-    "__std_asctime" @203
-    "__std_asin" @204
-    "__std_atan" @205
-    "__std_atan2" @206
-    "__std_atexit" @207
-    "__std_atof" @208
-    "__std_atofl" @209
-    "__std_atoi" @210
-    "__std_atol" @211
-    "__std_atoll" @212
-    "__std_bcmp" @213
-    "__std_bcopy" @214
-    "__std_brk" @215
-    "__std_bsearch" @216
-    "__std_bzero" @217
-    "__std_cbrt" @218
-    "__std_ceil" @219
-    "__std_chdir" @220
-    "__std_chdrive" @221
-    "__std_chmod" @222
-    "__std_chsize" @223
-    "__std_clearerr" @224
-    "__std_clock" @225
-    "__std_close" @226
-    "__std_closedir" @227
-    "__std_cos" @228
-    "__std_cosh" @229
-    "__std_creat" @230
-    "__std_ctime" @231
-    "__std_cuserid" @232
-    "__std_difftime" @233
-    "__std_div" @234
-    "__std_dup" @235
-    "__std_dup2" @236
-    "__std_endpwent" @237
-    "__std_eof" @238
-    "__std_execl" @239
-    "__std_execle" @240
-    "__std_execlp" @241
-    "__std_execlpe" @242
-    "__std_execv" @243
-    "__std_execve" @244
-    "__std_execvp" @245
-    "__std_execvpe" @246
-    "__std_exit" @247
-    "__std_exp" @248
-    "__std_expand" @249
-    "__std_fabs" @250
-    "__std_fclose" @251
-    "__std_fcntl" @252
-    "__std_fdopen" @253
-    "__std_feof" @254
-    "__std_ferror" @255
-    "__std_fflush" @256
-    "__std_ffs" @257
-    "__std_fgetc" @258
-    "__std_fgetchar" @259
-    "__std_fgetpos" @260
-    "__std_fgets" @261
-    "__std_filelength" @262
-    "__std_fileno" @263
-    "__std_flock" @264
-    "__std_floor" @265
-    "__std_flushall" @266
-    "__std_fmod" @267
-    "__std_fnmatch" @268
-    "__std_fopen" @269
-    "__std_fork" @270
-    "__std_fpathconf" @271
-    "__std_fputc" @272
-    "__std_fputchar" @273
-    "__std_fputs" @274
-    "__std_fread" @275
-    "__std_freopen" @276
-    "__std_frexp" @277
-    "__std_fscanf" @278
-    "__std_fseek" @279
-    "__std_fsetpos" @280
-    "__std_fstat" @281
-    "__std_fsync" @282
-    "__std_ftell" @283
-    "__std_ftime" @284
-    "__std_ftruncate" @285
-    "__std_ftw" @286
-    "__std_fwrite" @287
-    "__std_gcvt" @288
-    "__std_getchar" @289
-    "__std_getcwd" @290
-    "__std_getenv" @291
-    "__std_getgid" @292
-    "__std_getgrnam" @293
-    "__std_getgroups" @294
-    "__std_getlogin" @295
-    "__std_getopt" @296
-    "__std_getpagesize" @297
-    "__std_getpass" @298
-    "__std_getpgrp" @299
-    "__std_getpid" @300
-    "__std_getppid" @301
-    "__std_getpw" @302
-    "__std_getpwent" @303
-    "__std_getpwnam" @304
-    "__std_getpwuid" @305
-    "__std_gets" @306
-    "__std_gettimeofday" @307
-    "__std_getuid" @308
-    "__std_getw" @309
-    "__std_getwd" @310
-    "__std_gmtime" @311
-    "__std_index" @312
-    "__std_ioctl" @313
-    "__std_isatty" @314
-    "__std_kill" @315
-    "__std_labs" @316
-    "__std_ldexp" @317
-    "__std_ldiv" @318
-    "__std_localtime" @319
-    "__std_log" @320
-    "__std_log10" @321
-    "__std_longjmp" @322
-    "__std_lseek" @323
-    "__std_mblen" @324
-    "__std_mbstowcs" @325
-    "__std_mbtowc" @326
-    "__std_memccpy" @327
-    "__std_memchr" @328
-    "__std_memcmp" @329
-    "__std_memcpy" @330
-    "__std_memicmp" @331
-    "__std_memmove" @332
-    "__std_memset" @333
-    "__std_mkdir" @334
-    "__std_mkstemp" @335
-    "__std_mktemp" @336
-    "__std_mktime" @337
-    "__std_modf" @338
-    "__std_open" @339
-    "__std_opendir" @340
-    "__std_pathconf" @341
-    "__std_pause" @342
-    "__std_pclose" @343
-    "__std_perror" @344
-    "__std_pipe" @345
-    "__std_popen" @346
-    "__std_pow" @347
-    "__std_putchar" @348
-    "__std_putenv" @349
-    "__std_puts" @350
-    "__std_putw" @351
-    "__std_qsort" @352
-    "__std_raise" @353
-    "__std_rand" @354
-    "__std_read" @355
-    "__std_readdir" @356
-    "__std_readv" @357
-    "__std_remove" @358
-    "__std_rename" @359
-    "__std_rewind" @360
-    "__std_rewinddir" @361
-    "__std_rindex" @362
-    "__std_rmdir" @363
-    "__std_sbrk" @364
-    "__std_scanf" @365
-    "__std_seekdir" @366
-    "__std_select" @367
-    "__std_setbuf" @368
-    "__std_setbuffer" @369
-    "__std_setgid" @370
-    "__std_setjmp" @371
-    "__std_setmode" @372
-    "__std_setpgid" @373
-    "__std_setpwent" @374
-    "__std_setsid" @375
-    "__std_settimeofday" @376
-    "__std_setuid" @377
-    "__std_setvbuf" @378
-    "__std_sigaction" @379
-    "__std_sigaddset" @380
-    "__std_sigdelset" @381
-    "__std_sigemptyset" @382
-    "__std_sigfillset" @383
-    "__std_sigismember" @384
-    "__std_signal" @385
-    "__std_sigpending" @386
-    "__std_sigprocmask" @387
-    "__std_sigsuspend" @388
-    "__std_sin" @389
-    "__std_sinh" @390
-    "__std_sleep" @391
-    "__std_snprintf" @392
-    "__std_sopen" @393
-    "__std_spawnl" @394
-    "__std_spawnle" @395
-    "__std_spawnlp" @396
-    "__std_spawnlpe" @397
-    "__std_spawnv" @398
-    "__std_spawnve" @399
-    "__std_spawnvp" @400
-    "__std_spawnvpe" @401
-    "__std_sprintf" @402
-    "__std_sqrt" @403
-    "__std_srand" @404
-    "__std_sscanf" @405
-    "__std_stat" @406
-    "__std_swab" @407
-    "__std_sysconf" @408
-    "__std_sys_errlist" @409
-    "__std_sys_nerr" @410
-    "__std_system" @411
-    "__std_tan" @412
-    "__std_tanh" @413
-    "__std_tell" @414
-    "__std_telldir" @415
-    "__std_time" @416
-    "__std_times" @417
-    "__std_tmpfile" @418
-    "__std_tmpnam" @419
-    "__std_truncate" @420
-    "__std_ttyname" @421
-    "__std_tzset" @422
-    "__std_ulimit" @423
-    "__std_umask" @424
-    "__std_uname" @425
-    "__std_ungetc" @426
-    "__std_unlink" @427
-    "__std_utime" @428
-    "__std_utimes" @429
-    "__std_vfprintf" @430
-    "__std_vfscanf" @431
-    "__std_vprintf" @432
-    "__std_vscanf" @433
-    "__std_vsnprintf" @434
-    "__std_vsprintf" @435
-    "__std_vsscanf" @436
-    "__std_wait" @437
-    "__std_waitpid" @438
-    "__std_wcstombs" @439
-    "__std_wctomb" @440
-    "__std_write" @441
-    "__std_writev" @442
-    "__stream_read" @443
-    "__stream_write" @444
-    "__strncpy" @445
-    "__std_strtoll" @446
-    "__std_strtoull" @447
-    "__beginthread" @448
-    "__bi_add_bb" @449
-    "__bi_cmp_bb" @450
-    "__bi_cmp_pow2" @451
-    "__bi_div_add_back" @452
-    "__bi_div_estimate" @453
-    "__bi_div_rem_bb" @454
-    "__bi_div_rem_bw" @455
-    "__bi_div_rem_pow2" @456
-    "__bi_div_subtract" @457
-    "__bi_fls" @458
-    "__bi_hdiv_rem_b" @459
-    "__bi_mul_bb" @460
-    "__bi_mul_bw" @461
-    "__bi_pow5" @462
-    "__bi_set_b" @463
-    "__bi_set_d" @464
-    "__bi_set_w" @465
-    "__bi_shl_b" @466
-    "__bi_shl_w" @467
-    "__bi_shr_b" @468
-    "__bi_sub_mul_bw" @469
-    "__bi_wdiv_rem_pow2" @470
-    "__std_cbrtl" @471
-    "__std_cfgetispeed" @472
-    "__std_cfgetospeed" @473
-    "__std_cfsetispeed" @474
-    "__std_cfsetospeed" @475
-    "__std_cfsetspeed" @476
-    "___chdir" @477
-    "__chdir2" @478
-    "___chmod" @479
-    "___chsize" @480
-    "__clear87" @481
-    "___close" @482
-    "__closestream" @483
-    "__compute_dst_table" @484
-    "__const_HALF" @485
-    "__const_M_ONE" @486
-    "__const_NAN" @487
-    "__const_ONE" @488
-    "__const_TWO" @489
-    "__const_ZERO" @490
-    "__control87" @491
-    "__core" @492
-    "__crlf" @493
-    "___ctordtorInit1" @494
-    "___ctordtorTerm1" @495
-    "__day" @496
-    "__defext" @497
-    "__dt_free" @498
-    "___dtoa" @499
-    "__dt_read" @500
-    "__dt_sort" @501
-    "__dt_split" @502
-    "___dup" @503
-    "___dup2" @504
-    "__endbuf1" @505
-    "___endthread" @506
-    "__endthread" @507
-    "__envargs" @508
-    "__errno" @509
-    "__errno_fun" @510
-    "__execname" @511
-    "___exit" @512
-    "__exit" @513
-    "__exit_streams" @514
-    "__fassign" @515
-    "__fbuf" @516
-    "__fcloseall" @517
-    "___fcntl" @518
-    "__fflush_nolock" @519
-    "__filesys" @520
-    "__fill" @521
-    "___findfirst" @522
-    "___findnext" @523
-    "__flush" @524
-    "__flushstream" @525
-    "__fmutex_checked_close" @526
-    "__fmutex_checked_create" @527
-    "__fmutex_checked_open" @528
-    "__fmutex_checked_release" @529
-    "__fmutex_checked_request" @530
-    "__fmutex_close" @531
-    "__fmutex_create" @532
-    "__fmutex_dummy" @533
-    "__fmutex_open" @534
-    "___fmutex_release_internal" @535
-    "___fmutex_request_internal" @536
-    "__fnexplode" @537
-    "__fnexplodefree" @538
-    "__fngetdrive" @539
-    "__fnisabs" @540
-    "__fnisrel" @541
-    "__fnlwr" @542
-    "__fnlwr2" @543
-    "__fnslashify" @544
-    "___fork" @545
-    "___fpclassify" @546
-    "___fpclassifyf" @547
-    "___fpclassifyl" @548
-    "__fpreset" @549
-    "__fseek_hdr" @550
-    "__fseek_nolock" @551
-    "__fsetmode" @552
-    "__fsopen" @553
-    "___fstat" @554
-    "__ftell_nolock" @555
-    "___ftime" @556
-    "___ftruncate" @557
-    "__fullpath" @558
-    "__fwrite_nolock" @559
-    "___getcwd" @560
-    "__getcwd1" @561
-    "__getcwd2" @562
-    "__getdrive" @563
-    "__std_getegid" @564
-    "__std_geteuid" @565
-    "__getext" @566
-    "__getext2" @567
-    "__std_getgrgid" @568
-    "__getname" @569
-    "__getpass1" @570
-    "__getpass2" @571
-    "__gettid" @572
-    "__getvol" @573
-    "__glob" @574
-    "__globfree" @575
-    "__gmt2loc" @576
-    "__gmtime" @577
-    "__heapchk" @578
-    "__heapmin" @579
-    "__heapset" @580
-    "__heap_walk" @581
-    "___imphandle" @582
-    "__imphandle" @583
-    "__input" @584
-    "__int86" @585
-    "___ioctl1" @586
-    "___ioctl2" @587
-    "_isalnum" @588
-    "_isalpha" @589
-    "_iscntrl" @590
-    "_isdigit" @591
-    "___isfinite" @592
-    "___isfinitef" @593
-    "___isfinitel" @594
-    "_isgraph" @595
-    "_islower" @596
-    "___isnan" @597
-    "___isnanf" @598
-    "___isnanl" @599
-    "___isnormal" @600
-    "___isnormalf" @601
-    "___isnormall" @602
-    "_isprint" @603
-    "_ispunct" @604
-    "_isspace" @605
-    "__isterm" @606
-    "_isupper" @607
-    "_isxdigit" @608
-    "__libc_16to32" @609
-    "__libc_32to16" @610
-    "__libc_thunk1" @611
-    "__loc2gmt" @612
-    "__localtime" @613
-    "___lseek" @614
-    "__makepath" @615
-    "__memcount" @616
-    "__memdif" @617
-    "__memrchr" @618
-    "__memswap" @619
-    "__mfclose" @620
-    "__mfopen" @621
-    "__mheap" @622
-    "___mkdir" @623
-    "__mktime" @624
-    "__month_day_leap" @625
-    "__month_day_non_leap" @626
-    "__msize" @627
-    "__newstream" @628
-    "___newthread" @629
-    "__nfiles" @630
-    "___open" @631
-    "__openstream" @632
-    "__os2_bad" @633
-    "__output" @634
-    "__path" @635
-    "___pipe" @636
-    "___read" @637
-    "___read_kbd" @638
-    "__read_kbd" @639
-    "__remext" @640
-    "___remove_zeros" @641
-    "__response" @642
-    "__rfnlwr" @643
-    "___rmdir" @644
-    "__rmtmp" @645
-    "__rmutex_checked_close" @646
-    "__rmutex_checked_create" @647
-    "__rmutex_checked_open" @648
-    "__rmutex_close" @649
-    "__rmutex_create" @650
-    "__rmutex_dummy" @651
-    "__rmutex_fork" @652
-    "__rmutex_open" @653
-    "__wildcard" @654
-    "__scrsize" @655
-    "__searchenv" @656
-    "__seek_hdr" @657
-    "___select" @658
-    "__setdummymore" @659
-    "__setmore" @660
-    "___settime" @661
-    "__sfnlwr" @662
-    "_sig_info" @663
-    "__std_siglongjmp" @664
-    "___signbit" @665
-    "___signbitf" @666
-    "___signbitl" @667
-    "__std_sigsetjmp" @668
-    "__sleep2" @669
-    "___small_atod" @670
-    "___small_dtoa" @671
-    "___smutex_request_internal" @672
-    "___spawnve" @673
-    "__splitargs" @674
-    "__splitpath" @675
-    "___stat" @676
-    "__status87" @677
-    "___swchar" @678
-    "__swchar" @679
-    "__sys_deliver_pending_signals" @680
-    "__utmalloc" @681
-    "__sys_dump_heap_objs" @682
-    "__sys_exception" @683
-    "__sys_expand_heap_by" @684
-    "__sys_expand_heap_obj_by" @685
-    "__sys_get_clock" @686
-    "___sys_newthread" @687
-    "__sys_p2t" @688
-    "__sys_set_errno" @689
-    "__sys_shrink_heap_by" @690
-    "__sys_shrink_heap_obj_by" @691
-    "__sys_shrink_heap_to" @692
-    "___wait" @693
-    "__sys_sig_valid" @694
-    "___waitpid" @695
-    "__sys_thread" @696
-    "__vsopen" @697
-    "__tcalloc" @698
-    "__std_tcdrain" @699
-    "__std_tcflow" @700
-    "__std_tcflush" @701
-    "__std_tcgetattr" @702
-    "__std_tcgetpgrp" @703
-    "__std_tcsendbreak" @704
-    "__std_tcsetattr" @705
-    "__std_tcsetpgrp" @706
-    "__std_tempnam" @707
-    "__tfree" @708
-    "__theapmin" @709
-    "__thread" @710
-    "___threadid" @711
-    "__threadstore" @712
-    "___write" @713
-    "__tmpbuf1" @714
-    "__tmpidx_lock" @715
-    "__tmpidxnam" @716
-    "__tmpidx_unlock" @717
-    "_tolower" @718
-    "_toupper" @719
-    "__trealloc" @720
-    "__trslash" @721
-    "___ttyname" @722
-    "__uaddmem" @723
-    "__ucalloc" @724
-    "__uclose" @725
-    "__ucreate" @726
-    "__ucreate2" @727
-    "__udefault" @728
-    "__udestroy" @729
-    "__uflags" @730
-    "__uheapchk" @731
-    "__uheapmin" @732
-    "__uheapset" @733
-    "__uheap_type" @734
-    "__uheap_walk" @735
-    "__uheap_walk2" @736
-    "__uldiv" @737
-    "___ulimit" @738
-    "__um_walk_error" @739
-    "__um_walk_no_lock" @740
-    "__ungetc_nolock" @741
-    "___unwind2" @742
-    "__uopen" @743
-    "__ustats" @744
-    "__utcalloc" @745
-    "__utdefault" @746
-    "___utimes" @747
-    "___convert_codepage" @748
-    "___do_Unicode" @749
-    "___from_ucs" @750
-    "_isascii" @751
-    "___gnu_basename" @752
-    "__std_basename" @753
-    "__std_dirname" @754
-    "__std_lltoa" @755
-    "__std_localeconv" @756
-    "__std_ltoa" @757
-    "__std_setlocale" @758
-    "__std_ulltoa" @759
-    "__std_ultoa" @760
-    "_toascii" @761
-    "___to_ucs" @762
-    "__std_acosl" @763
-    "__std_asinl" @764
-    "__std_atan2l" @765
-    "__std_atanl" @766
-    "__std_ceill" @767
-    "__std_copysign" @768
-    "__std_copysignf" @769
-    "__std_copysignl" @770
-    "__std_coshl" @771
-    "__std_cosl" @772
-    "__std_expl" @773
-    "__std_fabsl" @774
-    "__std_floorl" @775
-    "__std_fmodl" @776
-    "__std_frexpl" @777
-    "__fxam" @778
-    "__fxaml" @779
-    "__std_hypot" @780
-    "__std_hypotl" @781
-    "__std_ldexpl" @782
-    "__std_log10l" @783
-    "__std_logl" @784
-    "__std_modfl" @785
-    "__std_nextafter" @786
-    "__std_nextafterf" @787
-    "__std_nextafterl" @788
-    "__std_powl" @789
-    "__std_rint" @790
-    "__std_rintl" @791
-    "__std_sinhl" @792
-    "__std_sinl" @793
-    "__std_sqrtl" @794
-    "__std_tanhl" @795
-    "__std_tanl" @796
-    "__std_trunc" @797
-    "__std_truncl" @798
-    "__ead_add" @799
-    "__ead_clear" @800
-    "__ead_copy" @801
-    "__ead_count" @802
-    "__ead_create" @803
-    "__ead_delete" @804
-    "__ead_destroy" @805
-    "__ead_enum" @806
-    "__ead_fea2list_size" @807
-    "__ead_fea2list_to_fealist" @808
-    "__ead_fealist_to_fea2list" @809
-    "__ead_find" @810
-    "__ead_get_fea2list" @811
-    "__ead_get_flags" @812
-    "__ead_get_name" @813
-    "__ead_get_value" @814
-    "__ead_make_index" @815
-    "__ead_name_len" @816
-    "__ead_read" @817
-    "__ead_replace" @818
-    "__ead_size_buffer" @819
-    "__ead_sort" @820
-    "__ead_use_fea2list" @821
-    "__ead_value_size" @822
-    "__ead_write" @823
-    "__ea_free" @824
-    "__ea_get" @825
-    "__ea_put" @826
-    "__ea_remove" @827
-    "__ea_set_errno" @828
-    "__ea_write" @829
-    "__std_setenv" @830
-    "__std_unsetenv" @831
-    "__std_lockf" @832
-    "__lmalloc" @833
-    "__std_fseeko" @834
-    "__std_ftello" @835
-    "__std_readdir_r" @836
-    "__std_lstat" @837
-    "_srandomdev" @838
-    "_random" @839
-    "_initstate" @840
-    "_setstate" @841
-    "_srandom" @842
-    "_lchmod" @843
-    "_stpcpy" @844
-    "_strlcat" @845
-    "_strlcpy" @846
-    "_strcasestr" @847
-    "_strnstr" @848
-    "_strsep" @849
-    "_heapsort" @850
-    "_mergesort" @851
-    "_radixsort" @852
-    "_sradixsort" @853
-    "__dorand48" @854
-    "__std_srand48" @855
-    "__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
+    "__CRT_init" @101
+    "__CRT_term" @102
+    "__HUGE_VAL" @103
+    "__LHUGE_VAL" @104
+    "___alloc_thread" @105
+    "___atod" @106
+    "___chdir" @107
+    "___chmod" @108
+    "___chsize" @109
+    "___close" @110
+    "___convert_codepage" @111
+    "___ctordtorInit1" @112
+    "___ctordtorTerm1" @113
+    "___do_Unicode" @114
+    "___dtoa" @115
+    "___dup" @116
+    "___dup2" @117
+    "___endthread" @118
+    "___exit" @119
+    "___fcntl" @120
+    "___findfirst" @121
+    "___findnext" @122
+    "___fmutex_release_internal" @123
+    "___fmutex_request_internal" @124
+    "___fork" @125
+    "___fpclassify" @126
+    "___fpclassifyf" @127
+    "___fpclassifyl" @128
+    "___from_ucs" @129
+    "___fstat" @130
+    "___ftime" @131
+    "___ftruncate" @132
+    "___getcwd" @133
+    "___gnu_basename" @134
+    "___imphandle" @135
+    "___init" @136
+    "___init_app" @137
+    "___init_dll" @138
+    "___initthread" @139
+    "___ioctl1" @140
+    "___ioctl2" @141
+    "___isfinite" @142
+    "___isfinitef" @143
+    "___isfinitel" @144
+    "___isnan" @145
+    "___isnanf" @146
+    "___isnanl" @147
+    "___isnormal" @148
+    "___isnormalf" @149
+    "___isnormall" @150
+    "___libc_FH" @151
+    "___libc_FHAllocate" @152
+    "___libc_FHClose" @153
+    "___libc_FHEnsureHandles" @154
+    "___libc_HasHighMem" @155
+    "___libc_HeapEndVoting" @156
+    "___libc_HeapGetResult" @157
+    "___libc_HeapVote" @158
+    "___libc_HimemDefaultAlloc" @159
+    "___libc_HimemDefaultRelease" @160
+    "___lseek" @161
+    "___mkdir" @162
+    "___newthread" @163
+    "___open" @164
+    "___pipe" @165
+    "___read" @166
+    "___read_kbd" @167
+    "___remove_zeros" @168
+    "___rmdir" @169
+    "___select" @170
+    "___settime" @171
+    "___signbit" @172
+    "___signbitf" @173
+    "___signbitl" @174
+    "___small_atod" @175
+    "___small_dtoa" @176
+    "___smutex_request_internal" @177
+    "___spawnve" @178
+    "___stat" @179
+    "___swchar" @180
+    "___threadid" @181
+    "___to_ucs" @182
+    "___ttyname" @183
+    "___ulimit" @184
+    "___unwind2" @185
+    "___utimes" @186
+    "___wait" @187
+    "___waitpid" @188
+    "___write" @189
+    "__abspath" @190
+    "__assert" @191
+    "__beginthread" @192
+    "__bi_add_bb" @193
+    "__bi_cmp_bb" @194
+    "__bi_cmp_pow2" @195
+    "__bi_div_add_back" @196
+    "__bi_div_estimate" @197
+    "__bi_div_rem_bb" @198
+    "__bi_div_rem_bw" @199
+    "__bi_div_rem_pow2" @200
+    "__bi_div_subtract" @201
+    "__bi_fls" @202
+    "__bi_hdiv_rem_b" @203
+    "__bi_mul_bb" @204
+    "__bi_mul_bw" @205
+    "__bi_pow5" @206
+    "__bi_set_b" @207
+    "__bi_set_d" @208
+    "__bi_set_w" @209
+    "__bi_shl_b" @210
+    "__bi_shl_w" @211
+    "__bi_shr_b" @212
+    "__bi_sub_mul_bw" @213
+    "__bi_wdiv_rem_pow2" @214
+    "__chdir2" @215
+    "__clear87" @216
+    "__closestream" @217
+    "__compute_dst_table" @218
+    "__const_HALF" @219
+    "__const_M_ONE" @220
+    "__const_NAN" @221
+    "__const_ONE" @222
+    "__const_TWO" @223
+    "__const_ZERO" @224
+    "__control87" @225
+    "__core" @226
+    "__crlf" @227
+    "__day" @228
+    "__defext" @229
+    "__dorand48" @230
+    "__dt_free" @231
+    "__dt_read" @232
+    "__dt_sort" @233
+    "__dt_split" @234
+    "__ea_free" @235
+    "__ea_get" @236
+    "__ea_put" @237
+    "__ea_remove" @238
+    "__ea_set_errno" @239
+    "__ea_write" @240
+    "__ead_add" @241
+    "__ead_clear" @242
+    "__ead_copy" @243
+    "__ead_count" @244
+    "__ead_create" @245
+    "__ead_delete" @246
+    "__ead_destroy" @247
+    "__ead_enum" @248
+    "__ead_fea2list_size" @249
+    "__ead_fea2list_to_fealist" @250
+    "__ead_fealist_to_fea2list" @251
+    "__ead_find" @252
+    "__ead_get_fea2list" @253
+    "__ead_get_flags" @254
+    "__ead_get_name" @255
+    "__ead_get_value" @256
+    "__ead_make_index" @257
+    "__ead_name_len" @258
+    "__ead_read" @259
+    "__ead_replace" @260
+    "__ead_size_buffer" @261
+    "__ead_sort" @262
+    "__ead_use_fea2list" @263
+    "__ead_value_size" @264
+    "__ead_write" @265
+    "__emxload_connect" @266
+    "__emxload_disconnect" @267
+    "__emxload_do_connect" @268
+    "__emxload_do_disconnect" @269
+    "__emxload_do_receive" @270
+    "__emxload_do_request" @271
+    "__emxload_do_wait" @272
+    "__emxload_env" @273
+    "__emxload_list_get" @274
+    "__emxload_list_start" @275
+    "__emxload_prog" @276
+    "__emxload_request" @277
+    "__emxload_stop" @278
+    "__emxload_this" @279
+    "__emxload_unload" @280
+    "__endbuf1" @281
+    "__endthread" @282
+    "__envargs" @283
+    "__errno" @284
+    "__errno_fun" @285
+    "__execname" @286
+    "__exit" @287
+    "__exit_streams" @288
+    "__fassign" @289
+    "__fbuf" @290
+    "__fcloseall" @291
+    "__fflush_nolock" @292
+    "__filesys" @293
+    "__fill" @294
+    "__flush" @295
+    "__flushstream" @296
+    "__fmutex_checked_close" @297
+    "__fmutex_checked_create" @298
+    "__fmutex_checked_open" @299
+    "__fmutex_checked_release" @300
+    "__fmutex_checked_request" @301
+    "__fmutex_close" @302
+    "__fmutex_create" @303
+    "__fmutex_dummy" @304
+    "__fmutex_open" @305
+    "__fnexplode" @306
+    "__fnexplodefree" @307
+    "__fngetdrive" @308
+    "__fnisabs" @309
+    "__fnisrel" @310
+    "__fnlwr" @311
+    "__fnlwr2" @312
+    "__fnslashify" @313
+    "__fpreset" @314
+    "__fseek_hdr" @315
+    "__fseek_nolock" @316
+    "__fsetmode" @317
+    "__fsopen" @318
+    "__ftell_nolock" @319
+    "__fullpath" @320
+    "__fwrite_nolock" @321
+    "__fxam" @322
+    "__fxaml" @323
+    "__getcwd1" @324
+    "__getcwd2" @325
+    "__getdrive" @326
+    "__getext" @327
+    "__getext2" @328
+    "__getname" @329
+    "__getpass1" @330
+    "__getpass2" @331
+    "__gettid" @332
+    "__getvol" @333
+    "__std_glob" @334
+    "__std_globfree" @335
+    "__gmt2loc" @336
+    "__gmtime" @337
+    "__hcalloc" @338
+    "__heap_walk" @339
+    "__heapchk" @340
+    "__heapmin" @341
+    "__heapset" @342
+    "__hinitheap" @343
+    "__hmalloc" @344
+    "__hrealloc" @345
+    "__imphandle" @346
+    "__init1_tmp" @347
+    "__init_streams" @348
+    "__input" @349
+    "__int86" @350
+    "__isterm" @351
+    "__lcalloc" @352
+    "__libc_16to32" @353
+    "__libc_32to16" @354
+    "__libc_thunk1" @355
+    "__linitheap" @356
+    "__lmalloc" @357
+    "__loc2gmt" @358
+    "__localtime" @359
+    "__lrealloc" @360
+    "__makepath" @361
+    "__memcount" @362
+    "__memdif" @363
+    "__memrchr" @364
+    "__memswap" @365
+    "__mfclose" @366
+    "__mfopen" @367
+    "__mheap" @368
+    "__mktime" @369
+    "__month_day_leap" @370
+    "__month_day_non_leap" @371
+    "__msize" @372
+    "__newstream" @373
+    "__openstream" @374
+    "__os2_bad" @375
+    "__output" @376
+    "__path" @377
+    "__read_kbd" @378
+    "__remext" @379
+    "__response" @380
+    "__rfnlwr" @381
+    "__rmtmp" @382
+    "__rmutex_checked_close" @383
+    "__rmutex_checked_create" @384
+    "__rmutex_checked_open" @385
+    "__rmutex_close" @386
+    "__rmutex_create" @387
+    "__rmutex_dummy" @388
+    "__rmutex_fork" @389
+    "__rmutex_open" @390
+    "__scrsize" @391
+    "__searchenv" @392
+    "__seek_hdr" @393
+    "__setdummymore" @394
+    "__setmore" @395
+    "__sfnlwr" @396
+    "__sleep2" @397
+    "__splitargs" @398
+    "__splitpath" @399
+    "__status87" @400
+    "__std_abort" @401
+    "__std_abs" @402
+    "__std_access" @403
+    "__std_acos" @404
+    "__std_acosl" @405
+    "__std_asctime" @406
+    "__std_asin" @407
+    "__std_asinl" @408
+    "__std_atan" @409
+    "__std_atan2" @410
+    "__std_atan2l" @411
+    "__std_atanl" @412
+    "__std_atexit" @413
+    "__std_atof" @414
+    "__std_atofl" @415
+    "__std_atoi" @416
+    "__std_atol" @417
+    "__std_atoll" @418
+    "__std_basename" @419
+    "__std_bcmp" @420
+    "__std_bcopy" @421
+    "__std_brk" @422
+    "__std_bsearch" @423
+    "__std_bzero" @424
+    "__std_calloc" @425
+    "__std_cbrt" @426
+    "__std_cbrtl" @427
+    "__std_ceil" @428
+    "__std_ceill" @429
+    "__std_cfgetispeed" @430
+    "__std_cfgetospeed" @431
+    "__std_cfsetispeed" @432
+    "__std_cfsetospeed" @433
+    "__std_cfsetspeed" @434
+    "__std_chdir" @435
+    "__std_chdrive" @436
+    "__std_chmod" @437
+    "__std_chsize" @438
+    "__std_clearerr" @439
+    "__std_clock" @440
+    "__std_close" @441
+    "__std_closedir" @442
+    "__std_copysign" @443
+    "__std_copysignf" @444
+    "__std_copysignl" @445
+    "__std_cos" @446
+    "__std_cosh" @447
+    "__std_coshl" @448
+    "__std_cosl" @449
+    "__std_creat" @450
+    "__std_ctime" @451
+    "__std_cuserid" @452
+    "__std_difftime" @453
+    "__std_dirname" @454
+    "__std_div" @455
+    "__std_drand48" @456
+    "__std_dup" @457
+    "__std_dup2" @458
+    "__std_endpwent" @459
+    "__std_eof" @460
+    "__std_erand48" @461
+    "__std_execl" @462
+    "__std_execle" @463
+    "__std_execlp" @464
+    "__std_execlpe" @465
+    "__std_execv" @466
+    "__std_execve" @467
+    "__std_execvp" @468
+    "__std_execvpe" @469
+    "__std_exit" @470
+    "__std_exp" @471
+    "__std_expand" @472
+    "__std_expl" @473
+    "__std_fabs" @474
+    "__std_fabsl" @475
+    "__std_fclose" @476
+    "__std_fcntl" @477
+    "__std_fdopen" @478
+    "__std_feof" @479
+    "__std_ferror" @480
+    "__std_fflush" @481
+    "__std_ffs" @482
+    "__std_fgetc" @483
+    "__std_fgetchar" @484
+    "__std_fgetpos" @485
+    "__std_fgets" @486
+    "__std_filelength" @487
+    "__std_fileno" @488
+    "__std_flock" @489
+    "__std_floor" @490
+    "__std_floorl" @491
+    "__std_flushall" @492
+    "__std_fmod" @493
+    "__std_fmodl" @494
+    "__std_fnmatch" @495
+    "__std_fopen" @496
+    "__std_fork" @497
+    "__std_fpathconf" @498
+    "__std_fprintf" @499
+    "__std_fputc" @500
+    "__std_fputchar" @501
+    "__std_fputs" @502
+    "__std_fread" @503
+    "__std_free" @504
+    "__std_freopen" @505
+    "__std_frexp" @506
+    "__std_frexpl" @507
+    "__std_fscanf" @508
+    "__std_fseek" @509
+    "__std_fseeko" @510
+    "__std_fsetpos" @511
+    "__std_fstat" @512
+    "__std_fsync" @513
+    "__std_ftell" @514
+    "__std_ftello" @515
+    "__std_ftime" @516
+    "__std_ftruncate" @517
+    "__std_ftw" @518
+    "__std_fwrite" @519
+    "__std_gcvt" @520
+    "__std_getchar" @521
+    "__std_getcwd" @522
+    "__std_getegid" @523
+    "__std_getenv" @524
+    "__std_geteuid" @525
+    "__std_getgid" @526
+    "__std_getgrgid" @527
+    "__std_getgrnam" @528
+    "__std_getgroups" @529
+    "__std_getlogin" @530
+    "__std_getopt" @531
+    "__std_getpagesize" @532
+    "__std_getpass" @533
+    "__std_getpgrp" @534
+    "__std_getpid" @535
+    "__std_getppid" @536
+    "__std_getpw" @537
+    "__std_getpwent" @538
+    "__std_getpwnam" @539
+    "__std_getpwuid" @540
+    "__std_gets" @541
+    "__std_gettimeofday" @542
+    "__std_getuid" @543
+    "__std_getw" @544
+    "__std_getwd" @545
+    "__std_gmtime" @546
+    "__std_hypot" @547
+    "__std_hypotl" @548
+    "__std_index" @549
+    "__std_ioctl" @550
+    "__std_isatty" @551
+    "__std_jrand48" @552
+    "__std_kill" @553
+    "__std_labs" @554
+    "__std_lcong48" @555
+    "__std_ldexp" @556
+    "__std_ldexpl" @557
+    "__std_ldiv" @558
+    "__std_lltoa" @559
+    "__std_localeconv" @560
+    "__std_localtime" @561
+    "__std_lockf" @562
+    "__std_log" @563
+    "__std_log10" @564
+    "__std_log10l" @565
+    "__std_logl" @566
+    "__std_longjmp" @567
+    "__std_lrand48" @568
+    "__std_lseek" @569
+    "__std_lstat" @570
+    "__std_ltoa" @571
+    "__std_malloc" @572
+    "__std_mblen" @573
+    "__std_mbstowcs" @574
+    "__std_mbtowc" @575
+    "__std_memccpy" @576
+    "__std_memchr" @577
+    "__std_memcmp" @578
+    "__std_memcpy" @579
+    "__std_memicmp" @580
+    "__std_memmove" @581
+    "__std_memset" @582
+    "__std_mkdir" @583
+    "__std_mkstemp" @584
+    "__std_mktemp" @585
+    "__std_mktime" @586
+    "__std_modf" @587
+    "__std_modfl" @588
+    "__std_mrand48" @589
+    "__std_nextafter" @590
+    "__std_nextafterf" @591
+    "__std_nextafterl" @592
+    "__std_nrand48" @593
+    "__std_open" @594
+    "__std_opendir" @595
+    "__std_pathconf" @596
+    "__std_pause" @597
+    "__std_pclose" @598
+    "__std_perror" @599
+    "__std_pipe" @600
+    "__std_popen" @601
+    "__std_posix_memalign" @602
+    "__std_pow" @603
+    "__std_powl" @604
+    "__std_printf" @605
+    "__std_putchar" @606
+    "__std_putenv" @607
+    "__std_puts" @608
+    "__std_putw" @609
+    "__std_qsort" @610
+    "__std_qsort_r" @611
+    "__std_raise" @612
+    "__std_rand" @613
+    "__std_read" @614
+    "__std_readdir" @615
+    "__std_readdir_r" @616
+    "__std_readv" @617
+    "__std_realloc" @618
+    "__std_remove" @619
+    "__std_rename" @620
+    "__std_rewind" @621
+    "__std_rewinddir" @622
+    "__std_rindex" @623
+    "__std_rint" @624
+    "__std_rintl" @625
+    "__std_rmdir" @626
+    "__std_sbrk" @627
+    "__std_scanf" @628
+    "__std_seed48" @629
+    "__std_seekdir" @630
+    "__std_select" @631
+    "__std_setbuf" @632
+    "__std_setbuffer" @633
+    "__std_setenv" @634
+    "__std_setgid" @635
+    "__std_setjmp" @636
+    "__std_setlocale" @637
+    "__std_setmode" @638
+    "__std_setpgid" @639
+    "__std_setpwent" @640
+    "__std_setsid" @641
+    "__std_settimeofday" @642
+    "__std_setuid" @643
+    "__std_setvbuf" @644
+    "__std_sigaction" @645
+    "__std_sigaddset" @646
+    "__std_sigdelset" @647
+    "__std_sigemptyset" @648
+    "__std_sigfillset" @649
+    "__std_sigismember" @650
+    "__std_siglongjmp" @651
+    "__std_signal" @652
+    "__std_sigpending" @653
+    "__std_sigprocmask" @654
+    "__std_sigsetjmp" @655
+    "__std_sigsuspend" @656
+    "__std_sin" @657
+    "__std_sinh" @658
+    "__std_sinhl" @659
+    "__std_sinl" @660
+    "__std_sleep" @661
+    "__std_snprintf" @662
+    "__std_sopen" @663
+    "__std_spawnl" @664
+    "__std_spawnle" @665
+    "__std_spawnlp" @666
+    "__std_spawnlpe" @667
+    "__std_spawnv" @668
+    "__std_spawnve" @669
+    "__std_spawnvp" @670
+    "__std_spawnvpe" @671
+    "__std_sprintf" @672
+    "__std_sqrt" @673
+    "__std_sqrtl" @674
+    "__std_srand" @675
+    "__std_srand48" @676
+    "__std_sscanf" @677
+    "__std_stat" @678
+    "__std_strcat" @679
+    "__std_strchr" @680
+    "__std_strcmp" @681
+    "__std_strcoll" @682
+    "__std_strcpy" @683
+    "__std_strcspn" @684
+    "__std_strdup" @685
+    "__std_strerror" @686
+    "__std_strftime" @687
+    "__std_stricmp" @688
+    "__std_strlen" @689
+    "__std_strlwr" @690
+    "__std_strncat" @691
+    "__std_strncmp" @692
+    "__std_strncpy" @693
+    "__std_strnicmp" @694
+    "__std_strnset" @695
+    "__std_strpbrk" @696
+    "__std_strptime" @697
+    "__std_strrchr" @698
+    "__std_strrev" @699
+    "__std_strset" @700
+    "__std_strspn" @701
+    "__std_strstr" @702
+    "__std_strtod" @703
+    "__std_strtof" @704
+    "__std_strtok" @705
+    "__std_strtol" @706
+    "__std_strtold" @707
+    "__std_strtoll" @708
+    "__std_strtoul" @709
+    "__std_strtoull" @710
+    "__std_strupr" @711
+    "__std_strxfrm" @712
+    "__std_swab" @713
+    "__std_sys_errlist" @714
+    "__std_sys_nerr" @715
+    "__std_sysconf" @716
+    "__std_system" @717
+    "__std_tan" @718
+    "__std_tanh" @719
+    "__std_tanhl" @720
+    "__std_tanl" @721
+    "__std_tcdrain" @722
+    "__std_tcflow" @723
+    "__std_tcflush" @724
+    "__std_tcgetattr" @725
+    "__std_tcgetpgrp" @726
+    "__std_tcsendbreak" @727
+    "__std_tcsetattr" @728
+    "__std_tcsetpgrp" @729
+    "__std_tell" @730
+    "__std_telldir" @731
+    "__std_tempnam" @732
+    "__std_time" @733
+    "__std_times" @734
+    "__std_tmpfile" @735
+    "__std_tmpnam" @736
+    "__std_trunc" @737
+    "__std_truncate" @738
+    "__std_truncl" @739
+    "__std_ttyname" @740
+    "__std_tzset" @741
+    "__std_ulimit" @742
+    "__std_ulltoa" @743
+    "__std_ultoa" @744
+    "__std_umask" @745
+    "__std_uname" @746
+    "__std_ungetc" @747
+    "__std_unlink" @748
+    "__std_unsetenv" @749
+    "__std_utime" @750
+    "__std_utimes" @751
+    "__std_vfprintf" @752
+    "__std_vfscanf" @753
+    "__std_vprintf" @754
+    "__std_vscanf" @755
+    "__std_vsnprintf" @756
+    "__std_vsprintf" @757
+    "__std_vsscanf" @758
+    "__std_wait" @759
+    "__std_waitpid" @760
+    "__std_wcstombs" @761
+    "__std_wctomb" @762
+    "__std_write" @763
+    "__std_writev" @764
+    "__stream_read" @765
+    "__stream_write" @766
+    "__strncpy" @767
+    "__swchar" @768
+    "__sys_dump_heap_objs" @769
+    "__sys_exception" @770
+    "__tcalloc" @771
+    "__tfree" @772
+    "__theapmin" @773
+    "__thread" @774
+    "__threadstore" @775
+    "__tmalloc" @776
+    "__tmpbuf1" @777
+    "__tmpidx_lock" @778
+    "__tmpidx_unlock" @779
+    "__tmpidxnam" @780
+    "__trealloc" @781
+    "__trslash" @782
+    "__uaddmem" @783
+    "__ucalloc" @784
+    "__uclose" @785
+    "__ucreate" @786
+    "__ucreate2" @787
+    "__udefault" @788
+    "__udestroy" @789
+    "__uflags" @790
+    "__uheap_type" @791
+    "__uheap_walk" @792
+    "__uheap_walk2" @793
+    "__uheapchk" @794
+    "__uheapmin" @795
+    "__uheapset" @796
+    "__uldiv" @797
+    "__um_addmem_nolock" @798
+    "__um_alloc_no_lock" @799
+    "__um_crumb_free_maybe_lock" @800
+    "__um_default_alloc" @801
+    "__um_default_expand" @802
+    "__um_default_release" @803
+    "__um_default_shrink" @804
+    "__um_find_bucket" @805
+    "__um_free_maybe_lock" @806
+    "__um_init_default_regular_heap" @807
+    "__um_init_default_tiled_heap" @808
+    "__um_lump_alloc" @809
+    "__um_lump_coalesce_free" @810
+    "__um_lump_free_maybe_lock" @811
+    "__um_lump_link_heap" @812
+    "__um_lump_make_free" @813
+    "__um_lump_unlink_bucket" @814
+    "__um_lump_unlink_heap" @815
+    "__um_realloc" @816
+    "__um_seg_addmem" @817
+    "__um_seg_setmem" @818
+    "__um_walk_error" @819
+    "__um_walk_no_lock" @820
+    "__umalloc" @821
+    "__ungetc_nolock" @822
+    "__uopen" @823
+    "__ustats" @824
+    "__utcalloc" @825
+    "__utdefault" @826
+    "__utmalloc" @827
+    "__vsopen" @828
+    "__wildcard" @829
+    "__year_day" @830
+    "_heapsort" @831
+    "_initstate" @832
+    "_isalnum" @833
+    "_isalpha" @834
+    "_isascii" @835
+    "_iscntrl" @836
+    "_isdigit" @837
+    "_isgraph" @838
+    "_islower" @839
+    "_isprint" @840
+    "_ispunct" @841
+    "_isspace" @842
+    "_isupper" @843
+    "_isxdigit" @844
+    "_lchmod" @845
+    "_mergesort" @846
+    "_radixsort" @847
+    "_random" @848
+    "_setstate" @849
+    "_sig_info" @850
+    "_sradixsort" @851
+    "_srandom" @852
+    "_srandomdev" @853
+    "_stpcpy" @854
+    "_strcasestr" @855
+    "_strlcat" @856
+    "_strlcpy" @857
+    "_strnstr" @858
+    "_strsep" @859
+    "_toascii" @860
+    "_tolower" @861
+    "_toupper" @862
+    "___collate_range_cmp" @863
Index: trunk/src/emx/src/lib/startup/startup.c
===================================================================
--- trunk/src/emx/src/lib/startup/startup.c	(revision 870)
+++ trunk/src/emx/src/lib/startup/startup.c	(revision 871)
@@ -10,4 +10,5 @@
 #include <emx/startup.h>
 
+#if 0 /* dead */
 /* See app/iodata.c. */
 
@@ -15,4 +16,5 @@
 extern int _files[];
 extern int _lookahead[];
+#endif
 
 extern int __crtinit1__;
@@ -34,6 +36,8 @@
   startup_flag = 1;
 
+#if 0 /* moved to __init_dll() */
   /* Initialize the file handles. */
   init_files ();
+#endif
 
   /* Initialize streams etc. if required. */
@@ -51,4 +55,5 @@
 
 
+#if 0 /* moved to __init_dll() */
 /* Initialize the file handles. */
 
@@ -99,5 +104,5 @@
     }
 }
-
+#endif
 
 
@@ -121,4 +126,9 @@
  *                heap (or low if no high mem) when calling _hmalloc().
  *          - __init_dll calls __init_environ() which initializes environ and _org_environ.
+ *              - __init_environ() will call _hmalloc() thus initiating the high heap.
+ *          - __init_dll calls _sys_init_largefileio() which checks for LFN APIs.
+ *          - __init_dll calls _sys_init_filehandles() which initiates filehandle table.
+ *              - _sys_init_filehandles() will call _hmalloc() and a number of OS/2 APIs
+ *                to figure out what handles was inherited.
  *          - __init_dll then intializes _sys_clock0_ms with the current MS count.
  *      - dll0.s calls _DLL_InitTerm in startup/dllinit.c.
Index: trunk/src/emx/src/lib/sys/__chsize.c
===================================================================
--- trunk/src/emx/src/lib/sys/__chsize.c	(revision 870)
+++ trunk/src/emx/src/lib/sys/__chsize.c	(revision 871)
@@ -6,6 +6,8 @@
 #include "libc-alias.h"
 #define INCL_FSMACROS
+#define INCL_ERRORS
 #include <os2emx.h>
 #include <emx/syscalls.h>
+#include <emx/io.h>
 #include <limits.h>
 #include <errno.h>
@@ -13,27 +15,53 @@
 
 
-int __chsize (int hFile, __off_t cbFile)
+int __chsize(int fh, __off_t cbFile)
 {
-    ULONG rc;
-    FS_VAR();
+    PLIBCFH     pFH;
+    ULONG       rc;
 
-    FS_SAVE_LOAD();
+    /*
+     * Get filehandle.
+     */
+    pFH = __libc_FH(fh);
+    if (!pFH)
+    {
+        errno = EBADF;
+        return -1;
+    }
+
+    /*
+     * Do the stuff.
+     */
+    if (!pFH->pOps)
+    {
+        FS_VAR();
+        FS_SAVE_LOAD();
 #if OFF_MAX > LONG_MAX
-    if (__pfnDosSetFileSizeL)
-        rc = __pfnDosSetFileSizeL(hFile, cbFile);
+        if (__pfnDosSetFileSizeL)
+            rc = __pfnDosSetFileSizeL(fh, cbFile);
+        else
+        {
+            if (cbFile > LONG_MAX)
+            {
+                FS_RESTORE();
+                errno = EOVERFLOW;
+                return -1;
+            }
+            rc = DosSetFileSize(fh, cbFile);
+        }
+#else
+        rc = DosSetFileSize(fh, cbFile);
+#endif
+        FS_RESTORE();
+    }
     else
     {
-        if (cbFile > LONG_MAX)
-        {
-            errno = EOVERFLOW;
-            return -1;
-        }
-        rc = DosSetFileSize(hFile, cbFile);
+        /** not supported for non native filehandles. */
+        rc = ERROR_INVALID_FUNCTION;
     }
-#else
-    rc = DosSetFileSize(hFile, cbFile);
-#endif
-    FS_RESTORE();
 
+    /*
+     * Done.
+     */
     if (rc)
     {
Index: trunk/src/emx/src/lib/sys/__close.c
===================================================================
--- trunk/src/emx/src/lib/sys/__close.c	(revision 870)
+++ trunk/src/emx/src/lib/sys/__close.c	(revision 871)
@@ -1,24 +1,13 @@
-/* sys/close.c (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes */
+/* sys/close.c (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes
+                         -- Copyright (c) 2003 by Knut St. Osmunden */
 
 #include "libc-alias.h"
-#define INCL_FSMACROS
-#include <os2emx.h>
+#include <emx/io.h>
 #include <emx/syscalls.h>
-#include "syscalls.h"
 
-int __close (int handle)
+int __close(int fh)
 {
-  ULONG rc;
-  FS_VAR()
-
-  FS_SAVE_LOAD();
-  rc = DosClose (handle);
-  FS_RESTORE();
-  if (rc == 0)
-    return 0;
-  else
-    {
-      _sys_set_errno (rc);
-      return -1;
-    }
+    if (!__libc_FHClose(fh))
+        return -0;
+    return -1;
 }
Index: trunk/src/emx/src/lib/sys/__dup.c
===================================================================
--- trunk/src/emx/src/lib/sys/__dup.c	(revision 870)
+++ trunk/src/emx/src/lib/sys/__dup.c	(revision 871)
@@ -1,25 +1,67 @@
-/* sys/dup.c (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes */
+/* sys/dup.c (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes
+                       -- Copyright (c) 2003 by Knut St. Osmunden */
 
 #include "libc-alias.h"
 #define INCL_FSMACROS
 #include <os2emx.h>
+#include <errno.h>
+#include <emx/io.h>
 #include <emx/syscalls.h>
 #include "syscalls.h"
 
-int __dup (int handle)
+int __dup(int fh)
 {
-  ULONG rc;
-  HFILE hNew;
-  FS_VAR();
+    PLIBCFH     pFH;
+    int         fhNew;
+    ULONG       rc;
 
-  hNew = 0xffffffff;
-  FS_SAVE_LOAD();
-  rc = DosDupHandle (handle, &hNew);
-  FS_RESTORE();
-  if (rc != 0)
+    /*
+     * Get filehandle.
+     */
+    pFH = __libc_FH(fh);
+    if (!pFH)
     {
-      _sys_set_errno (rc);
-      return -1;
+        errno = EBADF;
+        return -1;
     }
-  return hNew;
+
+    /*
+     * Choose path.
+     */
+    if (!pFH->pOps)
+    {
+        HFILE   hNew = ~0;
+        FS_VAR();
+        FS_SAVE_LOAD();
+        rc = DosDupHandle(fh, &hNew);
+        FS_RESTORE();
+        fhNew = (int)hNew;
+        if (!rc)
+        {
+            PLIBCFH pFHNew;
+            rc = __libc_FHAllocate(hNew, pFH->fFlags, sizeof(LIBCFH), NULL, &pFHNew, NULL);
+            if (!rc)
+            {
+                pFHNew->fFlags      = pFH->fFlags;
+                pFHNew->iLookAhead  = pFH->iLookAhead;
+            }
+            else
+                DosClose(hNew);
+        }
+    }
+    else
+    {
+        fhNew = -1; /* any handle */
+        rc = pFH->pOps->pfnDuplicate(pFH, fh, &fhNew);
+    }
+
+    /*
+     * Done.
+     */
+    if (rc != 0)
+    {
+        _sys_set_errno(rc);
+        return -1;
+    }
+    return fhNew;
 }
Index: trunk/src/emx/src/lib/sys/__dup2.c
===================================================================
--- trunk/src/emx/src/lib/sys/__dup2.c	(revision 870)
+++ trunk/src/emx/src/lib/sys/__dup2.c	(revision 871)
@@ -1,28 +1,110 @@
-/* sys/dup2.c (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes */
+/* sys/dup2.c (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes
+                        -- Copyright (c) 2003 by Knut St. Osmunden */
 
 #include "libc-alias.h"
 #define INCL_FSMACROS
 #include <os2emx.h>
+#include <errno.h>
 #include <emx/syscalls.h>
+#include <emx/io.h>
 #include "syscalls.h"
 
-int __dup2 (int handle1, int handle2)
+int __dup2(int fh, int fhNew)
 {
-  ULONG rc, state;
-  HFILE hNew;
-  FS_VAR();
+    PLIBCFH     pFH;
+    PLIBCFH     pFHNew;
+    ULONG       rc;
 
-  hNew = handle2;
-  FS_SAVE_LOAD();
-  if (handle1 == handle2)
-    rc = DosQueryFHState (handle1, &state); /* Check HANDLE */
-  else
-    rc = DosDupHandle (handle1, &hNew);
-  FS_RESTORE();
-  if (rc != 0)
+    /*
+     * Validate the two handles.
+     * (Specs saith fhNew must not be below zero.)
+     */
+    if (    fhNew < 0
+        ||  !(pFH = __libc_FH(fh)))
     {
-      _sys_set_errno (rc);
-      return -1;
+        errno = EBADF;
+        return -1;
     }
-  return hNew;
+
+    /*
+     * If the two filehandles are the same, then just
+     * check that it's still around and return accordingly.
+     */
+    if (fhNew == fh)
+    {
+        ULONG   ulState;
+        FS_VAR();
+        FS_SAVE_LOAD();
+        rc = 0;
+        if (!pFH->pOps)
+            rc = DosQueryFHState(fh, &ulState);
+        FS_RESTORE();
+        if (rc)
+        {
+            _sys_set_errno(rc);
+            return -1;
+        }
+        return fhNew;
+    }
+
+    /*
+     * Ensure the specified handle is within the bounds
+     * of the number of filehandles this process can open.
+     * (Specs saith so, and others say OS/2 may crash if fhNew is out of range.)
+     */
+    rc = __libc_FHEnsureHandles(fhNew);
+    if (rc)
+    {
+        _sys_set_errno(rc);
+        return -1;
+    }
+
+    /*
+     * If fhNew exists and is not of the OS/2 native
+     * file handle type, we'll close it here.
+     */
+    pFHNew = __libc_FH(fhNew);
+    if (pFHNew && pFHNew->pOps)
+    {
+        rc = __libc_FHClose(fhNew);
+        if (rc)
+            return -1; /* it sets errno */
+    }
+
+    /*
+     * Do the stuff.
+     */
+    if (!pFH->pOps)
+    {
+        HFILE   hNew = fhNew;
+        FS_VAR();
+
+        FS_SAVE_LOAD();
+        rc = DosDupHandle(fh, &hNew);
+        if (!rc)
+        {
+            PLIBCFH pFHNew;
+            rc = __libc_FHAllocate(hNew, pFH->fFlags, sizeof(LIBCFH), NULL, &pFHNew, NULL);
+            if (!rc)
+            {
+                pFHNew->fFlags      = pFH->fFlags;
+                pFHNew->iLookAhead  = pFH->iLookAhead;
+            }
+            else
+                DosClose(hNew);
+        }
+        FS_RESTORE();
+    }
+    else
+        rc = pFH->pOps->pfnDuplicate(pFH, fh, &fhNew);
+
+    /*
+     * Done
+     */
+    if (rc)
+    {
+        _sys_set_errno(rc);
+        return -1;
+    }
+    return fhNew;
 }
Index: trunk/src/emx/src/lib/sys/__fcntl.c
===================================================================
--- trunk/src/emx/src/lib/sys/__fcntl.c	(revision 870)
+++ trunk/src/emx/src/lib/sys/__fcntl.c	(revision 871)
@@ -1,3 +1,4 @@
-/* sys/fcntl.c (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes */
+/* sys/fcntl.c (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes
+                         -- Copyright (c) 2003 by Knut St. Osmunden */
 
 #include "libc-alias.h"
@@ -9,4 +10,5 @@
 #define INCL_FSMACROS
 #include <os2emx.h>
+#include <emx/io.h>
 #include <emx/syscalls.h>
 #include "syscalls.h"
@@ -14,59 +16,110 @@
 static int __fcntl_locking(int handle, int request, struct flock *pflock);
 
-int __fcntl (int handle, int request, int arg)
+int __fcntl(int handle, int request, int arg)
 {
-  ULONG rc;
-  ULONG state, new_state;
-  FS_VAR();
-
-  switch (request)
-    {
-    case F_SETFL:
-      return 0;
-    case F_GETFD:
-      FS_SAVE_LOAD();
-      rc = DosQueryFHState (handle, &state);
-      FS_RESTORE();
-      if (rc != 0)
-        {
-          _sys_set_errno (rc);
-          return -1;
-        }
-      return ((state & OPEN_FLAGS_NOINHERIT) ? 1 : 0);
-    case F_SETFD:
-      FS_SAVE_LOAD();
-      rc = DosQueryFHState (handle, &state);
-      FS_RESTORE();
-      if (rc != 0)
-        {
-          _sys_set_errno (rc);
-          return -1;
-        }
-      if (arg & 1)
-        new_state = state | OPEN_FLAGS_NOINHERIT;
-      else
-        new_state = state & ~OPEN_FLAGS_NOINHERIT;
-      if (new_state != state)
-        {
-          new_state &= 0x7f88;
-          FS_SAVE_LOAD();
-          rc = DosSetFHState (handle, new_state);
-          FS_RESTORE();
-          if (rc != 0)
-            {
-              _sys_set_errno (rc);
-              return -1;
-            }
-        }
-      return 0;
-
-    case F_GETLK:   /* get record locking information */
-    case F_SETLK:   /* set record locking information */
-    case F_SETLKW:  /* F_SETLK; wait if blocked */
-      return __fcntl_locking(handle, request, (struct flock*)arg);
-
-    default:
-      errno = EINVAL;
-      return -1;
+    ULONG     rc;
+    ULONG     fulState;
+    PLIBCFH   pFH;
+    FS_VAR();
+
+    /*
+     * Get the file handle data.
+     */
+    pFH = __libc_FH(handle);
+    if (!pFH)
+    {
+        errno = EBADF;
+        return -1;
+    }
+
+    if (!pFH->pOps)
+    {
+        /*
+         * Standard OS/2 File handle.
+         */
+        switch (request)
+        {
+            /*
+             * Get file status flags and access modes.
+             */
+            case F_GETFL:
+                return pFH->fFlags & (O_ACCMODE | O_APPEND | O_NONBLOCK | O_SYNC /*| O_*SYNC*/);
+
+            /*
+             * Set file status flags.
+             */
+            case F_SETFL:
+                /** @todo implement this properly. See FCNTLFLAGS. */
+                return 0;
+
+            /*
+             * Get file descriptor flags.
+             * (At the moment FD_CLOEXEC is the only flag.)
+             */
+            case F_GETFD:
+                FS_SAVE_LOAD();
+                rc = DosQueryFHState(handle, &fulState);
+                FS_RESTORE();
+                if (rc != 0)
+                {
+                    _sys_set_errno(rc);
+                    return -1;
+                }
+                return ((fulState & OPEN_FLAGS_NOINHERIT) ? FD_CLOEXEC : 0);
+
+            /*
+             * Set file descriptor flags.
+             * (At the moment FD_CLOEXEC is the only flag.)
+             */
+            case F_SETFD:
+                FS_SAVE_LOAD();
+                rc = DosQueryFHState(handle, &fulState);
+                if (!rc)
+                {
+                    ULONG fulNewState;
+                    if (arg & FD_CLOEXEC)
+                        fulNewState = fulState | OPEN_FLAGS_NOINHERIT;
+                    else
+                        fulNewState = fulState & ~OPEN_FLAGS_NOINHERIT;
+                    if (fulNewState != fulState)
+                    {
+                        fulNewState &= 0x7f88; /* Mask the flags accepted the API. */
+                        rc = DosSetFHState(handle, fulNewState);
+                    }
+                }
+                FS_RESTORE();
+                if (rc)
+                {
+                    _sys_set_errno (rc);
+                    return -1;
+                }
+                return 0;
+
+            /*
+             * File locking.
+             */
+            case F_GETLK:   /* get record locking information */
+            case F_SETLK:   /* set record locking information */
+            case F_SETLKW:  /* F_SETLK; wait if blocked */
+                return __fcntl_locking(handle, request, (struct flock*)arg);
+
+            default:
+                errno = EINVAL;
+                return -1;
+        }
+    }
+    else
+    {
+        /*
+         * Non-standard handle - call registered method.
+         */
+        int rcRet = 0;
+        rc = pFH->pOps->pfnFileControl(pFH, handle, request, arg, &rcRet);
+        if (rc)
+        {
+            _sys_set_errno(rc);
+            return -1;
+        }
+        return rcRet;
     }
 }
@@ -78,5 +131,5 @@
    it's take from elsewhere. */
 
-static int __fcntl_locking (int hFile, int request, struct flock *pflock)
+static int __fcntl_locking(int hFile, int request, struct flock *pflock)
 {
     APIRET        rc;
@@ -140,5 +193,5 @@
         }
         if (    offStart < 0
-            ||  cbRange + offStart < 0 )
+            ||  cbRange + offStart < 0)
         {
             errno = EINVAL;
@@ -195,10 +248,10 @@
                      && (   cbRange > LONG_MAX
                          || offStart + cbRange > LONG_MAX)
-                     )
-                )
-              {
+                    )
+               )
+            {
                 errno = EOVERFLOW;
                 return -1;
-              }
+            }
 #endif
             memset(&aflock[(fLock + 1) & 1], 0, sizeof(aflock[0]));
Index: trunk/src/emx/src/lib/sys/__fstat.c
===================================================================
--- trunk/src/emx/src/lib/sys/__fstat.c	(revision 870)
+++ trunk/src/emx/src/lib/sys/__fstat.c	(revision 871)
@@ -7,6 +7,8 @@
 #include <os2emx.h>
 #include <string.h>
+#include <errno.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <emx/io.h>
 #include <emx/syscalls.h>
 #include "syscalls.h"
@@ -14,130 +16,149 @@
 int __fstat(int hFile, struct stat *pStat)
 {
-    ULONG rc;
-    ULONG ulType;
-    ULONG flFlags;
+    ULONG   rc;
+    ULONG   ulType;
+    ULONG   flFlags;
+    PLIBCFH pFH;
     FS_VAR();
 
     /*
-     * Use query handle type to figure out the file type.
+     * Get filehandle.
      */
-    memset(pStat, 0, sizeof(*pStat));
-    FS_SAVE_LOAD();
-    rc = DosQueryHType(hFile, &ulType, &flFlags);
-    if (rc)
+    pFH = __libc_FH(hFile);
+    if (!pFH)
     {
-        FS_RESTORE();
-        _sys_set_errno(rc);
+        errno = EBADF;
         return -1;
     }
-    switch (ulType & 0xff)
+
+    if (!pFH->pOps)
     {
-        case FHT_CHRDEV:
-            pStat->st_mode = S_IFCHR;
-            break;
-        case FHT_PIPE:
-            pStat->st_mode = S_IFSOCK;
-            break;
-        default:
-            pStat->st_mode = S_IFREG;
-            break;
-    }
-
-    if (pStat->st_mode == S_IFREG)
-    {
-        union
-        {
-            FILESTATUS3     fsts3;
-            FILESTATUS3L    fsts3L;
-        } info;
-    #if OFF_MAX > LONG_MAX
-        int     fLarge = 0;
-    #endif
-
         /*
-         * Get file info.
+         * Use query handle type to figure out the file type.
          */
-#if OFF_MAX > LONG_MAX
-        if (__pfnDosOpenL)
-        {
-            rc = DosQueryFileInfo(hFile, FIL_STANDARDL, &info, sizeof(info.fsts3L));
-            fLarge = 1;
-        }
-        else
-#endif
-            rc = DosQueryFileInfo(hFile, FIL_STANDARD, &info, sizeof(info.fsts3));
+        memset(pStat, 0, sizeof(*pStat));
+        rc = DosQueryHType(hFile, &ulType, &flFlags);
         if (rc)
         {
             FS_RESTORE();
-            _sys_set_errno (rc);
+            _sys_set_errno(rc);
             return -1;
         }
+        switch (pFH->fFlags & F_TYPEMASK)
+        {
+            case F_DEV:     pStat->st_mode = S_IFCHR; break;
+            case F_SOCKET:  pStat->st_mode = S_IFSOCK; break;
+            case F_PIPE:    pStat->st_mode = S_IFSOCK/*??*/; break;
+            default:
+            case F_FILE:    pStat->st_mode = S_IFREG; break;
+        }
 
-        /*
-         * Format stats struct.
-         *      We know the info struct layouts!
-         *      Only cbFile, cbFileAlloc and attrFile need be accessed
-         *      using the specific structure.
-         */
-        /* Times: FAT might not return create and access time. */
-        pStat->st_mtime = _sys_p2t(info.fsts3.ftimeLastWrite, info.fsts3.fdateLastWrite);
-        if (    FTIMEZEROP(info.fsts3.ftimeCreation)
-            &&  FDATEZEROP(info.fsts3.fdateCreation))
-            pStat->st_ctime = pStat->st_mtime;
-        else
-            pStat->st_ctime = _sys_p2t(info.fsts3.ftimeCreation, info.fsts3.fdateCreation);
-        if (    FTIMEZEROP(info.fsts3.ftimeLastAccess)
-            &&  FDATEZEROP(info.fsts3.fdateLastAccess))
-            pStat->st_atime = pStat->st_mtime;
-        else
-            pStat->st_atime = _sys_p2t(info.fsts3.ftimeLastAccess, info.fsts3.fdateLastAccess);
+        FS_SAVE_LOAD();
+        if (pStat->st_mode == S_IFREG)
+        {
+            union
+            {
+                FILESTATUS3     fsts3;
+                FILESTATUS3L    fsts3L;
+            } info;
+        #if OFF_MAX > LONG_MAX
+            int     fLarge = 0;
+        #endif
+
+            /*
+             * Get file info.
+             */
+#if OFF_MAX > LONG_MAX
+            if (__pfnDosOpenL)
+            {
+                rc = DosQueryFileInfo(hFile, FIL_STANDARDL, &info, sizeof(info.fsts3L));
+                fLarge = 1;
+            }
+            else
+#endif
+                rc = DosQueryFileInfo(hFile, FIL_STANDARD, &info, sizeof(info.fsts3));
+            if (rc)
+            {
+                FS_RESTORE();
+                _sys_set_errno (rc);
+                return -1;
+            }
+
+            /*
+             * Format stats struct.
+             *      We know the info struct layouts!
+             *      Only cbFile, cbFileAlloc and attrFile need be accessed
+             *      using the specific structure.
+             */
+            /* Times: FAT might not return create and access time. */
+            pStat->st_mtime = _sys_p2t(info.fsts3.ftimeLastWrite, info.fsts3.fdateLastWrite);
+            if (    FTIMEZEROP(info.fsts3.ftimeCreation)
+                &&  FDATEZEROP(info.fsts3.fdateCreation))
+                pStat->st_ctime = pStat->st_mtime;
+            else
+                pStat->st_ctime = _sys_p2t(info.fsts3.ftimeCreation, info.fsts3.fdateCreation);
+            if (    FTIMEZEROP(info.fsts3.ftimeLastAccess)
+                &&  FDATEZEROP(info.fsts3.fdateLastAccess))
+                pStat->st_atime = pStat->st_mtime;
+            else
+                pStat->st_atime = _sys_p2t(info.fsts3.ftimeLastAccess, info.fsts3.fdateLastAccess);
 
 #if OFF_MAX > LONG_MAX
-        if (fLarge)
-        {
-            pStat->st_size = info.fsts3L.cbFile;
-            pStat->st_blocks = info.fsts3L.cbFileAlloc / S_BLKSIZE;
-            rc = info.fsts3L.attrFile;
+            if (fLarge)
+            {
+                pStat->st_size = info.fsts3L.cbFile;
+                pStat->st_blocks = info.fsts3L.cbFileAlloc / S_BLKSIZE;
+                rc = info.fsts3L.attrFile;
+            }
+            else
+#endif
+            {
+                pStat->st_size = info.fsts3.cbFile;
+                pStat->st_blocks = info.fsts3.cbFileAlloc / S_BLKSIZE;
+                rc = info.fsts3.attrFile;
+            }
+            pStat->st_attr = rc;
+            if (rc & FILE_READONLY)
+                pStat->st_mode |= (S_IREAD >> 6) * 0111;
+            else
+                pStat->st_mode |= ((S_IREAD|S_IWRITE) >> 6) * 0111;
         }
         else
-#endif
         {
-            pStat->st_size = info.fsts3.cbFile;
-            pStat->st_blocks = info.fsts3.cbFileAlloc / S_BLKSIZE;
-            rc = info.fsts3.attrFile;
+            pStat->st_size = 0;
+            rc = DosQueryFHState(hFile, &flFlags);
+            if (rc)
+            {
+                FS_RESTORE();
+                _sys_set_errno (rc);
+                return -1;
+            }
+            if ((flFlags & 7) == OPEN_ACCESS_READONLY)
+                pStat->st_mode |= (S_IREAD >> 6) * 0111;
+            else
+                pStat->st_mode |= ((S_IREAD|S_IWRITE) >> 6) * 0111;
         }
-        pStat->st_attr = rc;
-        if (rc & FILE_READONLY)
-            pStat->st_mode |= (S_IREAD >> 6) * 0111;
-        else
-            pStat->st_mode |= ((S_IREAD|S_IWRITE) >> 6) * 0111;
+
+        /* default fake stuff */
+        pStat->st_uid = 0;
+        pStat->st_gid = 0;
+        pStat->st_ino = _sys_ino++;
+        if (_sys_ino == 0)
+            _sys_ino = 1;
+        pStat->st_dev = 0;
+        pStat->st_rdev = 0;
+        pStat->st_nlink = 1;
+        pStat->st_blksize = 4096*48;
+        FS_RESTORE();
     }
     else
     {
-        pStat->st_size = 0;
-        rc = DosQueryFHState(hFile, &flFlags);
-        if (rc)
-        {
-            FS_RESTORE();
-            _sys_set_errno (rc);
-            return -1;
-        }
-        if ((flFlags & 7) == OPEN_ACCESS_READONLY)
-            pStat->st_mode |= (S_IREAD >> 6) * 0111;
-        else
-            pStat->st_mode |= ((S_IREAD|S_IWRITE) >> 6) * 0111;
+        /*
+         * Non-standard handle - fail.
+         */
+        errno = EPERM;
+        return -1;
     }
 
-    /* default fake stuff */
-    pStat->st_uid = 0;
-    pStat->st_gid = 0;
-    pStat->st_ino = _sys_ino++;
-    if (_sys_ino == 0)
-        _sys_ino = 1;
-    pStat->st_dev = 0;
-    pStat->st_rdev = 0;
-    pStat->st_nlink = 1;
-    pStat->st_blksize = 4096*48;
-    FS_RESTORE();
     return 0;
 }
Index: trunk/src/emx/src/lib/sys/__ftruncate.c
===================================================================
--- trunk/src/emx/src/lib/sys/__ftruncate.c	(revision 870)
+++ trunk/src/emx/src/lib/sys/__ftruncate.c	(revision 871)
@@ -7,7 +7,8 @@
 #define INCL_FSMACROS
 #include <os2emx.h>
-#include <emx/syscalls.h>
 #include <limits.h>
 #include <errno.h>
+#include <emx/io.h>
+#include <emx/syscalls.h>
 #include "syscalls.h"
 
@@ -15,65 +16,91 @@
 {
     ULONG       rc;
-    off_t       cbCur;
-    union
-    {
-        FILESTATUS3     fsts3;
-        FILESTATUS3L    fsts3L;
-    } info;
-    FS_VAR();
+    PLIBCFH     pFH;
 
     /*
-     * First step, figure out the current size.
+     * Get filehandle.
      */
-    FS_SAVE_LOAD();
-#if OFF_MAX > LONG_MAX
-    if (__pfnDosOpenL)
+    pFH = __libc_FH(hFile);
+    if (!pFH)
     {
-        rc = DosQueryFileInfo(hFile, FIL_STANDARDL, &info, sizeof(info.fsts3L));
-        cbCur = info.fsts3L.cbFile;
-    }
-    else
-#endif
-    {
-        rc = DosQueryFileInfo(hFile, FIL_STANDARD, &info, sizeof(info.fsts3));
-        cbCur = info.fsts3.cbFile;
-    }
-    FS_RESTORE();
-    if (rc)
-    {
-        _sys_set_errno(rc);
+        errno = EBADF;
         return -1;
     }
 
+    if (!pFH->pOps)
+    {
+        /*
+         * Standard OS/2 file handle.
+         */
+        off_t       cbCur;
+        union
+        {
+            FILESTATUS3     fsts3;
+            FILESTATUS3L    fsts3L;
+        } info;
+        FS_VAR();
 
-    /*
-     * Is the file larger than the truncation size?
-     * Then set the desired file size.
-     */
-    if (cbCur > cbFile)
-    {
+        /*
+         * First step, figure out the current size.
+         */
         FS_SAVE_LOAD();
 #if OFF_MAX > LONG_MAX
-        if (__pfnDosSetFileSizeL)
-            rc = __pfnDosSetFileSizeL(hFile, cbFile);
+        if (__pfnDosOpenL)
+        {
+            rc = DosQueryFileInfo(hFile, FIL_STANDARDL, &info, sizeof(info.fsts3L));
+            cbCur = info.fsts3L.cbFile;
+        }
         else
+#endif
         {
-            if (cbFile > __LONG_MAX)
-            {
-                FS_RESTORE();
-                errno = EOVERFLOW;
-                return -1;
-            }
-            rc = DosSetFileSize(hFile, cbFile);
+            rc = DosQueryFileInfo(hFile, FIL_STANDARD, &info, sizeof(info.fsts3));
+            cbCur = info.fsts3.cbFile;
         }
-#else
-        rc = DosSetFileSize(hFile, cbFile);
-#endif
         FS_RESTORE();
-        if (rc != 0)
+        if (rc)
         {
             _sys_set_errno(rc);
             return -1;
         }
+
+
+        /*
+         * Is the file larger than the truncation size?
+         * Then set the desired file size.
+         */
+        if (cbCur > cbFile)
+        {
+            FS_SAVE_LOAD();
+#if OFF_MAX > LONG_MAX
+            if (__pfnDosSetFileSizeL)
+                rc = __pfnDosSetFileSizeL(hFile, cbFile);
+            else
+            {
+                if (cbFile > __LONG_MAX)
+                {
+                    FS_RESTORE();
+                    errno = EOVERFLOW;
+                    return -1;
+                }
+                rc = DosSetFileSize(hFile, cbFile);
+            }
+#else
+            rc = DosSetFileSize(hFile, cbFile);
+#endif
+            FS_RESTORE();
+            if (rc != 0)
+            {
+                _sys_set_errno(rc);
+                return -1;
+            }
+        }
+    }
+    else
+    {
+        /*
+         * Non-standard file handle - fail.
+         */
+        errno = EPERM;
+        return -1;
     }
     return 0;
Index: trunk/src/emx/src/lib/sys/__imphandle.c
===================================================================
--- trunk/src/emx/src/lib/sys/__imphandle.c	(revision 870)
+++ trunk/src/emx/src/lib/sys/__imphandle.c	(revision 871)
@@ -1,9 +1,14 @@
-/* imphandl.c (emx+gcc) -- Copyright (c) 1994-1996 by Eberhard Mattes */
+/* imphandl.c (emx+gcc) -- Copyright (c) 1994-1996 by Eberhard Mattes
+                        -- Copyright (c) 2003 by Knut St. Osmunden */
 
 #include "libc-alias.h"
+#include <emx/io.h>
 #include <emx/syscalls.h>
 
-int __imphandle (int handle)
+int __imphandle(int fh)
 {
-  return handle;
+    PLIBCFH pFH = __libc_FH(fh);
+    if (pFH)
+        return fh;
+    return -1;
 }
Index: trunk/src/emx/src/lib/sys/__initdll.c
===================================================================
--- trunk/src/emx/src/lib/sys/__initdll.c	(revision 870)
+++ trunk/src/emx/src/lib/sys/__initdll.c	(revision 871)
@@ -122,8 +122,15 @@
      * Init long file I/O functions.
      * This is weak, so that it's only linked in when we're building with
-     * large file suppoort enabled.
+     * large file support enabled.
      */
     if (_sys_init_largefileio)
         _sys_init_largefileio();
+
+    /*
+     * Init file handles.
+     */
+    rc = _sys_init_filehandles();
+    if (rc)
+        return -1;
 
     /*
Index: trunk/src/emx/src/lib/sys/__ioctl1.c
===================================================================
--- trunk/src/emx/src/lib/sys/__ioctl1.c	(revision 870)
+++ trunk/src/emx/src/lib/sys/__ioctl1.c	(revision 871)
@@ -1,3 +1,4 @@
-/* sys/ioctl1.c (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes */
+/* sys/ioctl1.c (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes
+                          -- Copyright (c) 2003 by Knut St. Osmunden */
 
 #include "libc-alias.h"
@@ -5,29 +6,58 @@
 #define INCL_FSMACROS
 #include <os2emx.h>
+#include <emx/io.h>
 #include <emx/syscalls.h>
 #include "syscalls.h"
 
 
-int __ioctl1 (int handle, int code)
+/** Obsolete interface to DosQueryHType.
+ * @deprecated Do not use this!!
+ */
+int __ioctl1(int handle, int code)
 {
-  ULONG rc;
-  ULONG htype, hflags;
-  FS_VAR();
+    PLIBCFH  pFH;
 
-  if (code != 0)
+    /*
+     * Get filehandle.
+     */
+    pFH = __libc_FH(handle);
+    if (!pFH)
     {
-      errno = EINVAL;
-      return -1;
+        errno = EBADF;
+        return -1;
     }
-  FS_SAVE_LOAD();
-  rc = DosQueryHType (handle, &htype, &hflags);
-  FS_RESTORE();
-  if (rc != 0)
+    if (pFH->pOps)
     {
-      _sys_set_errno (rc);
-      return -1;
+        errno = EINVAL;
+        return -1;
     }
-  if ((htype & 0xff) == 0)
-    return 0;
-  return (hflags & 0x0f) | 0x80;
+
+    /*
+     * Check code.
+     */
+    switch (code)
+    {
+        /** @todo get rid of this hardcoded shit. */
+        case 0:
+        {
+            ULONG rc;
+            ULONG htype, hflags;
+            FS_VAR();
+            FS_SAVE_LOAD();
+            rc = DosQueryHType(handle, &htype, &hflags);
+            FS_RESTORE();
+            if (rc)
+            {
+                _sys_set_errno(rc);
+                return -1;
+            }
+            if ((htype & 0xff) == 0)
+              return 0;
+            return (hflags & 0x0f) | 0x80;
+        }
+    }
+
+    /* default */
+    errno = EINVAL;
+    return -1;
 }
Index: trunk/src/emx/src/lib/sys/__ioctl2.c
===================================================================
--- trunk/src/emx/src/lib/sys/__ioctl2.c	(revision 870)
+++ trunk/src/emx/src/lib/sys/__ioctl2.c	(revision 871)
@@ -1,3 +1,4 @@
-/* sys/ioctl2.c (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes */
+/* sys/ioctl2.c (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes
+                          -- Copyright (c) 2003 by Knut St. Osmunden */
 
 #include "libc-alias.h"
@@ -8,4 +9,6 @@
 #define INCL_FSMACROS
 #include <os2emx.h>
+#include <sys/filio.h>
+#include <emx/io.h>
 #include <emx/syscalls.h>
 #include "syscalls.h"
@@ -15,57 +18,104 @@
  */
 #define __IOCLW(a) ((unsigned short)(a))
+/** This is the syscall for ioctl(). */
+int __ioctl2(int handle, unsigned long request, int arg)
+{
+    PLIBCFH pFH;
+    ULONG   rc;
+    ULONG   type;
+    ULONG   flags;
+    int *   int_ptr;
+    FS_VAR();
 
-int __ioctl2 (int handle, unsigned long request, int arg)
-{
-  ULONG rc;
-  ULONG type, flags;
-  int *int_ptr;
-  FS_VAR();
-
-  switch (__IOCLW(request))
+    /*
+     * Get filehandle.
+     */
+    pFH = __libc_FH(handle);
+    if (!pFH)
     {
-    case __IOCLW(FGETHTYPE):
-      int_ptr = (int *)arg;
-      FS_SAVE_LOAD();
-      rc = DosQueryHType (handle, &type, &flags);
-      FS_RESTORE();
-      if (rc != 0)
-        {
-          _sys_set_errno (rc);
-          return -1;
-        }
-      switch (type & 0xff)
-        {
-        case 0:                 /* File */
-          *int_ptr = HT_FILE;
-          break;
-        case 1:                 /* Character device */
-          if (flags & 3)
-            *int_ptr = HT_DEV_CON;
-          else if (flags & 4)
-            *int_ptr = HT_DEV_NUL;
-          else if (flags & 8)
-            *int_ptr = HT_DEV_CLK;
-          else
-            *int_ptr = HT_DEV_OTHER;
-          break;
-        case 2:                 /* Pipe */
-          FS_SAVE_LOAD();
-          rc = DosQueryNPHState (handle, &flags);
-          FS_RESTORE();
-          if (rc == 0 || rc == ERROR_PIPE_NOT_CONNECTED)
-            *int_ptr = HT_NPIPE;
-          else
-            *int_ptr = HT_UPIPE;
-          break;
-        default:
-          errno = EINVAL;
-          return -1;
-        }
-      return 0;
-    default:
-      errno = EINVAL;
-      return -1;
+        errno = EBADF;
+        return -1;
     }
 
+    if (!pFH->pOps)
+    {
+        /*
+         * Standard OS/2 filehandle.
+         */
+        switch (__IOCLW(request))
+        {
+            case __IOCLW(FGETHTYPE):
+                int_ptr = (int *)arg;
+                FS_SAVE_LOAD();
+                rc = DosQueryHType (handle, &type, &flags);
+                FS_RESTORE();
+                if (rc != 0)
+                {
+                    _sys_set_errno (rc);
+                    return -1;
+                }
+                switch (type & 0xff)
+                {
+                    case 0:                 /* File */
+                        *int_ptr = HT_FILE;
+                        break;
+                    case 1:                 /* Character device */
+                        if (flags & 3)
+                            *int_ptr = HT_DEV_CON;
+                        else if (flags & 4)
+                            *int_ptr = HT_DEV_NUL;
+                        else if (flags & 8)
+                            *int_ptr = HT_DEV_CLK;
+                        else
+                            *int_ptr = HT_DEV_OTHER;
+                        break;
+                    case 2:                 /* Pipe */
+                        FS_SAVE_LOAD();
+                        rc = DosQueryNPHState (handle, &flags);
+                        FS_RESTORE();
+                        if (rc == 0 || rc == ERROR_PIPE_NOT_CONNECTED)
+                            *int_ptr = HT_NPIPE;
+                        else
+                            *int_ptr = HT_UPIPE;
+                        break;
+                    default:
+                        errno = EINVAL;
+                        return -1;
+                }
+                return 0;
+
+/** @todo lots of FIO* things to go!! */
+#if 0
+
+#define	FIOCLEX		 _IO('f', 1)		/* set close on exec on fd */
+#define	FIONCLEX	 _IO('f', 2)		/* remove close on exec */
+#define	FIONREAD	_IOR('f', 127, int)	/* get # bytes to read */
+#define	FIONBIO		_IOW('f', 126, int)	/* set/clear non-blocking i/o */
+#define	FIOASYNC	_IOW('f', 125, int)	/* set/clear async i/o */
+#define	FIOSETOWN	_IOW('f', 124, int)	/* set owner */
+#define	FIOGETOWN	_IOR('f', 123, int)	/* get owner */
+#define	FIODTYPE	_IOR('f', 122, int)	/* get d_flags type part */
+#define	FIOGETLBA	_IOR('f', 121, int)	/* get start blk # */
+
+#endif
+
+            default:
+                errno = EINVAL;
+                return -1;
+        }
+    }
+    else
+    {
+        /*
+         * Non-standard filehandle.
+         */
+        int rcRet;
+        rc = pFH->pOps->pfnIOControl(pFH, handle, request, arg, &rcRet);
+        if (rc)
+        {
+            _sys_set_errno(rc);
+            return -1;
+        }
+        return rcRet;
+    }
 }
Index: trunk/src/emx/src/lib/sys/__lseek.c
===================================================================
--- trunk/src/emx/src/lib/sys/__lseek.c	(revision 870)
+++ trunk/src/emx/src/lib/sys/__lseek.c	(revision 871)
@@ -7,7 +7,8 @@
 #define INCL_FSMACROS
 #include <os2emx.h>
-#include <emx/syscalls.h>
 #include <limits.h>
 #include <errno.h>
+#include <emx/io.h>
+#include <emx/syscalls.h>
 #include "syscalls.h"
 
@@ -15,7 +16,17 @@
 {
     ULONG   rc;
+    PLIBCFH pFH;
     off_t   cbNew;
     FS_VAR();
 
+    /*
+     * Get filehandle / validate input.
+     */
+    pFH = __libc_FH(hFile);
+    if (!pFH)
+    {
+        errno = EBADF;
+        return -1;
+    }
     if (origin == FILE_SECTOR)
     {
@@ -24,36 +35,50 @@
     }
 
-    FS_SAVE_LOAD();
+    if (!pFH->pOps)
+    {
+        /*
+         * Standard OS/2 filehandle.
+         */
+        FS_SAVE_LOAD();
 #if OFF_MAX > LONG_MAX
-    if (__pfnDosSetFilePtrL)
-    {
-        LONGLONG cbNewTmp;
-        rc = __pfnDosSetFilePtrL(hFile, off, origin, &cbNewTmp);
-        cbNew = cbNewTmp;
+        if (__pfnDosSetFilePtrL)
+        {
+            LONGLONG cbNewTmp;
+            rc = __pfnDosSetFilePtrL(hFile, off, origin, &cbNewTmp);
+            cbNew = cbNewTmp;
+        }
+        else
+        {
+            ULONG cbNewTmp;
+            if (off > LONG_MAX || off < LONG_MIN)
+            {
+                FS_RESTORE();
+                errno = EOVERFLOW;
+                return -1;
+            }
+            rc = DosSetFilePtr(hFile, off, origin, &cbNewTmp);
+            cbNew = cbNewTmp;
+        }
+#else
+        {
+            ULONG cbNewTmp;
+            rc = DosSetFilePtr(hFile, off, origin, &cbNewTmp);
+            cbNew = cbNewTmp;
+        }
+#endif
+        FS_RESTORE();
+
+        if (rc)
+        {
+            _sys_set_errno (rc);
+            return -1;
+        }
     }
     else
     {
-        ULONG cbNewTmp;
-        if (off > LONG_MAX || off < LONG_MIN)
-        {
-            FS_RESTORE();
-            errno = EOVERFLOW;
-            return -1;
-        }
-        rc = DosSetFilePtr(hFile, off, origin, &cbNewTmp);
-        cbNew = cbNewTmp;
-    }
-#else
-    {
-        ULONG cbNewTmp;
-        rc = DosSetFilePtr(hFile, off, origin, &cbNewTmp);
-        cbNew = cbNewTmp;
-    }
-#endif
-    FS_RESTORE();
-
-    if (rc)
-    {
-        _sys_set_errno (rc);
+        /*
+         * Non-standard filehandle - fail.
+         */
+        errno = EOPNOTSUPP;
         return -1;
     }
Index: trunk/src/emx/src/lib/sys/__open.c
===================================================================
--- trunk/src/emx/src/lib/sys/__open.c	(revision 870)
+++ trunk/src/emx/src/lib/sys/__open.c	(revision 871)
@@ -12,8 +12,9 @@
 #include <limits.h>
 #include <emx/syscalls.h>
+#include <emx/io.h>
 #include <alloca.h>
 #include "syscalls.h"
 
-int __open(const char *pszFile, int flags, off_t cbInitial)
+int __open(const char *pszFile, int flags, off_t cbInitial, unsigned fLibc, PLIBCFH *ppFH)
 {
     ULONG   rc;
@@ -119,4 +120,39 @@
     }
 #endif
+
+    if (!rc)
+    {
+        ULONG   fulType;
+        ULONG   fulDevFlags;
+
+        /*
+         * Figure the handle type.
+         */
+        rc = DosQueryHType(hFile, &fulType, &fulDevFlags);
+        if (!rc)
+        {
+            switch (fulType & 0xff)
+            {
+                default: /* paranoia */
+                case HANDTYPE_FILE:
+                    fLibc |= F_FILE;
+                    break;
+                case HANDTYPE_DEVICE:
+                    fLibc |= F_DEV;
+                    break;
+                case HANDTYPE_PIPE:
+                    fLibc |= F_PIPE;
+                    break;
+            }
+
+            /*
+             * Register the handle.
+             */
+            rc = __libc_FHAllocate(hFile, fLibc, sizeof(LIBCFH), NULL, ppFH, NULL);
+        }
+
+        if (rc)
+            DosClose(hFile);
+    }
     FS_RESTORE();
 
Index: trunk/src/emx/src/lib/sys/__pipe.c
===================================================================
--- trunk/src/emx/src/lib/sys/__pipe.c	(revision 870)
+++ trunk/src/emx/src/lib/sys/__pipe.c	(revision 871)
@@ -1,3 +1,4 @@
-/* sys/pipe.c (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes */
+/* sys/pipe.c (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes
+                        -- Copyright (c) 2003 by Knut St. Osmunden */
 
 #include "libc-alias.h"
@@ -6,21 +7,43 @@
 #include <os2safe.h>
 #include <os2emx.h>
+#include <sys/fcntl.h>
 #include <emx/syscalls.h>
+#include <emx/io.h>
 #include "syscalls.h"
 
-int __pipe (int *two_handles, int pipe_size)
+int __pipe(int *two_handles, int pipe_size, PLIBCFH *ppFHRead, PLIBCFH *ppFHWrite)
 {
-  ULONG rc;
-  FS_VAR();
+    ULONG rc;
+    FS_VAR();
 
-  FS_SAVE_LOAD();
-  rc = DosCreatePipe ((PHFILE)&two_handles[0], (PHFILE)&two_handles[1],
-                      pipe_size);
-  FS_RESTORE();
-  if (rc != 0)
+    FS_SAVE_LOAD();
+    /*
+     * Create the pipe
+     */
+    rc = DosCreatePipe((PHFILE)&two_handles[0], (PHFILE)&two_handles[1], pipe_size);
+    if (!rc)
     {
-      _sys_set_errno (rc);
-      return -1;
+        /*
+         * Register the handle.
+         */
+        rc = __libc_FHAllocate((HFILE)two_handles[0], F_PIPE | O_RDONLY, sizeof(LIBCFH), NULL, ppFHRead, NULL);
+        if (!rc)
+            rc = __libc_FHAllocate((HFILE)two_handles[1], F_PIPE | O_WRONLY, sizeof(LIBCFH), NULL, ppFHWrite, NULL);
+        if (rc)
+        {
+            DosClose((HFILE)two_handles[0]);
+            DosClose((HFILE)two_handles[1]);
+        }
     }
-  return 0;
+    FS_RESTORE();
+
+    /*
+     * Handle error.
+     */
+    if (rc)
+    {
+        _sys_set_errno(rc);
+        return -1;
+    }
+    return 0;
 }
Index: trunk/src/emx/src/lib/sys/__read.c
===================================================================
--- trunk/src/emx/src/lib/sys/__read.c	(revision 870)
+++ trunk/src/emx/src/lib/sys/__read.c	(revision 871)
@@ -1,55 +1,84 @@
-/* sys/read.c (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes */
+/* sys/read.c (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes
+                        -- Copyright (c) 2003 by Knut St. Osmunden */
 
 #include "libc-alias.h"
 #define INCL_FSMACROS
+#define INCL_FPCWMACROS
 #define INCL_ERRORS
 #include <os2emx.h>
+#include <errno.h>
 #include <stdlib.h>
 #include <memory.h>
 #include <emx/umalloc.h>
+#include <emx/io.h>
 #include <emx/syscalls.h>
 #include "syscalls.h"
 
-int __read (int handle, void *buf, size_t nbyte)
+int __read (int handle, void *buf, size_t cbToRead)
 {
-  ULONG rc;
-  ULONG n;
-  void *pvBuf_safe = NULL;
-  FS_VAR();
+    ULONG   rc;
+    PLIBCFH pFH;
+    ULONG   cbRead;
 
-  /*
-   * 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();
+    /*
+     * Get filehandle.
+     */
+    pFH = __libc_FH(handle);
+    if (!pFH)
+    {
+        errno = EBADF;
+        return -1;
+    }
 
-    if (!rc && (ulType & 0xf) == HANDTYPE_DEVICE)
-      {
-        pvBuf_safe = _lmalloc(nbyte);
-        if (!pvBuf_safe)
-            return ERROR_NOT_ENOUGH_MEMORY;
-        memcpy(pvBuf_safe, buf, nbyte);
-      }
-  }
+    if (!pFH->pOps)
+    {
+        /*
+         * Standard OS/2 filehandle.
+         */
+        void   *pvBuf_safe = NULL;
+        FS_VAR();
+        FSCW_VAR();
 
-  FS_SAVE_LOAD();
-  rc = DosRead (handle, pvBuf_safe ? pvBuf_safe : buf, nbyte, &n);
-  FS_RESTORE();
-  if (pvBuf_safe)
+        /*
+         * Devices doesn't like getting high addresses.
+         *      Allocate a buffer in the low heap.
+         */
+        if (    (pFH->fFlags & F_TYPEMASK) == F_DEV
+            &&  (unsigned)buf >= 512*1024*1024)
+        {
+            pvBuf_safe = _lmalloc(cbToRead);
+            if (!pvBuf_safe)
+                return ERROR_NOT_ENOUGH_MEMORY;
+            memcpy(pvBuf_safe, buf, cbToRead);
+        }
+
+        FS_SAVE_LOAD();
+        FSCW_SAVE();
+        rc = DosRead(handle, pvBuf_safe ? pvBuf_safe : buf, cbToRead, &cbRead);
+        FSCW_RESTORE();
+        FS_RESTORE();
+        if (pvBuf_safe)
+        {
+            memcpy(buf, pvBuf_safe, cbToRead);
+            free(pvBuf_safe);
+        }
+    }
+    else
     {
-      memcpy(buf, pvBuf_safe, nbyte);
-      free(pvBuf_safe);
+        /*
+         * Non-standard filehandle.
+         */
+        rc = pFH->pOps->pfnRead(pFH, handle, buf, cbToRead, &cbRead);
     }
-  if (rc == 0)
-    return n;
-  else
+
+    /*
+     * Handle errors.
+     */
+    if (rc)
     {
-      _sys_set_errno (rc);
-      return -1;
+        _sys_set_errno(rc);
+        return -1;
     }
+
+    return cbRead;
 }
Index: trunk/src/emx/src/lib/sys/__write.c
===================================================================
--- trunk/src/emx/src/lib/sys/__write.c	(revision 870)
+++ trunk/src/emx/src/lib/sys/__write.c	(revision 871)
@@ -1,64 +1,93 @@
-/* sys/write.c (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes */
+/* sys/write.c (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes
+                         -- Copyright (c) 2003 by Knut St. Osmunden */
 
 #include "libc-alias.h"
 #define INCL_FSMACROS
+#define INCL_FPCWMACROS
 #define INCL_ERRORS
 #include <os2emx.h>
 #include <memory.h>
 #include <stdlib.h>
+#include <errno.h>
+#include <emx/io.h>
+#include <emx/umalloc.h>
 #include <emx/syscalls.h>
-#include <emx/umalloc.h>
 #include "syscalls.h"
 
-int __write (int handle, const void *buf, size_t nbyte)
+int __write(int handle, const void *buf, size_t cbToWrite)
 {
-  ULONG rc;
-  ULONG n;
-  void *pvBuf_safe = NULL;
-  FS_VAR();
+    PLIBCFH pFH;
+    ULONG   rc;
+    ULONG   cbWritten;
+    FS_VAR();
+    FSCW_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;
-          }
-      }
-  }
+    /*
+     * Get filehandle.
+     */
+    pFH = __libc_FH(handle);
+    if (!pFH)
+    {
+        errno = EBADF;
+        return -1;
+    }
 
-  FS_SAVE_LOAD();
-  rc = DosWrite (handle, buf, nbyte, &n);
-  FS_RESTORE();
+    if (!pFH->pOps)
+    {
+        /*
+         * Standard OS/2 filehandle.
+         */
+        void *pvBuf_safe = NULL;
 
-  if (pvBuf_safe)
-      free(pvBuf_safe);
-  if (rc == 0)
-    return n;
-  else
+        /*
+         * Devices doesn't like getting high addresses.
+         */
+        if (    (pFH->fFlags & F_TYPEMASK) == F_DEV
+            &&  (unsigned)buf >= 512*1024*1024)
+        {
+            if (cbToWrite > 256)
+            {   /* use heap for large buffers */
+                pvBuf_safe = _lmalloc(cbToWrite);
+                if (!pvBuf_safe)
+                    return ERROR_NOT_ENOUGH_MEMORY;
+                memcpy(pvBuf_safe, buf, cbToWrite);
+                buf = pvBuf_safe;
+            }
+            else
+            {   /* use stack for small buffers */
+                pvBuf_safe = alloca(cbToWrite);
+                memcpy(pvBuf_safe, buf, cbToWrite);
+                buf = pvBuf_safe;
+                pvBuf_safe = NULL;
+            }
+        }
+
+        FS_SAVE_LOAD();
+        FSCW_SAVE();
+        rc = DosWrite(handle, buf, cbToWrite, &cbWritten);
+        FSCW_RESTORE();
+        FS_RESTORE();
+
+        if (pvBuf_safe)
+            free(pvBuf_safe);
+    }
+    else
     {
-      _sys_set_errno (rc);
-      return -1;
+        /*
+         * Non-standard filehandle.
+         */
+        rc = pFH->pOps->pfnWrite(pFH, handle, buf, cbToWrite, &cbWritten);
     }
+
+    /*
+     * Handle error.
+     */
+    if (rc)
+    {
+        _sys_set_errno(rc);
+        return -1;
+    }
+    return cbWritten;
 }
+
Index: trunk/src/emx/src/lib/sys/filehandles.c
===================================================================
--- trunk/src/emx/src/lib/sys/filehandles.c	(revision 871)
+++ trunk/src/emx/src/lib/sys/filehandles.c	(revision 871)
@@ -0,0 +1,756 @@
+/* $Id$ */
+/** @file
+ *
+ * LIBC File Handles.
+ *
+ * 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                                                               *
+*******************************************************************************/
+#define INCL_BASE
+#define INCL_ERRORS
+#define INCL_FSMACROS
+#include <os2.h>
+#include "libc-alias.h"
+#include <malloc.h>
+#include <sys/fcntl.h>
+#include <errno.h>
+#include <emx/io.h>
+#include <emx/umalloc.h>
+#include "syscalls.h"
+
+
+/*******************************************************************************
+*   Global Variables                                                           *
+*******************************************************************************/
+/** Mutex semaphor protecting all the global data.
+ * @todo This should've been a read/write lock (multiple read, exclusive write).
+ */
+static _fmutex              gmtx;
+/** Array of file handle pointers. */
+static PLIBCFH             *gpapFHs;
+/** Number of entires in the file handle table. */
+static unsigned             gcFHs;
+
+/** Array of preallocated handles - normal files only! */
+static LIBCFH               gaPreAllocated[40];
+/** Number of free handles in the preallocated array. */
+static unsigned             gcPreAllocatedAvail;
+
+
+/*******************************************************************************
+*   Internal Functions                                                         *
+*******************************************************************************/
+static int __libc_fhMoreHandles(unsigned cMin);
+
+
+/**
+ * Initiates the filehandle structures.
+ *
+ * @returns 0 on success.
+ * @returns -1 on failure.
+ */
+int     _sys_init_filehandles(void)
+{
+    ULONG   cMaxFHs = 0;
+    LONG    lDeltaFHs = 0;
+    int     rc;
+    int     i;
+
+    /*
+     * Only once.
+     */
+    if (gcFHs)
+    {
+#ifdef DEBUG
+        __asm__("int $3");
+#endif
+        return 0;
+    }
+
+    /*
+     * Init the mutex which should've been a read write lock.
+     */
+    rc = _fmutex_create(&gmtx, 0);
+    if (rc)
+        return rc;
+
+    /*
+     * Figure out the size of the pointer array and initiatlize it.
+     */
+    rc = DosSetRelMaxFH(&lDeltaFHs, &cMaxFHs);
+    if (rc)
+    {
+#ifdef DEBUG
+        __asm__("int $3");
+#endif
+        cMaxFHs = 20;
+    }
+    gcFHs = (cMaxFHs + 3) & ~3;     /* round up to nearest 4. */
+    gpapFHs = _hcalloc(gcFHs, sizeof(gpapFHs[0]));
+    if (!gpapFHs)
+        return -1;
+
+    gcPreAllocatedAvail = sizeof(gaPreAllocated) / sizeof(gaPreAllocated[0]);
+
+
+    /*
+     * Work thru the handles checking if they are in use.
+     * Was previously done in init_files() in startup.c.
+     *      We need to allocate the handles and initialize them accordingly.
+     * Note! This duplicates a bit of the __ioctl2 functionality for
+     *       reasons of speed.
+     */
+    for (i = 0; i < cMaxFHs; i++)
+    {
+        ULONG       fulType;
+        ULONG       fulDevFlags;
+        ULONG       fulMode;
+        unsigned    fLibc;
+
+        /*
+         * Is it in use and if so what kind of handle?
+         */
+        if (    (rc = DosQueryHType((HFILE)i, &fulType, &fulDevFlags)) != NO_ERROR
+            ||  (rc = DosQueryFHState((HFILE)i, &fulMode)) != NO_ERROR)
+        {
+#ifdef DEBUG
+            if (rc != ERROR_INVALID_HANDLE)
+                __asm__("int $3");
+#endif
+            continue;
+        }
+
+        /*
+         * Determin initial flags.
+         */
+        switch (fulType & 0xff)
+        {
+            default: /* paranoia */
+            case HANDTYPE_FILE:
+                fLibc = F_FILE;
+                break;
+            case HANDTYPE_DEVICE:
+                fLibc = F_DEV;
+                /* @todo inherit O_NDELAY */
+                break;
+            case HANDTYPE_PIPE:
+                fLibc = F_PIPE;
+                break;
+        }
+
+        /*
+         * There is some init_streams() dependency on all files to have non
+         * zero flags. Sure, we might change this, but for now keep this in mind
+         * when omitting O_TEXT.
+         * @todo inherit non text files.
+         */
+        fLibc |= O_TEXT;
+
+        /*
+         * Read write flags.
+         */
+        switch (fulMode & (OPEN_ACCESS_READONLY | OPEN_ACCESS_WRITEONLY | OPEN_ACCESS_READWRITE))
+        {
+            case OPEN_ACCESS_READONLY:      fLibc |= O_RDONLY; break;
+            case OPEN_ACCESS_WRITEONLY:     fLibc |= O_WRONLY; break;
+            default: /* paranoia */
+            case OPEN_ACCESS_READWRITE:     fLibc |= O_RDWR; break;
+        }
+
+        /*
+         * Enforce rules on the three standard handles - is this strictly
+         * speaking such a good idea? It's apparently required for the con device
+         * as that is opened as readwrite for all three in OS/2 (to safe SFNs?).
+         * However I think when it's not the console device this might be sort
+         * of rushing to conclusions...
+         */
+        if (i < 2 && (fulDevFlags & 0x3 /* CON or KBD dev */))
+        {
+            if (i == 0)
+                fLibc = (fLibc & ~O_ACCMODE) | O_RDONLY;
+            else
+                fLibc = (fLibc & ~O_ACCMODE) | O_WRONLY;
+        }
+
+        /*
+         * Allocate handle and initialize handle.
+         */
+        rc = __libc_FHAllocate(i, fLibc, sizeof(LIBCFH), NULL, NULL, NULL);
+        if (rc)
+        {
+#ifdef DEBUG
+            __asm__("int $3");
+#endif
+            return -1;
+        }
+    } /* fh init loop */
+
+    return 0;
+}
+
+
+/**
+ * Terminate the file handles.
+ *
+ * @returns 0 on success
+ * @returns -1 on failure (what ever that means).
+ */
+int     _sys_term_filehandles(void)
+{
+    if (!gcFHs)
+    {
+#ifdef DEBUG
+            __asm__("int $3");
+#endif
+        return 0;
+    }
+    gcFHs = 0;
+
+    /*
+     * Don't take the mutex as we might be in an crashing/hung process.
+     * no need to make matters worse by potentially waiting for ever here.
+     */
+    _fmutex_close(&gmtx);
+    memset(&gmtx, 0, sizeof(gmtx));
+
+    free(gpapFHs);
+    gpapFHs = NULL;
+
+    return 0;
+}
+
+
+/**
+ * Opens the dummy device for non OS/2 file handles.
+ *
+ * @returns 0 on success.
+ * @returns OS/2 error on failure.
+ * @param   fh  Filehandle to open the dummy device for.
+ *              Use -1 if no special handle is requested.
+ * @param   pfh Where to store the opened fake handle.
+ */
+static int __libc_fhOpenDummy(int fh, int *pfh)
+{
+    int     rc;
+    ULONG   ulAction;
+    HFILE   hFile = fh;
+    FS_VAR();
+
+    FS_SAVE_LOAD();
+    rc = DosOpen("\\DEV\\NUL", &hFile, &ulAction, 0, FILE_NORMAL,
+                 OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
+                 OPEN_SHARE_DENYNONE | OPEN_ACCESS_WRITEONLY,
+                 NULL);
+    if (!rc)
+    {
+        if (fh != -1 && hFile != fh)
+        {
+            HFILE hDup = fh;
+            rc = DosDupHandle(hFile, &hDup);
+            if (!rc)
+                *pfh = hDup;
+            DosClose(hFile);
+        }
+        else
+            *pfh = hFile;
+    }
+    FS_RESTORE();
+    return rc;
+}
+
+/**
+ * Frees handle data.
+ *
+ * @param   pFH Pointer to the handle to be freed.
+ * @param   fh  Handle number which the data used to be associated with.
+ *              Use -1 if it doesn't apply.
+ * @remark  Must own the mutex upon entry!
+ */
+static void __libc_fhFreeHandle(PLIBCFH pFH)
+{
+    /*
+     * Preallocated or heap?
+     */
+    if (    pFH >= &gaPreAllocated[0]
+        &&  pFH <  &gaPreAllocated[sizeof(gaPreAllocated) / sizeof(gaPreAllocated[0])])
+    {
+        pFH->fFlags     = 0;
+        pFH->iLookAhead = 0;
+        pFH->pOps       = NULL;
+        gcPreAllocatedAvail++;
+    }
+    else
+        free(pFH);
+}
+
+
+/**
+ * Try make room for more handles.
+ *
+ * @returns 0 on success.
+ * @returns OS/2 error code on failure.
+ * @param   cMin    Minimum number for the new max handle count.
+ * @remark  Lock must be owned upon entry!
+ */
+static int __libc_fhMoreHandles(unsigned cMin)
+{
+    int     rc;
+    ULONG   cNewMaxFHs = gcFHs;
+    LONG    lDeltaFHs;
+    FS_VAR();
+
+    /*
+     * How many handles?
+     * Now, we must be somewhat sensibel about incrementing this number
+     * into unreasonable values. If an application requires 10000+ files
+     * it must take steps to tell that to OS/2. If he has we'll receive
+     * cMin > 10000, else keep 10000 as a max limit for auto increase.
+     */
+    lDeltaFHs = 0;
+    cNewMaxFHs = 0;
+    FS_SAVE_LOAD();
+    if (    DosSetRelMaxFH(&lDeltaFHs, &cNewMaxFHs)
+        ||  cNewMaxFHs < gcFHs)
+        cNewMaxFHs = gcFHs;
+
+    if (cMin < cNewMaxFHs)
+    {   /* auto increment. */
+        cMin = cNewMaxFHs + 100;
+        if (cMin > 10000 && gcFHs > 10000)
+        {
+            FS_RESTORE();
+            return ERROR_TOO_MANY_OPEN_FILES;
+        }
+    }
+    lDeltaFHs = cMin - cNewMaxFHs;
+
+    /*
+     * Now to the actual increment.
+     * cMax will at this point hold the disired new max file handle count.
+     * Only we must take precautions in case someone have secretly done
+     * this without our knowledge.
+     */
+    rc = DosSetRelMaxFH(&lDeltaFHs, &cNewMaxFHs);
+    if (!rc && cMin > cNewMaxFHs)
+        rc = DosSetMaxFH((cNewMaxFHs = cMin));
+    FS_RESTORE();
+    if (!rc)
+    {
+
+        /*
+         * Reallocate the array of handle pointers.
+         */
+        PLIBCFH * papNewFHs = _hrealloc(gpapFHs, cNewMaxFHs * sizeof(gpapFHs[0]));
+        if (papNewFHs)
+        {
+            gpapFHs = papNewFHs;
+            memset(&gpapFHs[gcFHs], 0, (cNewMaxFHs - gcFHs) * sizeof(gpapFHs[0]));
+            gcFHs = cNewMaxFHs;
+        }
+    }
+
+    return rc;
+}
+
+
+/**
+ * Ensures space for the given handle.
+ *
+ * @returns 0 on success.
+ * @returns OS/2 error code on failure.
+ * @param   fh      Filehandle which must fit.
+ */
+int __libc_FHEnsureHandles(int fh)
+{
+    int rc;
+    if (fh < (int)gcFHs)
+    {
+        /*
+         * This holds as long as no fool have been changing the max FH
+         * outside our control. And if someone does, they have themselves
+         * to blame for any traps in DosDupHandle().
+         */
+        return 0;
+    }
+
+    if (_fmutex_request(&gmtx, 0))
+        return -1;
+
+    rc = __libc_fhMoreHandles(fh + 1);
+
+    _fmutex_release(&gmtx);
+    return rc;
+}
+
+
+
+
+
+/**
+ * Allocates a file handle.
+ *
+ * @returns 0 on success.
+ * @returns OS/2 error code and errno set to the corresponding error number.
+ * @param   fh      Number of the filehandle to allocate.
+ *                  Will fail if the handle is in use.
+ *                  Use -1 for any handle.
+ * @param   fFlags  Initial flags.
+ * @param   cb      Size of the file handle.
+ *                  Must not be less than the mandatory size (sizeof(LIBCFH)).
+ * @param   pOps    Value of the pOps field, NULL not allowed.
+ * @param   ppFH    Where to store the allocated file handle struct pointer. (NULL allowed)
+ * @param   pfh     Where to store the number of the filehandle allocated.
+ * @remark  The preallocated handles make this function somewhat big and messy.
+ */
+int __libc_FHAllocate(int fh, unsigned fFlags, int cb, PLIBCFHOPS pOps, PLIBCFH *ppFH, int *pfh)
+{
+    PLIBCFH     pFH;
+    int         rc;
+    FS_VAR();
+
+    /*
+     * If we know we cannot use the preallocated handles it's prefered to
+     * do the allocation outside the mutex.
+     */
+    pFH = NULL;
+    if (cb > sizeof(LIBCFH) || !gcPreAllocatedAvail)
+    {
+        pFH = _hmalloc(cb);
+        if (pFH)
+            return ERROR_NOT_ENOUGH_MEMORY;
+    }
+
+    /*
+     * Now take the lock.
+     */
+    if (_fmutex_request(&gmtx, 0))
+        return -1;
+
+    /*
+     * Now is the time to try use the pre allocated handles.
+     */
+    if (!pFH)
+    {
+        if (cb == sizeof(LIBCFH) && gcPreAllocatedAvail)
+        {
+            PLIBCFH pFHSearch;
+            for (pFHSearch = &gaPreAllocated[0];
+                 pFH < &gaPreAllocated[sizeof(gaPreAllocated) / sizeof(gaPreAllocated[0])];
+                 pFHSearch++)
+                if (!pFHSearch->fFlags)
+                {
+                    gcPreAllocatedAvail--;
+                    pFH = pFHSearch;
+                    break;
+                }
+#ifdef DEBUG
+            if (!pFH) __asm__("int $3");
+#endif
+        }
+
+        /*
+         * If the pre allocated handle table for some reason was
+         * full, we'll allocate the handle here.
+         */
+        if (!pFH)
+            pFH = _hmalloc(cb);
+    }
+
+    if (pFH)
+    {
+        /*
+         * Initiate the handle data.
+         */
+        pFH->fFlags     = fFlags;
+        pFH->iLookAhead = -1;
+        pFH->pOps       = pOps;
+
+        /*
+         * Insert into the handle table.
+         */
+        if (fh == -1)
+        {
+            /*
+             * Non OS/2 filehandle.
+             * Open dummy device to find a handle number.
+             */
+#ifdef DEBUG
+            if (!pOps)
+                __asm__("int $3");
+#endif
+            rc = __libc_fhOpenDummy(-1, &fh);
+            if (!rc)
+            {
+                /*
+                 * Enough space in the handle table?
+                 */
+                if (fh >= gcFHs)
+                    rc = __libc_fhMoreHandles(fh + 1);
+                if (!rc)
+                {
+                    /*
+                     * Free any old filehandle which death we didn't catch
+                     * and insert the new one.
+                     */
+                    if (gpapFHs[fh])
+                        __libc_fhFreeHandle(gpapFHs[fh]);
+                    gpapFHs[fh] = pFH;
+                }
+                else
+                {
+                    /* failure: close dummy */
+                    FS_SAVE_LOAD();
+                    DosClose((HFILE)fh);
+                    FS_RESTORE();
+                    fh = -1;
+                }
+            }
+        }
+        else
+        {
+            /*
+             * Special handle.
+             * Make sure there are enough file handles available.
+             */
+            rc = 0;
+            if (fh >= gcFHs)
+                rc = __libc_fhMoreHandles(fh + 1);
+
+            if (!rc)
+            {
+                /*
+                 * If not OS/2 filehandle, we have to make a fake handle.
+                 */
+                if (pOps)
+                    rc = __libc_fhOpenDummy(-1, &fh);
+
+                if (!rc)
+                {
+                    /*
+                     * Free any old filehandle which death we didn't catch
+                     * and insert the new one.
+                     */
+                    if (gpapFHs[fh])
+                        __libc_fhFreeHandle(gpapFHs[fh]);
+                    gpapFHs[fh] = pFH;
+                }
+            }
+        }
+    }
+    else
+        rc = ERROR_NOT_ENOUGH_MEMORY;
+
+    /*
+     * On failure cleanup any mess!
+     */
+    if (rc)
+    {
+        _sys_set_errno(rc);
+        if (pFH)
+            __libc_fhFreeHandle(pFH);
+        pFH = NULL;
+        fh = -1;
+    }
+
+    /*
+     * Return.
+     */
+    if (ppFH)
+        *ppFH = pFH;
+    if (pfh)
+        *pfh = fh;
+
+    _fmutex_release(&gmtx);
+    return rc;
+}
+
+/**
+ * Close (i.e. free) a file handle.
+ *
+ * @returns 0 on success.
+ * @returns OS/2 error code on failure and errno set to corresponding error number.
+ * @param   fh      Filehandle to close.
+ */
+int __libc_FHClose(int fh)
+{
+    PLIBCFH     pFH;
+    ULONG       rc;
+    FS_VAR();
+
+    if (_fmutex_request(&gmtx, 0))
+        return -1;
+
+    /*
+     * Validate input.
+     */
+    if (    (fh < 0 && fh >= gcFHs)
+        ||  !gpapFHs[fh])
+    {
+        _fmutex_release(&gmtx);
+#ifdef DEBUG
+        __asm__("int $3");
+#endif
+        errno = EBADF;
+        return -1;
+    }
+
+    pFH = gpapFHs[fh];
+
+    /*
+     * If this is an non OS/2 handle, let the subsystem clean it up first.
+     */
+    rc = 0;
+    if (pFH->pOps && pFH->pOps->pfnClose)
+        rc = pFH->pOps->pfnClose(pFH, fh);
+
+    /*
+     * We should continue closing the OS/2 handle if the previuos step
+     * were successful or if the handle has become invalid.
+     */
+    if (!rc || rc == ERROR_INVALID_HANDLE)
+    {
+        int rc2;
+        /*
+         * Close the OS/2 handle and remove the handle from the array
+         * making the space available to others.
+         * - This ain't the way which scales best, but it's the safe way.
+         */
+        FS_SAVE_LOAD();
+        rc2 = DosClose(fh);
+        FS_RESTORE();
+        if (!pFH->pOps)
+            rc = rc2;
+#ifdef DEBUG
+        else if (rc2) __asm__("int $3");
+#endif
+
+        /*
+         * If we successfully freed the handle, or it had become invalid
+         * we will free it now.
+         */
+        if (!rc || rc == ERROR_INVALID_HANDLE)
+        {
+            gpapFHs[fh] = NULL;
+            __libc_fhFreeHandle(pFH);
+        }
+    }
+
+    _fmutex_release(&gmtx);
+
+    if (rc)
+        _sys_set_errno(rc);
+
+    return rc;
+}
+
+
+/**
+ * Get the LIBC handle structure corresponding to a filehandle.
+ *
+ * @returns Pointer to handle structure on success.
+ * @returns NULL on failure.
+ * @param   fh  Handle to lookup.
+ */
+PLIBCFH __libc_FH(int fh)
+{
+    PLIBCFH pFH = NULL;
+
+    /** @todo shared access */
+    if (!_fmutex_request(&gmtx, 0))
+    {
+        if (fh >= 0 && fh < gcFHs)
+        {
+            pFH = gpapFHs[fh];
+            if (!pFH)
+            {
+                /*
+                 * Try import the handle.
+                 */
+                ULONG       rc;
+                ULONG       fulType;
+                ULONG       fulDevFlags;
+                ULONG       fulMode;
+                unsigned    fLibc;
+
+                /*
+                 * Is it in use and if so what kind of handle?
+                 */
+                if (    (rc = DosQueryHType((HFILE)fh, &fulType, &fulDevFlags)) != NO_ERROR
+                    ||  (rc = DosQueryFHState((HFILE)fh, &fulMode)) != NO_ERROR)
+                {
+                    errno = EBADF;
+                    _fmutex_release(&gmtx);
+                    return NULL;
+                }
+
+                /*
+                 * Determin initial flags.
+                 */
+                switch (fulType & 0xff)
+                {
+                    default: /* paranoia */
+                    case HANDTYPE_FILE:
+                        fLibc = F_FILE;
+                        break;
+                    case HANDTYPE_DEVICE:
+                        fLibc = F_DEV;
+                        /* @todo inherit O_NDELAY */
+                        break;
+                    case HANDTYPE_PIPE:
+                        fLibc = F_PIPE;
+                        break;
+                }
+
+                /*
+                 * Read write flags.
+                 */
+                switch (fulMode & (OPEN_ACCESS_READONLY | OPEN_ACCESS_WRITEONLY | OPEN_ACCESS_READWRITE))
+                {
+                    case OPEN_ACCESS_READONLY:      fLibc |= O_RDONLY; break;
+                    case OPEN_ACCESS_WRITEONLY:     fLibc |= O_WRONLY; break;
+                    default: /* paranoia */
+                    case OPEN_ACCESS_READWRITE:     fLibc |= O_RDWR; break;
+                }
+
+                /*
+                 * Textflag.
+                 */
+                extern int _fmode_bin;
+                if (!_fmode_bin)
+                    fLibc |= O_TEXT;
+
+
+                /*
+                 * Allocate a new handle for this filehandle.
+                 */
+                rc = __libc_FHAllocate(fh, fLibc, sizeof(LIBCFH), NULL, &pFH, NULL);
+                if (rc)
+                    pFH = NULL;
+            }
+        }
+
+        _fmutex_release(&gmtx);
+    }
+
+    return pFH;
+}
+
Index: trunk/src/emx/src/lib/sys/syscalls.h
===================================================================
--- trunk/src/emx/src/lib/sys/syscalls.h	(revision 870)
+++ trunk/src/emx/src/lib/sys/syscalls.h	(revision 871)
@@ -186,5 +186,5 @@
 
 
-/** @group Init functions
+/** @group Init Functions
  * @{ */
 extern void             __init(int fDefaultHeapInHighMem);
@@ -193,3 +193,10 @@
 extern int              _sys_init_environ(const char *pszEnv);
 extern void             _sys_init_largefileio(void);
-/** @} */
+extern int              _sys_init_filehandles(void);
+/** @} */
+
+/** @group Term Functions
+ * @{ */
+extern int              _sys_term_filehandles(void);
+/** @} */
+
Index: trunk/src/emx/version.smak
===================================================================
--- trunk/src/emx/version.smak	(revision 870)
+++ trunk/src/emx/version.smak	(revision 871)
@@ -4,7 +4,7 @@
 VH = 0
 # Middle part of version number
-VM = 4
+VM = 5
 # Low part of version number
-VL = 1
+VL = 0
 
 # The name of this package
