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;
}
|