]>
Commit | Line | Data |
---|---|---|
495aee44 | 1 | /* evalstring.c - evaluate a string as one or more shell commands. */ |
95732b49 | 2 | |
74091dd4 | 3 | /* Copyright (C) 1996-2022 Free Software Foundation, Inc. |
ccc6cda3 JA |
4 | |
5 | This file is part of GNU Bash, the Bourne Again SHell. | |
6 | ||
3185942a JA |
7 | Bash is free software: you can redistribute it and/or modify |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation, either version 3 of the License, or | |
10 | (at your option) any later version. | |
ccc6cda3 | 11 | |
3185942a JA |
12 | Bash is distributed in the hope that it will be useful, |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with Bash. If not, see <http://www.gnu.org/licenses/>. | |
19 | */ | |
ccc6cda3 JA |
20 | |
21 | #include <config.h> | |
22 | ||
23 | #if defined (HAVE_UNISTD_H) | |
cce855bc JA |
24 | # ifdef _MINIX |
25 | # include <sys/types.h> | |
26 | # endif | |
ccc6cda3 JA |
27 | # include <unistd.h> |
28 | #endif | |
29 | ||
30 | #include <stdio.h> | |
31 | #include <signal.h> | |
32 | ||
cce855bc JA |
33 | #include <errno.h> |
34 | ||
bb70624e | 35 | #include "filecntl.h" |
ccc6cda3 JA |
36 | #include "../bashansi.h" |
37 | ||
38 | #include "../shell.h" | |
39 | #include "../jobs.h" | |
40 | #include "../builtins.h" | |
41 | #include "../flags.h" | |
d233b485 | 42 | #include "../parser.h" |
ccc6cda3 JA |
43 | #include "../input.h" |
44 | #include "../execute_cmd.h" | |
cce855bc | 45 | #include "../redir.h" |
f73dda09 | 46 | #include "../trap.h" |
0001803f | 47 | #include "../bashintl.h" |
ccc6cda3 | 48 | |
3185942a JA |
49 | #include <y.tab.h> |
50 | ||
ccc6cda3 JA |
51 | #if defined (HISTORY) |
52 | # include "../bashhist.h" | |
53 | #endif | |
54 | ||
55 | #include "common.h" | |
0001803f | 56 | #include "builtext.h" |
ccc6cda3 | 57 | |
cce855bc JA |
58 | #if !defined (errno) |
59 | extern int errno; | |
60 | #endif | |
61 | ||
b72432fd JA |
62 | #define IS_BUILTIN(s) (builtin_address_internal(s, 0) != (struct builtin *)NULL) |
63 | ||
ccc6cda3 JA |
64 | int parse_and_execute_level = 0; |
65 | ||
8868edaf | 66 | static int cat_file PARAMS((REDIRECT *)); |
cce855bc | 67 | |
3185942a JA |
68 | #define PE_TAG "parse_and_execute top" |
69 | #define PS_TAG "parse_string top" | |
70 | ||
f1be666c JA |
71 | #if defined (HISTORY) |
72 | static void | |
73 | set_history_remembering () | |
74 | { | |
75 | remember_on_history = enable_history_list; | |
76 | } | |
77 | #endif | |
78 | ||
ac50fbac CR |
79 | static void |
80 | restore_lastcom (x) | |
81 | char *x; | |
82 | { | |
83 | FREE (the_printed_command_except_trap); | |
84 | the_printed_command_except_trap = x; | |
85 | } | |
86 | ||
74091dd4 CR |
87 | int |
88 | should_optimize_fork (command, subshell) | |
89 | COMMAND *command; | |
90 | int subshell; | |
91 | { | |
92 | return (running_trap == 0 && | |
93 | command->type == cm_simple && | |
94 | signal_is_trapped (EXIT_TRAP) == 0 && | |
95 | signal_is_trapped (ERROR_TRAP) == 0 && | |
96 | any_signals_trapped () < 0 && | |
97 | (subshell || (command->redirects == 0 && command->value.Simple->redirects == 0)) && | |
98 | ((command->flags & CMD_TIME_PIPELINE) == 0) && | |
99 | ((command->flags & CMD_INVERT_RETURN) == 0)); | |
100 | } | |
101 | ||
102 | /* This has extra tests to account for STARTUP_STATE == 2, which is for | |
103 | -c command but has been extended to command and process substitution | |
104 | (basically any time you call parse_and_execute in a subshell). */ | |
a0c0a00f CR |
105 | int |
106 | should_suppress_fork (command) | |
107 | COMMAND *command; | |
108 | { | |
8868edaf CR |
109 | int subshell; |
110 | ||
111 | subshell = subshell_environment & SUBSHELL_PROCSUB; /* salt to taste */ | |
a0c0a00f | 112 | return (startup_state == 2 && parse_and_execute_level == 1 && |
a0c0a00f | 113 | *bash_input.location.string == '\0' && |
ad1b3e68 | 114 | parser_expanding_alias () == 0 && |
74091dd4 | 115 | should_optimize_fork (command, subshell)); |
a0c0a00f CR |
116 | } |
117 | ||
41f5420d CR |
118 | int |
119 | can_optimize_connection (command) | |
120 | COMMAND *command; | |
121 | { | |
122 | return (*bash_input.location.string == '\0' && | |
ad1b3e68 | 123 | parser_expanding_alias () == 0 && |
41f5420d CR |
124 | (command->value.Connection->connector == AND_AND || command->value.Connection->connector == OR_OR || command->value.Connection->connector == ';') && |
125 | command->value.Connection->second->type == cm_simple); | |
126 | } | |
127 | ||
a0c0a00f | 128 | void |
74091dd4 | 129 | optimize_connection_fork (command) |
a0c0a00f CR |
130 | COMMAND *command; |
131 | { | |
132 | if (command->type == cm_connection && | |
41f5420d CR |
133 | (command->value.Connection->connector == AND_AND || command->value.Connection->connector == OR_OR || command->value.Connection->connector == ';') && |
134 | (command->value.Connection->second->flags & CMD_TRY_OPTIMIZING) && | |
ec8113b9 CR |
135 | (should_suppress_fork (command->value.Connection->second) || |
136 | ((subshell_environment & SUBSHELL_PAREN) && should_optimize_fork (command->value.Connection->second, 0)))) | |
a0c0a00f CR |
137 | { |
138 | command->value.Connection->second->flags |= CMD_NO_FORK; | |
139 | command->value.Connection->second->value.Simple->flags |= CMD_NO_FORK; | |
140 | } | |
141 | } | |
d233b485 CR |
142 | |
143 | void | |
144 | optimize_subshell_command (command) | |
145 | COMMAND *command; | |
146 | { | |
74091dd4 | 147 | if (should_optimize_fork (command, 0)) |
d233b485 CR |
148 | { |
149 | command->flags |= CMD_NO_FORK; | |
150 | command->value.Simple->flags |= CMD_NO_FORK; | |
151 | } | |
152 | else if (command->type == cm_connection && | |
74091dd4 CR |
153 | (command->value.Connection->connector == AND_AND || command->value.Connection->connector == OR_OR || command->value.Connection->connector == ';') && |
154 | command->value.Connection->second->type == cm_simple && | |
155 | parser_expanding_alias () == 0) | |
156 | { | |
157 | command->value.Connection->second->flags |= CMD_TRY_OPTIMIZING; | |
158 | command->value.Connection->second->value.Simple->flags |= CMD_TRY_OPTIMIZING; | |
159 | } | |
d233b485 | 160 | } |
8868edaf CR |
161 | |
162 | void | |
163 | optimize_shell_function (command) | |
164 | COMMAND *command; | |
165 | { | |
166 | COMMAND *fc; | |
167 | ||
168 | fc = (command->type == cm_group) ? command->value.Group->command : command; | |
169 | ||
170 | if (fc->type == cm_simple && should_suppress_fork (fc)) | |
171 | { | |
172 | fc->flags |= CMD_NO_FORK; | |
173 | fc->value.Simple->flags |= CMD_NO_FORK; | |
174 | } | |
175 | else if (fc->type == cm_connection && can_optimize_connection (fc) && should_suppress_fork (fc->value.Connection->second)) | |
176 | { | |
177 | fc->value.Connection->second->flags |= CMD_NO_FORK; | |
178 | fc->value.Connection->second->value.Simple->flags |= CMD_NO_FORK; | |
179 | } | |
180 | } | |
181 | ||
74091dd4 CR |
182 | int |
183 | can_optimize_cat_file (command) | |
184 | COMMAND *command; | |
185 | { | |
186 | return (command->type == cm_simple && !command->redirects && | |
187 | (command->flags & CMD_TIME_PIPELINE) == 0 && | |
188 | command->value.Simple->words == 0 && | |
189 | command->value.Simple->redirects && | |
190 | command->value.Simple->redirects->next == 0 && | |
191 | command->value.Simple->redirects->instruction == r_input_direction && | |
192 | command->value.Simple->redirects->redirector.dest == 0); | |
193 | } | |
194 | ||
ccc6cda3 JA |
195 | /* How to force parse_and_execute () to clean up after itself. */ |
196 | void | |
d233b485 CR |
197 | parse_and_execute_cleanup (old_running_trap) |
198 | int old_running_trap; | |
ccc6cda3 | 199 | { |
d233b485 | 200 | if (running_trap > 0) |
ccc6cda3 | 201 | { |
d233b485 CR |
202 | /* We assume if we have a different value for running_trap than when |
203 | we started (the only caller that cares is evalstring()), the | |
204 | original caller will perform the cleanup, and we should not step | |
205 | on them. */ | |
206 | if (running_trap != old_running_trap) | |
207 | run_trap_cleanup (running_trap - 1); | |
ccc6cda3 JA |
208 | unfreeze_jobs_list (); |
209 | } | |
ccc6cda3 | 210 | |
3185942a JA |
211 | if (have_unwind_protects ()) |
212 | run_unwind_frame (PE_TAG); | |
213 | else | |
214 | parse_and_execute_level = 0; /* XXX */ | |
215 | } | |
d166f048 | 216 | |
3185942a JA |
217 | static void |
218 | parse_prologue (string, flags, tag) | |
ccc6cda3 | 219 | char *string; |
d166f048 | 220 | int flags; |
3185942a | 221 | char *tag; |
ccc6cda3 | 222 | { |
ac50fbac | 223 | char *orig_string, *lastcom; |
3185942a | 224 | int x; |
ccc6cda3 JA |
225 | |
226 | orig_string = string; | |
227 | /* Unwind protect this invocation of parse_and_execute (). */ | |
3185942a | 228 | begin_unwind_frame (tag); |
ccc6cda3 JA |
229 | unwind_protect_int (parse_and_execute_level); |
230 | unwind_protect_jmp_buf (top_level); | |
231 | unwind_protect_int (indirection_level); | |
232 | unwind_protect_int (line_number); | |
ac50fbac | 233 | unwind_protect_int (line_number_for_err_trap); |
95732b49 | 234 | unwind_protect_int (loop_level); |
3185942a JA |
235 | unwind_protect_int (executing_list); |
236 | unwind_protect_int (comsub_ignore_return); | |
d166f048 | 237 | if (flags & (SEVAL_NONINT|SEVAL_INTERACT)) |
ccc6cda3 JA |
238 | unwind_protect_int (interactive); |
239 | ||
240 | #if defined (HISTORY) | |
f1be666c JA |
241 | if (parse_and_execute_level == 0) |
242 | add_unwind_protect (set_history_remembering, (char *)NULL); | |
243 | else | |
244 | unwind_protect_int (remember_on_history); /* can be used in scripts */ | |
d166f048 | 245 | # if defined (BANG_HISTORY) |
a0c0a00f | 246 | unwind_protect_int (history_expansion_inhibited); |
d166f048 | 247 | # endif /* BANG_HISTORY */ |
ccc6cda3 JA |
248 | #endif /* HISTORY */ |
249 | ||
bb70624e JA |
250 | if (interactive_shell) |
251 | { | |
252 | x = get_current_prompt_level (); | |
253 | add_unwind_protect (set_current_prompt_level, x); | |
254 | } | |
ac50fbac CR |
255 | |
256 | if (the_printed_command_except_trap) | |
257 | { | |
258 | lastcom = savestring (the_printed_command_except_trap); | |
259 | add_unwind_protect (restore_lastcom, lastcom); | |
260 | } | |
261 | ||
ccc6cda3 | 262 | add_unwind_protect (pop_stream, (char *)NULL); |
ac50fbac CR |
263 | if (parser_expanding_alias ()) |
264 | add_unwind_protect (parser_restore_alias, (char *)NULL); | |
265 | ||
7117c2d2 | 266 | if (orig_string && ((flags & SEVAL_NOFREE) == 0)) |
ccc6cda3 JA |
267 | add_unwind_protect (xfree, orig_string); |
268 | end_unwind_frame (); | |
269 | ||
3185942a JA |
270 | if (flags & (SEVAL_NONINT|SEVAL_INTERACT)) |
271 | interactive = (flags & SEVAL_NONINT) ? 0 : 1; | |
272 | ||
273 | #if defined (HISTORY) | |
274 | if (flags & SEVAL_NOHIST) | |
275 | bash_history_disable (); | |
a0c0a00f CR |
276 | # if defined (BANG_HISTORY) |
277 | if (flags & SEVAL_NOHISTEXP) | |
278 | history_expansion_inhibited = 1; | |
279 | # endif /* BANG_HISTORY */ | |
3185942a JA |
280 | #endif /* HISTORY */ |
281 | } | |
282 | ||
283 | /* Parse and execute the commands in STRING. Returns whatever | |
284 | execute_command () returns. This frees STRING. FLAGS is a | |
285 | flags word; look in common.h for the possible values. Actions | |
286 | are: | |
287 | (flags & SEVAL_NONINT) -> interactive = 0; | |
288 | (flags & SEVAL_INTERACT) -> interactive = 1; | |
289 | (flags & SEVAL_NOHIST) -> call bash_history_disable () | |
290 | (flags & SEVAL_NOFREE) -> don't free STRING when finished | |
291 | (flags & SEVAL_RESETLINE) -> reset line_number to 1 | |
a0c0a00f | 292 | (flags & SEVAL_NOHISTEXP) -> history_expansion_inhibited -> 1 |
ec8113b9 | 293 | (flags & SEVAL_NOOPTIMIZE) -> don't try to turn on optimizing flags |
3185942a JA |
294 | */ |
295 | ||
296 | int | |
297 | parse_and_execute (string, from_file, flags) | |
298 | char *string; | |
299 | const char *from_file; | |
300 | int flags; | |
301 | { | |
302 | int code, lreset; | |
303 | volatile int should_jump_to_top_level, last_result; | |
304 | COMMAND *volatile command; | |
ac50fbac | 305 | volatile sigset_t pe_sigmask; |
3185942a JA |
306 | |
307 | parse_prologue (string, flags, PE_TAG); | |
308 | ||
ccc6cda3 | 309 | parse_and_execute_level++; |
b80f6443 | 310 | |
3185942a JA |
311 | lreset = flags & SEVAL_RESETLINE; |
312 | ||
ac50fbac CR |
313 | #if defined (HAVE_POSIX_SIGNALS) |
314 | /* If we longjmp and are going to go on, use this to restore signal mask */ | |
a0c0a00f CR |
315 | sigemptyset ((sigset_t *)&pe_sigmask); |
316 | sigprocmask (SIG_BLOCK, (sigset_t *)NULL, (sigset_t *)&pe_sigmask); | |
ac50fbac CR |
317 | #endif |
318 | ||
b80f6443 JA |
319 | /* Reset the line number if the caller wants us to. If we don't reset the |
320 | line number, we have to subtract one, because we will add one just | |
321 | before executing the next command (resetting the line number sets it to | |
322 | 0; the first line number is 1). */ | |
323 | push_stream (lreset); | |
ac50fbac CR |
324 | if (parser_expanding_alias ()) |
325 | /* push current shell_input_line */ | |
326 | parser_save_alias (); | |
327 | ||
b80f6443 JA |
328 | if (lreset == 0) |
329 | line_number--; | |
330 | ||
ccc6cda3 | 331 | indirection_level++; |
ccc6cda3 JA |
332 | |
333 | code = should_jump_to_top_level = 0; | |
334 | last_result = EXECUTION_SUCCESS; | |
ccc6cda3 | 335 | |
a0c0a00f CR |
336 | /* We need to reset enough of the token state so we can start fresh. */ |
337 | if (current_token == yacc_EOF) | |
338 | current_token = '\n'; /* reset_parser() ? */ | |
339 | ||
ccc6cda3 | 340 | with_input_from_string (string, from_file); |
a0c0a00f | 341 | clear_shell_input_line (); |
ad1b3e68 | 342 | while (*(bash_input.location.string) || parser_expanding_alias ()) |
ccc6cda3 | 343 | { |
b80f6443 JA |
344 | command = (COMMAND *)NULL; |
345 | ||
ccc6cda3 JA |
346 | if (interrupt_state) |
347 | { | |
348 | last_result = EXECUTION_FAILURE; | |
349 | break; | |
350 | } | |
351 | ||
352 | /* Provide a location for functions which `longjmp (top_level)' to | |
353 | jump to. This prevents errors in substitution from restarting | |
354 | the reader loop directly, for example. */ | |
ac50fbac | 355 | code = setjmp_nosigs (top_level); |
ccc6cda3 JA |
356 | |
357 | if (code) | |
358 | { | |
359 | should_jump_to_top_level = 0; | |
360 | switch (code) | |
361 | { | |
b80f6443 | 362 | case ERREXIT: |
ac50fbac CR |
363 | /* variable_context -> 0 is what eval.c:reader_loop() does in |
364 | these circumstances. Don't bother with cleanup here because | |
365 | we don't want to run the function execution cleanup stuff | |
366 | that will cause pop_context and other functions to run. | |
74091dd4 CR |
367 | We call reset_local_contexts() instead, which just frees |
368 | context memory. | |
ac50fbac CR |
369 | XXX - change that if we want the function context to be |
370 | unwound. */ | |
371 | if (exit_immediately_on_error && variable_context) | |
372 | { | |
373 | discard_unwind_frame ("pe_dispose"); | |
74091dd4 | 374 | reset_local_contexts (); /* not in a function */ |
ac50fbac CR |
375 | } |
376 | should_jump_to_top_level = 1; | |
377 | goto out; | |
378 | case FORCE_EOF: | |
ccc6cda3 | 379 | case EXITPROG: |
b80f6443 JA |
380 | if (command) |
381 | run_unwind_frame ("pe_dispose"); | |
ccc6cda3 JA |
382 | /* Remember to call longjmp (top_level) after the old |
383 | value for it is restored. */ | |
384 | should_jump_to_top_level = 1; | |
385 | goto out; | |
386 | ||
74091dd4 CR |
387 | case EXITBLTIN: |
388 | if (command) | |
389 | { | |
390 | if (variable_context && signal_is_trapped (0)) | |
391 | { | |
392 | /* Let's make sure we run the exit trap in the function | |
393 | context, as we do when not running parse_and_execute. | |
394 | The pe_dispose unwind frame comes before any unwind- | |
395 | protects installed by the string we're evaluating, so | |
396 | it will undo the current function scope. */ | |
397 | dispose_command (command); | |
398 | discard_unwind_frame ("pe_dispose"); | |
399 | } | |
400 | else | |
401 | run_unwind_frame ("pe_dispose"); | |
402 | } | |
403 | should_jump_to_top_level = 1; | |
404 | goto out; | |
405 | ||
ccc6cda3 | 406 | case DISCARD: |
b80f6443 JA |
407 | if (command) |
408 | run_unwind_frame ("pe_dispose"); | |
28ef6c31 | 409 | last_result = last_command_exit_value = EXECUTION_FAILURE; /* XXX */ |
8868edaf | 410 | set_pipestatus_from_exit (last_command_exit_value); |
ccc6cda3 JA |
411 | if (subshell_environment) |
412 | { | |
413 | should_jump_to_top_level = 1; | |
414 | goto out; | |
415 | } | |
416 | else | |
417 | { | |
e8ce775d JA |
418 | #if 0 |
419 | dispose_command (command); /* pe_dispose does this */ | |
ac50fbac CR |
420 | #endif |
421 | #if defined (HAVE_POSIX_SIGNALS) | |
a0c0a00f | 422 | sigprocmask (SIG_SETMASK, (sigset_t *)&pe_sigmask, (sigset_t *)NULL); |
e8ce775d | 423 | #endif |
ccc6cda3 JA |
424 | continue; |
425 | } | |
426 | ||
427 | default: | |
b72432fd | 428 | command_error ("parse_and_execute", CMDERR_BADJUMP, code, 0); |
ccc6cda3 JA |
429 | break; |
430 | } | |
431 | } | |
74091dd4 | 432 | |
ccc6cda3 JA |
433 | if (parse_command () == 0) |
434 | { | |
6ddc9cf2 CR |
435 | int local_expalias, local_alflag; |
436 | ||
3185942a | 437 | if ((flags & SEVAL_PARSEONLY) || (interactive_shell == 0 && read_but_dont_execute)) |
ccc6cda3 JA |
438 | { |
439 | last_result = EXECUTION_SUCCESS; | |
440 | dispose_command (global_command); | |
441 | global_command = (COMMAND *)NULL; | |
442 | } | |
443 | else if (command = global_command) | |
444 | { | |
445 | struct fd_bitmap *bitmap; | |
446 | ||
ca6a2ba4 | 447 | if (flags & SEVAL_FUNCDEF) |
b64a0e1d | 448 | { |
ca6a2ba4 CR |
449 | char *x; |
450 | ||
451 | /* If the command parses to something other than a straight | |
452 | function definition, or if we have not consumed the entire | |
453 | string, or if the parser has transformed the function | |
454 | name (as parsing will if it begins or ends with shell | |
455 | whitespace, for example), reject the attempt */ | |
456 | if (command->type != cm_function_def || | |
457 | ((x = parser_remaining_input ()) && *x) || | |
458 | (STREQ (from_file, command->value.Function_def->name->word) == 0)) | |
459 | { | |
460 | internal_warning (_("%s: ignoring function definition attempt"), from_file); | |
461 | should_jump_to_top_level = 0; | |
462 | last_result = last_command_exit_value = EX_BADUSAGE; | |
8868edaf | 463 | set_pipestatus_from_exit (last_command_exit_value); |
ca6a2ba4 CR |
464 | reset_parser (); |
465 | break; | |
466 | } | |
b64a0e1d CR |
467 | } |
468 | ||
ccc6cda3 JA |
469 | bitmap = new_fd_bitmap (FD_BITMAP_SIZE); |
470 | begin_unwind_frame ("pe_dispose"); | |
471 | add_unwind_protect (dispose_fd_bitmap, bitmap); | |
d166f048 | 472 | add_unwind_protect (dispose_command, command); /* XXX */ |
ccc6cda3 JA |
473 | |
474 | global_command = (COMMAND *)NULL; | |
475 | ||
3185942a | 476 | if ((subshell_environment & SUBSHELL_COMSUB) && comsub_ignore_return) |
3185942a | 477 | command->flags |= CMD_IGNORE_RETURN; |
3185942a | 478 | |
ccc6cda3 | 479 | #if defined (ONESHOT) |
b72432fd JA |
480 | /* |
481 | * IF | |
482 | * we were invoked as `bash -c' (startup_state == 2) AND | |
483 | * parse_and_execute has not been called recursively AND | |
95732b49 | 484 | * we're not running a trap AND |
b72432fd | 485 | * we have parsed the full command (string == '\0') AND |
f1be666c | 486 | * we're not going to run the exit trap AND |
b72432fd | 487 | * we have a simple command without redirections AND |
95732b49 | 488 | * the command is not being timed AND |
a0c0a00f CR |
489 | * the command's return status is not being inverted AND |
490 | * there aren't any traps in effect | |
b72432fd JA |
491 | * THEN |
492 | * tell the execution code that we don't need to fork | |
493 | */ | |
a0c0a00f | 494 | if (should_suppress_fork (command)) |
ccc6cda3 JA |
495 | { |
496 | command->flags |= CMD_NO_FORK; | |
497 | command->value.Simple->flags |= CMD_NO_FORK; | |
498 | } | |
41f5420d CR |
499 | |
500 | /* Can't optimize forks out here execept for simple commands. | |
501 | This knows that the parser sets up commands as left-side heavy | |
502 | (&& and || are left-associative) and after the single parse, | |
503 | if we are at the end of the command string, the last in a | |
504 | series of connection commands is | |
505 | command->value.Connection->second. */ | |
ec8113b9 CR |
506 | else if (command->type == cm_connection && |
507 | (flags & SEVAL_NOOPTIMIZE) == 0 && | |
508 | can_optimize_connection (command)) | |
41f5420d CR |
509 | { |
510 | command->value.Connection->second->flags |= CMD_TRY_OPTIMIZING; | |
511 | command->value.Connection->second->value.Simple->flags |= CMD_TRY_OPTIMIZING; | |
512 | } | |
ccc6cda3 JA |
513 | #endif /* ONESHOT */ |
514 | ||
6ddc9cf2 CR |
515 | /* We play tricks in the parser and command_substitute() turning |
516 | expand_aliases on and off depending on which parsing pass and | |
517 | whether or not we're in posix mode. This only matters for | |
518 | parsing, and we let the higher layers deal with that. We just | |
519 | want to ensure that expand_aliases is set to the appropriate | |
520 | global value when we go to execute this command, so we save | |
521 | and restore it around the execution (we don't restore it if | |
522 | the global value of the flag (expaliases_flag) changes). */ | |
523 | local_expalias = expand_aliases; | |
524 | local_alflag = expaliases_flag; | |
525 | if (subshell_environment & SUBSHELL_COMSUB) | |
526 | expand_aliases = expaliases_flag; | |
527 | ||
cce855bc JA |
528 | /* See if this is a candidate for $( <file ). */ |
529 | if (startup_state == 2 && | |
28ef6c31 | 530 | (subshell_environment & SUBSHELL_COMSUB) && |
cce855bc | 531 | *bash_input.location.string == '\0' && |
74091dd4 | 532 | can_optimize_cat_file (command)) |
cce855bc JA |
533 | { |
534 | int r; | |
535 | r = cat_file (command->value.Simple->redirects); | |
536 | last_result = (r < 0) ? EXECUTION_FAILURE : EXECUTION_SUCCESS; | |
537 | } | |
538 | else | |
539 | last_result = execute_command_internal | |
ccc6cda3 | 540 | (command, 0, NO_PIPE, NO_PIPE, bitmap); |
ccc6cda3 JA |
541 | dispose_command (command); |
542 | dispose_fd_bitmap (bitmap); | |
543 | discard_unwind_frame ("pe_dispose"); | |
b64a0e1d | 544 | |
6ddc9cf2 CR |
545 | /* If the global value didn't change, we restore what we had. */ |
546 | if ((subshell_environment & SUBSHELL_COMSUB) && local_alflag == expaliases_flag) | |
547 | expand_aliases = local_expalias; | |
548 | ||
b64a0e1d | 549 | if (flags & SEVAL_ONECMD) |
ca6a2ba4 CR |
550 | { |
551 | reset_parser (); | |
552 | break; | |
553 | } | |
ccc6cda3 JA |
554 | } |
555 | } | |
556 | else | |
557 | { | |
d233b485 | 558 | last_result = EX_BADUSAGE; /* was EXECUTION_FAILURE */ |
ccc6cda3 | 559 | |
0001803f CR |
560 | if (interactive_shell == 0 && this_shell_builtin && |
561 | (this_shell_builtin == source_builtin || this_shell_builtin == eval_builtin) && | |
d233b485 | 562 | last_command_exit_value == EX_BADSYNTAX && posixly_correct && executing_command_builtin == 0) |
0001803f | 563 | { |
0001803f CR |
564 | should_jump_to_top_level = 1; |
565 | code = ERREXIT; | |
566 | last_command_exit_value = EX_BADUSAGE; | |
0001803f CR |
567 | } |
568 | ||
ccc6cda3 JA |
569 | /* Since we are shell compatible, syntax errors in a script |
570 | abort the execution of the script. Right? */ | |
571 | break; | |
572 | } | |
573 | } | |
574 | ||
575 | out: | |
576 | ||
3185942a | 577 | run_unwind_frame (PE_TAG); |
ccc6cda3 JA |
578 | |
579 | if (interrupt_state && parse_and_execute_level == 0) | |
580 | { | |
581 | /* An interrupt during non-interactive execution in an | |
28ef6c31 JA |
582 | interactive shell (e.g. via $PROMPT_COMMAND) should |
583 | not cause the shell to exit. */ | |
ccc6cda3 JA |
584 | interactive = interactive_shell; |
585 | throw_to_top_level (); | |
586 | } | |
587 | ||
74091dd4 CR |
588 | CHECK_TERMSIG; |
589 | ||
ccc6cda3 JA |
590 | if (should_jump_to_top_level) |
591 | jump_to_top_level (code); | |
592 | ||
593 | return (last_result); | |
594 | } | |
cce855bc | 595 | |
3185942a JA |
596 | /* Parse a command contained in STRING according to FLAGS and return the |
597 | number of characters consumed from the string. If non-NULL, set *ENDP | |
598 | to the position in the string where the parse ended. Used to validate | |
599 | command substitutions during parsing to obey Posix rules about finding | |
600 | the end of the command and balancing parens. */ | |
601 | int | |
74091dd4 | 602 | parse_string (string, from_file, flags, cmdp, endp) |
3185942a JA |
603 | char *string; |
604 | const char *from_file; | |
605 | int flags; | |
74091dd4 | 606 | COMMAND **cmdp; |
3185942a JA |
607 | char **endp; |
608 | { | |
609 | int code, nc; | |
610 | volatile int should_jump_to_top_level; | |
611 | COMMAND *volatile command, *oglobal; | |
612 | char *ostring; | |
ac50fbac | 613 | volatile sigset_t ps_sigmask; |
3185942a JA |
614 | |
615 | parse_prologue (string, flags, PS_TAG); | |
616 | ||
ac50fbac CR |
617 | #if defined (HAVE_POSIX_SIGNALS) |
618 | /* If we longjmp and are going to go on, use this to restore signal mask */ | |
a0c0a00f CR |
619 | sigemptyset ((sigset_t *)&ps_sigmask); |
620 | sigprocmask (SIG_BLOCK, (sigset_t *)NULL, (sigset_t *)&ps_sigmask); | |
ac50fbac CR |
621 | #endif |
622 | ||
3185942a JA |
623 | /* Reset the line number if the caller wants us to. If we don't reset the |
624 | line number, we have to subtract one, because we will add one just | |
625 | before executing the next command (resetting the line number sets it to | |
626 | 0; the first line number is 1). */ | |
627 | push_stream (0); | |
ac50fbac CR |
628 | if (parser_expanding_alias ()) |
629 | /* push current shell_input_line */ | |
630 | parser_save_alias (); | |
631 | ||
3185942a JA |
632 | code = should_jump_to_top_level = 0; |
633 | oglobal = global_command; | |
3185942a JA |
634 | |
635 | with_input_from_string (string, from_file); | |
74091dd4 | 636 | ostring = bash_input.location.string; |
ad1b3e68 | 637 | while (*(bash_input.location.string)) /* XXX - parser_expanding_alias () ? */ |
3185942a JA |
638 | { |
639 | command = (COMMAND *)NULL; | |
640 | ||
641 | #if 0 | |
642 | if (interrupt_state) | |
643 | break; | |
644 | #endif | |
645 | ||
646 | /* Provide a location for functions which `longjmp (top_level)' to | |
647 | jump to. */ | |
ac50fbac | 648 | code = setjmp_nosigs (top_level); |
3185942a JA |
649 | |
650 | if (code) | |
651 | { | |
74091dd4 CR |
652 | INTERNAL_DEBUG(("parse_string: longjmp executed: code = %d", code)); |
653 | ||
3185942a JA |
654 | should_jump_to_top_level = 0; |
655 | switch (code) | |
656 | { | |
657 | case FORCE_EOF: | |
658 | case ERREXIT: | |
659 | case EXITPROG: | |
74091dd4 | 660 | case EXITBLTIN: |
3185942a JA |
661 | case DISCARD: /* XXX */ |
662 | if (command) | |
663 | dispose_command (command); | |
664 | /* Remember to call longjmp (top_level) after the old | |
665 | value for it is restored. */ | |
666 | should_jump_to_top_level = 1; | |
667 | goto out; | |
668 | ||
669 | default: | |
ac50fbac | 670 | #if defined (HAVE_POSIX_SIGNALS) |
a0c0a00f | 671 | sigprocmask (SIG_SETMASK, (sigset_t *)&ps_sigmask, (sigset_t *)NULL); |
ac50fbac | 672 | #endif |
3185942a JA |
673 | command_error ("parse_string", CMDERR_BADJUMP, code, 0); |
674 | break; | |
675 | } | |
676 | } | |
677 | ||
678 | if (parse_command () == 0) | |
679 | { | |
74091dd4 CR |
680 | if (cmdp) |
681 | *cmdp = global_command; | |
682 | else | |
683 | dispose_command (global_command); | |
3185942a JA |
684 | global_command = (COMMAND *)NULL; |
685 | } | |
686 | else | |
687 | { | |
688 | if ((flags & SEVAL_NOLONGJMP) == 0) | |
689 | { | |
690 | should_jump_to_top_level = 1; | |
691 | code = DISCARD; | |
692 | } | |
693 | else | |
694 | reset_parser (); /* XXX - sets token_to_read */ | |
695 | break; | |
696 | } | |
697 | ||
698 | if (current_token == yacc_EOF || current_token == shell_eof_token) | |
74091dd4 CR |
699 | { |
700 | if (current_token == shell_eof_token) | |
701 | rewind_input_string (); | |
3185942a | 702 | break; |
74091dd4 | 703 | } |
3185942a JA |
704 | } |
705 | ||
8868edaf | 706 | out: |
3185942a JA |
707 | |
708 | global_command = oglobal; | |
709 | nc = bash_input.location.string - ostring; | |
710 | if (endp) | |
711 | *endp = bash_input.location.string; | |
712 | ||
713 | run_unwind_frame (PS_TAG); | |
714 | ||
a0c0a00f CR |
715 | /* If we return < 0, the caller (xparse_dolparen) will jump_to_top_level for |
716 | us, after doing cleanup */ | |
3185942a | 717 | if (should_jump_to_top_level) |
a0c0a00f CR |
718 | { |
719 | if (parse_and_execute_level == 0) | |
720 | top_level_cleanup (); | |
721 | if (code == DISCARD) | |
722 | return -DISCARD; | |
723 | jump_to_top_level (code); | |
724 | } | |
3185942a JA |
725 | |
726 | return (nc); | |
727 | } | |
728 | ||
74091dd4 CR |
729 | int |
730 | open_redir_file (r, fnp) | |
cce855bc | 731 | REDIRECT *r; |
74091dd4 | 732 | char **fnp; |
cce855bc | 733 | { |
0628567a | 734 | char *fn; |
f73dda09 | 735 | int fd, rval; |
cce855bc JA |
736 | |
737 | if (r->instruction != r_input_direction) | |
738 | return -1; | |
739 | ||
740 | /* Get the filename. */ | |
741 | if (posixly_correct && !interactive_shell) | |
742 | disallow_filename_globbing++; | |
743 | fn = redirection_expand (r->redirectee.filename); | |
744 | if (posixly_correct && !interactive_shell) | |
745 | disallow_filename_globbing--; | |
746 | ||
747 | if (fn == 0) | |
748 | { | |
8868edaf | 749 | redirection_error (r, AMBIGUOUS_REDIRECT, fn); |
cce855bc JA |
750 | return -1; |
751 | } | |
752 | ||
753 | fd = open(fn, O_RDONLY); | |
754 | if (fd < 0) | |
755 | { | |
756 | file_error (fn); | |
757 | free (fn); | |
74091dd4 CR |
758 | if (fnp) |
759 | *fnp = 0; | |
cce855bc JA |
760 | return -1; |
761 | } | |
762 | ||
74091dd4 CR |
763 | if (fnp) |
764 | *fnp = fn; | |
471fd9a3 CR |
765 | else |
766 | free (fn); | |
767 | ||
74091dd4 CR |
768 | return fd; |
769 | } | |
770 | ||
771 | /* Handle a $( < file ) command substitution. This expands the filename, | |
772 | returning errors as appropriate, then just cats the file to the standard | |
773 | output. */ | |
774 | static int | |
775 | cat_file (r) | |
776 | REDIRECT *r; | |
777 | { | |
778 | char *fn; | |
779 | int fd, rval; | |
780 | ||
781 | fd = open_redir_file (r, &fn); | |
782 | if (fd < 0) | |
783 | return -1; | |
784 | ||
7117c2d2 | 785 | rval = zcatfd (fd, 1, fn); |
cce855bc JA |
786 | |
787 | free (fn); | |
788 | close (fd); | |
789 | ||
f73dda09 | 790 | return (rval); |
cce855bc | 791 | } |
ac50fbac CR |
792 | |
793 | int | |
794 | evalstring (string, from_file, flags) | |
795 | char *string; | |
796 | const char *from_file; | |
797 | int flags; | |
798 | { | |
799 | volatile int r, rflag, rcatch; | |
d233b485 CR |
800 | volatile int was_trap; |
801 | ||
802 | /* Are we running a trap when we execute this function? */ | |
803 | was_trap = running_trap; | |
ac50fbac CR |
804 | |
805 | rcatch = 0; | |
806 | rflag = return_catch_flag; | |
807 | /* If we are in a place where `return' is valid, we have to catch | |
808 | `eval "... return"' and make sure parse_and_execute cleans up. Then | |
809 | we can trampoline to the previous saved return_catch location. */ | |
810 | if (rflag) | |
811 | { | |
812 | begin_unwind_frame ("evalstring"); | |
813 | ||
814 | unwind_protect_int (return_catch_flag); | |
815 | unwind_protect_jmp_buf (return_catch); | |
816 | ||
817 | return_catch_flag++; /* increment so we have a counter */ | |
818 | rcatch = setjmp_nosigs (return_catch); | |
819 | } | |
820 | ||
821 | if (rcatch) | |
822 | { | |
d233b485 CR |
823 | /* We care about whether or not we are running the same trap we were |
824 | when we entered this function. */ | |
825 | parse_and_execute_cleanup (was_trap); | |
ac50fbac CR |
826 | r = return_catch_value; |
827 | } | |
828 | else | |
829 | /* Note that parse_and_execute () frees the string it is passed. */ | |
830 | r = parse_and_execute (string, from_file, flags); | |
831 | ||
832 | if (rflag) | |
833 | { | |
834 | run_unwind_frame ("evalstring"); | |
835 | if (rcatch && return_catch_flag) | |
836 | { | |
837 | return_catch_value = r; | |
a0c0a00f | 838 | sh_longjmp (return_catch, 1); |
ac50fbac CR |
839 | } |
840 | } | |
841 | ||
842 | return (r); | |
843 | } |