Ejemplo n.º 1
0
int ConsoleFinder::RunConsole(const wxString &title)
{
	// start the xterm and put the shell to sleep with -e sleep 80000
	// fetch the xterm tty so we can issue to gdb a "tty /dev/pts/#"
	// redirecting program stdin/stdout/stderr to the xterm console.

#ifndef __WXMSW__
	wxString cmd;

	cmd = GetConsoleCommand();
	cmd.Replace(wxT("$(TITLE)"), title);
	cmd.Replace(wxT("$(CMD)"), wxString::Format(wxT("sleep %lu"), 80000 + wxGetProcessId()));

	wxLogMessage(wxString::Format(wxT("Launching console: %s"), cmd.c_str()));

	m_nConsolePid = wxExecute(cmd, wxEXEC_ASYNC|wxEXEC_MAKE_GROUP_LEADER);
	if (m_nConsolePid <= 0) {
		return -1;
	}

	// Issue the PS command to get the /dev/tty device name
	// First, wait for the xterm to settle down, else PS won't see the sleep task
	wxSleep(1);
	m_ConsoleTty = GetConsoleTty(m_nConsolePid);
	if (m_ConsoleTty.IsEmpty()) {
		FreeConsole();
		return -1;
	}
	return m_nConsolePid;

#else //__WXMSW__
	wxUnusedVar(title);
	return -1;
#endif
}
Ejemplo n.º 2
0
int cbDebuggerPlugin::RunNixConsole(wxString &consoleTty)
{
    consoleTty = wxEmptyString;
#ifndef __WXMSW__
    // Start a terminal and put the shell to sleep with -e sleep 80000.
    // Fetch the terminal's tty, so we can tell the debugger what TTY to use,
    // thus redirecting program's stdin/stdout/stderr to the terminal.

    wxString cmd;
    int consolePid = 0;
    // Use the terminal specified by the user in the Settings -> Environment.
    wxString term = Manager::Get()->GetConfigManager(_T("app"))->Read(_T("/console_terminal"), DEFAULT_CONSOLE_TERM);

    term.Replace(_T("$TITLE"), wxString(wxT("'"))+_("Program Console")+wxT("'"));
    cmd << term << _T(" ");

    const wxString &sleepCommand = MakeSleepCommand();
    cmd << sleepCommand;

    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(cmd);

    // The lifetime of wxProcess objects is very uncertain, so we are using a shared pointer to
    // prevent us accessing deleted objects.
    cb::shared_ptr<ConsoleProcessTerminationInfo> processInfo(new ConsoleProcessTerminationInfo);
    ConsoleProcess *process = new ConsoleProcess(processInfo);
    consolePid = wxExecute(cmd, wxEXEC_ASYNC, process);
    if (consolePid <= 0)
        return -1;

    // Try to find the TTY. We're using a loop, because some slow machines might make the check fail due
    // to a slow starting terminal.
    for (int ii = 0; ii < 100; ++ii)
    {
        // First, wait for the terminal to settle down, else PS won't see the sleep task
        Manager::Yield();
        ::wxMilliSleep(200);

        // Try to detect if the terminal command is present or its parameters are valid.
        if (processInfo->FailedToStart() /*&& ii > 0*/)
        {
            Log(F(wxT("Failed to execute terminal command: '%s' (exit code: %d)"),
                  cmd.wx_str(), processInfo->status), Logger::error);
            break;
        }

        // Try to find tty path and pid for the sleep command we've just executed.
        const ConsoleInfo &info = GetConsoleTty(consolePid);

        // If there is no sleep command yet, do another iteration after a small delay.
        if (!info.IsValid())
            continue;

        // Try to find if the console window is still alive. Newer terminals like gnome-terminal
        // try to be easier on resources and use a shared server process. For these terminals the
        // spawned terminal process exits immediately, but the sleep command is still executed.
        // If we detect such case we will return the PID for the sleep command instead of the PID
        // for the terminal.
        if (kill(consolePid, 0) == -1 && errno == ESRCH) {
            DebugLog(F(wxT("Using sleep command's PID as console PID %d, TTY %s"),
                       info.sleepPID, info.ttyPath.wx_str()));
            consoleTty = info.ttyPath;
            return info.sleepPID;
        }
        else
        {
            DebugLog(F(wxT("Using terminal's PID as console PID %d, TTY %s"), info.sleepPID, info.ttyPath.wx_str()));
            consoleTty = info.ttyPath;
            return consolePid;
        }
    }
    // failed to find the console tty
    if (consolePid != 0)
        ::wxKill(consolePid);
#endif // !__WWXMSW__
    return -1;
}