VirtualBox

Changeset 39434 in vbox for trunk/src/VBox/Additions


Ignore:
Timestamp:
Nov 28, 2011 12:51:34 PM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
75067
Message:

VBoxService/GuestCtrl: Use RTFileOpenBitBucket() for not used streams.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlThread.cpp

    r39427 r39434  
    2323#include <iprt/assert.h>
    2424#include <iprt/env.h>
     25#include <iprt/file.h>
    2526#include <iprt/getopt.h>
    2627#include <iprt/handle.h>
     
    389390{
    390391    int rc = VINF_SUCCESS;
    391     if (fPollEvt == RTPOLL_EVT_READ)
    392     {
    393         /** @todo r=bird: Drop this in favor of using /dev/null
    394          * (RTFileOpenBitBucket) instead of pipes. That'll simplify the code,
    395          * speed stuff up, avoid trouble is RTPoll is buggy and be
    396          * compatible with future wait-for-writeable-stderr/out host
    397          * notifications. */
    398         char   abBuf[_64K];
    399         size_t cbRead;
    400         rc = RTPipeRead(*phPipeR, abBuf, sizeof(abBuf), &cbRead);
    401         if (RT_SUCCESS(rc) && cbRead)
    402         {
    403 #ifdef DEBUG
    404             VBoxServiceVerbose(4, "ControlThread: Drain idPollHnd=%u, abBuf=0x%p, cbRead=%u\n",
    405                                idPollHnd, abBuf, cbRead);
    406 #endif
    407             /* Goes to bit bucket ... */
    408 
    409             /* Make sure we go another poll round in case there was too much data
    410                for the buffer to hold. */
    411             fPollEvt &= RTPOLL_EVT_ERROR;
    412         }
    413         else if (RT_FAILURE(rc))
    414         {
    415             fPollEvt |= RTPOLL_EVT_ERROR;
    416             AssertMsg(rc == VERR_BROKEN_PIPE, ("%Rrc\n", rc));
    417         }
     392
     393    if (fPollEvt & RTPOLL_EVT_READ)
     394    {
     395
     396        /* Make sure we go another poll round in case there was too much data
     397           for the buffer to hold. */
     398        fPollEvt &= RTPOLL_EVT_ERROR;
    418399    }
    419400
     
    602583        uint32_t idPollHnd;
    603584        uint32_t fPollEvt;
    604         rc2 = RTPollNoResume(hPollSet, /*cMsPollCur*/ RT_INDEFINITE_WAIT, &fPollEvt, &idPollHnd);
     585        rc2 = RTPollNoResume(hPollSet, cMsPollCur, &fPollEvt, &idPollHnd);
    605586        if (pThread->fShutdown)
    606587            continue;
     
    640621                break; /* We were asked to shutdown. */
    641622
    642             /* Do we have more to poll for (e.g. is there (still) something in our pollset
    643              * like stdout, stderr or stdin)? If we only have our notification pipe left we
    644              * need to bail out. */
    645             if (RTPollSetGetCount(hPollSet) > 1)
    646                 continue;
     623            continue;
    647624        }
    648625
     
    858835 *
    859836 * @returns IPRT status code.  No client replies made.
     837 * @param   pszHowTo            How to set up this standard handle.
    860838 * @param   fd                  Which standard handle it is (0 == stdin, 1 ==
    861839 *                              stdout, 2 == stderr).
     
    865843 *                              Always set.
    866844 * @param   phPipe              Where to return the end of the pipe that we
    867  *                              should service.  Always set.
    868  *
    869  * @todo r=bird: Open the bitbucket like txsDoExecHlpRedir does when the host
    870  *       isn't interested in the guest output.  This is easier to handle
    871  *       elsewhere.
    872  */
    873 static int VBoxServiceControlThreadSetupPipe(int fd, PRTHANDLE ph, PRTHANDLE *pph, PRTPIPE phPipe)
    874 {
    875     AssertPtrReturn(ph, VERR_INVALID_PARAMETER);
    876     AssertPtrReturn(pph, VERR_INVALID_PARAMETER);
    877     AssertPtrReturn(phPipe, VERR_INVALID_PARAMETER);
     845 *                              should service.
     846 */
     847static int VBoxServiceControlThreadSetupPipe(const char *pszHowTo, int fd,
     848                                             PRTHANDLE ph, PRTHANDLE *pph, PRTPIPE phPipe)
     849{
     850    AssertPtrReturn(ph, VERR_INVALID_POINTER);
     851    AssertPtrReturn(ph, VERR_INVALID_POINTER);
     852    AssertPtrReturn(pph, VERR_INVALID_POINTER);
    878853
    879854    int rc;
    880855
    881     /*
    882      * Setup a pipe for forwarding to/from the client.
    883      * The ph union struct will be filled with a pipe read/write handle
    884      * to represent the "other" end to phPipe.
    885      */
    886     if (fd == 0) /* stdin? */
    887     {
    888         /* Connect a wrtie pipe specified by phPipe to stdin. */
    889         rc = RTPipeCreate(&ph->u.hPipe, phPipe, RTPIPE_C_INHERIT_READ);
    890     }
    891     else /* stdout or stderr? */
    892     {
    893         /* Connect a read pipe specified by phPipe to stdout or stderr. */
    894         rc = RTPipeCreate(phPipe, &ph->u.hPipe, RTPIPE_C_INHERIT_WRITE);
    895     }
    896     if (RT_FAILURE(rc))
    897         return rc;
    898856    ph->enmType = RTHANDLETYPE_PIPE;
    899     *pph = ph;
     857    ph->u.hPipe = NIL_RTPIPE;
     858    *pph        = NULL;
     859    *phPipe     = NIL_RTPIPE;
     860
     861    if (!strcmp(pszHowTo, "|"))
     862    {
     863        /*
     864         * Setup a pipe for forwarding to/from the client.
     865         * The ph union struct will be filled with a pipe read/write handle
     866         * to represent the "other" end to phPipe.
     867         */
     868        if (fd == 0) /* stdin? */
     869        {
     870            /* Connect a wrtie pipe specified by phPipe to stdin. */
     871            rc = RTPipeCreate(&ph->u.hPipe, phPipe, RTPIPE_C_INHERIT_READ);
     872        }
     873        else /* stdout or stderr? */
     874        {
     875            /* Connect a read pipe specified by phPipe to stdout or stderr. */
     876            rc = RTPipeCreate(phPipe, &ph->u.hPipe, RTPIPE_C_INHERIT_WRITE);
     877        }
     878
     879        if (RT_FAILURE(rc))
     880            return rc;
     881
     882        ph->enmType = RTHANDLETYPE_PIPE;
     883        *pph = ph;
     884    }
     885    else if (!strcmp(pszHowTo, "/dev/null"))
     886    {
     887        /*
     888         * Redirect to/from /dev/null.
     889         */
     890        RTFILE hFile;
     891        rc = RTFileOpenBitBucket(&hFile, fd == 0 ? RTFILE_O_READ : RTFILE_O_WRITE);
     892        if (RT_FAILURE(rc))
     893            return rc;
     894
     895        ph->enmType = RTHANDLETYPE_FILE;
     896        ph->u.hFile = hFile;
     897        *pph = ph;
     898    }
     899    else /* Add other piping stuff here. */
     900        rc = VERR_INVALID_PARAMETER;
    900901
    901902    return rc;
     
    11911192            RTHANDLE    hStdIn;
    11921193            PRTHANDLE   phStdIn;
    1193             rc = VBoxServiceControlThreadSetupPipe(0 /*STDIN_FILENO*/, &hStdIn, &phStdIn, &pThread->pipeStdInW);
     1194            rc = VBoxServiceControlThreadSetupPipe("|", 0 /*STDIN_FILENO*/,
     1195                                                   &hStdIn, &phStdIn, &pThread->pipeStdInW);
    11941196            if (RT_SUCCESS(rc))
    11951197            {
     
    11971199                PRTHANDLE   phStdOut;
    11981200                RTPIPE      hStdOutR;
    1199                 rc = VBoxServiceControlThreadSetupPipe(1 /*STDOUT_FILENO*/, &hStdOut, &phStdOut, &hStdOutR);
     1201                rc = VBoxServiceControlThreadSetupPipe(  (pThread->uFlags & EXECUTEPROCESSFLAG_WAIT_STDOUT)
     1202                                                       ? "|" : "/dev/null",
     1203                                                       1 /*STDOUT_FILENO*/,
     1204                                                       &hStdOut, &phStdOut, &hStdOutR);
    12001205                if (RT_SUCCESS(rc))
    12011206                {
     
    12031208                    PRTHANDLE   phStdErr;
    12041209                    RTPIPE      hStdErrR;
    1205                     rc = VBoxServiceControlThreadSetupPipe(2 /*STDERR_FILENO*/, &hStdErr, &phStdErr, &hStdErrR);
     1210                    rc = VBoxServiceControlThreadSetupPipe(  (pThread->uFlags & EXECUTEPROCESSFLAG_WAIT_STDERR)
     1211                                                           ? "|" : "/dev/null",
     1212                                                           2 /*STDERR_FILENO*/,
     1213                                                           &hStdErr, &phStdErr, &hStdErrR);
    12061214                    if (RT_SUCCESS(rc))
    12071215                    {
     
    12191227                            /* Stdout. */
    12201228                            if (RT_SUCCESS(rc))
    1221                             {
    1222                                 uint32_t uFlags = RTPOLL_EVT_ERROR;
    1223                                 if (!(pThread->uFlags & EXECUTEPROCESSFLAG_WAIT_STDOUT))
    1224                                 {
    1225                                     uFlags |= RTPOLL_EVT_READ;
    1226                                     VBoxServiceVerbose(3, "ControlThread: Host is not interested in getting stdout for \"%s\", poll flags=0x%x\n",
    1227                                                         pThread->pszCmd, uFlags);
    1228                                 }
    1229                                 rc = RTPollSetAddPipe(hPollSet, hStdOutR, uFlags, VBOXSERVICECTRLPIPEID_STDOUT);
    1230                             }
     1229                                rc = RTPollSetAddPipe(hPollSet, hStdOutR, RTPOLL_EVT_ERROR, VBOXSERVICECTRLPIPEID_STDOUT);
    12311230                            /* Stderr. */
    12321231                            if (RT_SUCCESS(rc))
    1233                             {
    1234                                 uint32_t uFlags = RTPOLL_EVT_ERROR;
    1235                                 if (!(pThread->uFlags & EXECUTEPROCESSFLAG_WAIT_STDERR))
    1236                                 {
    1237                                     uFlags |= RTPOLL_EVT_READ;
    1238                                     VBoxServiceVerbose(3, "ControlThread: Host is not interested in getting stderr for \"%s\", poll flags=0x%x\n",
    1239                                                         pThread->pszCmd, uFlags);
    1240                                 }
    1241                                 rc = RTPollSetAddPipe(hPollSet, hStdErrR, uFlags, VBOXSERVICECTRLPIPEID_STDERR);
    1242                             }
     1232                                rc = RTPollSetAddPipe(hPollSet, hStdErrR, RTPOLL_EVT_ERROR, VBOXSERVICECTRLPIPEID_STDERR);
    12431233                            /* IPC notification pipe. */
    12441234                            if (RT_SUCCESS(rc))
Note: See TracChangeset for help on using the changeset viewer.

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