]>
Commit | Line | Data |
---|---|---|
1 | /* evalstring.c - evaluate a string as one or more shell commands. */ | |
2 | ||
3 | /* Copyright (C) 1996-2022 Free Software Foundation, Inc. | |
4 | ||
5 | This file is part of GNU Bash, the Bourne Again SHell. | |
6 | ||
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. | |
11 | ||
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 | */ | |
20 | ||
21 | #include <config.h> | |
22 | ||
23 | #if defined (HAVE_UNISTD_H) | |
24 | # ifdef _MINIX | |
25 | # include <sys/types.h> | |
26 | # endif | |
27 | # include <unistd.h> | |
28 | #endif | |
29 | ||
30 | #include <stdio.h> | |
31 | #include <signal.h> | |
32 | ||
33 | #include <errno.h> | |
34 | ||
35 | #include "filecntl.h" | |
36 | #include "../bashansi.h" | |
37 | ||
38 | #include "../shell.h" | |
39 | #include "../jobs.h" | |
40 | #include "../builtins.h" | |
41 | #include "../flags.h" | |
42 | #include "../parser.h" | |
43 | #include "../input.h" | |
44 | #include "../execute_cmd.h" | |
45 | #include "../redir.h" | |
46 | #include "../trap.h" | |
47 | #include "../bashintl.h" | |
48 | ||
49 | #include <y.tab.h> | |
50 | ||
51 | #if defined (HISTORY) | |
52 | # include "../bashhist.h" | |
53 | #endif | |
54 | ||
55 | #include "common.h" | |
56 | #include "builtext.h" | |
57 | ||
58 | #if !defined (errno) | |
59 | extern int errno; | |
60 | #endif | |
61 | ||
62 | #define IS_BUILTIN(s) (builtin_address_internal(s, 0) != (struct builtin *)NULL) | |
63 | ||
64 | int parse_and_execute_level = 0; | |
65 | ||
66 | static int cat_file PARAMS((REDIRECT *)); | |
67 | ||
68 | #define PE_TAG "parse_and_execute top" | |
69 | #define PS_TAG "parse_string top" | |
70 | ||
71 | #if defined (HISTORY) | |
72 | static void | |
73 | set_history_remembering () | |
74 | { | |
75 | remember_on_history = enable_history_list; | |
76 | } | |
77 | #endif | |
78 | ||
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 | ||
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). */ | |
105 | int | |
106 | should_suppress_fork (command) | |
107 | COMMAND *command; | |
108 | { | |
109 | int subshell; | |
110 | ||
111 | subshell = subshell_environment & SUBSHELL_PROCSUB; /* salt to taste */ | |
112 | return (startup_state == 2 && parse_and_execute_level == 1 && | |
113 | *bash_input.location.string == '\0' && | |
114 | parser_expanding_alias () == 0 && | |
115 | should_optimize_fork (command, subshell)); | |
116 | } | |
117 | ||
118 | int | |
119 | can_optimize_connection (command) | |
120 | COMMAND *command; | |
121 | { | |
122 | return (*bash_input.location.string == '\0' && | |
123 | parser_expanding_alias () == 0 && | |
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 | ||
128 | void | |
129 | optimize_connection_fork (command) | |
130 | COMMAND *command; | |
131 | { | |
132 | if (command->type == cm_connection && | |
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) && | |
135 | (should_suppress_fork (command->value.Connection->second) || | |
136 | ((subshell_environment & SUBSHELL_PAREN) && should_optimize_fork (command->value.Connection->second, 0)))) | |
137 | { | |
138 | command->value.Connection->second->flags |= CMD_NO_FORK; | |
139 | command->value.Connection->second->value.Simple->flags |= CMD_NO_FORK; | |
140 | } | |
141 | } | |
142 | ||
143 | void | |
144 | optimize_subshell_command (command) | |
145 | COMMAND *command; | |
146 | { | |
147 | if (should_optimize_fork (command, 0)) | |
148 | { | |
149 | command->flags |= CMD_NO_FORK; | |
150 | command->value.Simple->flags |= CMD_NO_FORK; | |
151 | } | |
152 | else if (command->type == cm_connection && | |
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 | } | |
160 | } | |
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 | ||
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 | ||
195 | /* How to force parse_and_execute () to clean up after itself. */ | |
196 | void | |
197 | parse_and_execute_cleanup (old_running_trap) | |
198 | int old_running_trap; | |
199 | { | |
200 | if (running_trap > 0) | |
201 | { | |
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); | |
208 | unfreeze_jobs_list (); | |
209 | } | |
210 | ||
211 | if (have_unwind_protects ()) | |
212 | run_unwind_frame (PE_TAG); | |
213 | else | |
214 | parse_and_execute_level = 0; /* XXX */ | |
215 | } | |
216 | ||
217 | static void | |
218 | parse_prologue (string, flags, tag) | |
219 | char *string; | |
220 | int flags; | |
221 | char *tag; | |
222 | { | |
223 | char *orig_string, *lastcom; | |
224 | int x; | |
225 | ||
226 | orig_string = string; | |
227 | /* Unwind protect this invocation of parse_and_execute (). */ | |
228 | begin_unwind_frame (tag); | |
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); | |
233 | unwind_protect_int (line_number_for_err_trap); | |
234 | unwind_protect_int (loop_level); | |
235 | unwind_protect_int (executing_list); | |
236 | unwind_protect_int (comsub_ignore_return); | |
237 | if (flags & (SEVAL_NONINT|SEVAL_INTERACT)) | |
238 | unwind_protect_int (interactive); | |
239 | ||
240 | #if defined (HISTORY) | |
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 */ | |
245 | # if defined (BANG_HISTORY) | |
246 | unwind_protect_int (history_expansion_inhibited); | |
247 | # endif /* BANG_HISTORY */ | |
248 | #endif /* HISTORY */ | |
249 | ||
250 | if (interactive_shell) | |
251 | { | |
252 | x = get_current_prompt_level (); | |
253 | add_unwind_protect (set_current_prompt_level, x); | |
254 | } | |
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 | ||
262 | add_unwind_protect (pop_stream, (char *)NULL); | |
263 | if (parser_expanding_alias ()) | |
264 | add_unwind_protect (parser_restore_alias, (char *)NULL); | |
265 | ||
266 | if (orig_string && ((flags & SEVAL_NOFREE) == 0)) | |
267 | add_unwind_protect (xfree, orig_string); | |
268 | end_unwind_frame (); | |
269 | ||
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 (); | |
276 | # if defined (BANG_HISTORY) | |
277 | if (flags & SEVAL_NOHISTEXP) | |
278 | history_expansion_inhibited = 1; | |
279 | # endif /* BANG_HISTORY */ | |
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 | |
292 | (flags & SEVAL_NOHISTEXP) -> history_expansion_inhibited -> 1 | |
293 | (flags & SEVAL_NOOPTIMIZE) -> don't try to turn on optimizing flags | |
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; | |
305 | volatile sigset_t pe_sigmask; | |
306 | ||
307 | parse_prologue (string, flags, PE_TAG); | |
308 | ||
309 | parse_and_execute_level++; | |
310 | ||
311 | lreset = flags & SEVAL_RESETLINE; | |
312 | ||
313 | #if defined (HAVE_POSIX_SIGNALS) | |
314 | /* If we longjmp and are going to go on, use this to restore signal mask */ | |
315 | sigemptyset ((sigset_t *)&pe_sigmask); | |
316 | sigprocmask (SIG_BLOCK, (sigset_t *)NULL, (sigset_t *)&pe_sigmask); | |
317 | #endif | |
318 | ||
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); | |
324 | if (parser_expanding_alias ()) | |
325 | /* push current shell_input_line */ | |
326 | parser_save_alias (); | |
327 | ||
328 | if (lreset == 0) | |
329 | line_number--; | |
330 | ||
331 | indirection_level++; | |
332 | ||
333 | code = should_jump_to_top_level = 0; | |
334 | last_result = EXECUTION_SUCCESS; | |
335 | ||
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 | ||
340 | with_input_from_string (string, from_file); | |
341 | clear_shell_input_line (); | |
342 | while (*(bash_input.location.string) || parser_expanding_alias ()) | |
343 | { | |
344 | command = (COMMAND *)NULL; | |
345 | ||
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. */ | |
355 | code = setjmp_nosigs (top_level); | |
356 | ||
357 | if (code) | |
358 | { | |
359 | should_jump_to_top_level = 0; | |
360 | switch (code) | |
361 | { | |
362 | case ERREXIT: | |
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. | |
367 | We call reset_local_contexts() instead, which just frees | |
368 | context memory. | |
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"); | |
374 | reset_local_contexts (); /* not in a function */ | |
375 | } | |
376 | should_jump_to_top_level = 1; | |
377 | goto out; | |
378 | case FORCE_EOF: | |
379 | case EXITPROG: | |
380 | if (command) | |
381 | run_unwind_frame ("pe_dispose"); | |
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 | ||
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 | ||
406 | case DISCARD: | |
407 | if (command) | |
408 | run_unwind_frame ("pe_dispose"); | |
409 | last_result = last_command_exit_value = EXECUTION_FAILURE; /* XXX */ | |
410 | set_pipestatus_from_exit (last_command_exit_value); | |
411 | if (subshell_environment) | |
412 | { | |
413 | should_jump_to_top_level = 1; | |
414 | goto out; | |
415 | } | |
416 | else | |
417 | { | |
418 | #if 0 | |
419 | dispose_command (command); /* pe_dispose does this */ | |
420 | #endif | |
421 | #if defined (HAVE_POSIX_SIGNALS) | |
422 | sigprocmask (SIG_SETMASK, (sigset_t *)&pe_sigmask, (sigset_t *)NULL); | |
423 | #endif | |
424 | continue; | |
425 | } | |
426 | ||
427 | default: | |
428 | command_error ("parse_and_execute", CMDERR_BADJUMP, code, 0); | |
429 | break; | |
430 | } | |
431 | } | |
432 | ||
433 | if (parse_command () == 0) | |
434 | { | |
435 | int local_expalias, local_alflag; | |
436 | ||
437 | if ((flags & SEVAL_PARSEONLY) || (interactive_shell == 0 && read_but_dont_execute)) | |
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 | ||
447 | if (flags & SEVAL_FUNCDEF) | |
448 | { | |
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; | |
463 | set_pipestatus_from_exit (last_command_exit_value); | |
464 | reset_parser (); | |
465 | break; | |
466 | } | |
467 | } | |
468 | ||
469 | bitmap = new_fd_bitmap (FD_BITMAP_SIZE); | |
470 | begin_unwind_frame ("pe_dispose"); | |
471 | add_unwind_protect (dispose_fd_bitmap, bitmap); | |
472 | add_unwind_protect (dispose_command, command); /* XXX */ | |
473 | ||
474 | global_command = (COMMAND *)NULL; | |
475 | ||
476 | if ((subshell_environment & SUBSHELL_COMSUB) && comsub_ignore_return) | |
477 | command->flags |= CMD_IGNORE_RETURN; | |
478 | ||
479 | #if defined (ONESHOT) | |
480 | /* | |
481 | * IF | |
482 | * we were invoked as `bash -c' (startup_state == 2) AND | |
483 | * parse_and_execute has not been called recursively AND | |
484 | * we're not running a trap AND | |
485 | * we have parsed the full command (string == '\0') AND | |
486 | * we're not going to run the exit trap AND | |
487 | * we have a simple command without redirections AND | |
488 | * the command is not being timed AND | |
489 | * the command's return status is not being inverted AND | |
490 | * there aren't any traps in effect | |
491 | * THEN | |
492 | * tell the execution code that we don't need to fork | |
493 | */ | |
494 | if (should_suppress_fork (command)) | |
495 | { | |
496 | command->flags |= CMD_NO_FORK; | |
497 | command->value.Simple->flags |= CMD_NO_FORK; | |
498 | } | |
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. */ | |
506 | else if (command->type == cm_connection && | |
507 | (flags & SEVAL_NOOPTIMIZE) == 0 && | |
508 | can_optimize_connection (command)) | |
509 | { | |
510 | command->value.Connection->second->flags |= CMD_TRY_OPTIMIZING; | |
511 | command->value.Connection->second->value.Simple->flags |= CMD_TRY_OPTIMIZING; | |
512 | } | |
513 | #endif /* ONESHOT */ | |
514 | ||
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 | ||
528 | /* See if this is a candidate for $( <file ). */ | |
529 | if (startup_state == 2 && | |
530 | (subshell_environment & SUBSHELL_COMSUB) && | |
531 | *bash_input.location.string == '\0' && | |
532 | can_optimize_cat_file (command)) | |
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 | |
540 | (command, 0, NO_PIPE, NO_PIPE, bitmap); | |
541 | dispose_command (command); | |
542 | dispose_fd_bitmap (bitmap); | |
543 | discard_unwind_frame ("pe_dispose"); | |
544 | ||
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 | ||
549 | if (flags & SEVAL_ONECMD) | |
550 | { | |
551 | reset_parser (); | |
552 | break; | |
553 | } | |
554 | } | |
555 | } | |
556 | else | |
557 | { | |
558 | last_result = EX_BADUSAGE; /* was EXECUTION_FAILURE */ | |
559 | ||
560 | if (interactive_shell == 0 && this_shell_builtin && | |
561 | (this_shell_builtin == source_builtin || this_shell_builtin == eval_builtin) && | |
562 | last_command_exit_value == EX_BADSYNTAX && posixly_correct && executing_command_builtin == 0) | |
563 | { | |
564 | should_jump_to_top_level = 1; | |
565 | code = ERREXIT; | |
566 | last_command_exit_value = EX_BADUSAGE; | |
567 | } | |
568 | ||
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 | ||
577 | run_unwind_frame (PE_TAG); | |
578 | ||
579 | if (interrupt_state && parse_and_execute_level == 0) | |
580 | { | |
581 | /* An interrupt during non-interactive execution in an | |
582 | interactive shell (e.g. via $PROMPT_COMMAND) should | |
583 | not cause the shell to exit. */ | |
584 | interactive = interactive_shell; | |
585 | throw_to_top_level (); | |
586 | } | |
587 | ||
588 | CHECK_TERMSIG; | |
589 | ||
590 | if (should_jump_to_top_level) | |
591 | jump_to_top_level (code); | |
592 | ||
593 | return (last_result); | |
594 | } | |
595 | ||
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 | |
602 | parse_string (string, from_file, flags, cmdp, endp) | |
603 | char *string; | |
604 | const char *from_file; | |
605 | int flags; | |
606 | COMMAND **cmdp; | |
607 | char **endp; | |
608 | { | |
609 | int code, nc; | |
610 | volatile int should_jump_to_top_level; | |
611 | COMMAND *volatile command, *oglobal; | |
612 | char *ostring; | |
613 | volatile sigset_t ps_sigmask; | |
614 | ||
615 | parse_prologue (string, flags, PS_TAG); | |
616 | ||
617 | #if defined (HAVE_POSIX_SIGNALS) | |
618 | /* If we longjmp and are going to go on, use this to restore signal mask */ | |
619 | sigemptyset ((sigset_t *)&ps_sigmask); | |
620 | sigprocmask (SIG_BLOCK, (sigset_t *)NULL, (sigset_t *)&ps_sigmask); | |
621 | #endif | |
622 | ||
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); | |
628 | if (parser_expanding_alias ()) | |
629 | /* push current shell_input_line */ | |
630 | parser_save_alias (); | |
631 | ||
632 | code = should_jump_to_top_level = 0; | |
633 | oglobal = global_command; | |
634 | ||
635 | with_input_from_string (string, from_file); | |
636 | ostring = bash_input.location.string; | |
637 | while (*(bash_input.location.string)) /* XXX - parser_expanding_alias () ? */ | |
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. */ | |
648 | code = setjmp_nosigs (top_level); | |
649 | ||
650 | if (code) | |
651 | { | |
652 | INTERNAL_DEBUG(("parse_string: longjmp executed: code = %d", code)); | |
653 | ||
654 | should_jump_to_top_level = 0; | |
655 | switch (code) | |
656 | { | |
657 | case FORCE_EOF: | |
658 | case ERREXIT: | |
659 | case EXITPROG: | |
660 | case EXITBLTIN: | |
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: | |
670 | #if defined (HAVE_POSIX_SIGNALS) | |
671 | sigprocmask (SIG_SETMASK, (sigset_t *)&ps_sigmask, (sigset_t *)NULL); | |
672 | #endif | |
673 | command_error ("parse_string", CMDERR_BADJUMP, code, 0); | |
674 | break; | |
675 | } | |
676 | } | |
677 | ||
678 | if (parse_command () == 0) | |
679 | { | |
680 | if (cmdp) | |
681 | *cmdp = global_command; | |
682 | else | |
683 | dispose_command (global_command); | |
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) | |
699 | { | |
700 | if (current_token == shell_eof_token) | |
701 | rewind_input_string (); | |
702 | break; | |
703 | } | |
704 | } | |
705 | ||
706 | out: | |
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 | ||
715 | /* If we return < 0, the caller (xparse_dolparen) will jump_to_top_level for | |
716 | us, after doing cleanup */ | |
717 | if (should_jump_to_top_level) | |
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 | } | |
725 | ||
726 | return (nc); | |
727 | } | |
728 | ||
729 | int | |
730 | open_redir_file (r, fnp) | |
731 | REDIRECT *r; | |
732 | char **fnp; | |
733 | { | |
734 | char *fn; | |
735 | int fd, rval; | |
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 | { | |
749 | redirection_error (r, AMBIGUOUS_REDIRECT, fn); | |
750 | return -1; | |
751 | } | |
752 | ||
753 | fd = open(fn, O_RDONLY); | |
754 | if (fd < 0) | |
755 | { | |
756 | file_error (fn); | |
757 | free (fn); | |
758 | if (fnp) | |
759 | *fnp = 0; | |
760 | return -1; | |
761 | } | |
762 | ||
763 | if (fnp) | |
764 | *fnp = fn; | |
765 | else | |
766 | free (fn); | |
767 | ||
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 | ||
785 | rval = zcatfd (fd, 1, fn); | |
786 | ||
787 | free (fn); | |
788 | close (fd); | |
789 | ||
790 | return (rval); | |
791 | } | |
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; | |
800 | volatile int was_trap; | |
801 | ||
802 | /* Are we running a trap when we execute this function? */ | |
803 | was_trap = running_trap; | |
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 | { | |
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); | |
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; | |
838 | sh_longjmp (return_catch, 1); | |
839 | } | |
840 | } | |
841 | ||
842 | return (r); | |
843 | } |