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