string _sh_command(string command, bool force_local, bool force_display_settings) { // Fetch display settings string display; if (command_shell != 0) display = XDisplayString(XtDisplay(command_shell)); else if (getenv("DISPLAY") != 0) display = getenv("DISPLAY"); else display = ""; // Make sure display contains host name if (display.contains("unix:", 0) || display.contains(":", 0)) { display = string(hostname()) + display.from(":"); } // Make sure display contains fully qualified host name if (display.contains(":") && !display.contains("::")) { string host = display.before(':'); display = string(fullhostname(host.chars())) + display.from(":"); } string settings = ""; if (!display.empty()) { settings += "DISPLAY=${DISPLAY-" + sh_quote(display) + "}; export DISPLAY; "; } settings += set_environment_command(); if (force_local || !remote_gdb()) { if (command.empty()) return ""; if (force_display_settings) command = settings + command; return "/bin/sh -c " + sh_quote(command); } string rsh = app_data.rsh_command; const string login = app_data.debugger_host_login; if (!login.empty()) rsh += " -l " + login; rsh += " " + gdb_host; if (!command.empty()) rsh += " /bin/sh -c " + sh_quote(sh_quote(settings + command)); return rsh; }
// Return NAME1=VALUE1 NAME2=VALUE2 for each name defined by PUT_ENVIRONMENT string set_environment_command() { string cmd; for (int i = 0; i < environment_names.size(); i++) { const string& name = environment_names[i]; char *env = getenv((char *)name); if (env != 0) cmd += name + "=" + sh_quote(env) + "; export " + name + "; "; } return cmd; }
GDBAgent *new_gdb(DebuggerType type, const AppData& app_data, XtAppContext app_context, int argc, char *argv[]) { // Build call static string gdb_call = app_data.debugger_command; if (app_data.play_log != 0) { gdb_call += string(" --PLAY ") + app_data.play_log; } else { switch(type) { case GDB: // Do not issue introductiory messages; output full file names. gdb_call += " -q -fullname"; break; case DBX: // Nothing special. (Anyway, every DBX has its own sets of // options, so there is not much we could do here.) break; case JDB: // Nothing special. break; case PERL: // Be sure to invoke the debugger. gdb_call += " -d"; break; case BASH: // Be sure to invoke the debugger. gdb_call += " --debugger"; break; case DBG: // Nothing special? break; case PYDB: // Nothing special. break; case XDB: // Enable line mode. gdb_call += " -L"; break; } } for (int i = 1; i < argc; i++) { string arg = argv[i]; gdb_call += " " + sh_quote(arg); } if (argc <= 1) { if (type == PERL) { // Invoked without args. Add a dummy `eval' arg. gdb_call += " -e 42"; } else if (type == BASH) { gdb_call += " -c ': type \\\"debug *script-name*\\\" to start your script.'"; } } GDBAgent *gdb; if (app_data.debugger_rhost == 0 || app_data.debugger_rhost[0] == '\0') { // Use direct invocation gdb_call = sh_command("exec " + gdb_call); gdb = new GDBAgent(app_context, gdb_call, type); } else { // Use interactive rsh gdb = new GDBAgent(app_context, sh_command(), type); gdb_call = "exec " + _sh_command("exec " + gdb_call, true, true) + "\n"; gdb->addHandler(Input, InvokeGDBFromShellHP, (void *)&gdb_call); } // Set up Agent resources switch (app_data.block_tty_input) { case On: gdb->block_tty_input(true); break; case Off: gdb->block_tty_input(false); break; case Auto: // Leave default setting unchanged break; } // Set up Agent resources switch (app_data.buffer_gdb_output) { case On: gdb->buffer_gdb_output(true); break; case Off: gdb->buffer_gdb_output(false); break; case Auto: // Tie buffering to existence of separate window gdb->buffer_gdb_output(app_data.separate_exec_window); break; } return gdb; }
// Fetch the X library directory, using xmkmf(1) static const _XtString xlibdir(Display *display, bool verbose = false) { static bool tried = false; static const _XtString dir = 0; if (tried) return dir; tried = true; if (!is_cmd_file(cmd_file("xmkmf"))) return dir; // No `xmkmf' in PATH if (!is_cmd_file(cmd_file("make"))) return dir; // No `make' in PATH static const char *shell_command = "" #include "xlibdir.C" ""; String me, my_class; XtGetApplicationNameAndClass(display, &me, &my_class); if (verbose) { std::cout << "Checking for X11 library directory... "; std::cout.flush(); } const string s1 = "/bin/sh -c " + sh_quote(shell_command); FILE *fp = popen(s1.chars(), "r"); if (fp == 0) { if (verbose) { std::cout << strerror(errno) << "\n"; std::cout.flush(); } return dir; } char buffer[PATH_MAX]; buffer[0] = '\0'; fgets(buffer, sizeof(buffer), fp); pclose(fp); int len = strlen(buffer); if (len > 0 && buffer[len - 1] == '\n') buffer[len - 1] = '\0'; if (buffer[0] == '/') // Sanity check dir = (String)XtNewString(buffer); if (verbose) { if (dir) std::cout << dir << "\n"; else std::cout << "(not found)\n"; std::cout.flush(); } return dir; }