1
//////////////////////////////////////////////////////////////////////////////
2
//////////////////////////////////////////////////////////////////////////////
4
// copyright : (C) 2008 by Eran Ifrah
5
// file name : consolefinder.cpp
7
// -------------------------------------------------------------------------
10
// / __ \ | | | | (_) |
11
// | / \/ ___ __| | ___| | _| |_ ___
12
// | | / _ \ / _ |/ _ \ | | | __/ _ )
13
// | \__/\ (_) | (_| | __/ |___| | || __/
14
// \____/\___/ \__,_|\___\_____/_|\__\___|
18
// This program is free software; you can redistribute it and/or modify
19
// it under the terms of the GNU General Public License as published by
20
// the Free Software Foundation; either version 2 of the License, or
21
// (at your option) any later version.
23
//////////////////////////////////////////////////////////////////////////////
24
//////////////////////////////////////////////////////////////////////////////
25
#include "consolefinder.h"
26
#include "procutils.h"
27
#include "exelocator.h"
29
ConsoleFinder::ConsoleFinder()
34
ConsoleFinder::~ConsoleFinder()
39
void ConsoleFinder::FreeConsole()
42
wxKill(m_nConsolePid, wxSIGKILL);
47
int ConsoleFinder::RunConsole(const wxString &title)
49
// start the xterm and put the shell to sleep with -e sleep 80000
50
// fetch the xterm tty so we can issue to gdb a "tty /dev/pts/#"
51
// redirecting program stdin/stdout/stderr to the xterm console.
57
#if defined (__WXGTK__)
59
cmd << wxT("xterm -title ");
60
cmd << wxT("'") << title << wxT("'");
63
cmd << wxString::Format(wxT("%d"),80000 + ::wxGetProcessId());
64
#elif defined (__WXMAC__)
65
cmd << wxT("osascript -e 'tell application \"Terminal\"' -e 'activate' -e 'do script with command \"sleep ")
66
<< wxString::Format(wxT("%d"),80000 + ::wxGetProcessId())
67
<< wxT("\"' -e 'end tell'");
70
//start xterm -e sleep {some unique # of seconds}
71
m_nConsolePid = wxExecute(cmd, wxEXEC_ASYNC);
72
if (m_nConsolePid <= 0){
76
// Issue the PS command to get the /dev/tty device name
77
// First, wait for the xterm to settle down, else PS won't see the sleep task
79
m_ConsoleTty = GetConsoleTty(m_nConsolePid);
80
if(m_ConsoleTty.IsEmpty()){
92
wxString ConsoleFinder::GetConsoleTty(int ConsolePid)
95
// execute the ps x -o command and read PS output to get the /dev/tty field
96
unsigned long ConsPid = ConsolePid;
98
wxArrayString psOutput;
99
wxArrayString psErrors;
101
psCmd << wxT("ps x -o tty,pid,command");
102
ProcUtils::ExecuteCommand(psCmd, psOutput);
106
ConsPidStr << ConsPid;
107
//find task with our unique sleep time
108
wxString uniqueSleepTimeStr;
109
uniqueSleepTimeStr << wxT("sleep ") << wxString::Format(wxT("%d"),80000 + ::wxGetProcessId());
110
// search the output of "ps pid" command
111
int knt = psOutput.GetCount();
112
for (int i=knt-1; i>-1; --i) {
113
psCmd = psOutput.Item(i);
114
// find the pts/# or tty/# or whatever it's called
115
// by seaching the output of "ps x -o tty,pid,command" command.
116
// The output of ps looks like:
118
// pts/0 13342 /bin/sh ./run.sh
119
// pts/0 13343 /home/pecanpecan/devel/trunk/src/devel/codeblocks
120
// pts/0 13361 /usr/bin/gdb -nx -fullname -quiet -args ./conio
121
// pts/0 13362 xterm -font -*-*-*-*-*-*-20-*-*-*-*-*-*-* -T Program Console -e sleep 93343
122
// pts/2 13363 sleep 93343
123
// ? 13365 /home/pecan/proj/conio/conio
124
// pts/1 13370 ps x -o tty,pid,command
126
if (psCmd.Contains(uniqueSleepTimeStr))
127
do { // check for correct "sleep" line
128
if (psCmd.Contains(wxT("-T"))) break; //error;wrong sleep line.
129
// found "sleep 93343" string, extract tty field
130
ConsTtyStr = wxT("/dev/") + psCmd.BeforeFirst(' ');
134
return wxEmptyString;
136
wxUnusedVar(ConsolePid);
137
return wxEmptyString;
141
bool ConsoleFinder::FindConsole(const wxString &title, wxString &consoleName)
143
int pid = RunConsole(title);
145
consoleName = m_ConsoleTty;
151
wxString ConsoleFinder::GetConsoleName()
155
wxChar *shell = wxGetenv(wxT("COMSPEC"));
157
shell = wxT("\\COMMAND.COM");
163
//try to locate the default terminal
166
if(ExeLocator::Locate(wxT("gnome-terminal"), where)){
167
terminal = wxT("gnome-terminal -e ");
169
else if(ExeLocator::Locate(wxT("konsole"), where)){
170
terminal = wxT("konsole");
172
else if(ExeLocator::Locate(wxT("xterm"), where)){
173
terminal = wxT("xterm -e ");
177
cmd = wxT("xterm -e ");