File: clConsoleGnomeTerminal.cpp

package info (click to toggle)
codelite 14.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 112,816 kB
  • sloc: cpp: 483,662; ansic: 150,144; php: 9,569; lex: 4,186; python: 3,417; yacc: 2,820; sh: 1,147; makefile: 52; xml: 13
file content (133 lines) | stat: -rw-r--r-- 4,331 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include "clConsoleGnomeTerminal.h"
#include "dirsaver.h"
#include "file_logger.h"
#include "fileutils.h"
#include "procutils.h"
#include <wx/tokenzr.h>
#include <wx/utils.h>

bool clConsoleGnomeTerminal::FindProcessByCommand(const wxString& name, wxString& tty, long& pid)
{
    clDEBUG() << "FindProcessByCommand is called";
    tty.Clear();
    pid = wxNOT_FOUND;

    // Run "ps -A -o pid,tty,command" to locate the terminal ID
    wxString psCommand;
    wxArrayString arrOutput;
    psCommand << "ps -A -o pid,tty,command";

    ProcUtils::SafeExecuteCommand(psCommand, arrOutput);

    for(size_t i = 0; i < arrOutput.GetCount(); ++i) {
        wxString curline = arrOutput.Item(i).Trim().Trim(false);
        wxArrayString tokens = ::wxStringTokenize(curline, " ", wxTOKEN_STRTOK);
        if(tokens.GetCount() < 3) { continue; }

        // replace tabs with spaces
        curline.Replace("\t", " ");

        // remove any duplicate spaces
        while(curline.Replace("  ", " ")) {}

        wxString tmp_pid = curline.BeforeFirst(' ');
        curline = curline.AfterFirst(' ');

        wxString tmp_tty = curline.BeforeFirst(' ');
        curline = curline.AfterFirst(' ');

        wxString command = curline; // the remainder
        command.Trim().Trim(false);

        if(command == name) {
            // we got our match
            tmp_tty = tmp_tty.AfterLast('/');
            tmp_tty.Prepend("/dev/pts/");
            tty = tmp_tty;
            tmp_pid.Trim().Trim(false).ToCLong(&pid);
            return true;
        }
    }
    return false;
}

clConsoleGnomeTerminal::clConsoleGnomeTerminal()
{
    SetTerminalCommand("gnome-terminal --working-directory=%WD% -e '%COMMAND%'");
    SetEmptyTerminalCommand("gnome-terminal --working-directory=%WD%");
}

clConsoleGnomeTerminal::~clConsoleGnomeTerminal() {}

bool clConsoleGnomeTerminal::Start()
{
    // Apply the environment variables before we launch the process
    clConsoleEnvironment env(GetEnvironment());
    env.Apply();
    return StartProcess(PrepareCommand());
}

bool clConsoleGnomeTerminal::StartForDebugger()
{
    // generate a random value to differntiate this instance of codelite
    // from other instances

    time_t curtime = time(NULL);
    int randomSeed = (curtime % 947);
    wxString secondsToSleep;

    secondsToSleep << (85765 + randomSeed);

    wxString sleepCommand = "/bin/sleep";
    sleepCommand << " " << secondsToSleep;

    wxString homedir = wxGetHomeDir();
    if(homedir.Contains(" ")) { homedir.Prepend("\"").Append("\""); }
    wxString commandToExecute = GetTerminalCommand();
    commandToExecute.Replace("%WD%", homedir);
    commandToExecute.Replace("%COMMAND%", sleepCommand);
    ::wxExecute(commandToExecute);

    // Let it start ... (wait for it up to 5 seconds)
    for(size_t i = 0; i < 100; ++i) {
        if(FindProcessByCommand(sleepCommand, m_tty, m_pid)) {
            // On GTK, redirection to TTY does not work with lldb
            // as a workaround, we create a symlink with different name

            // Keep the real tty
            m_realPts = m_tty;

            wxString symlinkName = m_tty;
            symlinkName.Replace("/dev/pts/", "/tmp/pts");
            wxString lnCommand;
            lnCommand << "ln -sf " << m_tty << " " << symlinkName;
            if(::system(lnCommand.mb_str(wxConvUTF8).data()) == 0) { m_tty.swap(symlinkName); }
            break;
        }
        wxThread::Sleep(50);
    }
    return !m_tty.IsEmpty();
}

wxString clConsoleGnomeTerminal::PrepareCommand()
{
    wxString commandToExecute;
    bool hasCommand = !GetCommand().IsEmpty();
    commandToExecute = hasCommand ? GetTerminalCommand() : GetEmptyTerminalCommand();
    if(!IsTerminalNeeded()) { commandToExecute = "%COMMAND%"; }

    if(IsTerminalNeeded()) {
        // set the working directory
        wxString workingDirectory = WrapWithQuotesIfNeeded(GetWorkingDirectory());
        if(workingDirectory.IsEmpty()) { workingDirectory = "."; }
        commandToExecute.Replace("%WD%", workingDirectory);
    }

    if(hasCommand) {
        wxFileName scriptPath = PrepareExecScript();
        wxString rowCommand;
        rowCommand << "/bin/bash -f \"" << scriptPath.GetFullPath() << "\"";
        commandToExecute.Replace("%COMMAND%", rowCommand);
    }
    return commandToExecute;
}