Пример #1
0
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);
}
Пример #2
0
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);
}
Пример #3
0
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;
}
Пример #4
0
/**
 * Writes the stream to standard output.
 *
 * @returns IPRT status code
 * @param   pStream             The stream.
 */
int ScmStreamWriteToStdOut(PSCMSTREAM pStream)
{
    int rc;

#ifdef RT_STRICT
    /*
     * Check that what we're going to write makes sense first.
     */
    rc = ScmStreamCheckItegrity(pStream);
    if (RT_FAILURE(rc))
        return rc;
#endif

    /*
     * Do the actual writing.
     */
    RTHANDLE h;
    rc = RTHandleGetStandard(RTHANDLESTD_OUTPUT, &h);
    if (RT_SUCCESS(rc))
    {
        switch (h.enmType)
        {
            case RTHANDLETYPE_FILE:
                rc = RTFileWrite(h.u.hFile, pStream->pch, pStream->cb, NULL);
                break;
            case RTHANDLETYPE_PIPE:
                rc = RTPipeWriteBlocking(h.u.hPipe, pStream->pch, pStream->cb, NULL);
                break;
            default:
                rc = VERR_INVALID_HANDLE;
                break;
        }
    }
    return rc;
}
Пример #5
0
int USBProxyBackendUsbIp::interruptWait(void)
{
    AssertReturn(!isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);

    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);

    int rc = RTPipeWriteBlocking(m->hWakeupPipeW, "", 1, NULL);
    if (RT_SUCCESS(rc))
        RTPipeFlush(m->hWakeupPipeW);
    LogFlowFunc(("returning %Rrc\n", rc));
    return rc;
}
Пример #6
0
int USBProxyBackendLinux::interruptWait(void)
{
    AssertReturn(!isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);

    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
#ifdef VBOX_USB_WITH_SYSFS
    LogFlowFunc(("mUsingUsbfsDevices=%d\n", mUsingUsbfsDevices));
    if (!mUsingUsbfsDevices)
    {
        mpWaiter->Interrupt();
        LogFlowFunc(("Returning VINF_SUCCESS\n"));
        return VINF_SUCCESS;
    }
#endif /* VBOX_USB_WITH_SYSFS */
    int rc = RTPipeWriteBlocking(mhWakeupPipeW, WAKE_UP_STRING, WAKE_UP_STRING_LEN, NULL);
    if (RT_SUCCESS(rc))
        RTPipeFlush(mhWakeupPipeW);
    LogFlowFunc(("returning %Rrc\n", rc));
    return rc;
}
Пример #7
0
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);
}
Пример #8
0
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);

}