15796c8dcSSimon Schubert /* MI Command Set - environment commands.
2*ef5ccd6cSJohn Marino Copyright (C) 2002-2013 Free Software Foundation, Inc.
35796c8dcSSimon Schubert
45796c8dcSSimon Schubert Contributed by Red Hat Inc.
55796c8dcSSimon Schubert
65796c8dcSSimon Schubert This file is part of GDB.
75796c8dcSSimon Schubert
85796c8dcSSimon Schubert This program is free software; you can redistribute it and/or modify
95796c8dcSSimon Schubert it under the terms of the GNU General Public License as published by
105796c8dcSSimon Schubert the Free Software Foundation; either version 3 of the License, or
115796c8dcSSimon Schubert (at your option) any later version.
125796c8dcSSimon Schubert
135796c8dcSSimon Schubert This program is distributed in the hope that it will be useful,
145796c8dcSSimon Schubert but WITHOUT ANY WARRANTY; without even the implied warranty of
155796c8dcSSimon Schubert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
165796c8dcSSimon Schubert GNU General Public License for more details.
175796c8dcSSimon Schubert
185796c8dcSSimon Schubert You should have received a copy of the GNU General Public License
195796c8dcSSimon Schubert along with this program. If not, see <http://www.gnu.org/licenses/>. */
205796c8dcSSimon Schubert
215796c8dcSSimon Schubert #include "defs.h"
225796c8dcSSimon Schubert #include "inferior.h"
235796c8dcSSimon Schubert #include "value.h"
245796c8dcSSimon Schubert #include "mi-out.h"
255796c8dcSSimon Schubert #include "mi-cmds.h"
265796c8dcSSimon Schubert #include "mi-getopt.h"
275796c8dcSSimon Schubert #include "symtab.h"
285796c8dcSSimon Schubert #include "target.h"
295796c8dcSSimon Schubert #include "environ.h"
305796c8dcSSimon Schubert #include "command.h"
315796c8dcSSimon Schubert #include "ui-out.h"
325796c8dcSSimon Schubert #include "top.h"
335796c8dcSSimon Schubert
345796c8dcSSimon Schubert #include "gdb_string.h"
355796c8dcSSimon Schubert #include "gdb_stat.h"
365796c8dcSSimon Schubert
375796c8dcSSimon Schubert static void env_mod_path (char *dirname, char **which_path);
38*ef5ccd6cSJohn Marino
395796c8dcSSimon Schubert extern void _initialize_mi_cmd_env (void);
405796c8dcSSimon Schubert
415796c8dcSSimon Schubert static const char path_var_name[] = "PATH";
425796c8dcSSimon Schubert static char *orig_path = NULL;
435796c8dcSSimon Schubert
445796c8dcSSimon Schubert /* The following is copied from mi-main.c so for m1 and below we can
455796c8dcSSimon Schubert perform old behavior and use cli commands. If ARGS is non-null,
465796c8dcSSimon Schubert append it to the CMD. */
47*ef5ccd6cSJohn Marino
485796c8dcSSimon Schubert static void
env_execute_cli_command(const char * cmd,const char * args)495796c8dcSSimon Schubert env_execute_cli_command (const char *cmd, const char *args)
505796c8dcSSimon Schubert {
515796c8dcSSimon Schubert if (cmd != 0)
525796c8dcSSimon Schubert {
535796c8dcSSimon Schubert struct cleanup *old_cleanups;
545796c8dcSSimon Schubert char *run;
55cf7f2e2dSJohn Marino
565796c8dcSSimon Schubert if (args != NULL)
575796c8dcSSimon Schubert run = xstrprintf ("%s %s", cmd, args);
585796c8dcSSimon Schubert else
595796c8dcSSimon Schubert run = xstrdup (cmd);
605796c8dcSSimon Schubert old_cleanups = make_cleanup (xfree, run);
615796c8dcSSimon Schubert execute_command ( /*ui */ run, 0 /*from_tty */ );
625796c8dcSSimon Schubert do_cleanups (old_cleanups);
635796c8dcSSimon Schubert return;
645796c8dcSSimon Schubert }
655796c8dcSSimon Schubert }
665796c8dcSSimon Schubert
675796c8dcSSimon Schubert /* Print working directory. */
68*ef5ccd6cSJohn Marino
695796c8dcSSimon Schubert void
mi_cmd_env_pwd(char * command,char ** argv,int argc)705796c8dcSSimon Schubert mi_cmd_env_pwd (char *command, char **argv, int argc)
715796c8dcSSimon Schubert {
72a45ae5f8SJohn Marino struct ui_out *uiout = current_uiout;
73a45ae5f8SJohn Marino
745796c8dcSSimon Schubert if (argc > 0)
75*ef5ccd6cSJohn Marino error (_("-environment-pwd: No arguments allowed"));
765796c8dcSSimon Schubert
775796c8dcSSimon Schubert if (mi_version (uiout) < 2)
785796c8dcSSimon Schubert {
795796c8dcSSimon Schubert env_execute_cli_command ("pwd", NULL);
805796c8dcSSimon Schubert return;
815796c8dcSSimon Schubert }
825796c8dcSSimon Schubert
835796c8dcSSimon Schubert /* Otherwise the mi level is 2 or higher. */
845796c8dcSSimon Schubert
855796c8dcSSimon Schubert if (! getcwd (gdb_dirbuf, sizeof (gdb_dirbuf)))
86c50c785cSJohn Marino error (_("-environment-pwd: error finding name of working directory: %s"),
875796c8dcSSimon Schubert safe_strerror (errno));
885796c8dcSSimon Schubert
895796c8dcSSimon Schubert ui_out_field_string (uiout, "cwd", gdb_dirbuf);
905796c8dcSSimon Schubert }
915796c8dcSSimon Schubert
925796c8dcSSimon Schubert /* Change working directory. */
93*ef5ccd6cSJohn Marino
945796c8dcSSimon Schubert void
mi_cmd_env_cd(char * command,char ** argv,int argc)955796c8dcSSimon Schubert mi_cmd_env_cd (char *command, char **argv, int argc)
965796c8dcSSimon Schubert {
975796c8dcSSimon Schubert if (argc == 0 || argc > 1)
98c50c785cSJohn Marino error (_("-environment-cd: Usage DIRECTORY"));
995796c8dcSSimon Schubert
1005796c8dcSSimon Schubert env_execute_cli_command ("cd", argv[0]);
1015796c8dcSSimon Schubert }
1025796c8dcSSimon Schubert
1035796c8dcSSimon Schubert static void
env_mod_path(char * dirname,char ** which_path)1045796c8dcSSimon Schubert env_mod_path (char *dirname, char **which_path)
1055796c8dcSSimon Schubert {
1065796c8dcSSimon Schubert if (dirname == 0 || dirname[0] == '\0')
1075796c8dcSSimon Schubert return;
1085796c8dcSSimon Schubert
1095796c8dcSSimon Schubert /* Call add_path with last arg 0 to indicate not to parse for
1105796c8dcSSimon Schubert separator characters. */
1115796c8dcSSimon Schubert add_path (dirname, which_path, 0);
1125796c8dcSSimon Schubert }
1135796c8dcSSimon Schubert
1145796c8dcSSimon Schubert /* Add one or more directories to start of executable search path. */
115*ef5ccd6cSJohn Marino
1165796c8dcSSimon Schubert void
mi_cmd_env_path(char * command,char ** argv,int argc)1175796c8dcSSimon Schubert mi_cmd_env_path (char *command, char **argv, int argc)
1185796c8dcSSimon Schubert {
119a45ae5f8SJohn Marino struct ui_out *uiout = current_uiout;
1205796c8dcSSimon Schubert char *exec_path;
1215796c8dcSSimon Schubert char *env;
1225796c8dcSSimon Schubert int reset = 0;
123*ef5ccd6cSJohn Marino int oind = 0;
1245796c8dcSSimon Schubert int i;
125*ef5ccd6cSJohn Marino char *oarg;
1265796c8dcSSimon Schubert enum opt
1275796c8dcSSimon Schubert {
1285796c8dcSSimon Schubert RESET_OPT
1295796c8dcSSimon Schubert };
130a45ae5f8SJohn Marino static const struct mi_opt opts[] =
1315796c8dcSSimon Schubert {
1325796c8dcSSimon Schubert {"r", RESET_OPT, 0},
1335796c8dcSSimon Schubert { 0, 0, 0 }
1345796c8dcSSimon Schubert };
1355796c8dcSSimon Schubert
1365796c8dcSSimon Schubert dont_repeat ();
1375796c8dcSSimon Schubert
1385796c8dcSSimon Schubert if (mi_version (uiout) < 2)
1395796c8dcSSimon Schubert {
1405796c8dcSSimon Schubert for (i = argc - 1; i >= 0; --i)
1415796c8dcSSimon Schubert env_execute_cli_command ("path", argv[i]);
1425796c8dcSSimon Schubert return;
1435796c8dcSSimon Schubert }
1445796c8dcSSimon Schubert
1455796c8dcSSimon Schubert /* Otherwise the mi level is 2 or higher. */
1465796c8dcSSimon Schubert while (1)
1475796c8dcSSimon Schubert {
148c50c785cSJohn Marino int opt = mi_getopt ("-environment-path", argc, argv, opts,
149*ef5ccd6cSJohn Marino &oind, &oarg);
150cf7f2e2dSJohn Marino
1515796c8dcSSimon Schubert if (opt < 0)
1525796c8dcSSimon Schubert break;
1535796c8dcSSimon Schubert switch ((enum opt) opt)
1545796c8dcSSimon Schubert {
1555796c8dcSSimon Schubert case RESET_OPT:
1565796c8dcSSimon Schubert reset = 1;
1575796c8dcSSimon Schubert break;
1585796c8dcSSimon Schubert }
1595796c8dcSSimon Schubert }
160*ef5ccd6cSJohn Marino argv += oind;
161*ef5ccd6cSJohn Marino argc -= oind;
1625796c8dcSSimon Schubert
1635796c8dcSSimon Schubert
1645796c8dcSSimon Schubert if (reset)
1655796c8dcSSimon Schubert {
1665796c8dcSSimon Schubert /* Reset implies resetting to original path first. */
1675796c8dcSSimon Schubert exec_path = xstrdup (orig_path);
1685796c8dcSSimon Schubert }
1695796c8dcSSimon Schubert else
1705796c8dcSSimon Schubert {
1715796c8dcSSimon Schubert /* Otherwise, get current path to modify. */
172cf7f2e2dSJohn Marino env = get_in_environ (current_inferior ()->environment, path_var_name);
1735796c8dcSSimon Schubert
1745796c8dcSSimon Schubert /* Can be null if path is not set. */
1755796c8dcSSimon Schubert if (!env)
1765796c8dcSSimon Schubert env = "";
1775796c8dcSSimon Schubert exec_path = xstrdup (env);
1785796c8dcSSimon Schubert }
1795796c8dcSSimon Schubert
1805796c8dcSSimon Schubert for (i = argc - 1; i >= 0; --i)
1815796c8dcSSimon Schubert env_mod_path (argv[i], &exec_path);
1825796c8dcSSimon Schubert
183cf7f2e2dSJohn Marino set_in_environ (current_inferior ()->environment, path_var_name, exec_path);
1845796c8dcSSimon Schubert xfree (exec_path);
185cf7f2e2dSJohn Marino env = get_in_environ (current_inferior ()->environment, path_var_name);
1865796c8dcSSimon Schubert ui_out_field_string (uiout, "path", env);
1875796c8dcSSimon Schubert }
1885796c8dcSSimon Schubert
1895796c8dcSSimon Schubert /* Add zero or more directories to the front of the source path. */
190*ef5ccd6cSJohn Marino
1915796c8dcSSimon Schubert void
mi_cmd_env_dir(char * command,char ** argv,int argc)1925796c8dcSSimon Schubert mi_cmd_env_dir (char *command, char **argv, int argc)
1935796c8dcSSimon Schubert {
194a45ae5f8SJohn Marino struct ui_out *uiout = current_uiout;
1955796c8dcSSimon Schubert int i;
196*ef5ccd6cSJohn Marino int oind = 0;
1975796c8dcSSimon Schubert int reset = 0;
198*ef5ccd6cSJohn Marino char *oarg;
1995796c8dcSSimon Schubert enum opt
2005796c8dcSSimon Schubert {
2015796c8dcSSimon Schubert RESET_OPT
2025796c8dcSSimon Schubert };
203a45ae5f8SJohn Marino static const struct mi_opt opts[] =
2045796c8dcSSimon Schubert {
2055796c8dcSSimon Schubert {"r", RESET_OPT, 0},
2065796c8dcSSimon Schubert { 0, 0, 0 }
2075796c8dcSSimon Schubert };
2085796c8dcSSimon Schubert
2095796c8dcSSimon Schubert dont_repeat ();
2105796c8dcSSimon Schubert
2115796c8dcSSimon Schubert if (mi_version (uiout) < 2)
2125796c8dcSSimon Schubert {
2135796c8dcSSimon Schubert for (i = argc - 1; i >= 0; --i)
2145796c8dcSSimon Schubert env_execute_cli_command ("dir", argv[i]);
2155796c8dcSSimon Schubert return;
2165796c8dcSSimon Schubert }
2175796c8dcSSimon Schubert
2185796c8dcSSimon Schubert /* Otherwise mi level is 2 or higher. */
2195796c8dcSSimon Schubert while (1)
2205796c8dcSSimon Schubert {
221c50c785cSJohn Marino int opt = mi_getopt ("-environment-directory", argc, argv, opts,
222*ef5ccd6cSJohn Marino &oind, &oarg);
223cf7f2e2dSJohn Marino
2245796c8dcSSimon Schubert if (opt < 0)
2255796c8dcSSimon Schubert break;
2265796c8dcSSimon Schubert switch ((enum opt) opt)
2275796c8dcSSimon Schubert {
2285796c8dcSSimon Schubert case RESET_OPT:
2295796c8dcSSimon Schubert reset = 1;
2305796c8dcSSimon Schubert break;
2315796c8dcSSimon Schubert }
2325796c8dcSSimon Schubert }
233*ef5ccd6cSJohn Marino argv += oind;
234*ef5ccd6cSJohn Marino argc -= oind;
2355796c8dcSSimon Schubert
2365796c8dcSSimon Schubert if (reset)
2375796c8dcSSimon Schubert {
2385796c8dcSSimon Schubert /* Reset means setting to default path first. */
2395796c8dcSSimon Schubert xfree (source_path);
2405796c8dcSSimon Schubert init_source_path ();
2415796c8dcSSimon Schubert }
2425796c8dcSSimon Schubert
2435796c8dcSSimon Schubert for (i = argc - 1; i >= 0; --i)
2445796c8dcSSimon Schubert env_mod_path (argv[i], &source_path);
2455796c8dcSSimon Schubert
2465796c8dcSSimon Schubert ui_out_field_string (uiout, "source-path", source_path);
2475796c8dcSSimon Schubert forget_cached_source_info ();
2485796c8dcSSimon Schubert }
2495796c8dcSSimon Schubert
2505796c8dcSSimon Schubert /* Set the inferior terminal device name. */
251*ef5ccd6cSJohn Marino
2525796c8dcSSimon Schubert void
mi_cmd_inferior_tty_set(char * command,char ** argv,int argc)2535796c8dcSSimon Schubert mi_cmd_inferior_tty_set (char *command, char **argv, int argc)
2545796c8dcSSimon Schubert {
2555796c8dcSSimon Schubert set_inferior_io_terminal (argv[0]);
2565796c8dcSSimon Schubert }
2575796c8dcSSimon Schubert
258*ef5ccd6cSJohn Marino /* Print the inferior terminal device name. */
259*ef5ccd6cSJohn Marino
2605796c8dcSSimon Schubert void
mi_cmd_inferior_tty_show(char * command,char ** argv,int argc)2615796c8dcSSimon Schubert mi_cmd_inferior_tty_show (char *command, char **argv, int argc)
2625796c8dcSSimon Schubert {
2635796c8dcSSimon Schubert const char *inferior_io_terminal = get_inferior_io_terminal ();
2645796c8dcSSimon Schubert
265c50c785cSJohn Marino if ( !mi_valid_noargs ("-inferior-tty-show", argc, argv))
266c50c785cSJohn Marino error (_("-inferior-tty-show: Usage: No args"));
2675796c8dcSSimon Schubert
2685796c8dcSSimon Schubert if (inferior_io_terminal)
269a45ae5f8SJohn Marino ui_out_field_string (current_uiout,
270a45ae5f8SJohn Marino "inferior_tty_terminal", inferior_io_terminal);
2715796c8dcSSimon Schubert }
2725796c8dcSSimon Schubert
2735796c8dcSSimon Schubert void
_initialize_mi_cmd_env(void)2745796c8dcSSimon Schubert _initialize_mi_cmd_env (void)
2755796c8dcSSimon Schubert {
276cf7f2e2dSJohn Marino struct gdb_environ *environment;
2775796c8dcSSimon Schubert char *env;
2785796c8dcSSimon Schubert
279cf7f2e2dSJohn Marino /* We want original execution path to reset to, if desired later.
280cf7f2e2dSJohn Marino At this point, current inferior is not created, so cannot use
281cf7f2e2dSJohn Marino current_inferior ()->environment. Also, there's no obvious
282*ef5ccd6cSJohn Marino place where this code can be moved such that it surely run
283cf7f2e2dSJohn Marino before any code possibly mangles original PATH. */
284cf7f2e2dSJohn Marino environment = make_environ ();
285cf7f2e2dSJohn Marino init_environ (environment);
286cf7f2e2dSJohn Marino env = get_in_environ (environment, path_var_name);
2875796c8dcSSimon Schubert
2885796c8dcSSimon Schubert /* Can be null if path is not set. */
2895796c8dcSSimon Schubert if (!env)
2905796c8dcSSimon Schubert env = "";
2915796c8dcSSimon Schubert orig_path = xstrdup (env);
292c50c785cSJohn Marino free_environ (environment);
2935796c8dcSSimon Schubert }
294