VirtualBox

Ignore:
Timestamp:
Aug 9, 2013 9:33:08 AM (12 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
87830
Message:

VBoxManage/VBoxManageGuestCtrl.cpp: Install proper console signal handlers for Windows; close the guest session on all platforms when being interrupted.

File:
1 edited

Legend:

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

    r47625 r47629  
    6868
    6969/** Set by the signal handler. */
    70 static volatile bool    g_fGuestCtrlCanceled = false;
     70static volatile bool         g_fGuestCtrlCanceled = false;
     71/** Our global session object which is also used in the
     72 *  signal handler to abort operations properly. */
     73static ComPtr<IGuestSession> g_pGuestSession;
    7174
    7275typedef struct COPYCONTEXT
     
    296299#ifndef VBOX_ONLY_DOCS
    297300
     301#ifdef RT_OS_WINDOWS
     302static BOOL WINAPI guestCtrlSignalHandler(DWORD dwCtrlType)
     303{
     304    bool fEventHandled = FALSE;
     305    switch (dwCtrlType)
     306    {
     307        /* User pressed CTRL+C or CTRL+BREAK or an external event was sent
     308         * via GenerateConsoleCtrlEvent(). */
     309        case CTRL_BREAK_EVENT:
     310        case CTRL_CLOSE_EVENT:
     311        case CTRL_C_EVENT:
     312            ASMAtomicWriteBool(&g_fGuestCtrlCanceled, true);
     313            if (!g_pGuestSession.isNull())
     314                g_pGuestSession->Close();
     315            fEventHandled = TRUE;
     316            break;
     317        default:
     318            break;
     319        /** @todo Add other events here. */
     320    }
     321
     322    return fEventHandled;
     323}
     324#else /* !RT_OS_WINDOWS */
    298325/**
    299326 * Signal handler that sets g_fGuestCtrlCanceled.
     
    307334    NOREF(iSignal);
    308335    ASMAtomicWriteBool(&g_fGuestCtrlCanceled, true);
    309 }
     336    if (!g_pGuestSession.isNull())
     337        g_pGuestSession->Close();
     338}
     339#endif
    310340
    311341/**
    312342 * Installs a custom signal handler to get notified
    313343 * whenever the user wants to intercept the program.
     344 *
     345 ** @todo Make this handler available for all VBoxManage modules?
    314346 */
    315 static void ctrlSignalHandlerInstall()
    316 {
     347static int ctrlSignalHandlerInstall(void)
     348{
     349    int rc = VINF_SUCCESS;
     350#ifdef RT_OS_WINDOWS
     351    if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)guestCtrlSignalHandler, TRUE /* Add handler */))
     352    {
     353        rc = RTErrConvertFromWin32(GetLastError());
     354        RTMsgError("Unable to install console control handler, rc=%Rrc\n", rc);
     355    }
     356#else
    317357    signal(SIGINT,   guestCtrlSignalHandler);
    318 #ifdef SIGBREAK
     358# ifdef SIGBREAK
    319359    signal(SIGBREAK, guestCtrlSignalHandler);
     360# endif
    320361#endif
     362    return rc;
    321363}
    322364
     
    324366 * Uninstalls a previously installed signal handler.
    325367 */
    326 static void ctrlSignalHandlerUninstall()
    327 {
     368static int ctrlSignalHandlerUninstall(void)
     369{
     370    int rc = VINF_SUCCESS;
     371#ifdef RT_OS_WINDOWS
     372    if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)NULL, FALSE /* Remove handler */))
     373    {
     374        rc = RTErrConvertFromWin32(GetLastError());
     375        RTMsgError("Unable to uninstall console control handler, rc=%Rrc\n", rc);
     376    }
     377#else
    328378    signal(SIGINT,   SIG_DFL);
    329 #ifdef SIGBREAK
     379# ifdef SIGBREAK
    330380    signal(SIGBREAK, SIG_DFL);
     381# endif
    331382#endif
     383    return rc;
    332384}
    333385
     
    835887        return errorSyntax(USAGE_GUESTCONTROL, "Output conversion not implemented yet!");
    836888
     889    ctrlSignalHandlerInstall();
     890
    837891    /*
    838892     * Start with the real work.
     
    848902     *        the session all over the places below again. Later. */
    849903
    850     ComPtr<IGuestSession> pGuestSession;
    851904    try
    852905    {
     
    860913                                      Bstr(strDomain).raw(),
    861914                                      Bstr(strVBoxManage).raw(),
    862                                       pGuestSession.asOutParam()));
     915                                      g_pGuestSession.asOutParam()));
    863916
    864917            /* Adjust process creation flags if we don't want to wait for process termination. */
     
    883936            aSessionWaitFlags.push_back(GuestSessionWaitForFlag_Start);
    884937            GuestSessionWaitResult_T sessionWaitResult;
    885             CHECK_ERROR_BREAK(pGuestSession, WaitForArray(ComSafeArrayAsInParam(aSessionWaitFlags), cMsTimeout, &sessionWaitResult));
     938            CHECK_ERROR_BREAK(g_pGuestSession, WaitForArray(ComSafeArrayAsInParam(aSessionWaitFlags), cMsTimeout, &sessionWaitResult));
    886939            ULONG uSessionID;
    887             CHECK_ERROR_BREAK(pGuestSession, COMGETTER(Id)(&uSessionID));
     940            CHECK_ERROR_BREAK(g_pGuestSession, COMGETTER(Id)(&uSessionID));
    888941
    889942            if (   sessionWaitResult == GuestSessionWaitResult_Start
     
    913966             */
    914967            ComPtr<IGuestProcess> pProcess;
    915             CHECK_ERROR_BREAK(pGuestSession, ProcessCreate(Bstr(strCmd).raw(),
     968            CHECK_ERROR_BREAK(g_pGuestSession, ProcessCreate(Bstr(strCmd).raw(),
    916969                                                           ComSafeArrayAsInParam(aArgs),
    917970                                                           ComSafeArrayAsInParam(aEnv),
     
    9901043                }
    9911044
    992                 if (FAILED(rc))
     1045                if (g_fGuestCtrlCanceled)
    9931046                    break;
    9941047
     
    10091062                }
    10101063
    1011                 if (RT_FAILURE(vrc))
     1064                if (   RT_FAILURE(vrc)
     1065                    || g_fGuestCtrlCanceled)
    10121066                    break;
    10131067
     
    10221076
    10231077            /* Report status back to the user. */
    1024             if (fCompleted)
     1078            if (   fCompleted
     1079                && !g_fGuestCtrlCanceled)
    10251080            {
    10261081                ProcessStatus_T procStatus;
     
    10561111    }
    10571112
     1113    ctrlSignalHandlerUninstall();
     1114
    10581115    bool fCloseSession = false;
    10591116    if (SUCCEEDED(rc))
     
    10701127
    10711128    if (   fCloseSession
    1072         && !pGuestSession.isNull())
     1129        && !g_pGuestSession.isNull())
    10731130    {
    10741131        if (fVerbose)
    10751132            RTPrintf("Closing guest session ...\n");
    1076         rc = pGuestSession->Close();
     1133        rc = g_pGuestSession->Close();
    10771134    }
    10781135    else if (!fCloseSession && fVerbose)
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