Changeset 1824


Ignore:
Timestamp:
Mar 13, 2005, 11:44:52 AM (20 years ago)
Author:
bird
Message:

Applied half a patch from Lorne. Implemented socket duplication.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/emx/src/lib/sys/tcpipver.c

    • Property cvs2svn:cvs-rev changed from 1.10 to 1.11
    r1823 r1824  
    88 *
    99 *
    10  * Copyright (c) 2004 knut st. osmundsen <bird-srcspam@anduin.net>
     10 * Copyright (c) 2004-2005 knut st. osmundsen <bird-srcspam@anduin.net>
    1111 *
    1212 *
     
    6666#include <InnoTekLIBC/tcpip.h>
    6767#include <InnoTekLIBC/fork.h>
     68#include <InnoTekLIBC/thread.h>
    6869#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SOCKET
    6970#include <InnoTekLIBC/logstrict.h>
     
    9596#ifdef TCPV40HDRS
    9697/* not included in the TCPV40HDRS - this is from the BSD4.4 stack headers
    97                                     and doesn't have to right!!! */
     98                                    and doesn't have to be right!!! */
    9899struct arpreq_tr {
    99100        struct  sockaddr arp_pa;                /* protocol address */
     
    159160static int TCPNAME(imp_recv)(int, void *, int, int);
    160161static int TCPNAME(imp_send)(int, const void *, int, int);
    161 static int TCPNAME(imp_removesocketfromlist)(int);
    162 static int TCPNAME(imp_addsockettolist)(int);
     162static _Bool TCPNAME(imp_removesocketfromlist)(int);
     163static void TCPNAME(imp_addsockettolist)(int);
    163164#ifdef TCPV40HDRS
    164165static int TCPNAME(imp_bsdselect)(int, fd_set *, fd_set *, fd_set *, struct timeval *);
     
    215216     */
    216217    rc = __libc_spmSocketDeref(pSocketFH->iSocket);
    217     if (!rc)
    218     {
     218    if (rc < 0)
     219        rc = rc; /* error */
     220    else if (!rc)
     221    {
     222        /*
     223         * Noone is using the socket now, close it.
     224         */
    219225        rc = TCPNAME(imp_soclose)(pSocketFH->iSocket);
    220226        if (rc)
     
    229235        }
    230236    }
    231     else if (rc > 0)
    232     {
    233         /** @todo socket duplication within the same process! A per process reference counting is required too! */
    234 
     237    else if (rc >> 16) /* (high word is process reference count) */
     238        /* The socket is duplicated within the current process, it will be close later when the other handle(s) is(/are) closed. */
     239        rc = 0;
     240    else
     241    {
    235242        /*
    236          * Someone is using the socket, we'll remove it from the list of
    237          * sockets owned by this process to prevent it from being closed.
     243         * Someone other process is using the socket, we'll remove it from the list of
     244         * sockets owned by this process to prevent it from being closed on exit. The other process(es)
     245         * will do the closing.
     246         *
     247         * Please note that removesocketfromlist returns a boolean success indicator and proably no errno.
    238248         */
    239249        rc = TCPNAME(imp_removesocketfromlist)(pSocketFH->iSocket);
    240         if (rc < 1) /** @todo investigate removesocketfromlist return code. */
    241         {
    242             LIBC_ASSERTM_FAILED("removesocketfromlist(%d) -> rc=%d sock_errno()->%d\n", pSocketFH->iSocket, rc, TCPNAME(imp_sock_errno)());
    243             rc = -__libc_TcpipGetSocketErrno();
    244         }
    245     }
    246     else
    247         rc = -EBADF;
     250        if (!rc)
     251        {
     252            LIBC_ASSERTM_FAILED("removesocketfromlist(%d) -> false! sock_errno()->%d\n", pSocketFH->iSocket, TCPNAME(imp_sock_errno)());
     253            rc = -EBADF; /* this is an internal error, it should *NOT* happen! */
     254        }
     255    }
    248256
    249257    /*
     
    281289    PLIBCSOCKETFH   pSocketFH = (PLIBCSOCKETFH)pFH;
    282290    int             rc;
    283 
    284     rc = TCPNAME(imp_recv)(pSocketFH->iSocket, pvBuf, cbRead, 0);
     291    int             fFlags = 0;
     292#if 0 /* doesn't work for 4.3 */
     293    if (pFH->fFlags & O_NONBLOCK)
     294        fFlags = MSG_DONTWAIT;
     295#endif
     296    rc = TCPNAME(imp_recv)(pSocketFH->iSocket, pvBuf, cbRead, fFlags);
    285297    if (rc < 0)
    286298    {
     
    309321    PLIBCSOCKETFH   pSocketFH = (PLIBCSOCKETFH)pFH;
    310322    int             rc;
    311 
    312     rc = TCPNAME(imp_send)(pSocketFH->iSocket, pvBuf, cbWrite, 0);
     323    int             fFlags = 0;
     324#if 0 /* doesn't work for 4.3 */
     325    if (pFH->fFlags & O_NONBLOCK)
     326        fFlags = MSG_DONTWAIT;
     327#endif
     328    rc = TCPNAME(imp_send)(pSocketFH->iSocket, pvBuf, cbWrite, fFlags);
    313329    if (rc < 0)
    314330    {
     
    336352static int TCPNAME(ops_Duplicate)(PLIBCFH pFH, int fh, int *pfhNew)
    337353{
    338     LIBCLOG_ENTER("pFH=%p:{iSocket=%d} fh=%d pfhNew=%p\n", (void *)pFH, ((PLIBCSOCKETFH)pFH)->iSocket, fh, (void *)pfhNew);
    339     LIBC_ASSERTM_FAILED("Duplication of sockets aren't supported yet.\n");
    340     /** @todo In order to properly support this we need to have per process reference counting
    341      * of the sockets too. This should be done in a high heap block and done on allocation to
    342      * get the exec/spaw inheritance right. */
    343     LIBCLOG_RETURN_INT(-ENOSYS);
     354    PLIBCSOCKETFH  pFHSocket = (PLIBCSOCKETFH)pFH;
     355    LIBCLOG_ENTER("pFH=%p:{iSocket=%d} fh=%d pfhNew=%p\n", (void *)pFH, pFHSocket->iSocket, fh, (void *)pfhNew);
     356
     357    /*
     358     * Allocate a new filehandle matching the request and copy the data over.
     359     */
     360    PLIBCSOCKETFH  pFHNew;
     361    int rc = TCPNAMEG(AllocFHEx)(*pfhNew, pFHSocket->iSocket, O_RDWR | F_SOCKET, 0/*old*/, pfhNew, &pFHNew);
     362    if (!rc)
     363    {
     364        pFHNew->core.fFlags      = pFHSocket->core.fFlags;
     365        pFHNew->core.iLookAhead  = pFHSocket->core.iLookAhead;
     366        pFHNew->core.Inode       = pFHSocket->core.Inode;
     367        pFHNew->core.Dev         = pFHSocket->core.Dev;
     368        LIBCLOG_RETURN_MSG(0, "ret 0 (0x0) *pfhNew=%d\n", *pfhNew);
     369    }
     370
     371    LIBCLOG_RETURN_INT(rc);
    344372}
    345373
     
    385413        {
    386414            /** @todo implement this properly. See FCNTLFLAGS. */
     415#if 1
    387416            LIBC_ASSERTM_FAILED("F_SETFL isn't implemented but returns success. arg=%#x\n", iArg);
    388417            *prc = 0;
     418#else
     419            pFH->fFlags= pFH->fFlags & ~(O_ACCMODE | O_APPEND | O_NONBLOCK | O_SYNC);
     420            pFH->fFlags= pFH->fFlags | fFlags;
     421            LIBCLOG_MSG("F_SETFL is implemented only partially but returns success. arg=%#x\n", pFH->fFlags);
     422            *prc = fFlags;
     423#endif
    389424            break;
    390425        }
     
    775810    PLIBCSOCKETFH   pSocketFH = (PLIBCSOCKETFH)pFH;
    776811    int rc = __libc_spmSocketRef(pSocketFH->iSocket);
    777     LIBC_ASSERTM(rc > 0, "__libc_spmSocketDeref(%d) -> rc=%d\n", pSocketFH->iSocket, rc);
     812    LIBC_ASSERTM(rc > 0, "__libc_spmSocketRef(%d) -> rc=%d\n", pSocketFH->iSocket, rc);
     813    if ((rc >> 16) == 1)
     814        TCPNAME(imp_addsockettolist)(pSocketFH->iSocket);
    778815    LIBCLOG_RETURN_INT(0);
    779816    rc = rc;
     
    795832{
    796833    LIBCLOG_ENTER("iSocket=%d\n", iSocket);
    797     PLIBCSOCKETFH pFH = TCPNAMEG(AllocFHEx)(-1, iSocket, O_RDWR | F_SOCKET, 1, pfh);
    798     LIBCLOG_RETURN_P(pFH);
     834    PLIBCSOCKETFH pFH;
     835    int rc = TCPNAMEG(AllocFHEx)(-1, iSocket, O_RDWR | F_SOCKET, 1, pfh, &pFH);
     836    if (!rc)
     837        LIBCLOG_RETURN_P(pFH);
     838    errno = -rc;
     839    return NULL;
    799840}
    800841
     
    807848 * processor where such actions are unnecessary.
    808849 *
    809  * @returns Pointer to socket handle on success.
    810  * @returns NULL and errno on failure.
     850 * @returns 0 on success.
     851 * @returns Negative error code (errno.h) on failure.
    811852 * @param   fh          The requested file handle.
    812853 *                      If -1 any file handle can be used.
     
    818859 *                      If clear we only increment the global reference counter.
    819860 * @param   pfh         Where to store the filename.
    820  */
    821 PLIBCSOCKETFH TCPNAMEG(AllocFHEx)(int fh, int iSocket, unsigned fFlags, int fNew, int *pfh)
     861 * @param   ppFHSocket  Where to store the allocated socket handle. Optional.
     862 */
     863int TCPNAMEG(AllocFHEx)(int fh, int iSocket, unsigned fFlags, int fNew, int *pfh, PLIBCSOCKETFH *ppFHSocket)
    822864{
    823865    LIBCLOG_ENTER("iSocket=%d\n", iSocket);
     
    856898            rc = __libc_spmSocketRef(iSocket);
    857899            LIBC_ASSERTM(rc > 0, "__libc_spmSocketRef(%d) -> rc=%d\n", iSocket, rc);
    858             rc = TCPNAME(imp_addsockettolist)(iSocket);
    859             LIBC_ASSERTM(!rc, "addsockettolist(%d) -> rc=%d\n", iSocket, rc);
    860         }
    861         LIBCLOG_RETURN_P(pFH);
    862     }
    863     else
    864         __libc_TcpipSetSocketErrno();
    865 
    866     LIBCLOG_RETURN_P(NULL);
     900            if ((rc >> 16) == 1) /* only first reference in this process */
     901                TCPNAME(imp_addsockettolist)(iSocket);
     902        }
     903        if (ppFHSocket)
     904            *ppFHSocket = pFH;
     905        LIBCLOG_RETURN_INT(0);
     906    }
     907    LIBCLOG_RETURN_P(rc);
    867908}
    868909
     
    10671108    LIBCLOG_MSG("calling native: cFDs=%d pRead=%p pWrite=%p, pExcept=%p tv=%p\n",
    10681109                cFDs, (void *)pRead, (void *)pWrite, (void *)pExcept, (void *)tv);
     1110    __LIBC_PTHREAD pThrd = __libc_threadCurrent();
     1111    pThrd->ulSigLastTS = 0;
    10691112    rc = TCPNAME(imp_bsdselect)(cFDs, pRead, pWrite, pExcept, tv);
    10701113    if (rc < 0)
     
    10721115        __libc_TcpipUpdateErrno();
    10731116        LIBCLOG_RETURN_INT(rc);
     1117    }
     1118    else if (!rc && pThrd->ulSigLastTS)      /* detect interruption */
     1119    {
     1120        __libc_TcpipSetErrno(EINTR);
     1121        LIBCLOG_RETURN_INT(-1);
    10741122    }
    10751123
     
    12431291}
    12441292
    1245 static int     TCPNAME(imp_addsockettolist)(int s)
     1293static void     TCPNAME(imp_addsockettolist)(int s)
    12461294{
    12471295    LIBCLOG_ENTER("iSocket=%d\n", s);
    1248     static int (*TCPCALL pfn)(int s);
     1296    static void (*TCPCALL pfn)(int s);
    12491297    if (!pfn && TCPNAME(get_imp)(ORD_ADDSOCKETTOLIST, (void **)(void *)&pfn))
    1250         LIBCLOG_RETURN_INT(-1);
    1251     int rc = pfn(s);
    1252     LIBCLOG_RETURN_INT(rc);
    1253 }
    1254 
    1255 static int     TCPNAME(imp_removesocketfromlist)(int s)
     1298        LIBCLOG_RETURN_VOID();
     1299    pfn(s);
     1300    LIBCLOG_RETURN_VOID();
     1301}
     1302
     1303static _Bool    TCPNAME(imp_removesocketfromlist)(int s)
    12561304{
    12571305    LIBCLOG_ENTER("iSocket=%d\n", s);
    12581306    static int (*TCPCALL pfn)(int s);
    12591307    if (!pfn && TCPNAME(get_imp)(ORD_REMOVESOCKETFROMLIST, (void **)(void *)&pfn))
    1260         LIBCLOG_RETURN_INT(-1);
     1308        LIBCLOG_RETURN_INT(0);
    12611309    int rc = pfn(s);
    1262     LIBCLOG_RETURN_INT(rc);
     1310    LIBCLOG_RETURN_INT(!!rc); /* paranoia!!!! */
    12631311}
    12641312
     
    13151363        int rc = __libc_spmSocketDeref(pFH->iSocket);
    13161364        LIBC_ASSERTM(rc >= 0, "__libc_spmSocketDeref(%d) -> rc=%d\n", pFH->iSocket, rc);
     1365        if (rc < 0)
     1366            rc = 0; /* we'd rather have failures and fix the problem than stale sockets and bugs. */
    13171367        if (!rc)
    13181368        {
     
    13231373            LIBC_ASSERTM(!rc, "soclose(%d) -> rc=%d sock_errno()->%d\n", pFH->iSocket, rc, TCPNAME(imp_sock_errno)());
    13241374        }
     1375        else if (rc >> 16) /* (high word is process reference count) */
     1376            /* The socket is duplicated within the current process, it will be close later when the other handle(s) is(/are) closed. */
     1377            rc = 0;
    13251378        else
    13261379        {
     
    13281381             * If in use by other process, we'll remove it from the list of sockets
    13291382             * owned by this process to prevent it from begin closed.
     1383             *
     1384             * Please note that removesocketfromlist is returning a boolean success indicator and probably no errno.
    13301385             */
    13311386            rc = TCPNAME(imp_removesocketfromlist)(pFH->iSocket);
    1332             LIBC_ASSERTM(rc >= 1, "removesocketfromlist(%d) -> rc=%d sock_errno()->%d\n", pFH->iSocket, rc, TCPNAME(imp_sock_errno)());
     1387            LIBC_ASSERTM(rc == 1, "removesocketfromlist(%d) -> rc=%d sock_errno()->%d\n", pFH->iSocket, rc, TCPNAME(imp_sock_errno)());
    13331388        }
    13341389
Note: See TracChangeset for help on using the changeset viewer.