1 /* MI Command Set - environment commands. 2 Copyright (C) 2002-2013 Free Software Foundation, Inc. 3 4 Contributed by Red Hat Inc. 5 6 This file is part of GDB. 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 20 21 #include "defs.h" 22 #include "inferior.h" 23 #include "value.h" 24 #include "mi-out.h" 25 #include "mi-cmds.h" 26 #include "mi-getopt.h" 27 #include "symtab.h" 28 #include "target.h" 29 #include "environ.h" 30 #include "command.h" 31 #include "ui-out.h" 32 #include "top.h" 33 34 #include "gdb_string.h" 35 #include "gdb_stat.h" 36 37 static void env_mod_path (char *dirname, char **which_path); 38 39 extern void _initialize_mi_cmd_env (void); 40 41 static const char path_var_name[] = "PATH"; 42 static char *orig_path = NULL; 43 44 /* The following is copied from mi-main.c so for m1 and below we can 45 perform old behavior and use cli commands. If ARGS is non-null, 46 append it to the CMD. */ 47 48 static void 49 env_execute_cli_command (const char *cmd, const char *args) 50 { 51 if (cmd != 0) 52 { 53 struct cleanup *old_cleanups; 54 char *run; 55 56 if (args != NULL) 57 run = xstrprintf ("%s %s", cmd, args); 58 else 59 run = xstrdup (cmd); 60 old_cleanups = make_cleanup (xfree, run); 61 execute_command ( /*ui */ run, 0 /*from_tty */ ); 62 do_cleanups (old_cleanups); 63 return; 64 } 65 } 66 67 /* Print working directory. */ 68 69 void 70 mi_cmd_env_pwd (char *command, char **argv, int argc) 71 { 72 struct ui_out *uiout = current_uiout; 73 74 if (argc > 0) 75 error (_("-environment-pwd: No arguments allowed")); 76 77 if (mi_version (uiout) < 2) 78 { 79 env_execute_cli_command ("pwd", NULL); 80 return; 81 } 82 83 /* Otherwise the mi level is 2 or higher. */ 84 85 if (! getcwd (gdb_dirbuf, sizeof (gdb_dirbuf))) 86 error (_("-environment-pwd: error finding name of working directory: %s"), 87 safe_strerror (errno)); 88 89 ui_out_field_string (uiout, "cwd", gdb_dirbuf); 90 } 91 92 /* Change working directory. */ 93 94 void 95 mi_cmd_env_cd (char *command, char **argv, int argc) 96 { 97 if (argc == 0 || argc > 1) 98 error (_("-environment-cd: Usage DIRECTORY")); 99 100 env_execute_cli_command ("cd", argv[0]); 101 } 102 103 static void 104 env_mod_path (char *dirname, char **which_path) 105 { 106 if (dirname == 0 || dirname[0] == '\0') 107 return; 108 109 /* Call add_path with last arg 0 to indicate not to parse for 110 separator characters. */ 111 add_path (dirname, which_path, 0); 112 } 113 114 /* Add one or more directories to start of executable search path. */ 115 116 void 117 mi_cmd_env_path (char *command, char **argv, int argc) 118 { 119 struct ui_out *uiout = current_uiout; 120 char *exec_path; 121 char *env; 122 int reset = 0; 123 int oind = 0; 124 int i; 125 char *oarg; 126 enum opt 127 { 128 RESET_OPT 129 }; 130 static const struct mi_opt opts[] = 131 { 132 {"r", RESET_OPT, 0}, 133 { 0, 0, 0 } 134 }; 135 136 dont_repeat (); 137 138 if (mi_version (uiout) < 2) 139 { 140 for (i = argc - 1; i >= 0; --i) 141 env_execute_cli_command ("path", argv[i]); 142 return; 143 } 144 145 /* Otherwise the mi level is 2 or higher. */ 146 while (1) 147 { 148 int opt = mi_getopt ("-environment-path", argc, argv, opts, 149 &oind, &oarg); 150 151 if (opt < 0) 152 break; 153 switch ((enum opt) opt) 154 { 155 case RESET_OPT: 156 reset = 1; 157 break; 158 } 159 } 160 argv += oind; 161 argc -= oind; 162 163 164 if (reset) 165 { 166 /* Reset implies resetting to original path first. */ 167 exec_path = xstrdup (orig_path); 168 } 169 else 170 { 171 /* Otherwise, get current path to modify. */ 172 env = get_in_environ (current_inferior ()->environment, path_var_name); 173 174 /* Can be null if path is not set. */ 175 if (!env) 176 env = ""; 177 exec_path = xstrdup (env); 178 } 179 180 for (i = argc - 1; i >= 0; --i) 181 env_mod_path (argv[i], &exec_path); 182 183 set_in_environ (current_inferior ()->environment, path_var_name, exec_path); 184 xfree (exec_path); 185 env = get_in_environ (current_inferior ()->environment, path_var_name); 186 ui_out_field_string (uiout, "path", env); 187 } 188 189 /* Add zero or more directories to the front of the source path. */ 190 191 void 192 mi_cmd_env_dir (char *command, char **argv, int argc) 193 { 194 struct ui_out *uiout = current_uiout; 195 int i; 196 int oind = 0; 197 int reset = 0; 198 char *oarg; 199 enum opt 200 { 201 RESET_OPT 202 }; 203 static const struct mi_opt opts[] = 204 { 205 {"r", RESET_OPT, 0}, 206 { 0, 0, 0 } 207 }; 208 209 dont_repeat (); 210 211 if (mi_version (uiout) < 2) 212 { 213 for (i = argc - 1; i >= 0; --i) 214 env_execute_cli_command ("dir", argv[i]); 215 return; 216 } 217 218 /* Otherwise mi level is 2 or higher. */ 219 while (1) 220 { 221 int opt = mi_getopt ("-environment-directory", argc, argv, opts, 222 &oind, &oarg); 223 224 if (opt < 0) 225 break; 226 switch ((enum opt) opt) 227 { 228 case RESET_OPT: 229 reset = 1; 230 break; 231 } 232 } 233 argv += oind; 234 argc -= oind; 235 236 if (reset) 237 { 238 /* Reset means setting to default path first. */ 239 xfree (source_path); 240 init_source_path (); 241 } 242 243 for (i = argc - 1; i >= 0; --i) 244 env_mod_path (argv[i], &source_path); 245 246 ui_out_field_string (uiout, "source-path", source_path); 247 forget_cached_source_info (); 248 } 249 250 /* Set the inferior terminal device name. */ 251 252 void 253 mi_cmd_inferior_tty_set (char *command, char **argv, int argc) 254 { 255 set_inferior_io_terminal (argv[0]); 256 } 257 258 /* Print the inferior terminal device name. */ 259 260 void 261 mi_cmd_inferior_tty_show (char *command, char **argv, int argc) 262 { 263 const char *inferior_io_terminal = get_inferior_io_terminal (); 264 265 if ( !mi_valid_noargs ("-inferior-tty-show", argc, argv)) 266 error (_("-inferior-tty-show: Usage: No args")); 267 268 if (inferior_io_terminal) 269 ui_out_field_string (current_uiout, 270 "inferior_tty_terminal", inferior_io_terminal); 271 } 272 273 void 274 _initialize_mi_cmd_env (void) 275 { 276 struct gdb_environ *environment; 277 char *env; 278 279 /* We want original execution path to reset to, if desired later. 280 At this point, current inferior is not created, so cannot use 281 current_inferior ()->environment. Also, there's no obvious 282 place where this code can be moved such that it surely run 283 before any code possibly mangles original PATH. */ 284 environment = make_environ (); 285 init_environ (environment); 286 env = get_in_environ (environment, path_var_name); 287 288 /* Can be null if path is not set. */ 289 if (!env) 290 env = ""; 291 orig_path = xstrdup (env); 292 free_environ (environment); 293 } 294