Changeset 892


Ignore:
Timestamp:
Dec 11, 2003, 2:30:25 AM (22 years ago)
Author:
bird
Message:

#697: select() & bugfixing.

Location:
trunk/src/emx
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/emx/include/emx/io.h

    • Property cvs2svn:cvs-rev changed from 1.6 to 1.7
    r891 r892  
    289289     */
    290290    int (*pfnIOControl)(struct __libc_FileHandle *pFH, int fh, int iIOControl, int iArg, int *prc);
     291    /** Select operation.
     292     * The select operation is only performed if all handles have the same
     293     * select routine (the main worker checks this).
     294     *
     295     * @returns 0 on success.
     296     * @returns OS/2 error code or negated errno on failure.
     297     * @param   cFHs        Range of handles to be tested.
     298     * @param   pRead       Bitmap for file handles to wait upon to become ready for reading.
     299     * @param   pWrite      Bitmap for file handles to wait upon to become ready for writing.
     300     * @param   pExcept     Bitmap of file handles to wait on (error) exceptions from.
     301     * @param   tv          Timeout value.
     302     * @param   prc         Where to store the value which upon success is
     303     *                      returned to the caller.
     304     */
     305    int (*pfnSelect)(int cFHs, struct fd_set *pRead, struct fd_set *pWrite, struct fd_set *pExcept, struct timeval *tv, int *prc);
    291306
    292307} LIBCFHOPS, *PLIBCFHOPS/*, const * PCLIBCFHOPS*/;
  • trunk/src/emx/include/emx/syscalls.h

    • Property cvs2svn:cvs-rev changed from 1.7 to 1.8
    r891 r892  
    196196void *__sbrk (int incr);
    197197void __scrsize (int *dst);
    198 int __select (struct _select *args);
     198int __select(int nfds, struct fd_set *readfds, struct fd_set *writefds,
     199             struct fd_set *exceptfds, struct timeval *tv);
    199200int __send (int handle, __const__ void *buf, int len, unsigned flags);
    200201int __sendto (__const__ struct _sendto *args);
  • trunk/src/emx/src/lib/io/select.c

    • Property cvs2svn:cvs-rev changed from 1.6 to 1.7
    r891 r892  
    1 /* select.c (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes */
     1/* $Id: $ */
     2/** @file
     3 *
     4 * select().
     5 *
     6 * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
     7 *
     8 *
     9 * This file is part of Innotek LIBC.
     10 *
     11 * Innotek LIBC is free software; you can redistribute it and/or modify
     12 * it under the terms of the GNU Lesser General Public License as published
     13 * by the Free Software Foundation; either version 2 of the License, or
     14 * (at your option) any later version.
     15 *
     16 * Innotek LIBC is distributed in the hope that it will be useful,
     17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     19 * GNU Lesser General Public License for more details.
     20 *
     21 * You should have received a copy of the GNU Lesser General Public License
     22 * along with Innotek LIBC; if not, write to the Free Software
     23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     24 *
     25 */
    226
    327#include "libc-alias.h"
    4 #include <stdlib.h>
    5 #include <memory.h>
    6 #include <io.h>
    7 #include <sys/types.h>
    8 #include <sys/time.h>
    9 #include <emx/io.h>
    1028#include <emx/syscalls.h>
    1129
    12 int _STD(select) (int nfds, fd_set *readfds, fd_set *writefds,
    13                   fd_set *exceptfds, struct timeval *timeout)
     30int _STD(select)(int nfds, fd_set *readfds, fd_set *writefds,
     31                 fd_set *exceptfds, struct timeval *tv)
    1432{
    15 /** @todo rewrite select */
    16   struct _select args = {0,0,0,0,0};
    17 #if 0
    18   args.nfds = nfds;
    19   args.readfds = readfds;
    20   args.writefds = writefds;
    21   args.exceptfds = exceptfds;
    22   args.timeout = timeout;
    23   if (readfds != NULL)
    24     {
    25       fd_set *tmp;
    26       struct timeval tv;
    27       int i, j, k, n, nb, nw, rc;
    28       struct fdvec *pv;
    29 
    30       nw = (nfds + 31) / 32;
    31       if (nw < 256 / 32)
    32         nw = 256 / 32;
    33       nb = nw * 4;
    34       tmp = alloca (nb);
    35       memset (tmp, 0, nb);
    36       j = 0; n = 0; pv = &_fdvec_head;
    37       while (n < nfds && pv != NULL)
    38         {
    39           k = nfds - n;
    40           if (pv->n < k) k = pv->n;
    41           for (i = 0; i < k; ++i, ++n)
    42             if (pv->lookahead[i] >= 0 && FD_ISSET (n, readfds))
    43               {
    44                 FD_SET (n, tmp); /* handles ready due to look ahead */
    45                 ++j;
    46               }
    47           pv = pv->next;
    48         }
    49       if (j != 0)                /* there are handles with active look ahead */
    50         {
    51           tv.tv_sec = 0; tv.tv_usec = 0;      /* immediately return */
    52           args.timeout = &tv;
    53           rc = __select (&args);
    54           if (rc == 0)          /* no handles ready -> use look ahead */
    55             {
    56               memcpy (readfds, tmp, nb);
    57               rc = j;
    58             }
    59           else if (rc > 0)      /* merge */
    60             for (i = 0; i < n; ++i)
    61               if (FD_ISSET (i, tmp) && !FD_ISSET (i, readfds))
    62                 {
    63                   FD_SET (i, readfds);
    64                   if (!((writefds != NULL && FD_ISSET (i, writefds))
    65                         || (exceptfds != NULL && FD_ISSET (i, exceptfds))))
    66                     ++rc;
    67                 }
    68           return rc;
    69         }
    70     }
    71 #endif
    72   return __select (&args);
     33    return __select(nfds, readfds, writefds, exceptfds, tv);
    7334}
  • trunk/src/emx/src/lib/socket/socket.imp

    • Property cvs2svn:cvs-rev changed from 1.6 to 1.7
    r891 r892  
    2626__libsocket_soabort     tcpip32   19 ?
    2727os2_sock_errno          tcpip32   20 ?
    28 _os2_sock_errno         tcpip32   20 ?
     28__libsocket_sock_errno  tcpip32   20 ?
    2929__libsocket_recvmsg     tcpip32   21 ?
    3030__libsocket_sendmsg     tcpip32   22 ?
  • trunk/src/emx/src/lib/socket/socket.smak

    • Property cvs2svn:cvs-rev changed from 1.11 to 1.12
    r891 r892  
    3232.TCF    := -I$. -DTCPV40HDRS
    3333.IMPS   := src/lib/socket/socket_tcpipv4.imp
    34 .INSDIR := lib/tcpipv4
     34.INSDIR := lib/tcpipv4/
    3535.TKEEP  := 1
    3636include mkimplib.smak
  • trunk/src/emx/src/lib/socket/socket_tcpipv4.imp

    • Property cvs2svn:cvs-rev changed from 1.5 to 1.6
    r891 r892  
    2626__libsocket_soabort     so32dll   19 ?
    2727os2_sock_errno          so32dll   20 ?
    28 _os2_sock_errno         so32dll   20 ?
     28__libsocket_sock_errno  so32dll   20 ?
    2929__libsocket_recvmsg     so32dll   21 ?
    3030__libsocket_sendmsg     so32dll   22 ?
  • trunk/src/emx/src/lib/socket/socketops.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r891 r892  
    112112static int __libsocket_ops_FileControl(PLIBCFH pFH, int fh, int iIOControl, int iArg, int *prc);
    113113static int __libsocket_ops_IOControl(PLIBCFH pFH, int fh, int iIOControl, int iArg, int *prc);
     114static int __libsocket_ops_Select(int cFHs, struct fd_set *pRead, struct fd_set *pWrite, struct fd_set *pExcept, struct timeval *tv, int *prc);
    114115
    115116
     
    126127    __libsocket_ops_Duplicate,
    127128    __libsocket_ops_FileControl,
    128     __libsocket_ops_IOControl
     129    __libsocket_ops_IOControl,
     130    __libsocket_ops_Select
    129131};
    130132
     
    193195    }
    194196
    195     *pcbWritten = 0;
     197    *pcbWritten = rc;
    196198    return 0;
    197 
    198199}
    199200
     
    532533    return -ENOSYS;
    533534}
     535
     536
     537/** Select operation.
     538 * The select operation is only performed if all handles have the same
     539 * select routine (the main worker checks this).
     540 *
     541 * @returns 0 on success.
     542 * @returns OS/2 error code or negated errno on failure.
     543 * @param   cFHs        Range of handles to be tested.
     544 * @param   pRead       Bitmap for file handles to wait upon to become ready for reading.
     545 * @param   pWrite      Bitmap for file handles to wait upon to become ready for writing.
     546 * @param   pExcept     Bitmap of file handles to wait on (error) exceptions from.
     547 * @param   tv          Timeout value.
     548 * @param   prc         Where to store the value which upon success is
     549 *                      returned to the caller.
     550 */
     551static int __libsocket_ops_Select(int cFHs, struct fd_set *pRead, struct fd_set *pWrite, struct fd_set *pExcept, struct timeval *tv, int *prc)
     552{
     553    int rc;
     554    int saved_errno = errno;
     555    rc = bsdselect(cFHs, pRead, pWrite, pExcept, tv);
     556    *prc = rc;
     557    rc = rc >= 0 ? 0 : -errno;
     558    errno = saved_errno;
     559    return rc;
     560}
     561
  • trunk/src/emx/src/lib/sys/__select.c

    • Property cvs2svn:cvs-rev changed from 1.3 to 1.4
    r891 r892  
     1/* $Id$ */
     2/** @file
     3 *
     4 * __select().
     5 *
     6 * Copyright (c) 2003 knut st. osmundsen <bird-srcspam@anduin.net>
     7 *
     8 *
     9 * This file is part of Innotek LIBC.
     10 *
     11 * Innotek LIBC is free software; you can redistribute it and/or modify
     12 * it under the terms of the GNU Lesser General Public License as published
     13 * by the Free Software Foundation; either version 2 of the License, or
     14 * (at your option) any later version.
     15 *
     16 * Innotek LIBC is distributed in the hope that it will be useful,
     17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     19 * GNU Lesser General Public License for more details.
     20 *
     21 * You should have received a copy of the GNU Lesser General Public License
     22 * along with Innotek LIBC; if not, write to the Free Software
     23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     24 *
     25 */
     26
    127#include "libc-alias.h"
     28#define INCL_FSMACROS
     29#define INCL_DOSPROCESS
     30#include <os2emx.h>
    231#include <stdlib.h>
     32#include <string.h>
     33#include <errno.h>
     34#include <sys/time.h>
     35#include <sys/select.h>
     36#include <emx/io.h>
    337#include <emx/syscalls.h>
     38#include "syscalls.h"
    439
    5 int __select (struct _select *args)
     40int __select(int nfds, struct fd_set *readfds, struct fd_set *writefds,
     41             struct fd_set *exceptfds, struct timeval *tv)
    642{
    7   (void)args;
    8   perror ("select() not implemented");
    9   return 0;
     43    struct fd_set  *pLookAhead = NULL;
     44    int             cLookAhead = 0;
     45    int   (*pfnSelect)(int cFHs, struct fd_set *pRead, struct fd_set *pWrite, struct fd_set *pExcept, struct timeval *tv, int *prc)
     46        = NULL;
     47    int rc;
     48    int rc2 = -1;
     49    int i;
     50
     51    /*
     52     * Iterate thru the bitmaps checking the handles.
     53     */
     54    for (i = 0; i < nfds; i++)
     55    {
     56        if (    (readfds   && FD_ISSET(i, readfds))
     57            ||  (writefds  && FD_ISSET(i, writefds))
     58            ||  (exceptfds && FD_ISSET(i, exceptfds)))
     59        {
     60            PLIBCFH pFH = __libc_FH(i);
     61            if (!pFH)
     62            {
     63                errno = EBADF;
     64                return -1;
     65            }
     66
     67            /*
     68             * We don't like OS/2 handles, nor handles with differnet select routines.
     69             */
     70            if (    !pFH->pOps
     71                ||  (pfnSelect && pFH->pOps->pfnSelect != pfnSelect))
     72            {
     73                errno = EINVAL;
     74                return -1;
     75            }
     76            if (!pfnSelect)
     77                pfnSelect = pFH->pOps->pfnSelect;
     78
     79            /*
     80             * Check lookahead.
     81             */
     82            if (pFH->iLookAhead >= 0 && readfds)
     83            {
     84                if (!pLookAhead)
     85                {
     86                    /* allocate set. */
     87                    int cb = (nfds + 31) / 8;
     88                    pLookAhead = alloca(cb);
     89                    if (!pLookAhead)
     90                    {
     91                        errno = ENOMEM;
     92                        return -1;
     93                    }
     94                    memset(pLookAhead, 0, cb);
     95                }
     96                FD_SET(i, pLookAhead);
     97                cLookAhead++;
     98            }
     99        }
     100    }
     101
     102    if (pLookAhead)
     103    {
     104        /*
     105         * Do a select an merge the ready lookahead stuff with
     106         * the result.
     107         */
     108        struct timeval  tvzero = {0,0};
     109        rc = pfnSelect(nfds, readfds, writefds, exceptfds, &tvzero, &rc2);
     110        if (!rc)
     111        {
     112            if (rc2 > 0)
     113            {   /* merge */
     114                for (i = 0; i < nfds; i++)
     115                {
     116                    if (    FD_ISSET(i, pLookAhead)
     117                        && !FD_ISSET(i, readfds))
     118                    {
     119                        if (    (!writefds  || !FD_ISSET(i, writefds))
     120                            &&  (!exceptfds || !FD_ISSET(i, exceptfds)))
     121                            rc++;
     122                        FD_SET(i, readfds);
     123                    }
     124                }
     125            }
     126            else if (rc2 == 0)
     127            {   /* copy */
     128                memcpy(readfds, pLookAhead, (nfds + 7) / 8);
     129                rc = cLookAhead;
     130            }
     131        }
     132    }
     133    else if (pfnSelect)
     134    {
     135        /*
     136         * Do a straight select.
     137         */
     138        rc = pfnSelect(nfds, readfds, writefds, exceptfds, tv, &rc2);
     139    }
     140    else if (tv)
     141    {
     142        FS_VAR();
     143        /* wait for the given amount of time. */
     144        rc2 = rc = 0;
     145        FS_SAVE_LOAD();
     146        DosSleep(tv->tv_sec * 1000 + tv->tv_usec / 1000);
     147        FS_RESTORE();
     148    }
     149    else
     150    {
     151        /* @todo check specs!!! */
     152        errno = EINVAL;
     153        return -1;
     154    }
     155
     156
     157    /* set errno */
     158    if (rc)
     159    {
     160        if (rc > 0)
     161            _sys_set_errno(rc);
     162        else
     163            errno = -rc;
     164    }
     165
     166    return rc2;
    10167}
  • trunk/src/emx/src/lib/sys/filehandles.c

    • Property cvs2svn:cvs-rev changed from 1.2 to 1.3
    r891 r892  
    438438    {
    439439        pFH = _hmalloc(cb);
    440         if (pFH)
     440        if (!pFH)
    441441            return ERROR_NOT_ENOUGH_MEMORY;
    442442    }
  • trunk/src/emx/src/libsocket/socket.imp

    • Property cvs2svn:cvs-rev changed from 1.6 to 1.7
    r891 r892  
    2626__libsocket_soabort     tcpip32   19 ?
    2727os2_sock_errno          tcpip32   20 ?
    28 _os2_sock_errno         tcpip32   20 ?
     28__libsocket_sock_errno  tcpip32   20 ?
    2929__libsocket_recvmsg     tcpip32   21 ?
    3030__libsocket_sendmsg     tcpip32   22 ?
  • trunk/src/emx/src/libsocket/socket.smak

    • Property cvs2svn:cvs-rev changed from 1.11 to 1.12
    r891 r892  
    3232.TCF    := -I$. -DTCPV40HDRS
    3333.IMPS   := src/lib/socket/socket_tcpipv4.imp
    34 .INSDIR := lib/tcpipv4
     34.INSDIR := lib/tcpipv4/
    3535.TKEEP  := 1
    3636include mkimplib.smak
  • trunk/src/emx/src/libsocket/socket_tcpipv4.imp

    • Property cvs2svn:cvs-rev changed from 1.5 to 1.6
    r891 r892  
    2626__libsocket_soabort     so32dll   19 ?
    2727os2_sock_errno          so32dll   20 ?
    28 _os2_sock_errno         so32dll   20 ?
     28__libsocket_sock_errno  so32dll   20 ?
    2929__libsocket_recvmsg     so32dll   21 ?
    3030__libsocket_sendmsg     so32dll   22 ?
  • trunk/src/emx/src/libsocket/socketops.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r891 r892  
    112112static int __libsocket_ops_FileControl(PLIBCFH pFH, int fh, int iIOControl, int iArg, int *prc);
    113113static int __libsocket_ops_IOControl(PLIBCFH pFH, int fh, int iIOControl, int iArg, int *prc);
     114static int __libsocket_ops_Select(int cFHs, struct fd_set *pRead, struct fd_set *pWrite, struct fd_set *pExcept, struct timeval *tv, int *prc);
    114115
    115116
     
    126127    __libsocket_ops_Duplicate,
    127128    __libsocket_ops_FileControl,
    128     __libsocket_ops_IOControl
     129    __libsocket_ops_IOControl,
     130    __libsocket_ops_Select
    129131};
    130132
     
    193195    }
    194196
    195     *pcbWritten = 0;
     197    *pcbWritten = rc;
    196198    return 0;
    197 
    198199}
    199200
     
    532533    return -ENOSYS;
    533534}
     535
     536
     537/** Select operation.
     538 * The select operation is only performed if all handles have the same
     539 * select routine (the main worker checks this).
     540 *
     541 * @returns 0 on success.
     542 * @returns OS/2 error code or negated errno on failure.
     543 * @param   cFHs        Range of handles to be tested.
     544 * @param   pRead       Bitmap for file handles to wait upon to become ready for reading.
     545 * @param   pWrite      Bitmap for file handles to wait upon to become ready for writing.
     546 * @param   pExcept     Bitmap of file handles to wait on (error) exceptions from.
     547 * @param   tv          Timeout value.
     548 * @param   prc         Where to store the value which upon success is
     549 *                      returned to the caller.
     550 */
     551static int __libsocket_ops_Select(int cFHs, struct fd_set *pRead, struct fd_set *pWrite, struct fd_set *pExcept, struct timeval *tv, int *prc)
     552{
     553    int rc;
     554    int saved_errno = errno;
     555    rc = bsdselect(cFHs, pRead, pWrite, pExcept, tv);
     556    *prc = rc;
     557    rc = rc >= 0 ? 0 : -errno;
     558    errno = saved_errno;
     559    return rc;
     560}
     561
Note: See TracChangeset for help on using the changeset viewer.