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