source: vendor/bash/3.1-p17/builtins/evalstring.c

Last change on this file was 3231, checked in by bird, 18 years ago

eol style.

  • Property svn:eol-style set to native
File size: 9.3 KB
Line 
1/* Evaluate a string as one or more shell commands.
2
3 Copyright (C) 1996-2005 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 it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License along
18 with Bash; see the file COPYING. If not, write to the Free Software
19 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
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
47#if defined (HISTORY)
48# include "../bashhist.h"
49#endif
50
51#include "common.h"
52
53#if !defined (errno)
54extern int errno;
55#endif
56
57#define IS_BUILTIN(s) (builtin_address_internal(s, 0) != (struct builtin *)NULL)
58
59extern int indirection_level, startup_state, subshell_environment;
60extern int line_number;
61extern int last_command_exit_value;
62extern int running_trap;
63extern int loop_level;
64extern int posixly_correct;
65
66int parse_and_execute_level = 0;
67
68static int cat_file __P((REDIRECT *));
69
70/* How to force parse_and_execute () to clean up after itself. */
71void
72parse_and_execute_cleanup ()
73{
74 if (running_trap)
75 {
76 run_trap_cleanup (running_trap - 1);
77 unfreeze_jobs_list ();
78 }
79 run_unwind_frame ("parse_and_execute_top");
80}
81
82/* Parse and execute the commands in STRING. Returns whatever
83 execute_command () returns. This frees STRING. FLAGS is a
84 flags word; look in common.h for the possible values. Actions
85 are:
86 (flags & SEVAL_NONINT) -> interactive = 0;
87 (flags & SEVAL_INTERACT) -> interactive = 1;
88 (flags & SEVAL_NOHIST) -> call bash_history_disable ()
89 (flags & SEVAL_NOFREE) -> don't free STRING when finished
90 (flags & SEVAL_RESETLINE) -> reset line_number to 1
91*/
92
93int
94parse_and_execute (string, from_file, flags)
95 char *string;
96 const char *from_file;
97 int flags;
98{
99 int code, x, lreset;
100 volatile int should_jump_to_top_level, last_result;
101 char *orig_string;
102 COMMAND *volatile command;
103
104 orig_string = string;
105 /* Unwind protect this invocation of parse_and_execute (). */
106 begin_unwind_frame ("parse_and_execute_top");
107 unwind_protect_int (parse_and_execute_level);
108 unwind_protect_jmp_buf (top_level);
109 unwind_protect_int (indirection_level);
110 unwind_protect_int (line_number);
111 unwind_protect_int (loop_level);
112 if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
113 unwind_protect_int (interactive);
114
115 lreset = flags & SEVAL_RESETLINE;
116
117#if defined (HISTORY)
118 unwind_protect_int (remember_on_history); /* can be used in scripts */
119# if defined (BANG_HISTORY)
120 if (interactive_shell)
121 {
122 unwind_protect_int (history_expansion_inhibited);
123 }
124# endif /* BANG_HISTORY */
125#endif /* HISTORY */
126
127 if (interactive_shell)
128 {
129 x = get_current_prompt_level ();
130 add_unwind_protect (set_current_prompt_level, x);
131 }
132
133 add_unwind_protect (pop_stream, (char *)NULL);
134 if (orig_string && ((flags & SEVAL_NOFREE) == 0))
135 add_unwind_protect (xfree, orig_string);
136 end_unwind_frame ();
137
138 parse_and_execute_level++;
139
140 /* Reset the line number if the caller wants us to. If we don't reset the
141 line number, we have to subtract one, because we will add one just
142 before executing the next command (resetting the line number sets it to
143 0; the first line number is 1). */
144 push_stream (lreset);
145 if (lreset == 0)
146 line_number--;
147
148 indirection_level++;
149 if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
150 interactive = (flags & SEVAL_NONINT) ? 0 : 1;
151
152#if defined (HISTORY)
153 if (flags & SEVAL_NOHIST)
154 bash_history_disable ();
155#endif /* HISTORY */
156
157 code = should_jump_to_top_level = 0;
158 last_result = EXECUTION_SUCCESS;
159
160 with_input_from_string (string, from_file);
161 while (*(bash_input.location.string))
162 {
163 command = (COMMAND *)NULL;
164
165 if (interrupt_state)
166 {
167 last_result = EXECUTION_FAILURE;
168 break;
169 }
170
171 /* Provide a location for functions which `longjmp (top_level)' to
172 jump to. This prevents errors in substitution from restarting
173 the reader loop directly, for example. */
174 code = setjmp (top_level);
175
176 if (code)
177 {
178 should_jump_to_top_level = 0;
179 switch (code)
180 {
181 case FORCE_EOF:
182 case ERREXIT:
183 case EXITPROG:
184 if (command)
185 run_unwind_frame ("pe_dispose");
186 /* Remember to call longjmp (top_level) after the old
187 value for it is restored. */
188 should_jump_to_top_level = 1;
189 goto out;
190
191 case DISCARD:
192 if (command)
193 run_unwind_frame ("pe_dispose");
194 last_result = last_command_exit_value = EXECUTION_FAILURE; /* XXX */
195 if (subshell_environment)
196 {
197 should_jump_to_top_level = 1;
198 goto out;
199 }
200 else
201 {
202#if 0
203 dispose_command (command); /* pe_dispose does this */
204#endif
205 continue;
206 }
207
208 default:
209 command_error ("parse_and_execute", CMDERR_BADJUMP, code, 0);
210 break;
211 }
212 }
213
214 if (parse_command () == 0)
215 {
216 if (interactive_shell == 0 && read_but_dont_execute)
217 {
218 last_result = EXECUTION_SUCCESS;
219 dispose_command (global_command);
220 global_command = (COMMAND *)NULL;
221 }
222 else if (command = global_command)
223 {
224 struct fd_bitmap *bitmap;
225
226 bitmap = new_fd_bitmap (FD_BITMAP_SIZE);
227 begin_unwind_frame ("pe_dispose");
228 add_unwind_protect (dispose_fd_bitmap, bitmap);
229 add_unwind_protect (dispose_command, command); /* XXX */
230
231 global_command = (COMMAND *)NULL;
232
233#if defined (ONESHOT)
234 /*
235 * IF
236 * we were invoked as `bash -c' (startup_state == 2) AND
237 * parse_and_execute has not been called recursively AND
238 * we're not running a trap AND
239 * we have parsed the full command (string == '\0') AND
240 * we have a simple command without redirections AND
241 * the command is not being timed AND
242 * the command's return status is not being inverted
243 * THEN
244 * tell the execution code that we don't need to fork
245 */
246 if (startup_state == 2 && parse_and_execute_level == 1 &&
247 running_trap == 0 &&
248 *bash_input.location.string == '\0' &&
249 command->type == cm_simple &&
250 !command->redirects && !command->value.Simple->redirects &&
251 ((command->flags & CMD_TIME_PIPELINE) == 0) &&
252 ((command->flags & CMD_INVERT_RETURN) == 0))
253 {
254 command->flags |= CMD_NO_FORK;
255 command->value.Simple->flags |= CMD_NO_FORK;
256 }
257#endif /* ONESHOT */
258
259 /* See if this is a candidate for $( <file ). */
260 if (startup_state == 2 &&
261 (subshell_environment & SUBSHELL_COMSUB) &&
262 *bash_input.location.string == '\0' &&
263 command->type == cm_simple && !command->redirects &&
264 (command->flags & CMD_TIME_PIPELINE) == 0 &&
265 command->value.Simple->words == 0 &&
266 command->value.Simple->redirects &&
267 command->value.Simple->redirects->next == 0 &&
268 command->value.Simple->redirects->instruction == r_input_direction)
269 {
270 int r;
271 r = cat_file (command->value.Simple->redirects);
272 last_result = (r < 0) ? EXECUTION_FAILURE : EXECUTION_SUCCESS;
273 }
274 else
275 last_result = execute_command_internal
276 (command, 0, NO_PIPE, NO_PIPE, bitmap);
277
278 dispose_command (command);
279 dispose_fd_bitmap (bitmap);
280 discard_unwind_frame ("pe_dispose");
281 }
282 }
283 else
284 {
285 last_result = EXECUTION_FAILURE;
286
287 /* Since we are shell compatible, syntax errors in a script
288 abort the execution of the script. Right? */
289 break;
290 }
291 }
292
293 out:
294
295 run_unwind_frame ("parse_and_execute_top");
296
297 if (interrupt_state && parse_and_execute_level == 0)
298 {
299 /* An interrupt during non-interactive execution in an
300 interactive shell (e.g. via $PROMPT_COMMAND) should
301 not cause the shell to exit. */
302 interactive = interactive_shell;
303 throw_to_top_level ();
304 }
305
306 if (should_jump_to_top_level)
307 jump_to_top_level (code);
308
309 return (last_result);
310}
311
312/* Handle a $( < file ) command substitution. This expands the filename,
313 returning errors as appropriate, then just cats the file to the standard
314 output. */
315static int
316cat_file (r)
317 REDIRECT *r;
318{
319 char lbuf[128], *fn;
320 int fd, rval;
321 ssize_t nr;
322
323 if (r->instruction != r_input_direction)
324 return -1;
325
326 /* Get the filename. */
327 if (posixly_correct && !interactive_shell)
328 disallow_filename_globbing++;
329 fn = redirection_expand (r->redirectee.filename);
330 if (posixly_correct && !interactive_shell)
331 disallow_filename_globbing--;
332
333 if (fn == 0)
334 {
335 redirection_error (r, AMBIGUOUS_REDIRECT);
336 return -1;
337 }
338
339 fd = open(fn, O_RDONLY);
340 if (fd < 0)
341 {
342 file_error (fn);
343 free (fn);
344 return -1;
345 }
346
347 rval = zcatfd (fd, 1, fn);
348
349 free (fn);
350 close (fd);
351
352 return (rval);
353}
Note: See TracBrowser for help on using the repository browser.