コード例 #1
0
ファイル: tstRTPipe.cpp プロジェクト: miguelinux/vbox
static void tstRTPipe5(void)
{
    RTTestISub("Inherit non-standard pipe handle, read end");

    char    szPathSelf[RTPATH_MAX];
    RTTESTI_CHECK_RETV(RTProcGetExecutablePath(szPathSelf, sizeof(szPathSelf)) == szPathSelf);

    RTPIPE  hPipeR;
    RTPIPE  hPipeW;
    RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, RTPIPE_C_INHERIT_READ), VINF_SUCCESS);

    RTHCINTPTR hNative = RTPipeToNative(hPipeR);
    RTTESTI_CHECK_RETV(hNative != -1);

    char szNative[64];
    RTStrPrintf(szNative, sizeof(szNative), "%RHi", hNative);
    const char *papszArgs[4] = { szPathSelf, "--child-5", szNative, NULL };

    RTPROCESS hChild;
    RTTESTI_CHECK_RC_RETV(RTProcCreate(szPathSelf, papszArgs, RTENV_DEFAULT, 0 /*fFlags*/, &hChild), VINF_SUCCESS);
    RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeR), VINF_SUCCESS);

    RTTESTI_CHECK_RC(RTPipeWriteBlocking(hPipeW, g_szTest5Message, sizeof(g_szTest5Message) - 1, NULL), VINF_SUCCESS);
    int rc;
    RTTESTI_CHECK_RC(rc = RTPipeClose(hPipeW), VINF_SUCCESS);
    if (RT_FAILURE(rc))
        RTTESTI_CHECK_RC(RTProcTerminate(hChild), VINF_SUCCESS);

    RTPROCSTATUS ProcStatus;
    RTTESTI_CHECK_RC(rc = RTProcWait(hChild, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS);
    if (RT_FAILURE(rc))
        return;
    RTTESTI_CHECK(   ProcStatus.enmReason == RTPROCEXITREASON_NORMAL
                  && ProcStatus.iStatus   == 0);
}
コード例 #2
0
/**
 * Destruct a host parallel driver instance.
 *
 * Most VM resources are freed by the VM. This callback is provided so that
 * any non-VM resources can be freed correctly.
 *
 * @param   pDrvIns     The driver instance data.
 */
static DECLCALLBACK(void) drvHostParallelDestruct(PPDMDRVINS pDrvIns)
{
    PDRVHOSTPARALLEL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTPARALLEL);
    LogFlowFunc(("iInstance=%d\n", pDrvIns->iInstance));
    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);

#ifndef VBOX_WITH_WIN_PARPORT_SUP

    int rc;

    if (pThis->hFileDevice != NIL_RTFILE)
        ioctl(RTFileToNative(pThis->hFileDevice), PPRELEASE);

    rc = RTPipeClose(pThis->hWakeupPipeW); AssertRC(rc);
    pThis->hWakeupPipeW = NIL_RTPIPE;

    rc = RTPipeClose(pThis->hWakeupPipeR); AssertRC(rc);
    pThis->hWakeupPipeR = NIL_RTPIPE;

    rc = RTFileClose(pThis->hFileDevice); AssertRC(rc); /** @todo r=bird: Why aren't this closed on Windows? */
    pThis->hFileDevice = NIL_RTFILE;

    if (pThis->pszDevicePath)
    {
        MMR3HeapFree(pThis->pszDevicePath);
        pThis->pszDevicePath = NULL;
    }
#endif /* VBOX_WITH_WIN_PARPORT_SUP */
}
コード例 #3
0
/**
 * Stop all service threads and free the device chain.
 */
USBProxyBackendUsbIp::~USBProxyBackendUsbIp()
{
    LogFlowThisFunc(("\n"));

    /*
     * Stop the service.
     */
    if (isActive())
        stop();

    /*
     * Free resources.
     */
    if (m->hPollSet != NIL_RTPOLLSET)
    {
        disconnect();

        int rc = RTPollSetRemove(m->hPollSet, USBIP_POLL_ID_PIPE);
        AssertRC(rc);
        rc = RTPollSetDestroy(m->hPollSet);
        AssertRC(rc);
        rc = RTPipeClose(m->hWakeupPipeR);
        AssertRC(rc);
        rc = RTPipeClose(m->hWakeupPipeW);
        AssertRC(rc);
    }

    if (m->pszHost)
        RTStrFree(m->pszHost);
    if (m->hMtxDevices != NIL_RTSEMFASTMUTEX)
        RTSemFastMutexDestroy(m->hMtxDevices);

    delete m;
}
コード例 #4
0
ファイル: tstRTPipe.cpp プロジェクト: miguelinux/vbox
static void tstRTPipe2(void)
{
    RTTestISub("Negative");

    RTPIPE  hPipeR = (RTPIPE)1;
    RTPIPE  hPipeW = (RTPIPE)1;
    RTTESTI_CHECK_RC(RTPipeCreate(&hPipeR, &hPipeW, ~0), VERR_INVALID_PARAMETER);
    RTTESTI_CHECK_RC(RTPipeCreate(NULL, &hPipeW, 0), VERR_INVALID_POINTER);
    RTTESTI_CHECK_RC(RTPipeCreate(&hPipeR, NULL, 0), VERR_INVALID_POINTER);
    RTTESTI_CHECK(hPipeR == (RTPIPE)1);
    RTTESTI_CHECK(hPipeW == (RTPIPE)1);


    RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, 0), VINF_SUCCESS);

    char abBuf[_4K];
    size_t cbRead = ~(size_t)3;
    RTTESTI_CHECK_RC(RTPipeRead(hPipeW, abBuf, 0, &cbRead), VERR_ACCESS_DENIED);
    RTTESTI_CHECK_RC(RTPipeRead(hPipeW, abBuf, 1, &cbRead), VERR_ACCESS_DENIED);
    RTTESTI_CHECK(cbRead == ~(size_t)3);
    RTTESTI_CHECK_RC(RTPipeReadBlocking(hPipeW, abBuf, 0, NULL), VERR_ACCESS_DENIED);
    RTTESTI_CHECK_RC(RTPipeReadBlocking(hPipeW, abBuf, 1, NULL), VERR_ACCESS_DENIED);

    size_t cbWrite = ~(size_t)5;
    RTTESTI_CHECK_RC(RTPipeWrite(hPipeR, "asdf", 0, &cbWrite), VERR_ACCESS_DENIED);
    RTTESTI_CHECK_RC(RTPipeWrite(hPipeR, "asdf", 4, &cbWrite), VERR_ACCESS_DENIED);
    RTTESTI_CHECK(cbWrite == ~(size_t)5);
    RTTESTI_CHECK_RC(RTPipeWriteBlocking(hPipeR, "asdf", 0, NULL), VERR_ACCESS_DENIED);
    RTTESTI_CHECK_RC(RTPipeWriteBlocking(hPipeR, "asdf", 4, NULL), VERR_ACCESS_DENIED);

    RTTESTI_CHECK_RC(RTPipeFlush(hPipeR), VERR_ACCESS_DENIED);

    RTTESTI_CHECK_RC(RTPipeClose(hPipeR), VINF_SUCCESS);
    RTTESTI_CHECK_RC(RTPipeClose(hPipeW), VINF_SUCCESS);
}
コード例 #5
0
ファイル: scmsubversion.cpp プロジェクト: bringhurst/vbox
/**
 * Reads from a pipe.
 *
 * @returns @a rc or other status code.
 * @param   rc              The current status of the operation.  Error status
 *                          are preserved and returned.
 * @param   phPipeR         Pointer to the pipe handle.
 * @param   pcbAllocated    Pointer to the buffer size variable.
 * @param   poffCur         Pointer to the buffer offset variable.
 * @param   ppszBuffer      Pointer to the buffer pointer variable.
 */
static int rtProcProcessOutput(int rc, PRTPIPE phPipeR, size_t *pcbAllocated, size_t *poffCur, char **ppszBuffer,
                               RTPOLLSET hPollSet, uint32_t idPollSet)
{
    size_t  cbRead;
    char    szTmp[_4K - 1];
    for (;;)
    {
        int rc2 = RTPipeRead(*phPipeR, szTmp, sizeof(szTmp), &cbRead);
        if (RT_SUCCESS(rc2) && cbRead)
        {
            /* Resize the buffer. */
            if (*poffCur + cbRead >= *pcbAllocated)
            {
                if (*pcbAllocated >= _1G)
                {
                    RTPollSetRemove(hPollSet, idPollSet);
                    rc2 = RTPipeClose(*phPipeR); AssertRC(rc2);
                    *phPipeR = NIL_RTPIPE;
                    return RT_SUCCESS(rc) ? VERR_TOO_MUCH_DATA : rc;
                }

                size_t cbNew = *pcbAllocated ? *pcbAllocated * 2 : sizeof(szTmp) + 1;
                Assert(*poffCur + cbRead < cbNew);
                rc2 = RTStrRealloc(ppszBuffer, cbNew);
                if (RT_FAILURE(rc2))
                {
                    RTPollSetRemove(hPollSet, idPollSet);
                    rc2 = RTPipeClose(*phPipeR); AssertRC(rc2);
                    *phPipeR = NIL_RTPIPE;
                    return RT_SUCCESS(rc) ? rc2 : rc;
                }
                *pcbAllocated = cbNew;
            }

            /* Append the new data, terminating it. */
            memcpy(*ppszBuffer + *poffCur, szTmp, cbRead);
            *poffCur += cbRead;
            (*ppszBuffer)[*poffCur] = '\0';

            /* Check for null terminators in the string. */
            if (RT_SUCCESS(rc) && memchr(szTmp, '\0', cbRead))
                rc = VERR_NO_TRANSLATION;

            /* If we read a full buffer, try read some more. */
            if (RT_SUCCESS(rc) && cbRead == sizeof(szTmp))
                continue;
        }
        else if (rc2 != VINF_TRY_AGAIN)
        {
            if (RT_FAILURE(rc) && rc2 != VERR_BROKEN_PIPE)
                rc = rc2;
            RTPollSetRemove(hPollSet, idPollSet);
            rc2 = RTPipeClose(*phPipeR); AssertRC(rc2);
            *phPipeR = NIL_RTPIPE;
        }
        return rc;
    }
}
コード例 #6
0
static void tstRTCreateProcEx2(const char *pszAsUser, const char *pszPassword)
{
    RTTestISub("Standard Err");

    RTPIPE hPipeR, hPipeW;
    RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, RTPIPE_C_INHERIT_WRITE), VINF_SUCCESS);
    const char * apszArgs[3] =
    {
        "non-existing-non-executable-file",
        "--testcase-child-2",
        NULL
    };
    RTHANDLE Handle;
    Handle.enmType = RTHANDLETYPE_PIPE;
    Handle.u.hPipe = hPipeW;
    RTPROCESS hProc;
    RTTESTI_CHECK_RC_RETV(RTProcCreateEx(g_szExecName, apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, NULL,
                                         NULL, &Handle, pszAsUser, pszPassword, &hProc), VINF_SUCCESS);
    RTTESTI_CHECK_RC(RTPipeClose(hPipeW), VINF_SUCCESS);

    char    szOutput[_4K];
    size_t  offOutput = 0;
    for (;;)
    {
        size_t cbLeft = sizeof(szOutput) - 1 - offOutput;
        RTTESTI_CHECK(cbLeft > 0);
        if (cbLeft == 0)
            break;

        size_t cbRead;
        int rc = RTPipeReadBlocking(hPipeR, &szOutput[offOutput], cbLeft, &cbRead);
        if (RT_FAILURE(rc))
        {
            RTTESTI_CHECK_RC(rc, VERR_BROKEN_PIPE);
            break;
        }
        offOutput += cbRead;
    }
    szOutput[offOutput] = '\0';
    RTTESTI_CHECK_RC(RTPipeClose(hPipeR), VINF_SUCCESS);

    RTPROCSTATUS ProcStatus = { -1, RTPROCEXITREASON_ABEND };
    RTTESTI_CHECK_RC(RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS);
    RTThreadSleep(10);

    if (ProcStatus.enmReason != RTPROCEXITREASON_NORMAL || ProcStatus.iStatus != 0)
        RTTestIFailed("enmReason=%d iStatus=%d", ProcStatus.enmReason, ProcStatus.iStatus);
    else if (   offOutput != sizeof("howdy") - 1
             || strcmp(szOutput, "howdy"))
        RTTestIFailed("wrong output: \"%s\" (len=%u)", szOutput, offOutput);
    else
        RTTestIPassed(NULL);
}
コード例 #7
0
/**
 * If any Usbfs-related resources are currently allocated, then free them
 * and mark them as freed.
 */
void USBProxyBackendLinux::doUsbfsCleanupAsNeeded()
{
    /*
     * Free resources.
     */
    RTFileClose(mhFile);
    mhFile = NIL_RTFILE;

    RTPipeClose(mhWakeupPipeR);
    RTPipeClose(mhWakeupPipeW);
    mhWakeupPipeW = mhWakeupPipeR = NIL_RTPIPE;
}
コード例 #8
0
/**
 * Initializes the object (called right after construction).
 *
 * @returns S_OK on success and non-fatal failures, some COM error otherwise.
 */
int USBProxyBackendUsbIp::init(void)
{
    int rc = VINF_SUCCESS;

    m = new Data;

    /** @todo: Pass in some config like host and port to connect to. */

    /* Setup wakeup pipe and poll set first. */
    rc = RTSemFastMutexCreate(&m->hMtxDevices);
    if (RT_SUCCESS(rc))
    {
        rc = RTPipeCreate(&m->hWakeupPipeR, &m->hWakeupPipeW, 0);
        if (RT_SUCCESS(rc))
        {
            rc = RTPollSetCreate(&m->hPollSet);
            if (RT_SUCCESS(rc))
            {
                rc = RTPollSetAddPipe(m->hPollSet, m->hWakeupPipeR,
                                      RTPOLL_EVT_READ, USBIP_POLL_ID_PIPE);
                if (RT_SUCCESS(rc))
                {
                    /* Connect to the USB/IP host. */
                    rc = reconnect();
                    if (RT_SUCCESS(rc))
                        rc = start(); /* Start service thread. */
                }

                if (RT_FAILURE(rc))
                {
                    RTPollSetRemove(m->hPollSet, USBIP_POLL_ID_PIPE);
                    int rc2 = RTPollSetDestroy(m->hPollSet);
                    AssertRC(rc2);
                }
            }

            if (RT_FAILURE(rc))
            {
                int rc2 = RTPipeClose(m->hWakeupPipeR);
                AssertRC(rc2);
                rc2 = RTPipeClose(m->hWakeupPipeW);
                AssertRC(rc2);
            }
        }
        if (RT_FAILURE(rc))
            RTSemFastMutexDestroy(m->hMtxDevices);
    }

    return rc;
}
コード例 #9
0
/**
 * Initialization routine for the usbfs based operation.
 *
 * @returns iprt status code.
 */
int USBProxyBackendLinux::initUsbfs(void)
{
    Assert(mUsingUsbfsDevices);

    /*
     * Open the devices file.
     */
    int rc;
    char *pszDevices = RTPathJoinA(mDevicesRoot.c_str(), "devices");
    if (pszDevices)
    {
        rc = RTFileOpen(&mhFile, pszDevices, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
        if (RT_SUCCESS(rc))
        {
            rc = RTPipeCreate(&mhWakeupPipeR, &mhWakeupPipeW, 0 /*fFlags*/);
            if (RT_SUCCESS(rc))
            {
                /*
                 * Start the poller thread.
                 */
                rc = start();
                if (RT_SUCCESS(rc))
                {
                    RTStrFree(pszDevices);
                    LogFlowThisFunc(("returns successfully\n"));
                    return VINF_SUCCESS;
                }

                RTPipeClose(mhWakeupPipeR);
                RTPipeClose(mhWakeupPipeW);
                mhWakeupPipeW = mhWakeupPipeR = NIL_RTPIPE;
            }
            else
                Log(("USBProxyBackendLinux::USBProxyBackendLinux: RTFilePipe failed with rc=%Rrc\n", rc));
            RTFileClose(mhFile);
        }

        RTStrFree(pszDevices);
    }
    else
    {
        rc = VERR_NO_MEMORY;
        Log(("USBProxyBackendLinux::USBProxyBackendLinux: out of memory!\n"));
    }

    LogFlowThisFunc(("returns failure!!! (rc=%Rrc)\n", rc));
    return rc;
}
コード例 #10
0
ファイル: tstRTPipe.cpp プロジェクト: miguelinux/vbox
static RTEXITCODE tstRTPipe4Child(const char *pszPipe)
{
    int rc = RTR3InitExeNoArguments(0);
    if (RT_FAILURE(rc))
        return RTMsgInitFailure(rc);

    int64_t iNative;
    rc = RTStrToInt64Full(pszPipe, 10, &iNative);
    if (RT_FAILURE(rc))
        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTStrToUInt64Full(%s) -> %Rrc\n", pszPipe, rc);

    RTPIPE hPipe;
    rc = RTPipeFromNative(&hPipe, (RTHCINTPTR)iNative, RTPIPE_N_WRITE);
    if (RT_FAILURE(rc))
        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPipeFromNative(,%s,WRITE) -> %Rrc\n", pszPipe, rc);

    rc = RTPipeWriteBlocking(hPipe, g_szTest4Message, sizeof(g_szTest4Message) - 1, NULL);
    if (RT_FAILURE(rc))
        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPipeWriteBlocking() -> %Rrc\n", rc);

    rc = RTPipeClose(hPipe);
    if (RT_FAILURE(rc))
        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPipeClose() -> %Rrc\n", rc);
    return RTEXITCODE_SUCCESS;
}
コード例 #11
0
ファイル: handle.cpp プロジェクト: gvsurenderreddy/virtualbox
RTDECL(int) RTHandleClose(PRTHANDLE ph)
{
    int rc = VINF_SUCCESS;
    if (ph)
    {
        switch (ph->enmType)
        {
            case RTHANDLETYPE_FILE:
                rc = RTFileClose(ph->u.hFile);
                ph->u.hFile = NIL_RTFILE;
                break;

            case RTHANDLETYPE_PIPE:
                rc = RTPipeClose(ph->u.hPipe);
                ph->u.hPipe = NIL_RTPIPE;
                break;

            case RTHANDLETYPE_SOCKET:
                AssertMsgFailed(("Socket not supported\n"));
                rc = VERR_NOT_SUPPORTED;
                break;

            case RTHANDLETYPE_THREAD:
                AssertMsgFailed(("Thread not supported\n"));
                rc = VERR_NOT_SUPPORTED;
                break;

            default:
                AssertMsgFailed(("Invalid type %d\n", ph->enmType));
                rc = VERR_INVALID_PARAMETER;
                break;
        }
    }
    return rc;
}
コード例 #12
0
ファイル: tstRTPipe.cpp プロジェクト: miguelinux/vbox
static void tstRTPipe4(void)
{
    RTTestISub("Inherit non-standard pipe handle, write end");

    char    szPathSelf[RTPATH_MAX];
    RTTESTI_CHECK_RETV(RTProcGetExecutablePath(szPathSelf, sizeof(szPathSelf)) == szPathSelf);

    RTPIPE  hPipeR;
    RTPIPE  hPipeW;
    RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, RTPIPE_C_INHERIT_WRITE), VINF_SUCCESS);

    RTHCINTPTR hNative = RTPipeToNative(hPipeW);
    RTTESTI_CHECK_RETV(hNative != -1);

    char szNative[64];
    RTStrPrintf(szNative, sizeof(szNative), "%RHi", hNative);
    const char *papszArgs[4] = { szPathSelf, "--child-4", szNative, NULL };

    RTPROCESS hChild;
    RTTESTI_CHECK_RC_RETV(RTProcCreate(szPathSelf, papszArgs, RTENV_DEFAULT, 0 /*fFlags*/, &hChild), VINF_SUCCESS);
    RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeW), VINF_SUCCESS);

    char    szTmp[1024];
    size_t  cbRead = 0;
    int     rc;
    RTTESTI_CHECK_RC(rc = RTPipeReadBlocking(hPipeR, szTmp, sizeof(szTmp) - 1, &cbRead), VINF_SUCCESS);
    if (RT_FAILURE(rc))
        cbRead = 0;
    RTTESTI_CHECK_RETV(cbRead < sizeof(szTmp));
    szTmp[cbRead] = '\0';

    size_t cbRead2;
    char szTmp2[4];
    RTTESTI_CHECK_RC(RTPipeReadBlocking(hPipeR, szTmp2, sizeof(szTmp2), &cbRead2), VERR_BROKEN_PIPE);
    RTTESTI_CHECK_RC(rc = RTPipeClose(hPipeR), VINF_SUCCESS);
    if (RT_FAILURE(rc))
        RTTESTI_CHECK_RC(RTProcTerminate(hChild), VINF_SUCCESS);

    RTPROCSTATUS ProcStatus;
    RTTESTI_CHECK_RC(rc = RTProcWait(hChild, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS);
    if (RT_FAILURE(rc))
        return;
    RTTESTI_CHECK(   ProcStatus.enmReason == RTPROCEXITREASON_NORMAL
                  && ProcStatus.iStatus   == 0);
    if (memcmp(szTmp, g_szTest4Message, sizeof(g_szTest4Message)))
        RTTestIFailed("Message mismatch.\n:Expected '%s'\nGot     '%s'\n", g_szTest4Message, szTmp);
}
コード例 #13
0
ファイル: tstRTPipe.cpp プロジェクト: miguelinux/vbox
static void tstRTPipe3(void)
{
    RTTestISub("Full write buffer");

    RTPIPE  hPipeR = (RTPIPE)999999;
    RTPIPE  hPipeW = (RTPIPE)999999;
    RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, 0), VINF_SUCCESS);

    static char s_abBuf[_256K];
    int         rc      = VINF_SUCCESS;
    size_t      cbTotal = 0;
    memset(s_abBuf, 0xff, sizeof(s_abBuf));
    for (;;)
    {
        RTTESTI_CHECK(cbTotal < _1G);
        if (cbTotal > _1G)
            break;

        size_t cbWritten = _1G;
        rc = RTPipeWrite(hPipeW, s_abBuf, sizeof(s_abBuf), &cbWritten);
        RTTESTI_CHECK_MSG(rc == VINF_SUCCESS || rc == VINF_TRY_AGAIN, ("rc=%Rrc\n", rc));
        if (rc != VINF_SUCCESS)
            break;
        cbTotal += cbWritten;
    }

    if (rc == VINF_TRY_AGAIN)
    {
        RTTestIPrintf(RTTESTLVL_ALWAYS, "cbTotal=%zu (%#zx)\n", cbTotal, cbTotal);
        RTTESTI_CHECK_RC(RTPipeSelectOne(hPipeW, 0), VERR_TIMEOUT);
        RTTESTI_CHECK_RC(RTPipeSelectOne(hPipeW, 1), VERR_TIMEOUT);
        size_t cbRead;
        RTTESTI_CHECK_RC(RTPipeRead(hPipeR, s_abBuf, RT_MIN(sizeof(s_abBuf), cbTotal) / 2, &cbRead), VINF_SUCCESS);
        RTTESTI_CHECK_RC(RTPipeSelectOne(hPipeW, 0), VINF_SUCCESS);
        RTTESTI_CHECK_RC(RTPipeSelectOne(hPipeW, 1), VINF_SUCCESS);

        size_t cbWritten = _1G;
        rc = RTPipeWrite(hPipeW, s_abBuf, sizeof(s_abBuf), &cbWritten);
        RTTESTI_CHECK(rc == VINF_SUCCESS);
    }

    RTTESTI_CHECK_RC(RTPipeClose(hPipeR), VINF_SUCCESS);
    RTTESTI_CHECK_RC(RTPipeClose(hPipeW), VINF_SUCCESS);
}
コード例 #14
0
/**
 * Closes the proxy device.
 */
static DECLCALLBACK(void) usbProxyFreeBSDClose(PUSBPROXYDEV pProxyDev)
{
    PUSBPROXYDEVFBSD pDevFBSD = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVFBSD);

    LogFlow(("usbProxyFreeBSDClose: pProxyDev=%s\n", pProxyDev->pUsbIns->pszName));

    /* sanity check */
    AssertPtrReturnVoid(pDevFBSD);

    usbProxyFreeBSDFsUnInit(pProxyDev);

    RTPipeClose(pDevFBSD->hPipeWakeupR);
    RTPipeClose(pDevFBSD->hPipeWakeupW);

    RTFileClose(pDevFBSD->hFile);
    pDevFBSD->hFile = NIL_RTFILE;

    LogFlow(("usbProxyFreeBSDClose: returns\n"));
}
コード例 #15
0
/**
 * Close the USB device.
 *
 * @param   pProxyDev   The device instance.
 */
static DECLCALLBACK(void) usbProxySolarisClose(PUSBPROXYDEV pProxyDev)
{
    LogFlow((USBPROXY ":usbProxySolarisClose: pProxyDev=%p\n", pProxyDev));

    PUSBPROXYDEVSOL pDevSol = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVSOL);

    /* Close the device (do not re-enumerate). */
    VBOXUSBREQ_CLOSE_DEVICE CloseReq;
    CloseReq.ResetLevel = VBOXUSB_RESET_LEVEL_CLOSE;
    usbProxySolarisIOCtl(pDevSol, VBOXUSB_IOCTL_CLOSE_DEVICE, &CloseReq, sizeof(CloseReq));

    pProxyDev->fDetached = true;
    usbProxySolarisCloseFile(pDevSol);

    /*
     * Now we can close it and free all the resources.
     */
    RTCritSectDelete(&pDevSol->CritSect);

    PUSBPROXYURBSOL pUrbSol = NULL;
    while ((pUrbSol = pDevSol->pInFlightHead) != NULL)
    {
        pDevSol->pInFlightHead = pUrbSol->pNext;
        RTMemFree(pUrbSol);
    }

    while ((pUrbSol = pDevSol->pFreeHead) != NULL)
    {
        pDevSol->pFreeHead = pUrbSol->pNext;
        RTMemFree(pUrbSol);
    }

    RTPipeClose(pDevSol->hPipeWakeupR);
    RTPipeClose(pDevSol->hPipeWakeupW);

    RTStrFree(pDevSol->pszDevicePath);
    pDevSol->pszDevicePath = NULL;

    USBLibTerm();
}
コード例 #16
0
ファイル: tstRTPipe.cpp プロジェクト: miguelinux/vbox
static RTEXITCODE tstRTPipe5Child(const char *pszPipe)
{
    int rc = RTR3InitExeNoArguments(0);
    if (RT_FAILURE(rc))
        return RTMsgInitFailure(rc);

    int64_t iNative;
    rc = RTStrToInt64Full(pszPipe, 10, &iNative);
    if (RT_FAILURE(rc))
        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTStrToUInt64Full(%s) -> %Rrc\n", pszPipe, rc);

    RTPIPE hPipe;
    rc = RTPipeFromNative(&hPipe, (RTHCINTPTR)iNative, RTPIPE_N_READ);
    if (RT_FAILURE(rc))
        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPipeFromNative(,%s,READ) -> %Rrc\n", pszPipe, rc);

    ///
    char    szTmp[1024];
    size_t  cbRead = 0;
    rc = RTPipeReadBlocking(hPipe, szTmp, sizeof(szTmp) - 1, &cbRead);
    if (RT_FAILURE(rc))
        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPipeReadBlocking() -> %Rrc\n", rc);
    szTmp[cbRead] = '\0';

    size_t cbRead2;
    char szTmp2[4];
    rc = RTPipeReadBlocking(hPipe, szTmp2, sizeof(szTmp2), &cbRead2);
    if (rc != VERR_BROKEN_PIPE)
        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPipeReadBlocking() -> %Rrc instead of VERR_BROKEN_PIPE\n", rc);

    rc = RTPipeClose(hPipe);
    if (RT_FAILURE(rc))
        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPipeClose() -> %Rrc\n", rc);

    if (memcmp(szTmp, g_szTest5Message, sizeof(g_szTest5Message)))
        return RTMsgErrorExit(RTEXITCODE_FAILURE, "Message mismatch.\n:Expected '%s'\nGot     '%s'\n", g_szTest5Message, szTmp);

    return RTEXITCODE_SUCCESS;
}
コード例 #17
0
/**
 * Opens the USB device.
 *
 * @returns VBox status code.
 * @param   pProxyDev       The device instance.
 * @param   pszAddress      The unique device identifier.
 *                          The format of this string is "VendorId:ProducIt:Release:StaticPath".
 * @param   pvBackend       Backend specific pointer, unused for the solaris backend.
 */
static DECLCALLBACK(int) usbProxySolarisOpen(PUSBPROXYDEV pProxyDev, const char *pszAddress, void *pvBackend)
{
    PUSBPROXYDEVSOL pDevSol = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVSOL);

    LogFlowFunc((USBPROXY ":usbProxySolarisOpen pProxyDev=%p pszAddress=%s pvBackend=%p\n", pProxyDev, pszAddress, pvBackend));

    /*
     * Initialize our USB R3 lib.
     */
    int rc = USBLibInit();
    if (RT_SUCCESS(rc))
    {
        /*
         * Allocate and initialize the solaris backend data.
         */
        AssertCompile(PATH_MAX >= MAXPATHLEN);
        char szDeviceIdent[PATH_MAX+48];
        rc = RTStrPrintf(szDeviceIdent, sizeof(szDeviceIdent), "%s", pszAddress);
        if (RT_SUCCESS(rc))
        {
            rc = RTCritSectInit(&pDevSol->CritSect);
            if (RT_SUCCESS(rc))
            {
                /*
                 * Create wakeup pipe.
                 */
                rc = RTPipeCreate(&pDevSol->hPipeWakeupR, &pDevSol->hPipeWakeupW, 0);
                if (RT_SUCCESS(rc))
                {
                    int Instance;
                    char *pszDevicePath = NULL;
                    rc = USBLibGetClientInfo(szDeviceIdent, &pszDevicePath, &Instance);
                    if (RT_SUCCESS(rc))
                    {
                        pDevSol->pszDevicePath = pszDevicePath;

                        /*
                         * Open the client driver.
                         */
                        RTFILE hFile;
                        rc = RTFileOpen(&hFile, pDevSol->pszDevicePath, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
                        if (RT_SUCCESS(rc))
                        {
                            pDevSol->hFile = hFile;
                            pDevSol->pProxyDev = pProxyDev;

                            /*
                             * Verify client driver version.
                             */
                            VBOXUSBREQ_GET_VERSION GetVersionReq;
                            bzero(&GetVersionReq, sizeof(GetVersionReq));
                            rc = usbProxySolarisIOCtl(pDevSol, VBOXUSB_IOCTL_GET_VERSION, &GetVersionReq, sizeof(GetVersionReq));
                            if (RT_SUCCESS(rc))
                            {
                                if (   GetVersionReq.u32Major == VBOXUSB_VERSION_MAJOR
                                    && GetVersionReq.u32Minor >= VBOXUSB_VERSION_MINOR)
                                {
                                    /*
                                     * Try & get the current cached config from Solaris.
                                     */
                                    usbProxySolarisGetActiveConfig(pDevSol);
                                    return VINF_SUCCESS;
                                }
                                else
                                {
                                    LogRel((USBPROXY ":version mismatch! driver v%d.%d expecting ~v%d.%d\n", GetVersionReq.u32Major,
                                            GetVersionReq.u32Minor, VBOXUSB_VERSION_MAJOR, VBOXUSB_VERSION_MINOR));
                                    rc = VERR_VERSION_MISMATCH;
                                }
                            }
                            else
                                LogRel((USBPROXY ":failed to query driver version. rc=%Rrc\n", rc));

                            RTFileClose(pDevSol->hFile);
                            pDevSol->hFile = NIL_RTFILE;
                            pDevSol->pProxyDev = NULL;
                        }
                        else
                            LogRel((USBPROXY ":failed to open device. rc=%Rrc pszDevicePath=%s\n", rc, pDevSol->pszDevicePath));

                        RTStrFree(pDevSol->pszDevicePath);
                        pDevSol->pszDevicePath = NULL;
                    }
                    else
                    {
                        LogRel((USBPROXY ":failed to get client info. rc=%Rrc pszDevicePath=%s\n", rc, pDevSol->pszDevicePath));
                        if (rc == VERR_NOT_FOUND)
                            rc = VERR_OPEN_FAILED;
                    }
                    RTPipeClose(pDevSol->hPipeWakeupR);
                    RTPipeClose(pDevSol->hPipeWakeupW);
                }

                RTCritSectDelete(&pDevSol->CritSect);
            }
            else
                LogRel((USBPROXY ":RTCritSectInit failed. rc=%Rrc pszAddress=%s\n", rc, pszAddress));
        }
        else
            LogRel((USBPROXY ":RTStrAPrintf failed. rc=%Rrc pszAddress=%s\n", rc, pszAddress));
    }
    else
        LogRel((USBPROXY ":USBLibInit failed. rc=%Rrc\n", rc));

    USBLibTerm();
    return rc;
}
コード例 #18
0
ファイル: scmsubversion.cpp プロジェクト: bringhurst/vbox
/**
 * Runs a process, collecting the standard output and/or standard error.
 *
 *
 * @returns IPRT status code
 * @retval  VERR_NO_TRANSLATION if the output of the program isn't valid UTF-8
 *          or contains a nul character.
 * @retval  VERR_TOO_MUCH_DATA if the process produced too much data.
 *
 * @param   pszExec     Executable image to use to create the child process.
 * @param   papszArgs   Pointer to an array of arguments to the child.  The
 *                      array terminated by an entry containing NULL.
 * @param   hEnv        Handle to the environment block for the child.
 * @param   fFlags      A combination of RTPROCEXEC_FLAGS_XXX.  The @a
 *                      ppszStdOut and @a ppszStdErr parameters takes precedence
 *                      over redirection flags.
 * @param   pStatus     Where to return the status on success.
 * @param   ppszStdOut  Where to return the text written to standard output. If
 *                      NULL then standard output will not be collected and go
 *                      to the standard output handle of the process.
 *                      Free with RTStrFree, regardless of return status.
 * @param   ppszStdErr  Where to return the text written to standard error. If
 *                      NULL then standard output will not be collected and go
 *                      to the standard error handle of the process.
 *                      Free with RTStrFree, regardless of return status.
 */
int RTProcExecToString(const char *pszExec, const char * const *papszArgs, RTENV hEnv, uint32_t fFlags,
                       PRTPROCSTATUS pStatus, char **ppszStdOut, char **ppszStdErr)
{
    int rc2;

    /*
     * Clear output arguments (no returning failure here, simply crash!).
     */
    AssertPtr(pStatus);
    pStatus->enmReason = RTPROCEXITREASON_ABEND;
    pStatus->iStatus   = RTEXITCODE_FAILURE;
    AssertPtrNull(ppszStdOut);
    if (ppszStdOut)
        *ppszStdOut = NULL;
    AssertPtrNull(ppszStdOut);
    if (ppszStdErr)
        *ppszStdErr = NULL;

    /*
     * Check input arguments.
     */
    AssertReturn(!(fFlags & ~RTPROCEXEC_FLAGS_VALID_MASK), VERR_INVALID_PARAMETER);

    /*
     * Do we need a standard input bitbucket?
     */
    int         rc = VINF_SUCCESS;
    PRTHANDLE   phChildStdIn = NULL;
    RTHANDLE    hChildStdIn;
    hChildStdIn.enmType = RTHANDLETYPE_FILE;
    hChildStdIn.u.hFile = NIL_RTFILE;
    if ((fFlags & RTPROCEXEC_FLAGS_STDIN_NULL) && RT_SUCCESS(rc))
    {
        phChildStdIn = &hChildStdIn;
        rc = RTFileOpenBitBucket(&hChildStdIn.u.hFile, RTFILE_O_READ);
    }

    /*
     * Create the output pipes / bitbuckets.
     */
    RTPIPE      hPipeStdOutR  = NIL_RTPIPE;
    PRTHANDLE   phChildStdOut = NULL;
    RTHANDLE    hChildStdOut;
    hChildStdOut.enmType = RTHANDLETYPE_PIPE;
    hChildStdOut.u.hPipe = NIL_RTPIPE;
    if (ppszStdOut && RT_SUCCESS(rc))
    {
        phChildStdOut = &hChildStdOut;
        rc = RTPipeCreate(&hPipeStdOutR, &hChildStdOut.u.hPipe, 0 /*fFlags*/);
    }
    else if ((fFlags & RTPROCEXEC_FLAGS_STDOUT_NULL) && RT_SUCCESS(rc))
    {
        phChildStdOut = &hChildStdOut;
        hChildStdOut.enmType = RTHANDLETYPE_FILE;
        hChildStdOut.u.hFile = NIL_RTFILE;
        rc = RTFileOpenBitBucket(&hChildStdOut.u.hFile, RTFILE_O_WRITE);
    }

    RTPIPE      hPipeStdErrR  = NIL_RTPIPE;
    PRTHANDLE   phChildStdErr = NULL;
    RTHANDLE    hChildStdErr;
    hChildStdErr.enmType = RTHANDLETYPE_PIPE;
    hChildStdErr.u.hPipe = NIL_RTPIPE;
    if (ppszStdErr && RT_SUCCESS(rc))
    {
        phChildStdErr = &hChildStdErr;
        rc = RTPipeCreate(&hPipeStdErrR, &hChildStdErr.u.hPipe, 0 /*fFlags*/);
    }
    else if ((fFlags & RTPROCEXEC_FLAGS_STDERR_NULL) && RT_SUCCESS(rc))
    {
        phChildStdErr = &hChildStdErr;
        hChildStdErr.enmType = RTHANDLETYPE_FILE;
        hChildStdErr.u.hFile = NIL_RTFILE;
        rc = RTFileOpenBitBucket(&hChildStdErr.u.hFile, RTFILE_O_WRITE);
    }

    if (RT_SUCCESS(rc))
    {
        RTPOLLSET hPollSet;
        rc = RTPollSetCreate(&hPollSet);
        if (RT_SUCCESS(rc))
        {
            if (hPipeStdOutR != NIL_RTPIPE && RT_SUCCESS(rc))
                rc = RTPollSetAddPipe(hPollSet, hPipeStdOutR, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, 1);
            if (hPipeStdErrR != NIL_RTPIPE)
                rc = RTPollSetAddPipe(hPollSet, hPipeStdErrR, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, 2);
        }
        if (RT_SUCCESS(rc))
        {
            /*
             * Create the process.
             */
            RTPROCESS hProc;
            rc = RTProcCreateEx(g_szSvnPath,
                                papszArgs,
                                RTENV_DEFAULT,
                                0 /*fFlags*/,
                                NULL /*phStdIn*/,
                                phChildStdOut,
                                phChildStdErr,
                                NULL /*pszAsUser*/,
                                NULL /*pszPassword*/,
                                &hProc);
            rc2 = RTHandleClose(&hChildStdErr); AssertRC(rc2);
            rc2 = RTHandleClose(&hChildStdOut); AssertRC(rc2);

            if (RT_SUCCESS(rc))
            {
                /*
                 * Process output and wait for the process to finish.
                 */
                size_t cbStdOut  = 0;
                size_t offStdOut = 0;
                size_t cbStdErr  = 0;
                size_t offStdErr = 0;
                for (;;)
                {
                    if (hPipeStdOutR != NIL_RTPIPE)
                        rc = rtProcProcessOutput(rc, &hPipeStdOutR, &cbStdOut, &offStdOut, ppszStdOut, hPollSet, 1);
                    if (hPipeStdErrR != NIL_RTPIPE)
                        rc = rtProcProcessOutput(rc, &hPipeStdErrR, &cbStdErr, &offStdErr, ppszStdErr, hPollSet, 2);
                    if (hPipeStdOutR == NIL_RTPIPE && hPipeStdErrR == NIL_RTPIPE)
                        break;

                    if (hProc != NIL_RTPROCESS)
                    {
                        rc2 = RTProcWait(hProc, RTPROCWAIT_FLAGS_NOBLOCK, pStatus);
                        if (rc2 != VERR_PROCESS_RUNNING)
                        {
                            if (RT_FAILURE(rc2))
                                rc = rc2;
                            hProc = NIL_RTPROCESS;
                        }
                    }

                    rc2 = RTPoll(hPollSet, 10000, NULL, NULL);
                    Assert(RT_SUCCESS(rc2) || rc2 == VERR_TIMEOUT);
                }

                if (RT_SUCCESS(rc))
                {
                    if (   (ppszStdOut && *ppszStdOut && !RTStrIsValidEncoding(*ppszStdOut))
                        || (ppszStdErr && *ppszStdErr && !RTStrIsValidEncoding(*ppszStdErr)) )
                        rc = VERR_NO_TRANSLATION;
                }

                /*
                 * No more output, just wait for it to finish.
                 */
                if (hProc != NIL_RTPROCESS)
                {
                    rc2 = RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, pStatus);
                    if (RT_FAILURE(rc2))
                        rc = rc2;
                }
            }
            RTPollSetDestroy(hPollSet);
        }
    }

    rc2 = RTHandleClose(&hChildStdErr); AssertRC(rc2);
    rc2 = RTHandleClose(&hChildStdOut); AssertRC(rc2);
    rc2 = RTHandleClose(&hChildStdIn);  AssertRC(rc2);
    rc2 = RTPipeClose(hPipeStdErrR);    AssertRC(rc2);
    rc2 = RTPipeClose(hPipeStdOutR);    AssertRC(rc2);
    return rc;
}
コード例 #19
0
ファイル: tstRTPipe.cpp プロジェクト: miguelinux/vbox
static void tstRTPipe1(void)
{
    RTTestISub("Basics");

    RTPIPE  hPipeR = NIL_RTPIPE;
    RTPIPE  hPipeW = NIL_RTPIPE;
    RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, 0), VINF_SUCCESS);
    RTTESTI_CHECK_RETV(hPipeR != NIL_RTPIPE);
    RTTESTI_CHECK_RETV(hPipeW != NIL_RTPIPE);
    RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeR), VINF_SUCCESS);
    RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeW), VINF_SUCCESS);
    RTTESTI_CHECK_RC_RETV(RTPipeClose(NIL_RTPIPE), VINF_SUCCESS);

    hPipeR = NIL_RTPIPE;
    hPipeW = NIL_RTPIPE;
    RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, RTPIPE_C_INHERIT_READ | RTPIPE_C_INHERIT_WRITE), VINF_SUCCESS);
    int rc = RTPipeFlush(hPipeW);
    RTTESTI_CHECK_MSG(rc == VERR_NOT_SUPPORTED || rc == VINF_SUCCESS, ("%Rrc\n", rc));
    RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeR), VINF_SUCCESS);
    RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeW), VINF_SUCCESS);

    RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, RTPIPE_C_INHERIT_READ), VINF_SUCCESS);
    RTTESTI_CHECK_RC_RETV(RTPipeSelectOne(hPipeR, 0), VERR_TIMEOUT);
    RTTESTI_CHECK_RC_RETV(RTPipeSelectOne(hPipeR, 1), VERR_TIMEOUT);
    RTTESTI_CHECK_RC_RETV(RTPipeSelectOne(hPipeW, 0), VINF_SUCCESS);
    RTTESTI_CHECK_RC_RETV(RTPipeSelectOne(hPipeW, 1), VINF_SUCCESS);
    RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeR), VINF_SUCCESS);
    RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeW), VINF_SUCCESS);

    RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, RTPIPE_C_INHERIT_WRITE), VINF_SUCCESS);
    RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeR), VINF_SUCCESS);
    RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeW), VINF_SUCCESS);

    RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, RTPIPE_C_INHERIT_READ), VINF_SUCCESS);

    size_t  cbRead = ~(size_t)0;
    char    abBuf[_64K + _4K];
    RTTESTI_CHECK_RC_RETV(RTPipeRead(hPipeR, abBuf, sizeof(abBuf), &cbRead), VINF_TRY_AGAIN);
    RTTESTI_CHECK_RETV(cbRead == 0);

    cbRead = ~(size_t)0;
    RTTESTI_CHECK_RC_RETV(RTPipeRead(hPipeR, abBuf, 1, &cbRead), VINF_TRY_AGAIN);
    RTTESTI_CHECK_RETV(cbRead == 0);

    cbRead = ~(size_t)0;
    RTTESTI_CHECK_RC_RETV(RTPipeRead(hPipeR, abBuf, 0, &cbRead), VINF_SUCCESS);
    RTTESTI_CHECK_RETV(cbRead == 0);

    size_t cbWritten = ~(size_t)2;
    RTTESTI_CHECK_RC_RETV(RTPipeWrite(hPipeW, abBuf, 0, &cbWritten), VINF_SUCCESS);
    RTTESTI_CHECK_RETV(cbWritten == 0);

    /* We can write a number of bytes without blocking (see PIPE_BUF on
       POSIX systems). */
    cbWritten = ~(size_t)2;
    RTTESTI_CHECK_RC_RETV(RTPipeWrite(hPipeW, "42", 2, &cbWritten), VINF_SUCCESS);
    RTTESTI_CHECK_MSG_RETV(cbWritten == 2, ("cbWritten=%zu\n", cbWritten));
    cbWritten = ~(size_t)2;
    RTTESTI_CHECK_RC_RETV(RTPipeWrite(hPipeW, "!", 1, &cbWritten), VINF_SUCCESS);
    RTTESTI_CHECK_RETV(cbWritten == 1);
    cbRead = ~(size_t)0;
    RTTESTI_CHECK_RC_RETV(RTPipeRead(hPipeR, abBuf, 3, &cbRead), VINF_SUCCESS);
    RTTESTI_CHECK_RETV(cbRead == 3);
    RTTESTI_CHECK_RETV(!memcmp(abBuf, "42!", 3));

    cbWritten = ~(size_t)2;
    RTTESTI_CHECK_RC_RETV(RTPipeWrite(hPipeW, "BigQ", 4, &cbWritten), VINF_SUCCESS);
    RTTESTI_CHECK_RETV(cbWritten == 4);
    RTTESTI_CHECK_RC_RETV(RTPipeSelectOne(hPipeR, 0), VINF_SUCCESS);
    RTTESTI_CHECK_RC_RETV(RTPipeSelectOne(hPipeR, 1), VINF_SUCCESS);
    cbRead = ~(size_t)0;
    RTTESTI_CHECK_RC_RETV(RTPipeQueryReadable(hPipeR, &cbRead), VINF_SUCCESS);
    RTTESTI_CHECK_MSG(cbRead == cbWritten, ("cbRead=%zu cbWritten=%zu\n", cbRead, cbWritten));
    cbRead = ~(size_t)0;
    RTTESTI_CHECK_RC_RETV(RTPipeRead(hPipeR, abBuf, sizeof(abBuf), &cbRead), VINF_SUCCESS);
    RTTESTI_CHECK_RETV(cbRead == 4);
    RTTESTI_CHECK_RETV(!memcmp(abBuf, "BigQ", 4));

    cbWritten = ~(size_t)2;
    RTTESTI_CHECK_RC_RETV(RTPipeWrite(hPipeW, "H2G2", 4, &cbWritten), VINF_SUCCESS);
    RTTESTI_CHECK_RETV(cbWritten == 4);
    cbRead = ~(size_t)0;
    RTTESTI_CHECK_RC_RETV(RTPipeQueryReadable(hPipeR, &cbRead), VINF_SUCCESS);
    RTTESTI_CHECK_MSG(cbRead == cbWritten, ("cbRead=%zu cbWritten=%zu\n", cbRead, cbWritten));
    cbRead = ~(size_t)0;
    RTTESTI_CHECK_RC_RETV(RTPipeRead(hPipeR, &abBuf[0], 1, &cbRead), VINF_SUCCESS);
    RTTESTI_CHECK_RETV(cbRead == 1);
    cbRead = ~(size_t)0;
    RTTESTI_CHECK_RC_RETV(RTPipeQueryReadable(hPipeR, &cbRead), VINF_SUCCESS);
    RTTESTI_CHECK_MSG(cbRead == cbWritten - 1, ("cbRead=%zu cbWritten=%zu\n", cbRead, cbWritten));
    cbRead = ~(size_t)0;
    RTTESTI_CHECK_RC_RETV(RTPipeRead(hPipeR, &abBuf[1], 1, &cbRead), VINF_SUCCESS);
    RTTESTI_CHECK_RETV(cbRead == 1);
    cbRead = ~(size_t)0;
    RTTESTI_CHECK_RC_RETV(RTPipeQueryReadable(hPipeR, &cbRead), VINF_SUCCESS);
    RTTESTI_CHECK_MSG(cbRead == cbWritten - 2, ("cbRead=%zu cbWritten=%zu\n", cbRead, cbWritten));
    cbRead = ~(size_t)0;
    RTTESTI_CHECK_RC_RETV(RTPipeRead(hPipeR, &abBuf[2], 1, &cbRead), VINF_SUCCESS);
    RTTESTI_CHECK_RETV(cbRead == 1);
    cbRead = ~(size_t)0;
    RTTESTI_CHECK_RC_RETV(RTPipeQueryReadable(hPipeR, &cbRead), VINF_SUCCESS);
    RTTESTI_CHECK_MSG(cbRead == cbWritten - 3, ("cbRead=%zu cbWritten=%zu\n", cbRead, cbWritten));
    cbRead = ~(size_t)0;
    RTTESTI_CHECK_RC_RETV(RTPipeRead(hPipeR, &abBuf[3], 1, &cbRead), VINF_SUCCESS);
    RTTESTI_CHECK_RETV(cbRead == 1);
    RTTESTI_CHECK_RETV(!memcmp(abBuf, "H2G2", 4));
    cbRead = ~(size_t)0;
    RTTESTI_CHECK_RC_RETV(RTPipeQueryReadable(hPipeR, &cbRead), VINF_SUCCESS);
    RTTESTI_CHECK_MSG(cbRead == cbWritten - 4, ("cbRead=%zu cbWritten=%zu\n", cbRead, cbWritten));

    RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeR), VINF_SUCCESS);
    RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeW), VINF_SUCCESS);


    RTTestISub("VERR_BROKEN_PIPE");
    RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, 0), VINF_SUCCESS);
    RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeR), VINF_SUCCESS);
    cbWritten = ~(size_t)2;
    RTTESTI_CHECK_RC(RTPipeWrite(hPipeW, "", 0, &cbWritten), VINF_SUCCESS);
    RTTESTI_CHECK(cbWritten == 0);
    cbWritten = ~(size_t)2;
    RTTESTI_CHECK_RC(RTPipeWrite(hPipeW, "4", 1, &cbWritten), VERR_BROKEN_PIPE);
    RTTESTI_CHECK(cbWritten == ~(size_t)2);
    RTTESTI_CHECK_RC(RTPipeClose(hPipeW), VINF_SUCCESS);

    RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, 0), VINF_SUCCESS);
    RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeW), VINF_SUCCESS);
    cbRead = ~(size_t)0;
    RTTESTI_CHECK_RC(RTPipeRead(hPipeR, abBuf, 0, &cbRead), VINF_SUCCESS);
    RTTESTI_CHECK(cbRead == 0);
    cbRead = ~(size_t)3;
    RTTESTI_CHECK_RC(RTPipeRead(hPipeR, abBuf, sizeof(abBuf), &cbRead), VERR_BROKEN_PIPE);
    RTTESTI_CHECK(cbRead == ~(size_t)3);
    RTTESTI_CHECK_RC(RTPipeClose(hPipeR), VINF_SUCCESS);

    RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, 0), VINF_SUCCESS);
    cbWritten = ~(size_t)2;
    RTTESTI_CHECK_RC(RTPipeWrite(hPipeW, "42", 2, &cbWritten), VINF_SUCCESS);
    RTTESTI_CHECK(cbWritten == 2);
    RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeW), VINF_SUCCESS);
    cbRead = ~(size_t)0;
    RTTESTI_CHECK_RC_RETV(RTPipeRead(hPipeR, abBuf, 0, &cbRead), VINF_SUCCESS);
    RTTESTI_CHECK(cbRead == 0);
    cbRead = ~(size_t)0;
    RTTESTI_CHECK_RC(RTPipeRead(hPipeR, &abBuf[0], 1, &cbRead), VINF_SUCCESS);
    RTTESTI_CHECK(cbRead == 1);
    cbRead = ~(size_t)0;
    RTTESTI_CHECK_RC(RTPipeRead(hPipeR, &abBuf[1], 1, &cbRead), VINF_SUCCESS);
    RTTESTI_CHECK(cbRead == 1);
    RTTESTI_CHECK(!memcmp(abBuf, "42", 2));
    cbRead = ~(size_t)0;
    RTTESTI_CHECK_RC(RTPipeRead(hPipeR, abBuf, 0, &cbRead), VINF_SUCCESS);
    RTTESTI_CHECK(cbRead == 0);
    cbRead = ~(size_t)3;
    RTTESTI_CHECK_RC_RETV(RTPipeRead(hPipeR, abBuf, sizeof(abBuf), &cbRead), VERR_BROKEN_PIPE);
    RTTESTI_CHECK(cbRead == ~(size_t)3);
    RTTESTI_CHECK_RC(RTPipeClose(hPipeR), VINF_SUCCESS);

    RTTestISub("Blocking");
    RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, 0), VINF_SUCCESS);
    RTTESTI_CHECK_RC_RETV(RTPipeWrite(hPipeW, "42!", 3, &cbWritten), VINF_SUCCESS);
    RTTESTI_CHECK(cbWritten == 3);
    RTTESTI_CHECK_RC_RETV(RTPipeReadBlocking(hPipeR, abBuf, 3, NULL), VINF_SUCCESS);
    RTTESTI_CHECK(!memcmp(abBuf, "42!", 3));
    RTTESTI_CHECK_RC(RTPipeClose(hPipeW), VINF_SUCCESS);
    RTTESTI_CHECK_RC_RETV(RTPipeReadBlocking(hPipeR, &abBuf[0], 0, NULL), VINF_SUCCESS);
    cbRead = ~(size_t)42;
    RTTESTI_CHECK_RC_RETV(RTPipeReadBlocking(hPipeR, &abBuf[0], 0, &cbRead), VINF_SUCCESS);
    RTTESTI_CHECK(cbRead == 0);
    RTTESTI_CHECK_RC_RETV(RTPipeReadBlocking(hPipeR, &abBuf[0], 1, NULL), VERR_BROKEN_PIPE);
    cbRead = ~(size_t)42;
    RTTESTI_CHECK_RC_RETV(RTPipeReadBlocking(hPipeR, &abBuf[0], 1, &cbRead), VERR_BROKEN_PIPE);
    RTTESTI_CHECK(cbRead == 0);
    RTTESTI_CHECK_RC(RTPipeClose(hPipeR), VINF_SUCCESS);

    RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, 0), VINF_SUCCESS);
    RTTESTI_CHECK_RC_RETV(RTPipeWriteBlocking(hPipeW, "42!", 3, NULL), VINF_SUCCESS);
    RTTESTI_CHECK(cbWritten == 3);
    cbRead = ~(size_t)0;
    RTTESTI_CHECK_RC_RETV(RTPipeRead(hPipeR, &abBuf[0], 1, &cbRead), VINF_SUCCESS);
    RTTESTI_CHECK(cbRead == 1);
    RTTESTI_CHECK_RC_RETV(RTPipeReadBlocking(hPipeR, &abBuf[1], 1, NULL), VINF_SUCCESS);
    RTTESTI_CHECK_RC_RETV(RTPipeReadBlocking(hPipeR, &abBuf[2], 1, NULL), VINF_SUCCESS);
    RTTESTI_CHECK(!memcmp(abBuf, "42!", 3));
    RTTESTI_CHECK_RC(RTPipeClose(hPipeR), VINF_SUCCESS);
    RTTESTI_CHECK_RC_RETV(RTPipeWriteBlocking(hPipeW, "", 0, NULL), VINF_SUCCESS);
    cbWritten = ~(size_t)9;
    RTTESTI_CHECK_RC_RETV(RTPipeWriteBlocking(hPipeW, "", 0, &cbWritten), VINF_SUCCESS);
    RTTESTI_CHECK(cbWritten == 0);
    RTTESTI_CHECK_RC_RETV(RTPipeWriteBlocking(hPipeW, "42", 2, NULL), VERR_BROKEN_PIPE);
    cbWritten = ~(size_t)9;
    RTTESTI_CHECK_RC_RETV(RTPipeWriteBlocking(hPipeW, "42", 2, &cbWritten), VERR_BROKEN_PIPE);
    RTTESTI_CHECK(cbWritten == 0);
    RTTESTI_CHECK_RC(RTPipeClose(hPipeW), VINF_SUCCESS);
}
コード例 #20
0
/**
 * Destruct a TCP socket stream driver instance.
 *
 * Most VM resources are freed by the VM. This callback is provided so that
 * any non-VM resources can be freed correctly.
 *
 * @param   pDrvIns     The driver instance data.
 */
static DECLCALLBACK(void) drvTCPDestruct(PPDMDRVINS pDrvIns)
{
    PDRVTCP pThis = PDMINS_2_DATA(pDrvIns, PDRVTCP);
    LogFlow(("%s: %s\n", __FUNCTION__, pThis->pszLocation));
    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);

    drvTCPShutdownListener(pThis);

    /*
     * While the thread exits, clean up as much as we can.
     */
    if (pThis->hTcpSock != NIL_RTSOCKET)
    {
        int rc = RTPollSetRemove(pThis->hPollSet, DRVTCP_POLLSET_ID_SOCKET);
        AssertRC(rc);

        rc = RTSocketShutdown(pThis->hTcpSock, true /* fRead */, true /* fWrite */);
        AssertRC(rc);

        rc = RTSocketClose(pThis->hTcpSock);
        AssertRC(rc); RT_NOREF(rc);

        pThis->hTcpSock = NIL_RTSOCKET;
    }

    if (pThis->hPipeWakeR != NIL_RTPIPE)
    {
        int rc = RTPipeClose(pThis->hPipeWakeR);
        AssertRC(rc);

        pThis->hPipeWakeR = NIL_RTPIPE;
    }

    if (pThis->hPipeWakeW != NIL_RTPIPE)
    {
        int rc = RTPipeClose(pThis->hPipeWakeW);
        AssertRC(rc);

        pThis->hPipeWakeW = NIL_RTPIPE;
    }

    if (pThis->hPollSet != NIL_RTPOLLSET)
    {
        int rc = RTPollSetDestroy(pThis->hPollSet);
        AssertRC(rc);

        pThis->hPollSet = NIL_RTPOLLSET;
    }

    MMR3HeapFree(pThis->pszLocation);
    pThis->pszLocation = NULL;

    /*
     * Wait for the thread.
     */
    if (pThis->ListenThread != NIL_RTTHREAD)
    {
        int rc = RTThreadWait(pThis->ListenThread, 30000, NULL);
        if (RT_SUCCESS(rc))
            pThis->ListenThread = NIL_RTTHREAD;
        else
            LogRel(("DrvTCP%d: listen thread did not terminate (%Rrc)\n", pDrvIns->iInstance, rc));
    }
}
コード例 #21
0
ファイル: tstRTPoll.cpp プロジェクト: miguelinux/vbox
static void tstRTPoll1(void)
{
    RTTestISub("Basics");

    /* create and destroy. */
    RTPOLLSET hSet = NIL_RTPOLLSET;
    RTTESTI_CHECK_RC_RETV(RTPollSetCreate(&hSet), VINF_SUCCESS);
    RTTESTI_CHECK_RETV(hSet != NIL_RTPOLLSET);
    RTTESTI_CHECK_RC(RTPollSetDestroy(hSet), VINF_SUCCESS);
    RTTESTI_CHECK_RC(RTPollSetDestroy(NIL_RTPOLLSET), VINF_SUCCESS);

    /* empty set, adding a NIL handle. */
    hSet = NIL_RTPOLLSET;
    RTTESTI_CHECK_RC_RETV(RTPollSetCreate(&hSet), VINF_SUCCESS);
    RTTESTI_CHECK_RETV(hSet != NIL_RTPOLLSET);

    RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 0);
    RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSet, 0, NULL), VERR_POLL_HANDLE_ID_NOT_FOUND);

    RTTESTI_CHECK_RC(RTPollSetAddPipe(hSet, NIL_RTPIPE, RTPOLL_EVT_READ, 1 /*id*/), VINF_SUCCESS);
    RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 0);
    RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSet, 1 /*id*/, NULL), VERR_POLL_HANDLE_ID_NOT_FOUND);
    RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 0), VERR_POLL_HANDLE_ID_NOT_FOUND);
    RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 0);

    RTTESTI_CHECK_RC(RTPollSetDestroy(hSet), VINF_SUCCESS);

    /*
     * Set with pipes
     */
    RTPIPE hPipeR;
    RTPIPE hPipeW;
    RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, 0/*fFlags*/), VINF_SUCCESS);

    hSet = NIL_RTPOLLSET;
    RTTESTI_CHECK_RC_RETV(RTPollSetCreate(&hSet), VINF_SUCCESS);
    RTTESTI_CHECK_RETV(hSet != NIL_RTPOLLSET);

    /* add the read pipe */
    RTTESTI_CHECK_RC_RETV(RTPollSetAddPipe(hSet, hPipeR, RTPOLL_EVT_READ, 1 /*id*/), VINF_SUCCESS);
    RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 1);
    RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSet, 1 /*id*/, NULL), VINF_SUCCESS);
    RTHANDLE Handle;
    RTTESTI_CHECK_RC_RETV(RTPollSetQueryHandle(hSet, 1 /*id*/, &Handle), VINF_SUCCESS);
    RTTESTI_CHECK(Handle.enmType == RTHANDLETYPE_PIPE);
    RTTESTI_CHECK(Handle.u.hPipe == hPipeR);

    /* poll on the set, should time out. */
    RTTESTI_CHECK_RC(RTPoll(hSet, 0, NULL,  NULL), VERR_TIMEOUT);
    RTTESTI_CHECK_RC(RTPoll(hSet, 1, NULL,  NULL), VERR_TIMEOUT);

    /* add the write pipe with error detection only, check that poll still times out. remove it again. */
    RTTESTI_CHECK_RC(RTPollSetAddPipe(hSet, hPipeW, RTPOLL_EVT_ERROR, 11 /*id*/), VINF_SUCCESS);
    RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 2);
    RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSet, 11 /*id*/, NULL), VINF_SUCCESS);

    RTTESTI_CHECK_RC(RTPoll(hSet, 0, NULL,  NULL), VERR_TIMEOUT);
    RTTESTI_CHECK_RC(RTPoll(hSet, 1, NULL,  NULL), VERR_TIMEOUT);

    RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 11), VINF_SUCCESS);
    RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 1);

    /* add the write pipe */
    RTTESTI_CHECK_RC(RTPollSetAddPipe(hSet, hPipeW, RTPOLL_EVT_WRITE, 10 /*id*/), VINF_SUCCESS);
    RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 2);
    RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSet, 10 /*id*/, NULL), VINF_SUCCESS);

    RTTESTI_CHECK_RC_RETV(RTPollSetQueryHandle(hSet, 10 /*id*/, &Handle), VINF_SUCCESS);
    RTTESTI_CHECK(Handle.enmType == RTHANDLETYPE_PIPE);
    RTTESTI_CHECK(Handle.u.hPipe == hPipeW);

    RTTESTI_CHECK_RC_RETV(RTPollSetQueryHandle(hSet, 1 /*id*/, &Handle), VINF_SUCCESS);
    RTTESTI_CHECK(Handle.enmType == RTHANDLETYPE_PIPE);
    RTTESTI_CHECK(Handle.u.hPipe == hPipeR);

    /* poll on the set again, now it should indicate hPipeW is ready. */
    int rc;
    RTTESTI_CHECK_RC(RTPoll(hSet, 0,   NULL,  NULL), VINF_SUCCESS);
    RTTESTI_CHECK_RC(rc = RTPoll(hSet, 100, NULL,  NULL), VINF_SUCCESS);
    if (RT_SUCCESS(rc))
        RTTESTI_CHECK_RC(RTPoll(hSet, RT_INDEFINITE_WAIT, NULL,  NULL), VINF_SUCCESS);

    RTTESTI_CHECK_RC(rc = RTPollNoResume(hSet, 0,   NULL,  NULL), VINF_SUCCESS);
    RTTESTI_CHECK_RC(rc = RTPollNoResume(hSet, 100, NULL,  NULL), VINF_SUCCESS);
    if (RT_SUCCESS(rc))
        RTTESTI_CHECK_RC(rc = RTPollNoResume(hSet, RT_INDEFINITE_WAIT, NULL,  NULL), VINF_SUCCESS);

    uint32_t fEvents = UINT32_MAX;
    uint32_t id      = UINT32_MAX;
    RTTESTI_CHECK_RC(RTPoll(hSet, 0, &fEvents, &id), VINF_SUCCESS);
    RTTESTI_CHECK(id == 10);
    RTTESTI_CHECK(fEvents == RTPOLL_EVT_WRITE);

    fEvents = UINT32_MAX;
    id      = UINT32_MAX;
    RTTESTI_CHECK_RC(rc = RTPoll(hSet, 250, &fEvents, &id), VINF_SUCCESS);
    RTTESTI_CHECK(id == 10);
    RTTESTI_CHECK(fEvents == RTPOLL_EVT_WRITE);

    if (RT_SUCCESS(rc))
    {
        fEvents = UINT32_MAX;
        id      = UINT32_MAX;
        RTTESTI_CHECK_RC(RTPoll(hSet, RT_INDEFINITE_WAIT, &fEvents, &id), VINF_SUCCESS);
        RTTESTI_CHECK(id == 10);
        RTTESTI_CHECK(fEvents == RTPOLL_EVT_WRITE);
    }

    fEvents = UINT32_MAX;
    id      = UINT32_MAX;
    RTTESTI_CHECK_RC(RTPollNoResume(hSet, 0, &fEvents, &id), VINF_SUCCESS);
    RTTESTI_CHECK(id == 10);
    RTTESTI_CHECK(fEvents == RTPOLL_EVT_WRITE);

    fEvents = UINT32_MAX;
    id      = UINT32_MAX;
    RTTESTI_CHECK_RC(rc = RTPollNoResume(hSet, 100, &fEvents, &id), VINF_SUCCESS);
    RTTESTI_CHECK(id == 10);
    RTTESTI_CHECK(fEvents == RTPOLL_EVT_WRITE);

    if (RT_SUCCESS(rc))
    {
        fEvents = UINT32_MAX;
        id      = UINT32_MAX;
        RTTESTI_CHECK_RC(RTPollNoResume(hSet, RT_INDEFINITE_WAIT, &fEvents, &id), VINF_SUCCESS);
        RTTESTI_CHECK(id == 10);
        RTTESTI_CHECK(fEvents == RTPOLL_EVT_WRITE);
    }

    /* Write to the pipe. Currently ASSUMING we'll get the read ready now... Good idea? */
    RTTESTI_CHECK_RC(rc = RTPipeWriteBlocking(hPipeW, "hello", 5, NULL), VINF_SUCCESS);
    if (RT_SUCCESS(rc))
    {
        fEvents = UINT32_MAX;
        id      = UINT32_MAX;
        RTTESTI_CHECK_RC(RTPoll(hSet, 0, &fEvents, &id), VINF_SUCCESS);
        RTTESTI_CHECK(id == 1);
        RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);

        fEvents = UINT32_MAX;
        id      = UINT32_MAX;
        RTTESTI_CHECK_RC(rc = RTPoll(hSet, 256, &fEvents, &id), VINF_SUCCESS);
        RTTESTI_CHECK(id == 1);
        RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);

        if (RT_SUCCESS(rc))
        {
            fEvents = UINT32_MAX;
            id      = UINT32_MAX;
            RTTESTI_CHECK_RC(RTPoll(hSet, RT_INDEFINITE_WAIT, &fEvents, &id), VINF_SUCCESS);
            RTTESTI_CHECK(id == 1);
            RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);
        }

        fEvents = UINT32_MAX;
        id      = UINT32_MAX;
        RTTESTI_CHECK_RC(RTPollNoResume(hSet, 0, &fEvents, &id), VINF_SUCCESS);
        RTTESTI_CHECK(id == 1);
        RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);

        fEvents = UINT32_MAX;
        id      = UINT32_MAX;
        RTTESTI_CHECK_RC(rc = RTPollNoResume(hSet, 383, &fEvents, &id), VINF_SUCCESS);
        RTTESTI_CHECK(id == 1);
        RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);

        if (RT_SUCCESS(rc))
        {
            fEvents = UINT32_MAX;
            id      = UINT32_MAX;
            RTTESTI_CHECK_RC(RTPollNoResume(hSet, RT_INDEFINITE_WAIT, &fEvents, &id), VINF_SUCCESS);
            RTTESTI_CHECK(id == 1);
            RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);
        }
    }

    /* Remove the read pipe, do a quick poll check. */
    RTTESTI_CHECK_RC_RETV(RTPollSetRemove(hSet, 1), VINF_SUCCESS);
    RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 1);
    RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSet, 1 /*id*/, NULL), VERR_POLL_HANDLE_ID_NOT_FOUND);
    RTTESTI_CHECK_RC_RETV(RTPollSetQueryHandle(hSet, 10 /*id*/, &Handle), VINF_SUCCESS);
    RTTESTI_CHECK(Handle.enmType == RTHANDLETYPE_PIPE);
    RTTESTI_CHECK(Handle.u.hPipe == hPipeW);

    RTTESTI_CHECK_RC(RTPoll(hSet, 0, NULL, NULL), VINF_SUCCESS);

    /* Add it back and check that we now get the write handle when polling.
       (Is this FIFOing a good idea?) */
    RTTESTI_CHECK_RC_RETV(RTPoll(hSet, 0, NULL, NULL), VINF_SUCCESS);

    RTTESTI_CHECK_RC_RETV(RTPollSetAddPipe(hSet, hPipeR, RTPOLL_EVT_READ, 1 /*id*/), VINF_SUCCESS);
    RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 2);
    RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSet, 1 /*id*/, NULL), VINF_SUCCESS);

    RTTESTI_CHECK_RC_RETV(RTPollSetQueryHandle(hSet, 1 /*id*/, &Handle), VINF_SUCCESS);
    RTTESTI_CHECK(Handle.enmType == RTHANDLETYPE_PIPE);
    RTTESTI_CHECK(Handle.u.hPipe == hPipeR);

    RTTESTI_CHECK_RC_RETV(RTPollSetQueryHandle(hSet, 10 /*id*/, &Handle), VINF_SUCCESS);
    RTTESTI_CHECK(Handle.enmType == RTHANDLETYPE_PIPE);
    RTTESTI_CHECK(Handle.u.hPipe == hPipeW);

    fEvents = UINT32_MAX;
    id      = UINT32_MAX;
    RTTESTI_CHECK_RC(rc = RTPollNoResume(hSet, 555, &fEvents, &id), VINF_SUCCESS);
    RTTESTI_CHECK(id == 10);
    RTTESTI_CHECK(fEvents == RTPOLL_EVT_WRITE);

    /* Remove it again and break the pipe by closing the read end. */
    RTTESTI_CHECK_RC_RETV(RTPollSetRemove(hSet, 1), VINF_SUCCESS);
    RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 1);
    RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSet, 1 /*id*/, NULL), VERR_POLL_HANDLE_ID_NOT_FOUND);
    RTTESTI_CHECK_RC_RETV(RTPollSetQueryHandle(hSet, 10 /*id*/, &Handle), VINF_SUCCESS);
    RTTESTI_CHECK(Handle.enmType == RTHANDLETYPE_PIPE);
    RTTESTI_CHECK(Handle.u.hPipe == hPipeW);

    RTTESTI_CHECK_RC(RTPoll(hSet, 0, NULL, NULL), VINF_SUCCESS);

    RTTESTI_CHECK_RC(RTPipeClose(hPipeR), VINF_SUCCESS);

    fEvents = UINT32_MAX;
    id      = UINT32_MAX;
    RTTESTI_CHECK_RC(RTPollNoResume(hSet, 0, &fEvents, &id), VINF_SUCCESS);
    RTTESTI_CHECK(id == 10);
    RTTESTI_CHECK_MSG(   fEvents == RTPOLL_EVT_ERROR \
                      || fEvents == (RTPOLL_EVT_ERROR | RTPOLL_EVT_WRITE), ("%#x\n", fEvents));

    RTTESTI_CHECK_RC(RTPollSetDestroy(hSet), VINF_SUCCESS);
    RTTESTI_CHECK_RC(RTPipeClose(hPipeW), VINF_SUCCESS);

    /*
     * Check FIFO order when removing and adding.
     *
     * Note! FIFO order is not guaranteed when a handle has more than one entry
     * in the set.
     */
    RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, 0/*fFlags*/), VINF_SUCCESS);
    RTPIPE hPipeR2, hPipeW2;
    RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR2, &hPipeW2, 0/*fFlags*/), VINF_SUCCESS);
    RTPIPE hPipeR3, hPipeW3;
    RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR3, &hPipeW3, 0/*fFlags*/), VINF_SUCCESS);
    RTTESTI_CHECK_RC_RETV(RTPollSetCreate(&hSet), VINF_SUCCESS);
    RTTESTI_CHECK_RC_RETV(RTPollSetAddPipe(hSet, hPipeR,  RTPOLL_EVT_READ,  1 /*id*/), VINF_SUCCESS);
    RTTESTI_CHECK_RC_RETV(RTPollSetAddPipe(hSet, hPipeW,  RTPOLL_EVT_WRITE, 2 /*id*/), VINF_SUCCESS);
    RTTESTI_CHECK_RC_RETV(RTPollSetAddPipe(hSet, hPipeR2, RTPOLL_EVT_READ,  3 /*id*/), VINF_SUCCESS);
    RTTESTI_CHECK_RC_RETV(RTPollSetAddPipe(hSet, hPipeW2, RTPOLL_EVT_WRITE, 4 /*id*/), VINF_SUCCESS);
    RTTESTI_CHECK_RC_RETV(RTPollSetAddPipe(hSet, hPipeR3, RTPOLL_EVT_READ,  5 /*id*/), VINF_SUCCESS);

    id = UINT32_MAX; fEvents = UINT32_MAX;
    RTTESTI_CHECK_RC(RTPoll(hSet, 5, &fEvents, &id), VINF_SUCCESS);
    RTTESTI_CHECK(id == 2);
    RTTESTI_CHECK(fEvents == RTPOLL_EVT_WRITE);

    RTTESTI_CHECK_RC(RTPipeWriteBlocking(hPipeW,  "hello", 5, NULL), VINF_SUCCESS);
    RTTESTI_CHECK_RC(RTPipeWriteBlocking(hPipeW2, "hello", 5, NULL), VINF_SUCCESS);
    RTTESTI_CHECK_RC(RTPipeWriteBlocking(hPipeW3, "hello", 5, NULL), VINF_SUCCESS);
    id = UINT32_MAX; fEvents = UINT32_MAX;
    RTTESTI_CHECK_RC(RTPoll(hSet, 5, &fEvents, &id), VINF_SUCCESS);
    RTTESTI_CHECK(id == 1);
    RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);

    RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 1), VINF_SUCCESS);
    id = UINT32_MAX; fEvents = UINT32_MAX;
    RTTESTI_CHECK_RC(RTPoll(hSet, 5, &fEvents, &id), VINF_SUCCESS);
    RTTESTI_CHECK(id == 2);
    RTTESTI_CHECK(fEvents == RTPOLL_EVT_WRITE);

    RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 2), VINF_SUCCESS);
    id = UINT32_MAX; fEvents = UINT32_MAX;
    RTTESTI_CHECK_RC(RTPoll(hSet, 5, &fEvents, &id), VINF_SUCCESS);
    RTTESTI_CHECK(id == 3);
    RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);

    RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 3), VINF_SUCCESS);
    id = UINT32_MAX; fEvents = UINT32_MAX;
    RTTESTI_CHECK_RC(RTPoll(hSet, 5, &fEvents, &id), VINF_SUCCESS);
    RTTESTI_CHECK(id == 4);
    RTTESTI_CHECK(fEvents == RTPOLL_EVT_WRITE);

    RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 4), VINF_SUCCESS);
    id = UINT32_MAX; fEvents = UINT32_MAX;
    RTTESTI_CHECK_RC(RTPoll(hSet, 5, &fEvents, &id), VINF_SUCCESS);
    RTTESTI_CHECK(id == 5);
    RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);

    RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 5), VINF_SUCCESS);
    id = UINT32_MAX; fEvents = UINT32_MAX;
    RTTESTI_CHECK_RC(RTPoll(hSet, 5, &fEvents, &id), VERR_TIMEOUT);

    RTTESTI_CHECK_RC(RTPipeClose(hPipeW),   VINF_SUCCESS);
    RTTESTI_CHECK_RC(RTPipeClose(hPipeR),   VINF_SUCCESS);
    RTTESTI_CHECK_RC(RTPipeClose(hPipeW2),  VINF_SUCCESS);
    RTTESTI_CHECK_RC(RTPipeClose(hPipeR2),  VINF_SUCCESS);
    RTTESTI_CHECK_RC(RTPipeClose(hPipeW3),  VINF_SUCCESS);
    RTTESTI_CHECK_RC(RTPipeClose(hPipeR3),  VINF_SUCCESS);
    RTTESTI_CHECK_RC(RTPollSetDestroy(hSet),  VINF_SUCCESS);

}
コード例 #22
0
ファイル: tstRTPoll.cpp プロジェクト: miguelinux/vbox
static void tstRTPoll2(void)
{
    RTTestISub("Negative");

    /*
     * Bad set pointer and handle values.
     */
    RTTESTI_CHECK_RC(RTPollSetCreate(NULL), VERR_INVALID_POINTER);
    RTPOLLSET hSetInvl = (RTPOLLSET)(intptr_t)-3;
    RTTESTI_CHECK_RC(RTPollSetDestroy(hSetInvl), VERR_INVALID_HANDLE);
    RTHANDLE Handle;
    Handle.enmType = RTHANDLETYPE_PIPE;
    Handle.u.hPipe = NIL_RTPIPE;
    RTTESTI_CHECK_RC(RTPollSetAdd(hSetInvl, &Handle, RTPOLL_EVT_ERROR, 1), VERR_INVALID_HANDLE);
    RTTESTI_CHECK_RC(RTPollSetRemove(hSetInvl, 1), VERR_INVALID_HANDLE);
    RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSetInvl, 1, NULL), VERR_INVALID_HANDLE);
    RTTESTI_CHECK(RTPollSetGetCount(hSetInvl) == UINT32_MAX);
    RTTESTI_CHECK_RC(RTPoll(hSetInvl, 0, NULL, NULL),  VERR_INVALID_HANDLE);
    RTTESTI_CHECK_RC(RTPollNoResume(hSetInvl, 0, NULL, NULL),  VERR_INVALID_HANDLE);

    /*
     * Invalid arguments and other stuff.
     */
    RTPOLLSET hSet = NIL_RTPOLLSET;
    RTTESTI_CHECK_RC_RETV(RTPollSetCreate(&hSet), VINF_SUCCESS);

    RTTESTI_CHECK_RC(RTPoll(hSet, RT_INDEFINITE_WAIT, NULL, NULL), VERR_DEADLOCK);
    RTTESTI_CHECK_RC(RTPollNoResume(hSet, RT_INDEFINITE_WAIT, NULL, NULL), VERR_DEADLOCK);

    RTTESTI_CHECK_RC(RTPollSetRemove(hSet, UINT32_MAX), VERR_INVALID_PARAMETER);
    RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSet, 1,  NULL), VERR_POLL_HANDLE_ID_NOT_FOUND);

    RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 1), VERR_POLL_HANDLE_ID_NOT_FOUND);

    RTTESTI_CHECK_RC(RTPollSetAdd(hSet, NULL, RTPOLL_EVT_ERROR, 1), VINF_SUCCESS);
    RTTESTI_CHECK_RC(RTPollSetAdd(hSet, &Handle, RTPOLL_EVT_ERROR, UINT32_MAX), VERR_INVALID_PARAMETER);
    RTTESTI_CHECK_RC(RTPollSetAdd(hSet, &Handle, UINT32_MAX, 3), VERR_INVALID_PARAMETER);
    Handle.enmType = RTHANDLETYPE_INVALID;
    RTTESTI_CHECK_RC(RTPollSetAdd(hSet, &Handle, RTPOLL_EVT_ERROR, 3), VERR_INVALID_PARAMETER);
    RTTESTI_CHECK_RC(RTPollSetAdd(hSet, NULL, RTPOLL_EVT_ERROR, UINT32_MAX), VERR_INVALID_PARAMETER);

    /* duplicate id */
    RTPIPE hPipeR;
    RTPIPE hPipeW;
    RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, 0/*fFlags*/), VINF_SUCCESS);
    RTTESTI_CHECK_RC(RTPollSetAddPipe(hSet, hPipeR, RTPOLL_EVT_ERROR, 0), VINF_SUCCESS);
    RTTESTI_CHECK_RC(RTPollSetAddPipe(hSet, hPipeR, RTPOLL_EVT_ERROR, 0), VERR_POLL_HANDLE_ID_EXISTS);
    RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 0), VINF_SUCCESS);
    RTPipeClose(hPipeR);
    RTPipeClose(hPipeW);

    /* non-pollable handle */
    RTFILE hBitBucket;
    RTTESTI_CHECK_RC_RETV(RTFileOpenBitBucket(&hBitBucket, RTFILE_O_WRITE), VINF_SUCCESS);
    Handle.enmType = RTHANDLETYPE_FILE;
    Handle.u.hFile = hBitBucket;
    RTTESTI_CHECK_RC(RTPollSetAdd(hSet, &Handle, RTPOLL_EVT_WRITE, 10), VERR_POLL_HANDLE_NOT_POLLABLE);
    RTFileClose(hBitBucket);

    RTTESTI_CHECK_RC_RETV(RTPollSetDestroy(hSet), VINF_SUCCESS);



}