1 //===-- CommandObjectQuit.cpp -----------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/lldb-python.h"
11 
12 #include "CommandObjectQuit.h"
13 
14 // C Includes
15 // C++ Includes
16 // Other libraries and framework includes
17 // Project includes
18 #include "lldb/Interpreter/CommandInterpreter.h"
19 #include "lldb/Interpreter/CommandReturnObject.h"
20 
21 using namespace lldb;
22 using namespace lldb_private;
23 
24 //-------------------------------------------------------------------------
25 // CommandObjectQuit
26 //-------------------------------------------------------------------------
27 
CommandObjectQuit(CommandInterpreter & interpreter)28 CommandObjectQuit::CommandObjectQuit (CommandInterpreter &interpreter) :
29     CommandObjectParsed (interpreter, "quit", "Quit out of the LLDB debugger.", "quit")
30 {
31 }
32 
~CommandObjectQuit()33 CommandObjectQuit::~CommandObjectQuit ()
34 {
35 }
36 
37 // returns true if there is at least one alive process
38 // is_a_detach will be true if all alive processes will be detached when you quit
39 // and false if at least one process will be killed instead
40 bool
ShouldAskForConfirmation(bool & is_a_detach)41 CommandObjectQuit::ShouldAskForConfirmation (bool& is_a_detach)
42 {
43     if (m_interpreter.GetPromptOnQuit() == false)
44         return false;
45     bool should_prompt = false;
46     is_a_detach = true;
47     for (uint32_t debugger_idx = 0;
48          debugger_idx < Debugger::GetNumDebuggers();
49          debugger_idx++)
50     {
51         DebuggerSP debugger_sp(Debugger::GetDebuggerAtIndex(debugger_idx));
52         if (!debugger_sp)
53             continue;
54         const TargetList& target_list(debugger_sp->GetTargetList());
55         for (uint32_t target_idx = 0;
56              target_idx < target_list.GetNumTargets();
57              target_idx++)
58         {
59             TargetSP target_sp(target_list.GetTargetAtIndex(target_idx));
60             if (!target_sp)
61                 continue;
62             ProcessSP process_sp(target_sp->GetProcessSP());
63             if (process_sp
64                 && process_sp->IsValid()
65                 && process_sp->IsAlive()
66                 && process_sp->WarnBeforeDetach())
67             {
68                 should_prompt = true;
69                 if (process_sp->GetShouldDetach() == false)
70                 {
71                     // if we need to kill at least one process, just say so and return
72                     is_a_detach = false;
73                     return should_prompt;
74                 }
75             }
76         }
77     }
78     return should_prompt;
79 }
80 
81 bool
DoExecute(Args & command,CommandReturnObject & result)82 CommandObjectQuit::DoExecute (Args& command, CommandReturnObject &result)
83 {
84     bool is_a_detach = true;
85     if (ShouldAskForConfirmation (is_a_detach))
86     {
87         StreamString message;
88         message.Printf("Quitting LLDB will %s one or more processes. Do you really want to proceed", (is_a_detach ? "detach from" : "kill"));
89         if (!m_interpreter.Confirm(message.GetData(), true))
90         {
91             result.SetStatus(eReturnStatusFailed);
92             return false;
93         }
94     }
95     m_interpreter.BroadcastEvent (CommandInterpreter::eBroadcastBitQuitCommandReceived);
96     result.SetStatus (eReturnStatusQuit);
97     return true;
98 }
99 
100