1 /* MI Command Set - environment commands. 2 3 Copyright (C) 2002, 2003, 2004, 2007, 2008, 2009 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 if (args != NULL) 56 run = xstrprintf ("%s %s", cmd, args); 57 else 58 run = xstrdup (cmd); 59 old_cleanups = make_cleanup (xfree, run); 60 execute_command ( /*ui */ run, 0 /*from_tty */ ); 61 do_cleanups (old_cleanups); 62 return; 63 } 64 } 65 66 67 /* Print working directory. */ 68 void 69 mi_cmd_env_pwd (char *command, char **argv, int argc) 70 { 71 if (argc > 0) 72 error (_("mi_cmd_env_pwd: No arguments required")); 73 74 if (mi_version (uiout) < 2) 75 { 76 env_execute_cli_command ("pwd", NULL); 77 return; 78 } 79 80 /* Otherwise the mi level is 2 or higher. */ 81 82 if (! getcwd (gdb_dirbuf, sizeof (gdb_dirbuf))) 83 error (_("mi_cmd_env_pwd: error finding name of working directory: %s"), 84 safe_strerror (errno)); 85 86 ui_out_field_string (uiout, "cwd", gdb_dirbuf); 87 } 88 89 /* Change working directory. */ 90 void 91 mi_cmd_env_cd (char *command, char **argv, int argc) 92 { 93 if (argc == 0 || argc > 1) 94 error (_("mi_cmd_env_cd: Usage DIRECTORY")); 95 96 env_execute_cli_command ("cd", argv[0]); 97 } 98 99 static void 100 env_mod_path (char *dirname, char **which_path) 101 { 102 if (dirname == 0 || dirname[0] == '\0') 103 return; 104 105 /* Call add_path with last arg 0 to indicate not to parse for 106 separator characters. */ 107 add_path (dirname, which_path, 0); 108 } 109 110 /* Add one or more directories to start of executable search path. */ 111 void 112 mi_cmd_env_path (char *command, char **argv, int argc) 113 { 114 char *exec_path; 115 char *env; 116 int reset = 0; 117 int optind = 0; 118 int i; 119 char *optarg; 120 enum opt 121 { 122 RESET_OPT 123 }; 124 static struct mi_opt opts[] = 125 { 126 {"r", RESET_OPT, 0}, 127 { 0, 0, 0 } 128 }; 129 130 dont_repeat (); 131 132 if (mi_version (uiout) < 2) 133 { 134 for (i = argc - 1; i >= 0; --i) 135 env_execute_cli_command ("path", argv[i]); 136 return; 137 } 138 139 /* Otherwise the mi level is 2 or higher. */ 140 while (1) 141 { 142 int opt = mi_getopt ("mi_cmd_env_path", argc, argv, opts, 143 &optind, &optarg); 144 if (opt < 0) 145 break; 146 switch ((enum opt) opt) 147 { 148 case RESET_OPT: 149 reset = 1; 150 break; 151 } 152 } 153 argv += optind; 154 argc -= optind; 155 156 157 if (reset) 158 { 159 /* Reset implies resetting to original path first. */ 160 exec_path = xstrdup (orig_path); 161 } 162 else 163 { 164 /* Otherwise, get current path to modify. */ 165 env = get_in_environ (inferior_environ, path_var_name); 166 167 /* Can be null if path is not set. */ 168 if (!env) 169 env = ""; 170 exec_path = xstrdup (env); 171 } 172 173 for (i = argc - 1; i >= 0; --i) 174 env_mod_path (argv[i], &exec_path); 175 176 set_in_environ (inferior_environ, path_var_name, exec_path); 177 xfree (exec_path); 178 env = get_in_environ (inferior_environ, path_var_name); 179 ui_out_field_string (uiout, "path", env); 180 } 181 182 /* Add zero or more directories to the front of the source path. */ 183 void 184 mi_cmd_env_dir (char *command, char **argv, int argc) 185 { 186 int i; 187 int optind = 0; 188 int reset = 0; 189 char *optarg; 190 enum opt 191 { 192 RESET_OPT 193 }; 194 static struct mi_opt opts[] = 195 { 196 {"r", RESET_OPT, 0}, 197 { 0, 0, 0 } 198 }; 199 200 dont_repeat (); 201 202 if (mi_version (uiout) < 2) 203 { 204 for (i = argc - 1; i >= 0; --i) 205 env_execute_cli_command ("dir", argv[i]); 206 return; 207 } 208 209 /* Otherwise mi level is 2 or higher. */ 210 while (1) 211 { 212 int opt = mi_getopt ("mi_cmd_env_dir", argc, argv, opts, 213 &optind, &optarg); 214 if (opt < 0) 215 break; 216 switch ((enum opt) opt) 217 { 218 case RESET_OPT: 219 reset = 1; 220 break; 221 } 222 } 223 argv += optind; 224 argc -= optind; 225 226 if (reset) 227 { 228 /* Reset means setting to default path first. */ 229 xfree (source_path); 230 init_source_path (); 231 } 232 233 for (i = argc - 1; i >= 0; --i) 234 env_mod_path (argv[i], &source_path); 235 236 ui_out_field_string (uiout, "source-path", source_path); 237 forget_cached_source_info (); 238 } 239 240 /* Set the inferior terminal device name. */ 241 void 242 mi_cmd_inferior_tty_set (char *command, char **argv, int argc) 243 { 244 set_inferior_io_terminal (argv[0]); 245 } 246 247 /* Print the inferior terminal device name */ 248 void 249 mi_cmd_inferior_tty_show (char *command, char **argv, int argc) 250 { 251 const char *inferior_io_terminal = get_inferior_io_terminal (); 252 253 if ( !mi_valid_noargs ("mi_cmd_inferior_tty_show", argc, argv)) 254 error (_("mi_cmd_inferior_tty_show: Usage: No args")); 255 256 if (inferior_io_terminal) 257 ui_out_field_string (uiout, "inferior_tty_terminal", inferior_io_terminal); 258 } 259 260 void 261 _initialize_mi_cmd_env (void) 262 { 263 char *env; 264 265 /* We want original execution path to reset to, if desired later. */ 266 env = get_in_environ (inferior_environ, path_var_name); 267 268 /* Can be null if path is not set. */ 269 if (!env) 270 env = ""; 271 orig_path = xstrdup (env); 272 } 273