Commit | Line | Data |
---|---|---|
068890be | 1 | /* MI Command Set - environment commands. |
61baf725 | 2 | Copyright (C) 2002-2017 Free Software Foundation, Inc. |
1bac305b | 3 | |
068890be JJ |
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 | |
a9762ec7 | 10 | the Free Software Foundation; either version 3 of the License, or |
068890be JJ |
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 | |
a9762ec7 | 19 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
068890be | 20 | |
068890be JJ |
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" | |
53ce3c39 | 33 | #include <sys/stat.h> |
4ef3f3be | 34 | |
068890be JJ |
35 | static const char path_var_name[] = "PATH"; |
36 | static char *orig_path = NULL; | |
37 | ||
d303380b AC |
38 | /* The following is copied from mi-main.c so for m1 and below we can |
39 | perform old behavior and use cli commands. If ARGS is non-null, | |
40 | append it to the CMD. */ | |
2b03b41d | 41 | |
068890be | 42 | static void |
d303380b | 43 | env_execute_cli_command (const char *cmd, const char *args) |
068890be | 44 | { |
d303380b | 45 | if (cmd != 0) |
068890be | 46 | { |
e91a1fa7 | 47 | gdb::unique_xmalloc_ptr<char> run; |
102040f0 | 48 | |
d303380b | 49 | if (args != NULL) |
e91a1fa7 | 50 | run.reset (xstrprintf ("%s %s", cmd, args)); |
d303380b | 51 | else |
e91a1fa7 TT |
52 | run.reset (xstrdup (cmd)); |
53 | execute_command ( /*ui */ run.get (), 0 /*from_tty */ ); | |
068890be JJ |
54 | } |
55 | } | |
56 | ||
068890be | 57 | /* Print working directory. */ |
2b03b41d | 58 | |
ce8f13f8 | 59 | void |
9f33b8b7 | 60 | mi_cmd_env_pwd (const char *command, char **argv, int argc) |
068890be | 61 | { |
79a45e25 PA |
62 | struct ui_out *uiout = current_uiout; |
63 | ||
068890be | 64 | if (argc > 0) |
2b03b41d | 65 | error (_("-environment-pwd: No arguments allowed")); |
068890be JJ |
66 | |
67 | if (mi_version (uiout) < 2) | |
68 | { | |
69 | env_execute_cli_command ("pwd", NULL); | |
ce8f13f8 | 70 | return; |
068890be JJ |
71 | } |
72 | ||
73 | /* Otherwise the mi level is 2 or higher. */ | |
74 | ||
43573013 SDJ |
75 | gdb::unique_xmalloc_ptr<char> cwd (getcwd (NULL, 0)); |
76 | if (cwd == NULL) | |
1b05df00 | 77 | error (_("-environment-pwd: error finding name of working directory: %s"), |
bf1d7d9c | 78 | safe_strerror (errno)); |
43573013 SDJ |
79 | |
80 | uiout->field_string ("cwd", cwd.get ()); | |
068890be JJ |
81 | } |
82 | ||
83 | /* Change working directory. */ | |
2b03b41d | 84 | |
ce8f13f8 | 85 | void |
9f33b8b7 | 86 | mi_cmd_env_cd (const char *command, char **argv, int argc) |
068890be JJ |
87 | { |
88 | if (argc == 0 || argc > 1) | |
1b05df00 | 89 | error (_("-environment-cd: Usage DIRECTORY")); |
068890be | 90 | |
d303380b | 91 | env_execute_cli_command ("cd", argv[0]); |
068890be JJ |
92 | } |
93 | ||
94 | static void | |
5614fb77 | 95 | env_mod_path (const char *dirname, char **which_path) |
068890be JJ |
96 | { |
97 | if (dirname == 0 || dirname[0] == '\0') | |
98 | return; | |
99 | ||
100 | /* Call add_path with last arg 0 to indicate not to parse for | |
101 | separator characters. */ | |
102 | add_path (dirname, which_path, 0); | |
103 | } | |
104 | ||
105 | /* Add one or more directories to start of executable search path. */ | |
2b03b41d | 106 | |
ce8f13f8 | 107 | void |
9f33b8b7 | 108 | mi_cmd_env_path (const char *command, char **argv, int argc) |
068890be | 109 | { |
79a45e25 | 110 | struct ui_out *uiout = current_uiout; |
068890be | 111 | char *exec_path; |
a121b7c1 | 112 | const char *env; |
068890be | 113 | int reset = 0; |
7082409d | 114 | int oind = 0; |
068890be | 115 | int i; |
7082409d | 116 | char *oarg; |
068890be JJ |
117 | enum opt |
118 | { | |
119 | RESET_OPT | |
120 | }; | |
91174723 | 121 | static const struct mi_opt opts[] = |
068890be JJ |
122 | { |
123 | {"r", RESET_OPT, 0}, | |
d5d6fca5 | 124 | { 0, 0, 0 } |
068890be JJ |
125 | }; |
126 | ||
127 | dont_repeat (); | |
128 | ||
129 | if (mi_version (uiout) < 2) | |
130 | { | |
131 | for (i = argc - 1; i >= 0; --i) | |
d303380b | 132 | env_execute_cli_command ("path", argv[i]); |
ce8f13f8 | 133 | return; |
068890be JJ |
134 | } |
135 | ||
136 | /* Otherwise the mi level is 2 or higher. */ | |
137 | while (1) | |
138 | { | |
1b05df00 | 139 | int opt = mi_getopt ("-environment-path", argc, argv, opts, |
7082409d | 140 | &oind, &oarg); |
102040f0 | 141 | |
068890be JJ |
142 | if (opt < 0) |
143 | break; | |
144 | switch ((enum opt) opt) | |
145 | { | |
146 | case RESET_OPT: | |
147 | reset = 1; | |
148 | break; | |
149 | } | |
150 | } | |
7082409d AS |
151 | argv += oind; |
152 | argc -= oind; | |
068890be JJ |
153 | |
154 | ||
155 | if (reset) | |
156 | { | |
157 | /* Reset implies resetting to original path first. */ | |
158 | exec_path = xstrdup (orig_path); | |
159 | } | |
160 | else | |
161 | { | |
162 | /* Otherwise, get current path to modify. */ | |
9a6c7d9c | 163 | env = current_inferior ()->environment.get (path_var_name); |
068890be JJ |
164 | |
165 | /* Can be null if path is not set. */ | |
166 | if (!env) | |
167 | env = ""; | |
168 | exec_path = xstrdup (env); | |
169 | } | |
170 | ||
171 | for (i = argc - 1; i >= 0; --i) | |
172 | env_mod_path (argv[i], &exec_path); | |
173 | ||
9a6c7d9c | 174 | current_inferior ()->environment.set (path_var_name, exec_path); |
068890be | 175 | xfree (exec_path); |
9a6c7d9c | 176 | env = current_inferior ()->environment.get (path_var_name); |
112e8700 | 177 | uiout->field_string ("path", env); |
068890be JJ |
178 | } |
179 | ||
180 | /* Add zero or more directories to the front of the source path. */ | |
2b03b41d | 181 | |
ce8f13f8 | 182 | void |
9f33b8b7 | 183 | mi_cmd_env_dir (const char *command, char **argv, int argc) |
068890be | 184 | { |
79a45e25 | 185 | struct ui_out *uiout = current_uiout; |
068890be | 186 | int i; |
7082409d | 187 | int oind = 0; |
068890be | 188 | int reset = 0; |
7082409d | 189 | char *oarg; |
068890be JJ |
190 | enum opt |
191 | { | |
192 | RESET_OPT | |
193 | }; | |
91174723 | 194 | static const struct mi_opt opts[] = |
068890be JJ |
195 | { |
196 | {"r", RESET_OPT, 0}, | |
d5d6fca5 | 197 | { 0, 0, 0 } |
068890be JJ |
198 | }; |
199 | ||
200 | dont_repeat (); | |
201 | ||
202 | if (mi_version (uiout) < 2) | |
203 | { | |
204 | for (i = argc - 1; i >= 0; --i) | |
d303380b | 205 | env_execute_cli_command ("dir", argv[i]); |
ce8f13f8 | 206 | return; |
068890be JJ |
207 | } |
208 | ||
209 | /* Otherwise mi level is 2 or higher. */ | |
210 | while (1) | |
211 | { | |
1b05df00 | 212 | int opt = mi_getopt ("-environment-directory", argc, argv, opts, |
7082409d | 213 | &oind, &oarg); |
102040f0 | 214 | |
068890be JJ |
215 | if (opt < 0) |
216 | break; | |
217 | switch ((enum opt) opt) | |
218 | { | |
219 | case RESET_OPT: | |
220 | reset = 1; | |
221 | break; | |
222 | } | |
223 | } | |
7082409d AS |
224 | argv += oind; |
225 | argc -= oind; | |
068890be JJ |
226 | |
227 | if (reset) | |
228 | { | |
229 | /* Reset means setting to default path first. */ | |
230 | xfree (source_path); | |
231 | init_source_path (); | |
232 | } | |
233 | ||
234 | for (i = argc - 1; i >= 0; --i) | |
235 | env_mod_path (argv[i], &source_path); | |
068890be | 236 | |
112e8700 | 237 | uiout->field_string ("source-path", source_path); |
068890be | 238 | forget_cached_source_info (); |
068890be JJ |
239 | } |
240 | ||
3cb3b8df | 241 | /* Set the inferior terminal device name. */ |
2b03b41d | 242 | |
ce8f13f8 | 243 | void |
9f33b8b7 | 244 | mi_cmd_inferior_tty_set (const char *command, char **argv, int argc) |
3cb3b8df BR |
245 | { |
246 | set_inferior_io_terminal (argv[0]); | |
3cb3b8df BR |
247 | } |
248 | ||
2b03b41d SS |
249 | /* Print the inferior terminal device name. */ |
250 | ||
ce8f13f8 | 251 | void |
9f33b8b7 | 252 | mi_cmd_inferior_tty_show (const char *command, char **argv, int argc) |
3cb3b8df BR |
253 | { |
254 | const char *inferior_io_terminal = get_inferior_io_terminal (); | |
255 | ||
1b05df00 TT |
256 | if ( !mi_valid_noargs ("-inferior-tty-show", argc, argv)) |
257 | error (_("-inferior-tty-show: Usage: No args")); | |
3cb3b8df BR |
258 | |
259 | if (inferior_io_terminal) | |
112e8700 | 260 | current_uiout->field_string ("inferior_tty_terminal", inferior_io_terminal); |
3cb3b8df BR |
261 | } |
262 | ||
068890be JJ |
263 | void |
264 | _initialize_mi_cmd_env (void) | |
265 | { | |
a121b7c1 | 266 | const char *env; |
068890be | 267 | |
3f81c18a VP |
268 | /* We want original execution path to reset to, if desired later. |
269 | At this point, current inferior is not created, so cannot use | |
1c8e01c9 SDJ |
270 | current_inferior ()->environment. We use getenv here because it |
271 | is not necessary to create a whole new gdb_environ just for one | |
272 | variable. */ | |
273 | env = getenv (path_var_name); | |
068890be JJ |
274 | |
275 | /* Can be null if path is not set. */ | |
276 | if (!env) | |
277 | env = ""; | |
278 | orig_path = xstrdup (env); | |
279 | } |