Line data Source code
1 : /* evalstring.c - evaluate a string as one or more shell commands. */
2 :
3 : /* Copyright (C) 1996-2015 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 "../input.h"
43 : #include "../execute_cmd.h"
44 : #include "../redir.h"
45 : #include "../trap.h"
46 : #include "../bashintl.h"
47 :
48 : #include <y.tab.h>
49 :
50 : #if defined (HISTORY)
51 : # include "../bashhist.h"
52 : #endif
53 :
54 : #include "common.h"
55 : #include "builtext.h"
56 :
57 : #if !defined (errno)
58 : extern int errno;
59 : #endif
60 :
61 : #define IS_BUILTIN(s) (builtin_address_internal(s, 0) != (struct builtin *)NULL)
62 :
63 : extern int indirection_level, subshell_environment;
64 : extern int line_number, line_number_for_err_trap;
65 : extern int current_token, shell_eof_token;
66 : extern int last_command_exit_value;
67 : extern int running_trap;
68 : extern int loop_level;
69 : extern int executing_list;
70 : extern int comsub_ignore_return;
71 : extern int posixly_correct;
72 : extern int return_catch_flag, return_catch_value;
73 : extern sh_builtin_func_t *this_shell_builtin;
74 : extern char *the_printed_command_except_trap;
75 :
76 : int parse_and_execute_level = 0;
77 :
78 : static int cat_file __P((REDIRECT *));
79 :
80 : #define PE_TAG "parse_and_execute top"
81 : #define PS_TAG "parse_string top"
82 :
83 : #if defined (HISTORY)
84 : static void
85 9147636 : set_history_remembering ()
86 : {
87 9147636 : remember_on_history = enable_history_list;
88 9147636 : }
89 : #endif
90 :
91 : static void
92 9147645 : restore_lastcom (x)
93 : char *x;
94 : {
95 9147645 : FREE (the_printed_command_except_trap);
96 9147645 : the_printed_command_except_trap = x;
97 9147645 : }
98 :
99 : int
100 18292214 : should_suppress_fork (command)
101 : COMMAND *command;
102 : {
103 4884 : return (startup_state == 2 && parse_and_execute_level == 1 &&
104 4884 : running_trap == 0 &&
105 4884 : *bash_input.location.string == '\0' &&
106 3861 : command->type == cm_simple &&
107 3396 : signal_is_trapped (EXIT_TRAP) == 0 &&
108 3396 : signal_is_trapped (ERROR_TRAP) == 0 &&
109 1698 : any_signals_trapped () < 0 &&
110 1698 : command->redirects == 0 && command->value.Simple->redirects == 0 &&
111 18293653 : ((command->flags & CMD_TIME_PIPELINE) == 0) &&
112 : ((command->flags & CMD_INVERT_RETURN) == 0));
113 : }
114 :
115 : void
116 948 : optimize_fork (command)
117 : COMMAND *command;
118 : {
119 948 : if (command->type == cm_connection &&
120 1072 : (command->value.Connection->connector == AND_AND || command->value.Connection->connector == OR_OR) &&
121 124 : should_suppress_fork (command->value.Connection->second))
122 : {
123 0 : command->value.Connection->second->flags |= CMD_NO_FORK;
124 0 : command->value.Connection->second->value.Simple->flags |= CMD_NO_FORK;
125 : }
126 948 : }
127 :
128 : /* How to force parse_and_execute () to clean up after itself. */
129 : void
130 0 : parse_and_execute_cleanup ()
131 : {
132 0 : if (running_trap)
133 : {
134 0 : run_trap_cleanup (running_trap - 1);
135 0 : unfreeze_jobs_list ();
136 : }
137 :
138 0 : if (have_unwind_protects ())
139 0 : run_unwind_frame (PE_TAG);
140 : else
141 0 : parse_and_execute_level = 0; /* XXX */
142 0 : }
143 :
144 : static void
145 18292323 : parse_prologue (string, flags, tag)
146 : char *string;
147 : int flags;
148 : char *tag;
149 : {
150 18292323 : char *orig_string, *lastcom;
151 18292323 : int x;
152 :
153 18292323 : orig_string = string;
154 : /* Unwind protect this invocation of parse_and_execute (). */
155 18292323 : begin_unwind_frame (tag);
156 18292323 : unwind_protect_int (parse_and_execute_level);
157 18292323 : unwind_protect_jmp_buf (top_level);
158 18292323 : unwind_protect_int (indirection_level);
159 18292323 : unwind_protect_int (line_number);
160 18292323 : unwind_protect_int (line_number_for_err_trap);
161 18292323 : unwind_protect_int (loop_level);
162 18292323 : unwind_protect_int (executing_list);
163 18292323 : unwind_protect_int (comsub_ignore_return);
164 18292323 : if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
165 393 : unwind_protect_int (interactive);
166 :
167 : #if defined (HISTORY)
168 18292323 : if (parse_and_execute_level == 0)
169 9149039 : add_unwind_protect (set_history_remembering, (char *)NULL);
170 : else
171 9143284 : unwind_protect_int (remember_on_history); /* can be used in scripts */
172 : # if defined (BANG_HISTORY)
173 18292323 : unwind_protect_int (history_expansion_inhibited);
174 : # endif /* BANG_HISTORY */
175 : #endif /* HISTORY */
176 :
177 18292323 : if (interactive_shell)
178 : {
179 0 : x = get_current_prompt_level ();
180 0 : add_unwind_protect (set_current_prompt_level, x);
181 : }
182 :
183 18292323 : if (the_printed_command_except_trap)
184 : {
185 9149048 : lastcom = savestring (the_printed_command_except_trap);
186 9149048 : add_unwind_protect (restore_lastcom, lastcom);
187 : }
188 :
189 18292323 : add_unwind_protect (pop_stream, (char *)NULL);
190 18292323 : if (parser_expanding_alias ())
191 0 : add_unwind_protect (parser_restore_alias, (char *)NULL);
192 :
193 18292323 : if (orig_string && ((flags & SEVAL_NOFREE) == 0))
194 18292090 : add_unwind_protect (xfree, orig_string);
195 18292323 : end_unwind_frame ();
196 :
197 18292323 : if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
198 393 : interactive = (flags & SEVAL_NONINT) ? 0 : 1;
199 :
200 : #if defined (HISTORY)
201 18292323 : if (flags & SEVAL_NOHIST)
202 18292323 : bash_history_disable ();
203 : # if defined (BANG_HISTORY)
204 18292323 : if (flags & SEVAL_NOHISTEXP)
205 0 : history_expansion_inhibited = 1;
206 : # endif /* BANG_HISTORY */
207 : #endif /* HISTORY */
208 18292323 : }
209 :
210 : /* Parse and execute the commands in STRING. Returns whatever
211 : execute_command () returns. This frees STRING. FLAGS is a
212 : flags word; look in common.h for the possible values. Actions
213 : are:
214 : (flags & SEVAL_NONINT) -> interactive = 0;
215 : (flags & SEVAL_INTERACT) -> interactive = 1;
216 : (flags & SEVAL_NOHIST) -> call bash_history_disable ()
217 : (flags & SEVAL_NOFREE) -> don't free STRING when finished
218 : (flags & SEVAL_RESETLINE) -> reset line_number to 1
219 : (flags & SEVAL_NOHISTEXP) -> history_expansion_inhibited -> 1
220 : */
221 :
222 : int
223 18292090 : parse_and_execute (string, from_file, flags)
224 : char *string;
225 : const char *from_file;
226 : int flags;
227 : {
228 18292090 : int code, lreset;
229 18292090 : volatile int should_jump_to_top_level, last_result;
230 18292090 : COMMAND *volatile command;
231 18292090 : volatile sigset_t pe_sigmask;
232 :
233 18292090 : parse_prologue (string, flags, PE_TAG);
234 :
235 18292090 : parse_and_execute_level++;
236 :
237 18292090 : lreset = flags & SEVAL_RESETLINE;
238 :
239 : #if defined (HAVE_POSIX_SIGNALS)
240 : /* If we longjmp and are going to go on, use this to restore signal mask */
241 18292090 : sigemptyset ((sigset_t *)&pe_sigmask);
242 18292090 : sigprocmask (SIG_BLOCK, (sigset_t *)NULL, (sigset_t *)&pe_sigmask);
243 : #endif
244 :
245 : /* Reset the line number if the caller wants us to. If we don't reset the
246 : line number, we have to subtract one, because we will add one just
247 : before executing the next command (resetting the line number sets it to
248 : 0; the first line number is 1). */
249 18292090 : push_stream (lreset);
250 18292090 : if (parser_expanding_alias ())
251 : /* push current shell_input_line */
252 0 : parser_save_alias ();
253 :
254 18292090 : if (lreset == 0)
255 5431 : line_number--;
256 :
257 18292090 : indirection_level++;
258 :
259 18292090 : code = should_jump_to_top_level = 0;
260 18292090 : last_result = EXECUTION_SUCCESS;
261 :
262 : /* We need to reset enough of the token state so we can start fresh. */
263 18292090 : if (current_token == yacc_EOF)
264 32 : current_token = '\n'; /* reset_parser() ? */
265 :
266 18292090 : with_input_from_string (string, from_file);
267 18292090 : clear_shell_input_line ();
268 118873693 : while (*(bash_input.location.string))
269 : {
270 100586108 : command = (COMMAND *)NULL;
271 :
272 100586108 : if (interrupt_state)
273 : {
274 0 : last_result = EXECUTION_FAILURE;
275 0 : break;
276 : }
277 :
278 : /* Provide a location for functions which `longjmp (top_level)' to
279 : jump to. This prevents errors in substitution from restarting
280 : the reader loop directly, for example. */
281 100586183 : code = setjmp_nosigs (top_level);
282 :
283 100586183 : if (code)
284 : {
285 75 : should_jump_to_top_level = 0;
286 75 : switch (code)
287 : {
288 0 : case ERREXIT:
289 : /* variable_context -> 0 is what eval.c:reader_loop() does in
290 : these circumstances. Don't bother with cleanup here because
291 : we don't want to run the function execution cleanup stuff
292 : that will cause pop_context and other functions to run.
293 : XXX - change that if we want the function context to be
294 : unwound. */
295 0 : if (exit_immediately_on_error && variable_context)
296 : {
297 0 : discard_unwind_frame ("pe_dispose");
298 0 : variable_context = 0; /* not in a function */
299 : }
300 0 : should_jump_to_top_level = 1;
301 0 : goto out;
302 75 : case FORCE_EOF:
303 : case EXITPROG:
304 75 : if (command)
305 75 : run_unwind_frame ("pe_dispose");
306 : /* Remember to call longjmp (top_level) after the old
307 : value for it is restored. */
308 75 : should_jump_to_top_level = 1;
309 75 : goto out;
310 :
311 0 : case DISCARD:
312 0 : if (command)
313 0 : run_unwind_frame ("pe_dispose");
314 0 : last_result = last_command_exit_value = EXECUTION_FAILURE; /* XXX */
315 0 : if (subshell_environment)
316 : {
317 0 : should_jump_to_top_level = 1;
318 0 : goto out;
319 : }
320 : else
321 : {
322 : #if 0
323 : dispose_command (command); /* pe_dispose does this */
324 : #endif
325 : #if defined (HAVE_POSIX_SIGNALS)
326 0 : sigprocmask (SIG_SETMASK, (sigset_t *)&pe_sigmask, (sigset_t *)NULL);
327 : #endif
328 0 : continue;
329 : }
330 :
331 0 : default:
332 0 : command_error ("parse_and_execute", CMDERR_BADJUMP, code, 0);
333 : break;
334 : }
335 100586108 : }
336 :
337 100586108 : if (parse_command () == 0)
338 : {
339 100583081 : if ((flags & SEVAL_PARSEONLY) || (interactive_shell == 0 && read_but_dont_execute))
340 : {
341 0 : last_result = EXECUTION_SUCCESS;
342 0 : dispose_command (global_command);
343 0 : global_command = (COMMAND *)NULL;
344 : }
345 100583081 : else if (command = global_command)
346 : {
347 18292090 : struct fd_bitmap *bitmap;
348 :
349 18292090 : if (flags & SEVAL_FUNCDEF)
350 : {
351 0 : char *x;
352 :
353 : /* If the command parses to something other than a straight
354 : function definition, or if we have not consumed the entire
355 : string, or if the parser has transformed the function
356 : name (as parsing will if it begins or ends with shell
357 : whitespace, for example), reject the attempt */
358 0 : if (command->type != cm_function_def ||
359 0 : ((x = parser_remaining_input ()) && *x) ||
360 0 : (STREQ (from_file, command->value.Function_def->name->word) == 0))
361 : {
362 0 : internal_warning (_("%s: ignoring function definition attempt"), from_file);
363 0 : should_jump_to_top_level = 0;
364 0 : last_result = last_command_exit_value = EX_BADUSAGE;
365 0 : reset_parser ();
366 : break;
367 : }
368 : }
369 :
370 18292090 : bitmap = new_fd_bitmap (FD_BITMAP_SIZE);
371 18292090 : begin_unwind_frame ("pe_dispose");
372 18292090 : add_unwind_protect (dispose_fd_bitmap, bitmap);
373 18292090 : add_unwind_protect (dispose_command, command); /* XXX */
374 :
375 18292090 : global_command = (COMMAND *)NULL;
376 :
377 18292090 : if ((subshell_environment & SUBSHELL_COMSUB) && comsub_ignore_return)
378 78 : command->flags |= CMD_IGNORE_RETURN;
379 :
380 : #if defined (ONESHOT)
381 : /*
382 : * IF
383 : * we were invoked as `bash -c' (startup_state == 2) AND
384 : * parse_and_execute has not been called recursively AND
385 : * we're not running a trap AND
386 : * we have parsed the full command (string == '\0') AND
387 : * we're not going to run the exit trap AND
388 : * we have a simple command without redirections AND
389 : * the command is not being timed AND
390 : * the command's return status is not being inverted AND
391 : * there aren't any traps in effect
392 : * THEN
393 : * tell the execution code that we don't need to fork
394 : */
395 18292090 : if (should_suppress_fork (command))
396 : {
397 1439 : command->flags |= CMD_NO_FORK;
398 1439 : command->value.Simple->flags |= CMD_NO_FORK;
399 : }
400 18290651 : else if (command->type == cm_connection)
401 948 : optimize_fork (command);
402 : #endif /* ONESHOT */
403 :
404 : /* See if this is a candidate for $( <file ). */
405 18292090 : if (startup_state == 2 &&
406 4796 : (subshell_environment & SUBSHELL_COMSUB) &&
407 4796 : *bash_input.location.string == '\0' &&
408 2163 : command->type == cm_simple && !command->redirects &&
409 1698 : (command->flags & CMD_TIME_PIPELINE) == 0 &&
410 1698 : command->value.Simple->words == 0 &&
411 0 : command->value.Simple->redirects &&
412 0 : command->value.Simple->redirects->next == 0 &&
413 0 : command->value.Simple->redirects->instruction == r_input_direction &&
414 0 : command->value.Simple->redirects->redirector.dest == 0)
415 0 : {
416 0 : int r;
417 0 : r = cat_file (command->value.Simple->redirects);
418 0 : last_result = (r < 0) ? EXECUTION_FAILURE : EXECUTION_SUCCESS;
419 : }
420 : else
421 18292090 : last_result = execute_command_internal
422 : (command, 0, NO_PIPE, NO_PIPE, bitmap);
423 18290612 : dispose_command (command);
424 18290612 : dispose_fd_bitmap (bitmap);
425 18290612 : discard_unwind_frame ("pe_dispose");
426 :
427 18290612 : if (flags & SEVAL_ONECMD)
428 : {
429 0 : reset_parser ();
430 : break;
431 : }
432 : }
433 : }
434 : else
435 : {
436 3027 : last_result = EXECUTION_FAILURE;
437 :
438 3027 : if (interactive_shell == 0 && this_shell_builtin &&
439 1484 : (this_shell_builtin == source_builtin || this_shell_builtin == eval_builtin) &&
440 46 : last_command_exit_value == EX_BADSYNTAX && posixly_correct)
441 : {
442 0 : should_jump_to_top_level = 1;
443 0 : code = ERREXIT;
444 0 : last_command_exit_value = EX_BADUSAGE;
445 : }
446 :
447 : /* Since we are shell compatible, syntax errors in a script
448 : abort the execution of the script. Right? */
449 : break;
450 : }
451 : }
452 :
453 18287585 : out:
454 :
455 18290687 : run_unwind_frame (PE_TAG);
456 :
457 18290687 : if (interrupt_state && parse_and_execute_level == 0)
458 : {
459 : /* An interrupt during non-interactive execution in an
460 : interactive shell (e.g. via $PROMPT_COMMAND) should
461 : not cause the shell to exit. */
462 0 : interactive = interactive_shell;
463 0 : throw_to_top_level ();
464 : }
465 :
466 18290687 : if (should_jump_to_top_level)
467 75 : jump_to_top_level (code);
468 :
469 18290612 : return (last_result);
470 : }
471 :
472 : /* Parse a command contained in STRING according to FLAGS and return the
473 : number of characters consumed from the string. If non-NULL, set *ENDP
474 : to the position in the string where the parse ended. Used to validate
475 : command substitutions during parsing to obey Posix rules about finding
476 : the end of the command and balancing parens. */
477 : int
478 233 : parse_string (string, from_file, flags, endp)
479 : char *string;
480 : const char *from_file;
481 : int flags;
482 : char **endp;
483 : {
484 233 : int code, nc;
485 233 : volatile int should_jump_to_top_level;
486 233 : COMMAND *volatile command, *oglobal;
487 233 : char *ostring;
488 233 : volatile sigset_t ps_sigmask;
489 :
490 233 : parse_prologue (string, flags, PS_TAG);
491 :
492 : #if defined (HAVE_POSIX_SIGNALS)
493 : /* If we longjmp and are going to go on, use this to restore signal mask */
494 233 : sigemptyset ((sigset_t *)&ps_sigmask);
495 233 : sigprocmask (SIG_BLOCK, (sigset_t *)NULL, (sigset_t *)&ps_sigmask);
496 : #endif
497 :
498 : /*itrace("parse_string: `%s'", string);*/
499 : /* Reset the line number if the caller wants us to. If we don't reset the
500 : line number, we have to subtract one, because we will add one just
501 : before executing the next command (resetting the line number sets it to
502 : 0; the first line number is 1). */
503 233 : push_stream (0);
504 233 : if (parser_expanding_alias ())
505 : /* push current shell_input_line */
506 0 : parser_save_alias ();
507 :
508 233 : code = should_jump_to_top_level = 0;
509 233 : oglobal = global_command;
510 233 : ostring = string;
511 :
512 233 : with_input_from_string (string, from_file);
513 359 : while (*(bash_input.location.string))
514 : {
515 359 : command = (COMMAND *)NULL;
516 :
517 : #if 0
518 : if (interrupt_state)
519 : break;
520 : #endif
521 :
522 : /* Provide a location for functions which `longjmp (top_level)' to
523 : jump to. */
524 359 : code = setjmp_nosigs (top_level);
525 :
526 359 : if (code)
527 : {
528 : #if defined (DEBUG)
529 : itrace("parse_string: longjmp executed: code = %d", code);
530 : #endif
531 0 : should_jump_to_top_level = 0;
532 0 : switch (code)
533 : {
534 0 : case FORCE_EOF:
535 : case ERREXIT:
536 : case EXITPROG:
537 : case DISCARD: /* XXX */
538 0 : if (command)
539 0 : dispose_command (command);
540 : /* Remember to call longjmp (top_level) after the old
541 : value for it is restored. */
542 0 : should_jump_to_top_level = 1;
543 0 : goto out;
544 :
545 0 : default:
546 : #if defined (HAVE_POSIX_SIGNALS)
547 0 : sigprocmask (SIG_SETMASK, (sigset_t *)&ps_sigmask, (sigset_t *)NULL);
548 : #endif
549 0 : command_error ("parse_string", CMDERR_BADJUMP, code, 0);
550 : break;
551 : }
552 359 : }
553 :
554 359 : if (parse_command () == 0)
555 : {
556 350 : dispose_command (global_command);
557 350 : global_command = (COMMAND *)NULL;
558 : }
559 : else
560 : {
561 9 : if ((flags & SEVAL_NOLONGJMP) == 0)
562 : {
563 9 : should_jump_to_top_level = 1;
564 9 : code = DISCARD;
565 : }
566 : else
567 0 : reset_parser (); /* XXX - sets token_to_read */
568 : break;
569 : }
570 :
571 350 : if (current_token == yacc_EOF || current_token == shell_eof_token)
572 : break;
573 : }
574 :
575 224 : out:
576 :
577 233 : global_command = oglobal;
578 233 : nc = bash_input.location.string - ostring;
579 233 : if (endp)
580 233 : *endp = bash_input.location.string;
581 :
582 233 : run_unwind_frame (PS_TAG);
583 :
584 : /* If we return < 0, the caller (xparse_dolparen) will jump_to_top_level for
585 : us, after doing cleanup */
586 233 : if (should_jump_to_top_level)
587 : {
588 9 : if (parse_and_execute_level == 0)
589 9 : top_level_cleanup ();
590 9 : if (code == DISCARD)
591 : return -DISCARD;
592 0 : jump_to_top_level (code);
593 : }
594 :
595 : return (nc);
596 : }
597 :
598 : /* Handle a $( < file ) command substitution. This expands the filename,
599 : returning errors as appropriate, then just cats the file to the standard
600 : output. */
601 : static int
602 0 : cat_file (r)
603 : REDIRECT *r;
604 : {
605 0 : char *fn;
606 0 : int fd, rval;
607 :
608 0 : if (r->instruction != r_input_direction)
609 : return -1;
610 :
611 : /* Get the filename. */
612 0 : if (posixly_correct && !interactive_shell)
613 0 : disallow_filename_globbing++;
614 0 : fn = redirection_expand (r->redirectee.filename);
615 0 : if (posixly_correct && !interactive_shell)
616 0 : disallow_filename_globbing--;
617 :
618 0 : if (fn == 0)
619 : {
620 0 : redirection_error (r, AMBIGUOUS_REDIRECT);
621 0 : return -1;
622 : }
623 :
624 0 : fd = open(fn, O_RDONLY);
625 0 : if (fd < 0)
626 : {
627 0 : file_error (fn);
628 0 : free (fn);
629 0 : return -1;
630 : }
631 :
632 0 : rval = zcatfd (fd, 1, fn);
633 :
634 0 : free (fn);
635 0 : close (fd);
636 :
637 0 : return (rval);
638 : }
639 :
640 : int
641 61 : evalstring (string, from_file, flags)
642 : char *string;
643 : const char *from_file;
644 : int flags;
645 : {
646 61 : volatile int r, rflag, rcatch;
647 :
648 61 : rcatch = 0;
649 61 : rflag = return_catch_flag;
650 : /* If we are in a place where `return' is valid, we have to catch
651 : `eval "... return"' and make sure parse_and_execute cleans up. Then
652 : we can trampoline to the previous saved return_catch location. */
653 61 : if (rflag)
654 : {
655 0 : begin_unwind_frame ("evalstring");
656 :
657 0 : unwind_protect_int (return_catch_flag);
658 0 : unwind_protect_jmp_buf (return_catch);
659 :
660 0 : return_catch_flag++; /* increment so we have a counter */
661 0 : rcatch = setjmp_nosigs (return_catch);
662 : }
663 :
664 61 : if (rcatch)
665 : {
666 0 : parse_and_execute_cleanup ();
667 0 : r = return_catch_value;
668 : }
669 : else
670 : /* Note that parse_and_execute () frees the string it is passed. */
671 61 : r = parse_and_execute (string, from_file, flags);
672 :
673 60 : if (rflag)
674 : {
675 0 : run_unwind_frame ("evalstring");
676 0 : if (rcatch && return_catch_flag)
677 : {
678 0 : return_catch_value = r;
679 0 : sh_longjmp (return_catch, 1);
680 : }
681 : }
682 :
683 60 : return (r);
684 : }
|