VirtualBox

Changeset 49349 in vbox for trunk/src/VBox/Frontends


Ignore:
Timestamp:
Oct 31, 2013 4:40:46 PM (11 years ago)
Author:
vboxsync
Message:

Guest Control:

  • Implemented IGuestSession::DirectoryRemove, IGuestSession::DirectoryRemoveRecursive, IGuestSession::DirectoryRename + IGuestSession::FileRename.
  • Added appropriate commands to VBoxManage (basic support for now).
  • Implemented support for proper guest session process termination via SCM.
  • Implemented support for internal anonymous wait events which are not relying on the public API's VBoxEventType_T.
  • Various bugfixes.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp

    r49222 r49349  
    141141
    142142    PGCTLCMDCTX pCmdCtx;
    143     ComPtr<IGuestSession> pGuestSession;
    144143    bool fDryRun;
    145144    bool fHostToGuest;
     
    282281enum GETOPTDEF_RMDIR
    283282{
    284     GETOPTDEF_RMDIR_RECURSIVE = 2000
    285283};
    286284
     
    349347                 "                            [--domain <domain>] [--verbose]\n"
    350348                 "\n"
     349                 "                            ren[ame]|mv\n"
     350                 "                            <source>... <dest> --username <name>\n"
     351                 "                            [--passwordfile <file> | --password <password>]\n"
     352                 "                            [--domain <domain>] [--verbose]\n"
     353                 "\n"
    351354                 "                            createtemp[orary]|mktemp\n"
    352355                 "                            <template> --username <name>\n"
     
    729732    AssertPtrReturn(pCtx, RTEXITCODE_FAILURE);
    730733
     734#ifdef DEBUG_andy
     735    RTPrintf("Original argv:\n");
     736    for (int i=0; i<pArg->argc;i++)
     737        RTPrintf("\targv[%d]=%s\n", i, pArg->argv[i]);
     738#endif
     739
    731740    RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
    732741
     
    780789            pCtx->iArgc = 0;
    781790
     791            int iArgIdx = 2; /* Skip VM name and guest control command */
    782792            int ch;
    783793            RTGETOPTUNION ValueUnion;
     
    785795            RTGetOptInit(&GetState, pArg->argc, pArg->argv,
    786796                         s_aOptions, RT_ELEMENTS(s_aOptions),
    787                          2, /* Skip VM name and guest control command */
    788                          RTGETOPTINIT_FLAGS_OPTS_FIRST);
     797                         iArgIdx, 0);
    789798
    790799            while (   (ch = RTGetOpt(&GetState, &ValueUnion))
     
    797806                        if (!(uFlags & CTLCMDCTX_FLAGS_SESSION_ANONYMOUS))
    798807                            pCtx->strUsername = ValueUnion.psz;
     808                        iArgIdx = GetState.iNext;
    799809                        break;
    800810
     
    805815                                pCtx->strPassword = ValueUnion.psz;
    806816                        }
     817                        iArgIdx = GetState.iNext;
    807818                        break;
    808819
     
    811822                        if (!(uFlags & CTLCMDCTX_FLAGS_SESSION_ANONYMOUS))
    812823                            rcExit = readPasswordFile(ValueUnion.psz, &pCtx->strPassword);
     824                        iArgIdx = GetState.iNext;
    813825                        break;
    814826                    }
     
    817829                        if (!(uFlags & CTLCMDCTX_FLAGS_SESSION_ANONYMOUS))
    818830                            pCtx->strDomain = ValueUnion.psz;
     831                        iArgIdx = GetState.iNext;
    819832                        break;
    820833
    821834                    case 'v': /* Verbose */
    822835                        pCtx->fVerbose = true;
     836                        iArgIdx = GetState.iNext;
    823837                        break;
    824838
    825                     case VINF_GETOPT_NOT_OPTION:
    826                         /* Fall through is intentional. */
    827839                    default:
     840                        /* Simply skip; might be handled in a specific command
     841                         * handler later. */
     842                        break;
     843
     844                } /* switch */
     845
     846                int iArgDiff = GetState.iNext - iArgIdx;
     847                if (iArgDiff)
     848                {
     849#ifdef DEBUG_andy
     850                    RTPrintf("Not handled (iNext=%d, iArgsCur=%d):\n", GetState.iNext, iArgIdx);
     851#endif
     852                    for (int i = iArgIdx; i < GetState.iNext; i++)
    828853                    {
    829                         Assert(GetState.iNext);
    830                         char *pszArg = RTStrDup(pArg->argv[GetState.iNext - 1]);
     854                        char *pszArg = RTStrDup(pArg->argv[i]);
    831855                        if (!pszArg)
    832856                        {
     
    837861                        pCtx->ppaArgv[pCtx->iArgc] = pszArg;
    838862                        pCtx->iArgc++;
    839                         break;
     863#ifdef DEBUG_andy
     864                        RTPrintf("\targv[%d]=%s\n", i, pArg->argv[i]);
    840865                    }
    841 
    842                 } /* switch */
     866#endif
     867                    iArgIdx = GetState.iNext;
     868                }
     869
    843870            } /* while RTGetOpt */
    844871        }
     
    10771104    };
    10781105
     1106#ifdef DEBUG_andy
     1107    RTPrintf("first=%d\n", pCtx->iFirstArgc);
     1108    for (int i=0; i<pCtx->iArgc;i++)
     1109        RTPrintf("\targv[%d]=%s\n", i, pCtx->ppaArgv[i]);
     1110#endif
     1111
    10791112    int                     ch;
    10801113    RTGETOPTUNION           ValueUnion;
    10811114    RTGETOPTSTATE           GetState;
    1082     RTGetOptInit(&GetState, pCtx->iArgc, pCtx->ppaArgv, s_aOptions, RT_ELEMENTS(s_aOptions), pCtx->iFirstArgc, 0);
     1115    RTGetOptInit(&GetState, pCtx->iArgc, pCtx->ppaArgv, s_aOptions, RT_ELEMENTS(s_aOptions),
     1116                 pCtx->iFirstArgc, RTGETOPTINIT_FLAGS_OPTS_FIRST);
    10831117
    10841118    Utf8Str                              strCmd;
     
    11741208
    11751209                default:
    1176                     return RTGetOptPrintError(ch, &ValueUnion);
     1210                    /* Note: Necessary for handling non-options (after --) which
     1211                     *       contain a single dash, e.g. "-- foo.exe -s". */
     1212                    if (GetState.argc == GetState.iNext)
     1213                        aArgs.push_back(Bstr(ValueUnion.psz).raw());
     1214                    else
     1215                        return RTGetOptPrintError(ch, &ValueUnion);
    11771216                    break;
    11781217
     
    14101449    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
    14111450
    1412     PCOPYCONTEXT pContext = new COPYCONTEXT();
    1413     AssertPtrReturn(pContext, VERR_NO_MEMORY); /**< @todo r=klaus cannot happen with new */
    1414     ComPtr<IGuestSession> pGuestSession;
    1415     HRESULT rc = pCtx->pGuest->CreateSession(Bstr(pCtx->strUsername).raw(),
    1416                                              Bstr(pCtx->strPassword).raw(),
    1417                                              Bstr(pCtx->strDomain).raw(),
    1418                                              Bstr(strSessionName).raw(),
    1419                                              pGuestSession.asOutParam());
    1420     if (FAILED(rc))
    1421         return ctrlPrintError(pCtx->pGuest, COM_IIDOF(IGuest));
    1422 
    1423     pContext->pCmdCtx = pCtx;
    1424     pContext->fDryRun = fDryRun;
    1425     pContext->fHostToGuest = fHostToGuest;
    1426     pContext->pGuestSession = pGuestSession;
    1427 
    1428     *ppContext = pContext;
    1429 
    1430     return VINF_SUCCESS;
     1451    int vrc = VINF_SUCCESS;
     1452    try
     1453    {
     1454        PCOPYCONTEXT pContext = new COPYCONTEXT();
     1455
     1456        pContext->pCmdCtx = pCtx;
     1457        pContext->fDryRun = fDryRun;
     1458        pContext->fHostToGuest = fHostToGuest;
     1459
     1460        *ppContext = pContext;
     1461    }
     1462    catch (std::bad_alloc)
     1463    {
     1464        vrc = VERR_NO_MEMORY;
     1465    }
     1466
     1467    return vrc;
    14311468}
    14321469
     
    14391476{
    14401477    if (pContext)
    1441     {
    1442         if (pContext->pGuestSession)
    1443             pContext->pGuestSession->Close();
    14441478        delete pContext;
    1445     }
    14461479}
    14471480
     
    16171650        SafeArray<DirectoryCreateFlag_T> dirCreateFlags;
    16181651        dirCreateFlags.push_back(DirectoryCreateFlag_Parents);
    1619         HRESULT rc = pContext->pGuestSession->DirectoryCreate(Bstr(pszDir).raw(),
    1620                                                               0700, ComSafeArrayAsInParam(dirCreateFlags));
     1652        HRESULT rc = pContext->pCmdCtx->pGuestSession->DirectoryCreate(Bstr(pszDir).raw(),
     1653                                                                       0700, ComSafeArrayAsInParam(dirCreateFlags));
    16211654        if (FAILED(rc))
    1622             vrc = ctrlPrintError(pContext->pGuestSession, COM_IIDOF(IGuestSession));
     1655            vrc = ctrlPrintError(pContext->pCmdCtx->pGuestSession, COM_IIDOF(IGuestSession));
    16231656    }
    16241657    else /* ... or on the host. */
     
    16361669 * @return  IPRT status code.
    16371670 * @param   pContext                Pointer to current copy control context.
    1638  * @param   bGuest                  true if directory needs to be checked on the guest
     1671 * @param   fOnGuest                true if directory needs to be checked on the guest
    16391672 *                                  or false if on the host.
    16401673 * @param   pszDir                  Actual directory to check.
     
    16421675 *                                  given directory exists or not.
    16431676 */
    1644 static int ctrlCopyDirExists(PCOPYCONTEXT pContext, bool bGuest,
     1677static int ctrlCopyDirExists(PCOPYCONTEXT pContext, bool fOnGuest,
    16451678                             const char *pszDir, bool *fExists)
    16461679{
     
    16501683
    16511684    int vrc = VINF_SUCCESS;
    1652     if (bGuest)
     1685    if (fOnGuest)
    16531686    {
    16541687        BOOL fDirExists = FALSE;
    1655         HRESULT rc = pContext->pGuestSession->DirectoryExists(Bstr(pszDir).raw(), &fDirExists);
     1688        HRESULT rc = pContext->pCmdCtx->pGuestSession->DirectoryExists(Bstr(pszDir).raw(), &fDirExists);
    16561689        if (FAILED(rc))
    1657             vrc = ctrlPrintError(pContext->pGuestSession, COM_IIDOF(IGuestSession));
     1690            vrc = ctrlPrintError(pContext->pCmdCtx->pGuestSession, COM_IIDOF(IGuestSession));
    16581691        else
    16591692            *fExists = fDirExists ? true : false;
     
    17201753    {
    17211754        BOOL fFileExists = FALSE;
    1722         HRESULT rc = pContext->pGuestSession->FileExists(Bstr(pszFile).raw(), &fFileExists);
     1755        HRESULT rc = pContext->pCmdCtx->pGuestSession->FileExists(Bstr(pszFile).raw(), &fFileExists);
    17231756        if (FAILED(rc))
    1724             vrc = ctrlPrintError(pContext->pGuestSession, COM_IIDOF(IGuestSession));
     1757            vrc = ctrlPrintError(pContext->pCmdCtx->pGuestSession, COM_IIDOF(IGuestSession));
    17251758        else
    17261759            *fExists = fFileExists ? true : false;
     
    17961829    {
    17971830        SafeArray<CopyFileFlag_T> copyFlags;
    1798         rc = pContext->pGuestSession->CopyTo(Bstr(pszFileSource).raw(), Bstr(pszFileDest).raw(),
    1799                                              ComSafeArrayAsInParam(copyFlags),
    1800 
    1801                                              pProgress.asOutParam());
    1802     }
    1803     else
    1804     {
    1805         SafeArray<CopyFileFlag_T> copyFlags;
    1806         rc = pContext->pGuestSession->CopyFrom(Bstr(pszFileSource).raw(), Bstr(pszFileDest).raw(),
     1831        rc = pContext->pCmdCtx->pGuestSession->CopyTo(Bstr(pszFileSource).raw(), Bstr(pszFileDest).raw(),
    18071832                                               ComSafeArrayAsInParam(copyFlags),
    18081833                                               pProgress.asOutParam());
    18091834    }
     1835    else
     1836    {
     1837        SafeArray<CopyFileFlag_T> copyFlags;
     1838        rc = pContext->pCmdCtx->pGuestSession->CopyFrom(Bstr(pszFileSource).raw(), Bstr(pszFileDest).raw(),
     1839                                               ComSafeArrayAsInParam(copyFlags),
     1840                                               pProgress.asOutParam());
     1841    }
    18101842
    18111843    if (FAILED(rc))
    18121844    {
    1813         vrc = ctrlPrintError(pContext->pGuestSession, COM_IIDOF(IGuestSession));
     1845        vrc = ctrlPrintError(pContext->pCmdCtx->pGuestSession, COM_IIDOF(IGuestSession));
    18141846    }
    18151847    else
     
    20382070    SafeArray<DirectoryOpenFlag_T> dirOpenFlags; /* No flags supported yet. */
    20392071    ComPtr<IGuestDirectory> pDirectory;
    2040     HRESULT rc = pContext->pGuestSession->DirectoryOpen(Bstr(szCurDir).raw(), Bstr(pszFilter).raw(),
     2072    HRESULT rc = pContext->pCmdCtx->pGuestSession->DirectoryOpen(Bstr(szCurDir).raw(), Bstr(pszFilter).raw(),
    20412073                                                        ComSafeArrayAsInParam(dirOpenFlags),
    20422074                                                        pDirectory.asOutParam());
    20432075    if (FAILED(rc))
    2044         return ctrlPrintError(pContext->pGuestSession, COM_IIDOF(IGuestSession));
     2076        return ctrlPrintError(pContext->pCmdCtx->pGuestSession, COM_IIDOF(IGuestSession));
    20452077    ComPtr<IFsObjInfo> dirEntry;
    20462078    while (true)
     
    23852417    PCOPYCONTEXT pContext = NULL;
    23862418    vrc = ctrlCopyContextCreate(pCtx, fDryRun, fHostToGuest,
    2387                                 "VBoxManage Guest Control Copy", &pContext);
     2419                                  fHostToGuest
     2420                                ? "VBoxManage Guest Control - Copy to guest"
     2421                                : "VBoxManage Guest Control - Copy from guest", &pContext);
    23882422    if (RT_FAILURE(vrc))
    23892423    {
     
    25442578    AssertPtrReturn(pCtx, RTEXITCODE_FAILURE);
    25452579
    2546     /*
    2547      * Parse arguments.
    2548      *
    2549      * Note! No direct returns here, everyone must go thru the cleanup at the
    2550      *       end of this function.
    2551      */
    25522580    static const RTGETOPTDEF s_aOptions[] =
    25532581    {
     
    26192647    AssertPtrReturn(pCtx, RTEXITCODE_FAILURE);
    26202648
    2621     /*
    2622      * Parse arguments.
    2623      *
    2624      * Note! No direct returns here, everyone must go thru the cleanup at the
    2625      *       end of this function.
    2626      */
    26272649    static const RTGETOPTDEF s_aOptions[] =
    26282650    {
    2629         { "--recursive",           GETOPTDEF_RMDIR_RECURSIVE,       RTGETOPT_REQ_NOTHING }
     2651        { "--recursive",           'R',                             RTGETOPT_REQ_NOTHING }
    26302652    };
    26312653
     
    26442666        switch (ch)
    26452667        {
    2646             case GETOPTDEF_RMDIR_RECURSIVE:
     2668            case 'R':
    26472669                fRecursive = true;
    26482670                break;
     
    26952717                if (SUCCEEDED(rc))
    26962718                    CHECK_PROGRESS_ERROR(pProgress, ("Directory deletion failed"));
     2719
     2720                pProgress.setNull();
    26972721            }
    26982722            else
     
    27142738{
    27152739    AssertPtrReturn(pCtx, RTEXITCODE_FAILURE);
    2716 
    2717     /*
    2718      * Parse arguments.
    2719      *
    2720      * Note! No direct returns here, everyone must go thru the cleanup at the
    2721      *       end of this function.
    2722      */
    2723     static const RTGETOPTDEF s_aOptions[] = { 0 };
    27242740
    27252741    int ch;
     
    27272743    RTGETOPTSTATE GetState;
    27282744    RTGetOptInit(&GetState, pCtx->iArgc, pCtx->ppaArgv,
    2729                  s_aOptions, RT_ELEMENTS(s_aOptions), pCtx->iFirstArgc, RTGETOPTINIT_FLAGS_OPTS_FIRST);
     2745                 NULL /* s_aOptions */, 0 /* RT_ELEMENTS(s_aOptions) */,
     2746                 pCtx->iFirstArgc, RTGETOPTINIT_FLAGS_OPTS_FIRST);
    27302747
    27312748    DESTDIRMAP mapDirs;
     
    27722789}
    27732790
     2791static DECLCALLBACK(RTEXITCODE) handleCtrlRename(PGCTLCMDCTX pCtx)
     2792{
     2793    AssertPtrReturn(pCtx, RTEXITCODE_FAILURE);
     2794
     2795    static const RTGETOPTDEF s_aOptions[] = { 0 };
     2796
     2797    int ch;
     2798    RTGETOPTUNION ValueUnion;
     2799    RTGETOPTSTATE GetState;
     2800    RTGetOptInit(&GetState, pCtx->iArgc, pCtx->ppaArgv,
     2801                 NULL /*s_aOptions*/, 0 /*RT_ELEMENTS(s_aOptions)*/, pCtx->iFirstArgc, RTGETOPTINIT_FLAGS_OPTS_FIRST);
     2802
     2803    int vrc = VINF_SUCCESS;
     2804
     2805    bool fDryrun = false;
     2806    std::vector< Utf8Str > vecSources;
     2807    Utf8Str strDest;
     2808    com::SafeArray<PathRenameFlag_T> aRenameFlags;
     2809
     2810    try
     2811    {
     2812        /** @todo Make flags configurable. */
     2813        aRenameFlags.push_back(PathRenameFlag_NoReplace);
     2814
     2815        while (   (ch = RTGetOpt(&GetState, &ValueUnion))
     2816               && RT_SUCCESS(vrc))
     2817        {
     2818            /* For options that require an argument, ValueUnion has received the value. */
     2819            switch (ch)
     2820            {
     2821                /** @todo Implement a --dryrun command. */
     2822                /** @todo Implement rename flags. */
     2823
     2824                case VINF_GETOPT_NOT_OPTION:
     2825                    vecSources.push_back(Utf8Str(ValueUnion.psz));
     2826                    strDest = ValueUnion.psz;
     2827                    break;
     2828
     2829                default:
     2830                    return RTGetOptPrintError(ch, &ValueUnion);
     2831                    break;
     2832            }
     2833        }
     2834    }
     2835    catch (std::bad_alloc)
     2836    {
     2837        vrc = VERR_NO_MEMORY;
     2838    }
     2839
     2840    if (RT_FAILURE(vrc))
     2841        return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to initialize, rc=%Rrc\n", vrc);
     2842
     2843    uint32_t cSources = vecSources.size();
     2844    if (!cSources)
     2845        return errorSyntax(USAGE_GUESTCONTROL, "No source(s) to move specified!");
     2846    if (cSources < 2)
     2847        return errorSyntax(USAGE_GUESTCONTROL, "No destination specified!");
     2848
     2849    /* Delete last element, which now is the destination. */
     2850    vecSources.pop_back();
     2851    cSources = vecSources.size();
     2852
     2853    HRESULT rc = S_OK;
     2854
     2855    if (cSources > 1)
     2856    {
     2857        ComPtr<IGuestFsObjInfo> pFsObjInfo;
     2858        rc = pCtx->pGuestSession->DirectoryQueryInfo(Bstr(strDest).raw(), pFsObjInfo.asOutParam());
     2859        if (FAILED(rc))
     2860            return RTMsgErrorExit(RTEXITCODE_FAILURE, "Destination must be a directory\n");
     2861    }
     2862
     2863    /*
     2864     * Rename (move) the entries.
     2865     */
     2866    if (pCtx->fVerbose && cSources)
     2867        RTPrintf("Renaming %RU32 %s ...\n", cSources,
     2868                   cSources > 1
     2869                 ? "entries" : "entry");
     2870
     2871    std::vector< Utf8Str >::iterator it = vecSources.begin();
     2872    while (   (it != vecSources.end())
     2873           && !g_fGuestCtrlCanceled)
     2874    {
     2875        bool fSourceIsDirectory = false;
     2876        Utf8Str strCurSource = (*it);
     2877        Utf8Str strCurDest = strDest;
     2878
     2879        /** @todo Slooooow, but works for now. */
     2880        ComPtr<IGuestFsObjInfo> pFsObjInfo;
     2881        rc = pCtx->pGuestSession->FileQueryInfo(Bstr(strCurSource).raw(), pFsObjInfo.asOutParam());
     2882        if (FAILED(rc))
     2883        {
     2884            rc = pCtx->pGuestSession->DirectoryQueryInfo(Bstr(strCurSource).raw(), pFsObjInfo.asOutParam());
     2885            fSourceIsDirectory = SUCCEEDED(rc);
     2886        }
     2887        if (FAILED(rc))
     2888        {
     2889            if (pCtx->fVerbose)
     2890                RTPrintf("Warning: Cannot stat for element \"%s\": No such element\n",
     2891                         strCurSource.c_str());
     2892            it++;
     2893            continue; /* Skip. */
     2894        }
     2895
     2896        if (!fSourceIsDirectory)
     2897        {
     2898            char *pszFileName = RTPathFilename(strCurSource.c_str());
     2899            if (!pszFileName)
     2900            {
     2901                RTMsgError("Unable to extract file name from source \"%s\"",
     2902                           strCurSource.c_str());
     2903                break;
     2904            }
     2905
     2906            char szFileDest[RTPATH_MAX];
     2907            vrc = RTPathJoin(szFileDest, sizeof(szFileDest), strDest.c_str(), pszFileName);
     2908            if (RT_FAILURE(vrc))
     2909            {
     2910                RTMsgError("Unable to build destination name for source \"%s\", rc=%Rrc",
     2911                           strCurSource.c_str(), vrc);
     2912                break;
     2913            }
     2914
     2915            strCurDest = szFileDest;
     2916        }
     2917
     2918        if (pCtx->fVerbose)
     2919            RTPrintf("Renaming %s \"%s\" to \"%s\" ...\n",
     2920                     fSourceIsDirectory ? "directory" : "file",
     2921                     strCurSource.c_str(), strCurDest.c_str());
     2922
     2923        if (!fDryrun)
     2924        {
     2925            if (fSourceIsDirectory)
     2926            {
     2927                CHECK_ERROR_BREAK(pCtx->pGuestSession, DirectoryRename(Bstr(strCurSource).raw(),
     2928                                                                       Bstr(strCurDest).raw(),
     2929                                                                       ComSafeArrayAsInParam(aRenameFlags)));
     2930
     2931                /* Break here, since it makes no sense to rename mroe than one source to
     2932                 * the same directory. */
     2933                it = vecSources.end();
     2934                break;
     2935            }
     2936            else
     2937                CHECK_ERROR_BREAK(pCtx->pGuestSession, FileRename(Bstr(strCurSource).raw(),
     2938                                                                  Bstr(strCurDest).raw(),
     2939                                                                  ComSafeArrayAsInParam(aRenameFlags)));
     2940        }
     2941
     2942        it++;
     2943    }
     2944
     2945    if (   (it != vecSources.end())
     2946        && pCtx->fVerbose)
     2947    {
     2948        RTPrintf("Warning: Not all sources were renamed\n");
     2949    }
     2950
     2951    return FAILED(rc) ? RTEXITCODE_FAILURE : RTEXITCODE_SUCCESS;
     2952}
     2953
    27742954static DECLCALLBACK(RTEXITCODE) handleCtrlCreateTemp(PGCTLCMDCTX pCtx)
    27752955{
    27762956    AssertPtrReturn(pCtx, RTEXITCODE_FAILURE);
    27772957
    2778     /*
    2779      * Parse arguments.
    2780      *
    2781      * Note! No direct returns here, everyone must go thru the cleanup at the
    2782      *       end of this function.
    2783      */
    27842958    static const RTGETOPTDEF s_aOptions[] =
    27852959    {
     
    32463420        return errorSyntax(USAGE_GUESTCONTROL, "Must specify at least a PID to close");
    32473421
    3248     /*
    3249      * Parse arguments.
    3250      *
    3251      * Note! No direct returns here, everyone must go thru the cleanup at the
    3252      *       end of this function.
    3253      */
    32543422    static const RTGETOPTDEF s_aOptions[] =
    32553423    {
     
    34473615
    34483616    if (pCtx->iArgc < 1)
    3449         return errorSyntax(USAGE_GUESTCONTROL, "Must specify at least a session ID to close");
    3450 
    3451     /*
    3452      * Parse arguments.
    3453      *
    3454      * Note! No direct returns here, everyone must go thru the cleanup at the
    3455      *       end of this function.
    3456      */
     3617        return errorSyntax(USAGE_GUESTCONTROL, "Must specify at least a session to close");
     3618
    34573619    static const RTGETOPTDEF s_aOptions[] =
    34583620    {
     
    36023764    RTGETOPTSTATE GetState;
    36033765    RTGetOptInit(&GetState, pCtx->iArgc, pCtx->ppaArgv,
    3604                  s_aOptions, RT_ELEMENTS(s_aOptions), pCtx->iFirstArgc, RTGETOPTINIT_FLAGS_OPTS_FIRST);
     3766                 NULL /*s_aOptions*/, 0 /*RT_ELEMENTS(s_aOptions)*/, pCtx->iFirstArgc, RTGETOPTINIT_FLAGS_OPTS_FIRST);
    36053767
    36063768    while ((ch = RTGetOpt(&GetState, &ValueUnion)))
     
    37173879             || !RTStrICmp(pArg->argv[1], "removefile"))
    37183880        gctlCmd.pfnHandler = handleCtrlRemoveFile;
     3881    else if (   !RTStrICmp(pArg->argv[1], "ren")
     3882             || !RTStrICmp(pArg->argv[1], "rename")
     3883             || !RTStrICmp(pArg->argv[1], "mv"))
     3884        gctlCmd.pfnHandler = handleCtrlRename;
    37193885    else if (   !RTStrICmp(pArg->argv[1], "createtemporary")
    37203886             || !RTStrICmp(pArg->argv[1], "createtemp")
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