Index: /trunk/src/emx/include/emx/io.h
===================================================================
--- /trunk/src/emx/include/emx/io.h	(revision 891)
+++ /trunk/src/emx/include/emx/io.h	(revision 892)
@@ -289,4 +289,19 @@
      */
     int (*pfnIOControl)(struct __libc_FileHandle *pFH, int fh, int iIOControl, int iArg, int *prc);
+    /** Select operation.
+     * The select operation is only performed if all handles have the same
+     * select routine (the main worker checks this).
+     *
+     * @returns 0 on success.
+     * @returns OS/2 error code or negated errno on failure.
+     * @param   cFHs        Range of handles to be tested.
+     * @param   pRead       Bitmap for file handles to wait upon to become ready for reading.
+     * @param   pWrite      Bitmap for file handles to wait upon to become ready for writing.
+     * @param   pExcept     Bitmap of file handles to wait on (error) exceptions from.
+     * @param   tv          Timeout value.
+     * @param   prc         Where to store the value which upon success is
+     *                      returned to the caller.
+     */
+    int (*pfnSelect)(int cFHs, struct fd_set *pRead, struct fd_set *pWrite, struct fd_set *pExcept, struct timeval *tv, int *prc);
 
 } LIBCFHOPS, *PLIBCFHOPS/*, const * PCLIBCFHOPS*/;
Index: /trunk/src/emx/include/emx/syscalls.h
===================================================================
--- /trunk/src/emx/include/emx/syscalls.h	(revision 891)
+++ /trunk/src/emx/include/emx/syscalls.h	(revision 892)
@@ -196,5 +196,6 @@
 void *__sbrk (int incr);
 void __scrsize (int *dst);
-int __select (struct _select *args);
+int __select(int nfds, struct fd_set *readfds, struct fd_set *writefds,
+             struct fd_set *exceptfds, struct timeval *tv);
 int __send (int handle, __const__ void *buf, int len, unsigned flags);
 int __sendto (__const__ struct _sendto *args);
Index: /trunk/src/emx/src/lib/io/select.c
===================================================================
--- /trunk/src/emx/src/lib/io/select.c	(revision 891)
+++ /trunk/src/emx/src/lib/io/select.c	(revision 892)
@@ -1,73 +1,34 @@
-/* select.c (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes */
+/* $Id: $ */
+/** @file
+ *
+ * select().
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This file is part of Innotek LIBC.
+ *
+ * Innotek LIBC is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Innotek LIBC is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Innotek LIBC; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
 
 #include "libc-alias.h"
-#include <stdlib.h>
-#include <memory.h>
-#include <io.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <emx/io.h>
 #include <emx/syscalls.h>
 
-int _STD(select) (int nfds, fd_set *readfds, fd_set *writefds,
-                  fd_set *exceptfds, struct timeval *timeout)
+int _STD(select)(int nfds, fd_set *readfds, fd_set *writefds,
+                 fd_set *exceptfds, struct timeval *tv)
 {
-/** @todo rewrite select */
-  struct _select args = {0,0,0,0,0};
-#if 0
-  args.nfds = nfds;
-  args.readfds = readfds;
-  args.writefds = writefds;
-  args.exceptfds = exceptfds;
-  args.timeout = timeout;
-  if (readfds != NULL)
-    {
-      fd_set *tmp;
-      struct timeval tv;
-      int i, j, k, n, nb, nw, rc;
-      struct fdvec *pv;
-
-      nw = (nfds + 31) / 32;
-      if (nw < 256 / 32)
-        nw = 256 / 32;
-      nb = nw * 4;
-      tmp = alloca (nb);
-      memset (tmp, 0, nb);
-      j = 0; n = 0; pv = &_fdvec_head;
-      while (n < nfds && pv != NULL)
-        {
-          k = nfds - n;
-          if (pv->n < k) k = pv->n;
-          for (i = 0; i < k; ++i, ++n)
-            if (pv->lookahead[i] >= 0 && FD_ISSET (n, readfds))
-              {
-                FD_SET (n, tmp); /* handles ready due to look ahead */
-                ++j;
-              }
-          pv = pv->next;
-        }
-      if (j != 0)                /* there are handles with active look ahead */
-        {
-          tv.tv_sec = 0; tv.tv_usec = 0;      /* immediately return */
-          args.timeout = &tv;
-          rc = __select (&args);
-          if (rc == 0)          /* no handles ready -> use look ahead */
-            {
-              memcpy (readfds, tmp, nb);
-              rc = j;
-            }
-          else if (rc > 0)      /* merge */
-            for (i = 0; i < n; ++i)
-              if (FD_ISSET (i, tmp) && !FD_ISSET (i, readfds))
-                {
-                  FD_SET (i, readfds);
-                  if (!((writefds != NULL && FD_ISSET (i, writefds))
-                        || (exceptfds != NULL && FD_ISSET (i, exceptfds))))
-                    ++rc;
-                }
-          return rc;
-        }
-    }
-#endif
-  return __select (&args);
+    return __select(nfds, readfds, writefds, exceptfds, tv);
 }
Index: /trunk/src/emx/src/lib/socket/socket.imp
===================================================================
--- /trunk/src/emx/src/lib/socket/socket.imp	(revision 891)
+++ /trunk/src/emx/src/lib/socket/socket.imp	(revision 892)
@@ -26,5 +26,5 @@
 __libsocket_soabort     tcpip32   19 ?
 os2_sock_errno          tcpip32   20 ?
-_os2_sock_errno         tcpip32   20 ?
+__libsocket_sock_errno  tcpip32   20 ?
 __libsocket_recvmsg     tcpip32   21 ?
 __libsocket_sendmsg     tcpip32   22 ?
Index: /trunk/src/emx/src/lib/socket/socket.smak
===================================================================
--- /trunk/src/emx/src/lib/socket/socket.smak	(revision 891)
+++ /trunk/src/emx/src/lib/socket/socket.smak	(revision 892)
@@ -32,5 +32,5 @@
 .TCF    := -I$. -DTCPV40HDRS
 .IMPS   := src/lib/socket/socket_tcpipv4.imp
-.INSDIR	:= lib/tcpipv4
+.INSDIR	:= lib/tcpipv4/
 .TKEEP	:= 1
 include mkimplib.smak
Index: /trunk/src/emx/src/lib/socket/socket_tcpipv4.imp
===================================================================
--- /trunk/src/emx/src/lib/socket/socket_tcpipv4.imp	(revision 891)
+++ /trunk/src/emx/src/lib/socket/socket_tcpipv4.imp	(revision 892)
@@ -26,5 +26,5 @@
 __libsocket_soabort     so32dll   19 ?
 os2_sock_errno          so32dll   20 ?
-_os2_sock_errno         so32dll   20 ?
+__libsocket_sock_errno  so32dll   20 ?
 __libsocket_recvmsg     so32dll   21 ?
 __libsocket_sendmsg     so32dll   22 ?
Index: /trunk/src/emx/src/lib/socket/socketops.c
===================================================================
--- /trunk/src/emx/src/lib/socket/socketops.c	(revision 891)
+++ /trunk/src/emx/src/lib/socket/socketops.c	(revision 892)
@@ -112,4 +112,5 @@
 static int __libsocket_ops_FileControl(PLIBCFH pFH, int fh, int iIOControl, int iArg, int *prc);
 static int __libsocket_ops_IOControl(PLIBCFH pFH, int fh, int iIOControl, int iArg, int *prc);
+static int __libsocket_ops_Select(int cFHs, struct fd_set *pRead, struct fd_set *pWrite, struct fd_set *pExcept, struct timeval *tv, int *prc);
 
 
@@ -126,5 +127,6 @@
     __libsocket_ops_Duplicate,
     __libsocket_ops_FileControl,
-    __libsocket_ops_IOControl
+    __libsocket_ops_IOControl,
+    __libsocket_ops_Select
 };
 
@@ -193,7 +195,6 @@
     }
 
-    *pcbWritten = 0;
+    *pcbWritten = rc;
     return 0;
-
 }
 
@@ -532,2 +533,29 @@
     return -ENOSYS;
 }
+
+
+/** Select operation.
+ * The select operation is only performed if all handles have the same
+ * select routine (the main worker checks this).
+ *
+ * @returns 0 on success.
+ * @returns OS/2 error code or negated errno on failure.
+ * @param   cFHs        Range of handles to be tested.
+ * @param   pRead       Bitmap for file handles to wait upon to become ready for reading.
+ * @param   pWrite      Bitmap for file handles to wait upon to become ready for writing.
+ * @param   pExcept     Bitmap of file handles to wait on (error) exceptions from.
+ * @param   tv          Timeout value.
+ * @param   prc         Where to store the value which upon success is
+ *                      returned to the caller.
+ */
+static int __libsocket_ops_Select(int cFHs, struct fd_set *pRead, struct fd_set *pWrite, struct fd_set *pExcept, struct timeval *tv, int *prc)
+{
+    int rc;
+    int saved_errno = errno;
+    rc = bsdselect(cFHs, pRead, pWrite, pExcept, tv);
+    *prc = rc;
+    rc = rc >= 0 ? 0 : -errno;
+    errno = saved_errno;
+    return rc;
+}
+
Index: /trunk/src/emx/src/lib/sys/__select.c
===================================================================
--- /trunk/src/emx/src/lib/sys/__select.c	(revision 891)
+++ /trunk/src/emx/src/lib/sys/__select.c	(revision 892)
@@ -1,10 +1,167 @@
+/* $Id$ */
+/** @file
+ *
+ * __select().
+ *
+ * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
+ *
+ *
+ * This file is part of Innotek LIBC.
+ *
+ * Innotek LIBC is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Innotek LIBC is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Innotek LIBC; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
 #include "libc-alias.h"
+#define INCL_FSMACROS
+#define INCL_DOSPROCESS
+#include <os2emx.h>
 #include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/select.h>
+#include <emx/io.h>
 #include <emx/syscalls.h>
+#include "syscalls.h"
 
-int __select (struct _select *args)
+int __select(int nfds, struct fd_set *readfds, struct fd_set *writefds,
+             struct fd_set *exceptfds, struct timeval *tv)
 {
-  (void)args;
-  perror ("select() not implemented");
-  return 0;
+    struct fd_set  *pLookAhead = NULL;
+    int             cLookAhead = 0;
+    int   (*pfnSelect)(int cFHs, struct fd_set *pRead, struct fd_set *pWrite, struct fd_set *pExcept, struct timeval *tv, int *prc)
+        = NULL;
+    int rc;
+    int rc2 = -1;
+    int i;
+
+    /*
+     * Iterate thru the bitmaps checking the handles.
+     */
+    for (i = 0; i < nfds; i++)
+    {
+        if (    (readfds   && FD_ISSET(i, readfds))
+            ||  (writefds  && FD_ISSET(i, writefds))
+            ||  (exceptfds && FD_ISSET(i, exceptfds)))
+        {
+            PLIBCFH pFH = __libc_FH(i);
+            if (!pFH)
+            {
+                errno = EBADF;
+                return -1;
+            }
+
+            /*
+             * We don't like OS/2 handles, nor handles with differnet select routines.
+             */
+            if (    !pFH->pOps
+                ||  (pfnSelect && pFH->pOps->pfnSelect != pfnSelect))
+            {
+                errno = EINVAL;
+                return -1;
+            }
+            if (!pfnSelect)
+                pfnSelect = pFH->pOps->pfnSelect;
+
+            /*
+             * Check lookahead.
+             */
+            if (pFH->iLookAhead >= 0 && readfds)
+            {
+                if (!pLookAhead)
+                {
+                    /* allocate set. */
+                    int cb = (nfds + 31) / 8;
+                    pLookAhead = alloca(cb);
+                    if (!pLookAhead)
+                    {
+                        errno = ENOMEM;
+                        return -1;
+                    }
+                    memset(pLookAhead, 0, cb);
+                }
+                FD_SET(i, pLookAhead);
+                cLookAhead++;
+            }
+        }
+    }
+
+    if (pLookAhead)
+    {
+        /*
+         * Do a select an merge the ready lookahead stuff with
+         * the result.
+         */
+        struct timeval  tvzero = {0,0};
+        rc = pfnSelect(nfds, readfds, writefds, exceptfds, &tvzero, &rc2);
+        if (!rc)
+        {
+            if (rc2 > 0)
+            {   /* merge */
+                for (i = 0; i < nfds; i++)
+                {
+                    if (    FD_ISSET(i, pLookAhead)
+                        && !FD_ISSET(i, readfds))
+                    {
+                        if (    (!writefds  || !FD_ISSET(i, writefds))
+                            &&  (!exceptfds || !FD_ISSET(i, exceptfds)))
+                            rc++;
+                        FD_SET(i, readfds);
+                    }
+                }
+            }
+            else if (rc2 == 0)
+            {   /* copy */
+                memcpy(readfds, pLookAhead, (nfds + 7) / 8);
+                rc = cLookAhead;
+            }
+        }
+    }
+    else if (pfnSelect)
+    {
+        /*
+         * Do a straight select.
+         */
+        rc = pfnSelect(nfds, readfds, writefds, exceptfds, tv, &rc2);
+    }
+    else if (tv)
+    {
+        FS_VAR();
+        /* wait for the given amount of time. */
+        rc2 = rc = 0;
+        FS_SAVE_LOAD();
+        DosSleep(tv->tv_sec * 1000 + tv->tv_usec / 1000);
+        FS_RESTORE();
+    }
+    else
+    {
+        /* @todo check specs!!! */
+        errno = EINVAL;
+        return -1;
+    }
+
+
+    /* set errno */
+    if (rc)
+    {
+        if (rc > 0)
+            _sys_set_errno(rc);
+        else
+            errno = -rc;
+    }
+
+    return rc2;
 }
Index: /trunk/src/emx/src/lib/sys/filehandles.c
===================================================================
--- /trunk/src/emx/src/lib/sys/filehandles.c	(revision 891)
+++ /trunk/src/emx/src/lib/sys/filehandles.c	(revision 892)
@@ -438,5 +438,5 @@
     {
         pFH = _hmalloc(cb);
-        if (pFH)
+        if (!pFH)
             return ERROR_NOT_ENOUGH_MEMORY;
     }
Index: /trunk/src/emx/src/libsocket/socket.imp
===================================================================
--- /trunk/src/emx/src/libsocket/socket.imp	(revision 891)
+++ /trunk/src/emx/src/libsocket/socket.imp	(revision 892)
@@ -26,5 +26,5 @@
 __libsocket_soabort     tcpip32   19 ?
 os2_sock_errno          tcpip32   20 ?
-_os2_sock_errno         tcpip32   20 ?
+__libsocket_sock_errno  tcpip32   20 ?
 __libsocket_recvmsg     tcpip32   21 ?
 __libsocket_sendmsg     tcpip32   22 ?
Index: /trunk/src/emx/src/libsocket/socket.smak
===================================================================
--- /trunk/src/emx/src/libsocket/socket.smak	(revision 891)
+++ /trunk/src/emx/src/libsocket/socket.smak	(revision 892)
@@ -32,5 +32,5 @@
 .TCF    := -I$. -DTCPV40HDRS
 .IMPS   := src/lib/socket/socket_tcpipv4.imp
-.INSDIR	:= lib/tcpipv4
+.INSDIR	:= lib/tcpipv4/
 .TKEEP	:= 1
 include mkimplib.smak
Index: /trunk/src/emx/src/libsocket/socket_tcpipv4.imp
===================================================================
--- /trunk/src/emx/src/libsocket/socket_tcpipv4.imp	(revision 891)
+++ /trunk/src/emx/src/libsocket/socket_tcpipv4.imp	(revision 892)
@@ -26,5 +26,5 @@
 __libsocket_soabort     so32dll   19 ?
 os2_sock_errno          so32dll   20 ?
-_os2_sock_errno         so32dll   20 ?
+__libsocket_sock_errno  so32dll   20 ?
 __libsocket_recvmsg     so32dll   21 ?
 __libsocket_sendmsg     so32dll   22 ?
Index: /trunk/src/emx/src/libsocket/socketops.c
===================================================================
--- /trunk/src/emx/src/libsocket/socketops.c	(revision 891)
+++ /trunk/src/emx/src/libsocket/socketops.c	(revision 892)
@@ -112,4 +112,5 @@
 static int __libsocket_ops_FileControl(PLIBCFH pFH, int fh, int iIOControl, int iArg, int *prc);
 static int __libsocket_ops_IOControl(PLIBCFH pFH, int fh, int iIOControl, int iArg, int *prc);
+static int __libsocket_ops_Select(int cFHs, struct fd_set *pRead, struct fd_set *pWrite, struct fd_set *pExcept, struct timeval *tv, int *prc);
 
 
@@ -126,5 +127,6 @@
     __libsocket_ops_Duplicate,
     __libsocket_ops_FileControl,
-    __libsocket_ops_IOControl
+    __libsocket_ops_IOControl,
+    __libsocket_ops_Select
 };
 
@@ -193,7 +195,6 @@
     }
 
-    *pcbWritten = 0;
+    *pcbWritten = rc;
     return 0;
-
 }
 
@@ -532,2 +533,29 @@
     return -ENOSYS;
 }
+
+
+/** Select operation.
+ * The select operation is only performed if all handles have the same
+ * select routine (the main worker checks this).
+ *
+ * @returns 0 on success.
+ * @returns OS/2 error code or negated errno on failure.
+ * @param   cFHs        Range of handles to be tested.
+ * @param   pRead       Bitmap for file handles to wait upon to become ready for reading.
+ * @param   pWrite      Bitmap for file handles to wait upon to become ready for writing.
+ * @param   pExcept     Bitmap of file handles to wait on (error) exceptions from.
+ * @param   tv          Timeout value.
+ * @param   prc         Where to store the value which upon success is
+ *                      returned to the caller.
+ */
+static int __libsocket_ops_Select(int cFHs, struct fd_set *pRead, struct fd_set *pWrite, struct fd_set *pExcept, struct timeval *tv, int *prc)
+{
+    int rc;
+    int saved_errno = errno;
+    rc = bsdselect(cFHs, pRead, pWrite, pExcept, tv);
+    *prc = rc;
+    rc = rc >= 0 ? 0 : -errno;
+    errno = saved_errno;
+    return rc;
+}
+
