VirtualBox

Changeset 27613 in vbox for trunk/src


Ignore:
Timestamp:
Mar 23, 2010 1:12:54 AM (15 years ago)
Author:
vboxsync
Message:

iprt: Added RTPipeFromNative, implemented the windows version and added tests.

Location:
trunk/src/VBox/Runtime
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/os2/pipe-os2.cpp

    r27129 r27613  
    5252
    5353
     54RTDECL(int)  RTPipeFromNative(PRTPIPE phPipe, RTHCINTPTR hNativePipe, uint32_t fFlags)
     55{
     56    return VERR_NOT_IMPLEMENTED;
     57}
     58
     59
    5460RTDECL(RTHCINTPTR) RTPipeToNative(RTPIPE hPipe)
    5561{
    56     return (RTHCINTPTR)(unsigned int)-1;
     62    return -1;
    5763}
    5864
  • trunk/src/VBox/Runtime/r3/posix/pipe-posix.cpp

    r27312 r27613  
    182182}
    183183
     184RTDECL(int)  RTPipeFromNative(PRTPIPE phPipe, RTHCINTPTR hNativePipe, uint32_t fFlags)
     185{
     186    return VERR_NOT_IMPLEMENTED;
     187}
     188
    184189
    185190RTDECL(RTHCINTPTR) RTPipeToNative(RTPIPE hPipe)
    186191{
    187192    RTPIPEINTERNAL *pThis = hPipe;
    188     AssertPtrReturn(pThis, (RTHCINTPTR)(unsigned int)-1);
    189     AssertReturn(pThis->u32Magic == RTPIPE_MAGIC, (RTHCINTPTR)(unsigned int)-1);
     193    AssertPtrReturn(pThis, -1);
     194    AssertReturn(pThis->u32Magic == RTPIPE_MAGIC, -1);
    190195
    191196    return pThis->fd;
  • trunk/src/VBox/Runtime/r3/win/pipe-win.cpp

    r27553 r27613  
    136136#define FILE_PIPE_CLOSING_STATE         0x00000004
    137137
     138#define FILE_PIPE_INBOUND               0x00000000
     139#define FILE_PIPE_OUTBOUND              0x00000001
     140#define FILE_PIPE_FULL_DUPLEX           0x00000002
     141
     142#define FILE_PIPE_CLIENT_END            0x00000000
     143#define FILE_PIPE_SERVER_END            0x00000001
    138144
    139145extern "C" NTSYSAPI NTSTATUS WINAPI NtQueryInformationFile(HANDLE, PIO_STATUS_BLOCK, PVOID, LONG, FILE_INFORMATION_CLASS);
     
    429435
    430436
     437RTDECL(int)  RTPipeFromNative(PRTPIPE phPipe, RTHCINTPTR hNativePipe, uint32_t fFlags)
     438{
     439    AssertReturn(!(fFlags & ~RTPIPE_N_VALID_MASK), VERR_INVALID_PARAMETER);
     440    AssertReturn(!!(fFlags & RTPIPE_N_READ) != !!(fFlags & RTPIPE_N_WRITE), VERR_INVALID_PARAMETER);
     441
     442    /*
     443     * Get and validate the pipe handle info.
     444     */
     445    HANDLE hNative = (HANDLE)hNativePipe;
     446    AssertReturn(GetFileType(hNative) == FILE_TYPE_PIPE, VERR_INVALID_HANDLE);
     447
     448    DWORD cMaxInstances;
     449    DWORD fInfo;
     450    if (!GetNamedPipeInfo(hNative, &fInfo, NULL, NULL, &cMaxInstances))
     451        return RTErrConvertFromWin32(GetLastError());
     452    AssertReturn(!(fInfo & PIPE_TYPE_MESSAGE), VERR_INVALID_HANDLE);
     453    AssertReturn(cMaxInstances == 1, VERR_INVALID_HANDLE);
     454
     455    DWORD cInstances;
     456    DWORD fState;
     457    if (!GetNamedPipeHandleState(hNative, &fState, &cInstances, NULL, NULL, NULL, 0))
     458        return RTErrConvertFromWin32(GetLastError());
     459    AssertReturn(!(fState & PIPE_NOWAIT), VERR_INVALID_HANDLE);
     460    AssertReturn(!(fState & PIPE_READMODE_MESSAGE), VERR_INVALID_HANDLE);
     461    AssertReturn(cInstances <= 1, VERR_INVALID_HANDLE);
     462
     463    /*
     464     * Looks kind of OK, create a handle so we can try rtPipeQueryInfo on it
     465     * and see if we need to duplicate it to make that call work.
     466     */
     467    RTPIPEINTERNAL *pThis = (RTPIPEINTERNAL *)RTMemAllocZ(sizeof(RTPIPEINTERNAL));
     468    if (!pThis)
     469        return VERR_NO_MEMORY;
     470    int rc = RTCritSectInit(&pThis->CritSect);
     471    if (RT_SUCCESS(rc))
     472    {
     473        pThis->Overlapped.hEvent = CreateEvent(NULL, TRUE /*fManualReset*/,
     474                                               TRUE /*fInitialState*/, NULL /*pName*/);
     475        if (pThis->Overlapped.hEvent != NULL)
     476        {
     477            pThis->u32Magic        = RTPIPE_MAGIC;
     478            pThis->hPipe           = hNative;
     479            pThis->fRead           = !!(fFlags & RTPIPE_N_READ);
     480            //pThis->fIOPending      = false;
     481            //pThis->fZeroByteRead   = false;
     482            //pThis->fBrokenPipe     = false;
     483            //pThisR->fPromisedWritable= false;
     484            //pThis->cUsers          = 0;
     485            //pThis->pbBounceBuf     = NULL;
     486            //pThis->cbBounceBufUsed = 0;
     487            //pThis->cbBounceBufAlloc= 0;
     488            pThis->hPollSet        = NIL_RTPOLLSET;
     489
     490            HANDLE  hNative2 = INVALID_HANDLE_VALUE;
     491            FILE_PIPE_LOCAL_INFORMATION Info;
     492            if (rtPipeQueryInfo(pThis, &Info))
     493                rc = VINF_SUCCESS;
     494            else
     495            {
     496                if (DuplicateHandle(GetCurrentProcess() /*hSrcProcess*/, hNative /*hSrcHandle*/,
     497                                    GetCurrentProcess() /*hDstProcess*/, &hNative2 /*phDstHandle*/,
     498                                    pThis->fRead ? GENERIC_READ : GENERIC_WRITE | FILE_READ_ATTRIBUTES /*dwDesiredAccess*/,
     499                                    !!(fFlags & RTPIPE_N_INHERIT) /*fInheritHandle*/,
     500                                    0 /*dwOptions*/))
     501                {
     502                    pThis->hPipe = hNative2;
     503                    if (rtPipeQueryInfo(pThis, &Info))
     504                        rc = VINF_SUCCESS;
     505                    else
     506                    {
     507                        rc = VERR_ACCESS_DENIED;
     508                        CloseHandle(hNative2);
     509                    }
     510                }
     511                else
     512                    hNative2 = INVALID_HANDLE_VALUE;
     513            }
     514            if (RT_SUCCESS(rc))
     515            {
     516                /*
     517                 * Verify the pipe state and correct the inheritability.
     518                 */
     519                AssertStmt(   Info.NamedPipeState == FILE_PIPE_CONNECTED_STATE
     520                           || Info.NamedPipeState == FILE_PIPE_CLOSING_STATE
     521                           || Info.NamedPipeState == FILE_PIPE_DISCONNECTED_STATE,
     522                           VERR_INVALID_HANDLE);
     523                AssertStmt(   Info.NamedPipeConfiguration
     524                           == (   Info.NamedPipeEnd == FILE_PIPE_SERVER_END
     525                               ? (pThis->fRead ? FILE_PIPE_INBOUND  : FILE_PIPE_OUTBOUND)
     526                               : (pThis->fRead ? FILE_PIPE_OUTBOUND : FILE_PIPE_INBOUND) ),
     527                           VERR_INVALID_HANDLE);
     528                if (   RT_SUCCESS(rc)
     529                    && hNative2 == INVALID_HANDLE_VALUE
     530                    && !SetHandleInformation(hNative,
     531                                             HANDLE_FLAG_INHERIT /*dwMask*/,
     532                                             fFlags & RTPIPE_N_INHERIT ? HANDLE_FLAG_INHERIT : 0))
     533                {
     534                    rc = RTErrConvertFromWin32(GetLastError());
     535                    AssertMsgFailed(("%Rrc\n", rc));
     536                }
     537                if (RT_SUCCESS(rc))
     538                {
     539                    /*
     540                     * Ok, we're good!
     541                     */
     542                    if (hNative2 != INVALID_HANDLE_VALUE)
     543                        CloseHandle(hNative);
     544                    *phPipe = pThis;
     545                    return VINF_SUCCESS;
     546                }
     547            }
     548
     549            /* Bail out. */
     550            if (hNative2 != INVALID_HANDLE_VALUE)
     551                CloseHandle(hNative2);
     552            CloseHandle(pThis->Overlapped.hEvent);
     553        }
     554        RTCritSectDelete(&pThis->CritSect);
     555    }
     556    RTMemFree(pThis);
     557    return rc;
     558}
     559
     560
    431561RTDECL(RTHCINTPTR) RTPipeToNative(RTPIPE hPipe)
    432562{
    433563    RTPIPEINTERNAL *pThis = hPipe;
    434     AssertPtrReturn(pThis, (RTHCINTPTR)(unsigned int)-1);
    435     AssertReturn(pThis->u32Magic == RTPIPE_MAGIC, (RTHCINTPTR)(unsigned int)-1);
     564    AssertPtrReturn(pThis, -1);
     565    AssertReturn(pThis->u32Magic == RTPIPE_MAGIC, -1);
    436566
    437567    return (RTHCINTPTR)pThis->hPipe;
  • trunk/src/VBox/Runtime/r3/win/process-win.cpp

    r27579 r27613  
    604604RTR3DECL(int) RTProcTerminate(RTPROCESS Process)
    605605{
    606     HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, Process);
     606    int     rc       = VINF_SUCCESS;
     607    HANDLE  hProcess = rtProcWinFindPid(Process);
    607608    if (hProcess != NULL)
    608609    {
    609         BOOL fRc = TerminateProcess(hProcess, 127);
    610         CloseHandle(hProcess);
    611         if (fRc)
    612             return VINF_SUCCESS;
    613     }
    614     DWORD dwErr = GetLastError();
    615     return RTErrConvertFromWin32(dwErr);
     610        if (!TerminateProcess(hProcess, 127))
     611            rc = RTErrConvertFromWin32(GetLastError());
     612    }
     613    else
     614    {
     615        hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, Process);
     616        if (hProcess != NULL)
     617        {
     618            BOOL  fRc   = TerminateProcess(hProcess, 127);
     619            DWORD dwErr = GetLastError();
     620            CloseHandle(hProcess);
     621            if (!fRc)
     622                rc = RTErrConvertFromWin32(dwErr);
     623        }
     624    }
     625    return rc;
    616626}
    617627
  • trunk/src/VBox/Runtime/testcase/tstRTPipe.cpp

    r27553 r27613  
    3535#include <iprt/pipe.h>
    3636
     37#include <iprt/env.h>
    3738#include <iprt/err.h>
     39#include <iprt/initterm.h>
    3840#include <iprt/mem.h>
     41#include <iprt/message.h>
     42#include <iprt/param.h>
     43#include <iprt/process.h>
    3944#include <iprt/string.h>
    4045#include <iprt/test.h>
     46
     47
     48/*******************************************************************************
     49*   Global Variables                                                           *
     50*******************************************************************************/
     51static const char g_szTest4Message[] = "This is test #4, everything is working fine.\n\r";
     52static const char g_szTest5Message[] = "This is test #5, everything is working fine.\n\r";
     53
     54
     55static RTEXITCODE tstRTPipe5Child(const char *pszPipe)
     56{
     57    int rc = RTR3Init();
     58    if (RT_FAILURE(rc))
     59        return RTMsgInitFailure(rc);
     60
     61    int64_t iNative;
     62    rc = RTStrToInt64Full(pszPipe, 10, &iNative);
     63    if (RT_FAILURE(rc))
     64        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTStrToUInt64Full(%s) -> %Rrc\n", pszPipe, rc);
     65
     66    RTPIPE hPipe;
     67    rc = RTPipeFromNative(&hPipe, (RTHCINTPTR)iNative, RTPIPE_N_READ);
     68    if (RT_FAILURE(rc))
     69        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPipeFromNative(,%s,READ) -> %Rrc\n", pszPipe, rc);
     70
     71    ///
     72    char    szTmp[1024];
     73    size_t  cbRead = 0;
     74    rc = RTPipeReadBlocking(hPipe, szTmp, sizeof(szTmp) - 1, &cbRead);
     75    if (RT_FAILURE(rc))
     76        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPipeReadBlocking() -> %Rrc\n", rc);
     77    szTmp[cbRead] = '\0';
     78
     79    size_t cbRead2;
     80    char szTmp2[4];
     81    rc = RTPipeReadBlocking(hPipe, szTmp2, sizeof(szTmp2), &cbRead2);
     82    if (rc != VERR_BROKEN_PIPE)
     83        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPipeReadBlocking() -> %Rrc instead of VERR_BROKEN_PIPE\n", rc);
     84
     85    rc = RTPipeClose(hPipe);
     86    if (RT_FAILURE(rc))
     87        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPipeClose() -> %Rrc\n", rc);
     88
     89    if (memcmp(szTmp, g_szTest5Message, sizeof(g_szTest5Message)))
     90        return RTMsgErrorExit(RTEXITCODE_FAILURE, "Message mismatch.\n:Expected '%s'\nGot     '%s'\n", g_szTest5Message, szTmp);
     91
     92    return RTEXITCODE_SUCCESS;
     93}
     94
     95static void tstRTPipe5(void)
     96{
     97    RTTestISub("Inherit non-standard pipe handle, read end");
     98
     99    char    szPathSelf[RTPATH_MAX];
     100    RTTESTI_CHECK_RETV(RTProcGetExecutableName(szPathSelf, sizeof(szPathSelf)) == szPathSelf);
     101
     102    RTPIPE  hPipeR;
     103    RTPIPE  hPipeW;
     104    RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, RTPIPE_C_INHERIT_READ), VINF_SUCCESS);
     105
     106    RTHCINTPTR hNative = RTPipeToNative(hPipeR);
     107    RTTESTI_CHECK_RETV(hNative != -1);
     108
     109    char szNative[64];
     110    RTStrPrintf(szNative, sizeof(szNative), "%RHi", hNative);
     111    const char *papszArgs[4] = { szPathSelf, "--child-5", szNative, NULL };
     112
     113    RTPROCESS hChild;
     114    RTTESTI_CHECK_RC_RETV(RTProcCreate(szPathSelf, papszArgs, RTENV_DEFAULT, 0 /*fFlags*/, &hChild), VINF_SUCCESS);
     115    RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeR), VINF_SUCCESS);
     116
     117    RTTESTI_CHECK_RC(RTPipeWriteBlocking(hPipeW, g_szTest5Message, sizeof(g_szTest5Message) - 1, NULL), VINF_SUCCESS);
     118    int rc;
     119    RTTESTI_CHECK_RC(rc = RTPipeClose(hPipeW), VINF_SUCCESS);
     120    if (RT_FAILURE(rc))
     121        RTTESTI_CHECK_RC(RTProcTerminate(hChild), VINF_SUCCESS);
     122
     123    RTPROCSTATUS ProcStatus;
     124    RTTESTI_CHECK_RC(rc = RTProcWait(hChild, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS);
     125    if (RT_FAILURE(rc))
     126        return;
     127    RTTESTI_CHECK(   ProcStatus.enmReason == RTPROCEXITREASON_NORMAL
     128                  && ProcStatus.iStatus   == 0);
     129}
     130
     131
     132static RTEXITCODE tstRTPipe4Child(const char *pszPipe)
     133{
     134    int rc = RTR3Init();
     135    if (RT_FAILURE(rc))
     136        return RTMsgInitFailure(rc);
     137
     138    int64_t iNative;
     139    rc = RTStrToInt64Full(pszPipe, 10, &iNative);
     140    if (RT_FAILURE(rc))
     141        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTStrToUInt64Full(%s) -> %Rrc\n", pszPipe, rc);
     142
     143    RTPIPE hPipe;
     144    rc = RTPipeFromNative(&hPipe, (RTHCINTPTR)iNative, RTPIPE_N_WRITE);
     145    if (RT_FAILURE(rc))
     146        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPipeFromNative(,%s,WRITE) -> %Rrc\n", pszPipe, rc);
     147
     148    rc = RTPipeWriteBlocking(hPipe, g_szTest4Message, sizeof(g_szTest4Message) - 1, NULL);
     149    if (RT_FAILURE(rc))
     150        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPipeWriteBlocking() -> %Rrc\n", rc);
     151
     152    rc = RTPipeClose(hPipe);
     153    if (RT_FAILURE(rc))
     154        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPipeClose() -> %Rrc\n", rc);
     155    return RTEXITCODE_SUCCESS;
     156}
     157
     158static void tstRTPipe4(void)
     159{
     160    RTTestISub("Inherit non-standard pipe handle, write end");
     161
     162    char    szPathSelf[RTPATH_MAX];
     163    RTTESTI_CHECK_RETV(RTProcGetExecutableName(szPathSelf, sizeof(szPathSelf)) == szPathSelf);
     164
     165    RTPIPE  hPipeR;
     166    RTPIPE  hPipeW;
     167    RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, RTPIPE_C_INHERIT_WRITE), VINF_SUCCESS);
     168
     169    RTHCINTPTR hNative = RTPipeToNative(hPipeW);
     170    RTTESTI_CHECK_RETV(hNative != -1);
     171
     172    char szNative[64];
     173    RTStrPrintf(szNative, sizeof(szNative), "%RHi", hNative);
     174    const char *papszArgs[4] = { szPathSelf, "--child-4", szNative, NULL };
     175
     176    RTPROCESS hChild;
     177    RTTESTI_CHECK_RC_RETV(RTProcCreate(szPathSelf, papszArgs, RTENV_DEFAULT, 0 /*fFlags*/, &hChild), VINF_SUCCESS);
     178    RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeW), VINF_SUCCESS);
     179
     180    char    szTmp[1024];
     181    size_t  cbRead = 0;
     182    int     rc;
     183    RTTESTI_CHECK_RC(rc = RTPipeReadBlocking(hPipeR, szTmp, sizeof(szTmp) - 1, &cbRead), VINF_SUCCESS);
     184    if (RT_FAILURE(rc))
     185        cbRead = 0;
     186    RTTESTI_CHECK_RETV(cbRead < sizeof(szTmp));
     187    szTmp[cbRead] = '\0';
     188
     189    size_t cbRead2;
     190    char szTmp2[4];
     191    RTTESTI_CHECK_RC(RTPipeReadBlocking(hPipeR, szTmp2, sizeof(szTmp2), &cbRead2), VERR_BROKEN_PIPE);
     192    RTTESTI_CHECK_RC(rc = RTPipeClose(hPipeR), VINF_SUCCESS);
     193    if (RT_FAILURE(rc))
     194        RTTESTI_CHECK_RC(RTProcTerminate(hChild), VINF_SUCCESS);
     195
     196    RTPROCSTATUS ProcStatus;
     197    RTTESTI_CHECK_RC(rc = RTProcWait(hChild, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS);
     198    if (RT_FAILURE(rc))
     199        return;
     200    RTTESTI_CHECK(   ProcStatus.enmReason == RTPROCEXITREASON_NORMAL
     201                  && ProcStatus.iStatus   == 0);
     202    if (memcmp(szTmp, g_szTest4Message, sizeof(g_szTest4Message)))
     203        RTTestIFailed("Message mismatch.\n:Expected '%s'\nGot     '%s'\n", g_szTest4Message, szTmp);
     204}
    41205
    42206
     
    301465}
    302466
    303 int main()
    304 {
     467int main(int argc, char **argv)
     468{
     469    if (argc == 3 && !strcmp(argv[1], "--child-4"))
     470        return tstRTPipe4Child(argv[2]);
     471    if (argc == 3 && !strcmp(argv[1], "--child-5"))
     472        return tstRTPipe5Child(argv[2]);
     473
    305474    RTTEST hTest;
    306475    int rc = RTTestInitAndCreate("tstRTPipe", &hTest);
     
    324493
    325494        tstRTPipe3();
     495        tstRTPipe4();
     496        tstRTPipe5();
    326497    }
    327498
Note: See TracChangeset for help on using the changeset viewer.

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