]> git.ipfire.org Git - thirdparty/bash.git/blob - builtins/evalstring.c
Imported from ../bash-2.01.1.tar.gz.
[thirdparty/bash.git] / builtins / evalstring.c
1 /* Copyright (C) 1996 Free Software Foundation, Inc.
2
3 This file is part of GNU Bash, the Bourne Again SHell.
4
5 Bash is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 1, or (at your option) any later
8 version.
9
10 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with Bash; see the file COPYING. If not, write to the Free Software
17 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
18
19 #include <config.h>
20
21 #if defined (HAVE_UNISTD_H)
22 # include <unistd.h>
23 #endif
24
25 #include <stdio.h>
26 #include <signal.h>
27
28 #include "../bashansi.h"
29
30 #include "../shell.h"
31 #include "../jobs.h"
32 #include "../builtins.h"
33 #include "../flags.h"
34 #include "../input.h"
35 #include "../execute_cmd.h"
36
37 #if defined (HISTORY)
38 # include "../bashhist.h"
39 #endif
40
41 #include "common.h"
42
43 extern void run_trap_cleanup ();
44
45 extern int interactive, interactive_shell;
46 extern int indirection_level, startup_state, subshell_environment;
47 extern int line_number;
48 extern int last_command_exit_value;
49 extern int running_trap;
50 extern COMMAND *global_command;
51
52 int parse_and_execute_level = 0;
53
54 /* How to force parse_and_execute () to clean up after itself. */
55 void
56 parse_and_execute_cleanup ()
57 {
58 if (running_trap)
59 {
60 run_trap_cleanup (running_trap - 1);
61 unfreeze_jobs_list ();
62 }
63 run_unwind_frame ("parse_and_execute_top");
64 }
65
66 /* Parse and execute the commands in STRING. Returns whatever
67 execute_command () returns. This frees STRING. FLAGS is a
68 flags word; look in common.h for the possible values. Actions
69 are:
70 (flags & SEVAL_NONINT) -> interactive = 0;
71 (flags & SEVAL_INTERACT) -> interactive = 1;
72 (flags & SEVAL_NOHIST) -> call bash_history_disable ()
73 */
74
75 int
76 parse_and_execute (string, from_file, flags)
77 char *string;
78 char *from_file;
79 int flags;
80 {
81 int code;
82 volatile int should_jump_to_top_level, last_result;
83 char *orig_string;
84 COMMAND *volatile command;
85
86 orig_string = string;
87 /* Unwind protect this invocation of parse_and_execute (). */
88 begin_unwind_frame ("parse_and_execute_top");
89 unwind_protect_int (parse_and_execute_level);
90 unwind_protect_jmp_buf (top_level);
91 unwind_protect_int (indirection_level);
92 unwind_protect_int (line_number);
93 if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
94 unwind_protect_int (interactive);
95
96 #if defined (HISTORY)
97 unwind_protect_int (remember_on_history); /* can be used in scripts */
98 # if defined (BANG_HISTORY)
99 if (interactive_shell)
100 {
101 unwind_protect_int (history_expansion_inhibited);
102 }
103 # endif /* BANG_HISTORY */
104 #endif /* HISTORY */
105
106 add_unwind_protect (pop_stream, (char *)NULL);
107 if (orig_string)
108 add_unwind_protect (xfree, orig_string);
109 end_unwind_frame ();
110
111 parse_and_execute_level++;
112 push_stream (1); /* reset the line number */
113 indirection_level++;
114 if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
115 interactive = (flags & SEVAL_NONINT) ? 0 : 1;
116
117 #if defined (HISTORY)
118 if (flags & SEVAL_NOHIST)
119 bash_history_disable ();
120 #endif /* HISTORY */
121
122 code = should_jump_to_top_level = 0;
123 last_result = EXECUTION_SUCCESS;
124 command = (COMMAND *)NULL;
125
126 with_input_from_string (string, from_file);
127 while (*(bash_input.location.string))
128 {
129 if (interrupt_state)
130 {
131 last_result = EXECUTION_FAILURE;
132 break;
133 }
134
135 /* Provide a location for functions which `longjmp (top_level)' to
136 jump to. This prevents errors in substitution from restarting
137 the reader loop directly, for example. */
138 code = setjmp (top_level);
139
140 if (code)
141 {
142 should_jump_to_top_level = 0;
143 switch (code)
144 {
145 case FORCE_EOF:
146 case EXITPROG:
147 run_unwind_frame ("pe_dispose");
148 /* Remember to call longjmp (top_level) after the old
149 value for it is restored. */
150 should_jump_to_top_level = 1;
151 goto out;
152
153 case DISCARD:
154 run_unwind_frame ("pe_dispose");
155 last_command_exit_value = 1; /* XXX */
156 if (subshell_environment)
157 {
158 should_jump_to_top_level = 1;
159 goto out;
160 }
161 else
162 {
163 #if 0
164 dispose_command (command); /* pe_dispose does this */
165 #endif
166 continue;
167 }
168
169 default:
170 programming_error ("parse_and_execute: bad jump: code %d", code);
171 break;
172 }
173 }
174
175 if (parse_command () == 0)
176 {
177 if (interactive_shell == 0 && read_but_dont_execute)
178 {
179 last_result = EXECUTION_SUCCESS;
180 dispose_command (global_command);
181 global_command = (COMMAND *)NULL;
182 }
183 else if (command = global_command)
184 {
185 struct fd_bitmap *bitmap;
186
187 bitmap = new_fd_bitmap (FD_BITMAP_SIZE);
188 begin_unwind_frame ("pe_dispose");
189 add_unwind_protect (dispose_fd_bitmap, bitmap);
190 add_unwind_protect (dispose_command, command); /* XXX */
191
192 global_command = (COMMAND *)NULL;
193
194 #if defined (ONESHOT)
195 if (startup_state == 2 && *bash_input.location.string == '\0' &&
196 command->type == cm_simple && !command->redirects &&
197 !command->value.Simple->redirects &&
198 ((command->flags & CMD_TIME_PIPELINE) == 0))
199 {
200 command->flags |= CMD_NO_FORK;
201 command->value.Simple->flags |= CMD_NO_FORK;
202 }
203 #endif /* ONESHOT */
204
205 last_result = execute_command_internal
206 (command, 0, NO_PIPE, NO_PIPE, bitmap);
207
208 dispose_command (command);
209 dispose_fd_bitmap (bitmap);
210 discard_unwind_frame ("pe_dispose");
211 }
212 }
213 else
214 {
215 last_result = EXECUTION_FAILURE;
216
217 /* Since we are shell compatible, syntax errors in a script
218 abort the execution of the script. Right? */
219 break;
220 }
221 }
222
223 out:
224
225 run_unwind_frame ("parse_and_execute_top");
226
227 if (interrupt_state && parse_and_execute_level == 0)
228 {
229 /* An interrupt during non-interactive execution in an
230 interactive shell (e.g. via $PROMPT_COMMAND) should
231 not cause the shell to exit. */
232 interactive = interactive_shell;
233 throw_to_top_level ();
234 }
235
236 if (should_jump_to_top_level)
237 jump_to_top_level (code);
238
239 return (last_result);
240 }