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