VirtualBox

Ignore:
Timestamp:
Jun 17, 2010 6:56:26 AM (14 years ago)
Author:
vboxsync
Message:

Runtime/tcp+socket: Add function to write to a socket using a scatter/gather buffer

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/socket.cpp

    r28800 r30270  
    4545# include <unistd.h>
    4646# include <fcntl.h>
     47# include <sys/uio.h>
    4748#endif /* !RT_OS_WINDOWS */
    4849#include <limits.h>
     
    5960#include <iprt/thread.h>
    6061#include <iprt/time.h>
     62#include <iprt/mem.h>
     63#include <iprt/sg.h>
    6164
    6265#include "internal/magics.h"
     
    574577
    575578
     579RTDECL(int) RTSocketSgWrite(RTSOCKET hSocket, PCRTSGBUF pSgBuf)
     580{
     581    /*
     582     * Validate input.
     583     */
     584    RTSOCKETINT *pThis = hSocket;
     585    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     586    AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE);
     587    AssertPtrReturn(pSgBuf, VERR_INVALID_PARAMETER);
     588    AssertReturn(pSgBuf->cSeg > 0, VERR_INVALID_PARAMETER);
     589    AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS);
     590
     591    /*
     592     * Construct message descriptor (translate pSgBuf) and send it.
     593     */
     594    int rc = VINF_SUCCESS;
     595    do
     596    {
     597#ifdef RT_OS_WINDOWS
     598        AssertCompileSize(WSABUF, sizeof(RTSGSEG));
     599        AssertCompileMemberSize(WSABUF, buf, RT_SIZEOFMEMB(RTSGSEG, pvSeg));
     600        AssertCompileMemberSize(WSABUF, len, RT_SIZEOFMEMB(RTSGSEG, cbSeg));
     601
     602        LPWSABUF *paMsg = (LPWSABUF)RTMemTmpAllocZ(pSgBuf->cSeg * sizeof(WSABUF));
     603        AssertPtrBreakStmt(paMsg, rc = VERR_NO_MEMORY);
     604        for (unsigned i = 0; i < pSgBuf->cSeg; i++)
     605        {
     606            paMsg[i].buf = pSgBuf->pcaSeg[i].pvSeg;
     607            paMsg[i].len = pSgBuf->pcaSeg[i].cbSeg;
     608        }
     609
     610        WSAMSG msgHdr;
     611        DWORD dwSent;
     612        memset(&msgHdr, '\0', sizeof(msgHdr));
     613        msgHdr.lpBuffers = paMsg;
     614        msgHdr.dwBufferCount = pSgBuf->cSeg;
     615        int hrc = WSASendMsg(pThis->hNative, &msgHdr, MSG_NOSIGNAL, &dwSent,
     616                             NULL, NULL);
     617        ssize_t cbWritten;
     618        if (!hrc)
     619        {
     620            /* avoid overflowing ssize_t, the exact value isn't important */
     621            cbWritten = RT_MIN(dwSent, INT_MAX);
     622        }
     623        else
     624            cbWritten = -1;
     625#else
     626        AssertCompileSize(struct iovec, sizeof(RTSGSEG));
     627        AssertCompileMemberSize(struct iovec, iov_base, RT_SIZEOFMEMB(RTSGSEG, pvSeg));
     628        AssertCompileMemberSize(struct iovec, iov_len, RT_SIZEOFMEMB(RTSGSEG, cbSeg));
     629
     630        struct iovec *paMsg = (struct iovec *)RTMemTmpAllocZ(pSgBuf->cSeg * sizeof(struct iovec));
     631        AssertPtrBreakStmt(paMsg, rc = VERR_NO_MEMORY);
     632        for (unsigned i = 0; i < pSgBuf->cSeg; i++)
     633        {
     634            paMsg[i].iov_base = pSgBuf->pcaSeg[i].pvSeg;
     635            paMsg[i].iov_len = pSgBuf->pcaSeg[i].cbSeg;
     636        }
     637
     638        struct msghdr msgHdr;
     639        memset(&msgHdr, '\0', sizeof(msgHdr));
     640        msgHdr.msg_iov = paMsg;
     641        msgHdr.msg_iovlen = pSgBuf->cSeg;
     642        ssize_t cbWritten = sendmsg(pThis->hNative, &msgHdr, MSG_NOSIGNAL);
     643#endif
     644
     645        RTMemTmpFree(paMsg);
     646        if (RT_LIKELY(cbWritten >= 0))
     647            rc = VINF_SUCCESS;
     648        else
     649            rc = rtSocketError();
     650    } while (0);
     651
     652    rtSocketUnlock(pThis);
     653    return rc;
     654}
     655
     656
    576657RTDECL(int) RTSocketSelectOne(RTSOCKET hSocket, RTMSINTERVAL cMillies)
    577658{
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette