Пример #1
0
RTDECL(int) RTPipeReadBlocking(RTPIPE hPipe, void *pvBuf, size_t cbToRead, size_t *pcbRead)
{
    RTPIPEINTERNAL *pThis = hPipe;
    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
    AssertReturn(pThis->u32Magic == RTPIPE_MAGIC, VERR_INVALID_HANDLE);
    AssertReturn(pThis->fRead, VERR_ACCESS_DENIED);
    AssertPtr(pvBuf);

    int rc = rtPipeTryBlocking(pThis);
    if (RT_SUCCESS(rc))
    {
        size_t cbTotalRead = 0;
        while (cbToRead > 0)
        {
            ssize_t cbRead = read(pThis->fd, pvBuf, RT_MIN(cbToRead, SSIZE_MAX));
            if (cbRead < 0)
            {
                rc = RTErrConvertFromErrno(errno);
                break;
            }
            if (!cbRead && rtPipePosixHasHup(pThis))
            {
                rc = VERR_BROKEN_PIPE;
                break;
            }

            /* advance */
            pvBuf        = (char *)pvBuf + cbRead;
            cbTotalRead += cbRead;
            cbToRead    -= cbRead;
        }

        if (pcbRead)
        {
            *pcbRead = cbTotalRead;
            if (   RT_FAILURE(rc)
                && cbTotalRead
                && rc != VERR_INVALID_POINTER)
                rc = VINF_SUCCESS;
        }

        ASMAtomicDecU32(&pThis->u32State);
    }
    return rc;
}
Пример #2
0
RTDECL(int) RTPipeWriteBlocking(RTPIPE hPipe, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten)
{
    RTPIPEINTERNAL *pThis = hPipe;
    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
    AssertReturn(pThis->u32Magic == RTPIPE_MAGIC, VERR_INVALID_HANDLE);
    AssertReturn(!pThis->fRead, VERR_ACCESS_DENIED);
    AssertPtr(pvBuf);
    AssertPtrNull(pcbWritten);

    int rc = rtPipeTryBlocking(pThis);
    if (RT_SUCCESS(rc))
    {
        size_t cbTotalWritten = 0;
        while (cbToWrite > 0)
        {
            ssize_t cbWritten = write(pThis->fd, pvBuf, RT_MIN(cbToWrite, SSIZE_MAX));
            if (cbWritten < 0)
            {
                rc = RTErrConvertFromErrno(errno);
                break;
            }

            /* advance */
            pvBuf           = (char const *)pvBuf + cbWritten;
            cbTotalWritten += cbWritten;
            cbToWrite      -= cbWritten;
        }

        if (pcbWritten)
        {
            *pcbWritten = cbTotalWritten;
            if (   RT_FAILURE(rc)
                && cbTotalWritten
                && rc != VERR_INVALID_POINTER)
                rc = VINF_SUCCESS;
        }

        ASMAtomicDecU32(&pThis->u32State);
    }
    return rc;
}
Пример #3
0
RTDECL(int) RTPipeWriteBlocking(RTPIPE hPipe, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten)
{
    RTPIPEINTERNAL *pThis = hPipe;
    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
    AssertReturn(pThis->u32Magic == RTPIPE_MAGIC, VERR_INVALID_HANDLE);
    AssertReturn(!pThis->fRead, VERR_ACCESS_DENIED);
    AssertPtr(pvBuf);
    AssertPtrNull(pcbWritten);

    int rc = RTCritSectEnter(&pThis->CritSect);
    if (RT_SUCCESS(rc))
    {
        /* No concurrent readers, sorry. */
        if (pThis->cUsers == 0)
        {
            pThis->cUsers++;

            /*
             * If I/O is pending, wait for it to complete.
             */
            if (pThis->fIOPending)
            {
                rc = rtPipeWriteCheckCompletion(pThis);
                while (rc == VINF_TRY_AGAIN)
                {
                    Assert(pThis->fIOPending);
                    HANDLE hEvent = pThis->Overlapped.hEvent;
                    RTCritSectLeave(&pThis->CritSect);
                    WaitForSingleObject(pThis->Overlapped.hEvent, INFINITE);
                    RTCritSectEnter(&pThis->CritSect);
                }
            }
            if (RT_SUCCESS(rc))
            {
                Assert(!pThis->fIOPending);
                pThis->fPromisedWritable = false;

                /*
                 * Try write everything.
                 * No bounce buffering, cUsers protects us.
                 */
                size_t cbTotalWritten = 0;
                while (cbToWrite > 0)
                {
                    rc = ResetEvent(pThis->Overlapped.hEvent); Assert(rc == TRUE);
                    pThis->fIOPending = true;
                    RTCritSectLeave(&pThis->CritSect);

                    DWORD cbWritten = 0;
                    if (WriteFile(pThis->hPipe, pvBuf,
                                  cbToWrite <= ~(DWORD)0 ? (DWORD)cbToWrite : ~(DWORD)0,
                                  &cbWritten, &pThis->Overlapped))
                        rc = VINF_SUCCESS;
                    else if (GetLastError() == ERROR_IO_PENDING)
                    {
                        WaitForSingleObject(pThis->Overlapped.hEvent, INFINITE);
                        if (GetOverlappedResult(pThis->hPipe, &pThis->Overlapped, &cbWritten, TRUE /*fWait*/))
                            rc = VINF_SUCCESS;
                        else
                            rc = RTErrConvertFromWin32(GetLastError());
                    }
                    else if (GetLastError() == ERROR_NO_DATA)
                        rc = VERR_BROKEN_PIPE;
                    else
                        rc = RTErrConvertFromWin32(GetLastError());

                    RTCritSectEnter(&pThis->CritSect);
                    pThis->fIOPending = false;
                    if (RT_FAILURE(rc))
                        break;

                    /* advance */
                    pvBuf           = (char const *)pvBuf + cbWritten;
                    cbTotalWritten += cbWritten;
                    cbToWrite      -= cbWritten;
                }

                if (pcbWritten)
                {
                    *pcbWritten = cbTotalWritten;
                    if (   RT_FAILURE(rc)
                        && cbTotalWritten
                        && rc != VERR_INVALID_POINTER)
                        rc = VINF_SUCCESS;
                }
            }

            if (rc == VERR_BROKEN_PIPE)
                pThis->fBrokenPipe = true;

            pThis->cUsers--;
        }
        else
            rc = VERR_WRONG_ORDER;
        RTCritSectLeave(&pThis->CritSect);
    }
    return rc;

#if 1
    return VERR_NOT_IMPLEMENTED;
#else
    int rc = rtPipeTryBlocking(pThis);
    if (RT_SUCCESS(rc))
    {
        size_t cbTotalWritten = 0;
        while (cbToWrite > 0)
        {
            ssize_t cbWritten = write(pThis->fd, pvBuf, RT_MIN(cbToWrite, SSIZE_MAX));
            if (cbWritten < 0)
            {
                rc = RTErrConvertFromErrno(errno);
                break;
            }

            /* advance */
            pvBuf           = (char const *)pvBuf + cbWritten;
            cbTotalWritten += cbWritten;
            cbToWrite      -= cbWritten;
        }

        if (pcbWritten)
        {
            *pcbWritten = cbTotalWritten;
            if (   RT_FAILURE(rc)
                && cbTotalWritten
                && rc != VERR_INVALID_POINTER)
                rc = VINF_SUCCESS;
        }

        ASMAtomicDecU32(&pThis->u32State);
    }
    return rc;
#endif
}