]> git.ipfire.org Git - thirdparty/bash.git/blame - eval.c
fix for SIGINT in sourced script
[thirdparty/bash.git] / eval.c
CommitLineData
bb70624e 1/* eval.c -- reading and evaluating commands. */
ccc6cda3 2
ac50fbac 3/* Copyright (C) 1996-2011 Free Software Foundation, Inc.
ccc6cda3 4
bb70624e 5 This file is part of GNU Bash, the Bourne Again SHell.
ccc6cda3 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.
ccc6cda3 16
bb70624e 17 You should have received a copy of the GNU General Public License
3185942a
JA
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 "bashansi.h"
31#include <stdio.h>
32
a0c0a00f
CR
33#include <signal.h>
34
b80f6443
JA
35#include "bashintl.h"
36
ccc6cda3
JA
37#include "shell.h"
38#include "flags.h"
39#include "trap.h"
40
41#include "builtins/common.h"
42
43#include "input.h"
44#include "execute_cmd.h"
45
b72432fd
JA
46#if defined (HISTORY)
47# include "bashhist.h"
48#endif
49
ccc6cda3 50extern int EOF_reached;
f73dda09 51extern int indirection_level;
bb70624e 52extern int posixly_correct;
ccc6cda3 53extern int subshell_environment, running_under_emacs;
d166f048 54extern int last_command_exit_value, stdin_redir;
ccc6cda3
JA
55extern int need_here_doc;
56extern int current_command_number, current_command_line_count, line_number;
ccc6cda3 57extern int expand_aliases;
a0c0a00f 58extern char *ps0_prompt;
ccc6cda3 59
ac50fbac
CR
60#if defined (HAVE_POSIX_SIGNALS)
61extern sigset_t top_level_mask;
62#endif
63
7117c2d2
JA
64static void send_pwd_to_eterm __P((void));
65static sighandler alrm_catcher __P((int));
66
ccc6cda3
JA
67/* Read and execute commands until EOF is reached. This assumes that
68 the input source has already been initialized. */
69int
70reader_loop ()
71{
72 int our_indirection_level;
95732b49 73 COMMAND * volatile current_command;
ccc6cda3 74
f73dda09
JA
75 USE_VAR(current_command);
76
3185942a
JA
77 current_command = (COMMAND *)NULL;
78
ccc6cda3
JA
79 our_indirection_level = ++indirection_level;
80
81 while (EOF_Reached == 0)
82 {
83 int code;
84
ac50fbac 85 code = setjmp_nosigs (top_level);
ccc6cda3
JA
86
87#if defined (PROCESS_SUBSTITUTION)
88 unlink_fifo_list ();
89#endif /* PROCESS_SUBSTITUTION */
90
a0c0a00f
CR
91 /* XXX - why do we set this every time through the loop? And why do
92 it if SIGINT is trapped in an interactive shell? */
ccc6cda3
JA
93 if (interactive_shell && signal_is_ignored (SIGINT) == 0)
94 set_signal_handler (SIGINT, sigint_sighandler);
95
96 if (code != NOT_JUMPED)
97 {
98 indirection_level = our_indirection_level;
99
100 switch (code)
101 {
ac50fbac 102 /* Some kind of throw to top_level has occurred. */
ccc6cda3 103 case FORCE_EOF:
b80f6443 104 case ERREXIT:
ccc6cda3
JA
105 case EXITPROG:
106 current_command = (COMMAND *)NULL;
bb70624e
JA
107 if (exit_immediately_on_error)
108 variable_context = 0; /* not in a function */
ccc6cda3
JA
109 EOF_Reached = EOF;
110 goto exec_done;
111
112 case DISCARD:
3185942a
JA
113 /* Make sure the exit status is reset to a non-zero value, but
114 leave existing non-zero values (e.g., > 128 on signal)
115 alone. */
116 if (last_command_exit_value == 0)
117 last_command_exit_value = EXECUTION_FAILURE;
ccc6cda3
JA
118 if (subshell_environment)
119 {
120 current_command = (COMMAND *)NULL;
121 EOF_Reached = EOF;
122 goto exec_done;
123 }
124 /* Obstack free command elements, etc. */
125 if (current_command)
126 {
127 dispose_command (current_command);
128 current_command = (COMMAND *)NULL;
129 }
ac50fbac
CR
130#if defined (HAVE_POSIX_SIGNALS)
131 sigprocmask (SIG_SETMASK, &top_level_mask, (sigset_t *)NULL);
132#endif
ccc6cda3
JA
133 break;
134
135 default:
b72432fd 136 command_error ("reader_loop", CMDERR_BADJUMP, code, 0);
ccc6cda3
JA
137 }
138 }
139
140 executing = 0;
7117c2d2
JA
141 if (temporary_env)
142 dispose_used_env_vars ();
ccc6cda3
JA
143
144#if (defined (ultrix) && defined (mips)) || defined (C_ALLOCA)
145 /* Attempt to reclaim memory allocated with alloca (). */
146 (void) alloca (0);
147#endif
148
149 if (read_command () == 0)
150 {
151 if (interactive_shell == 0 && read_but_dont_execute)
152 {
153 last_command_exit_value = EXECUTION_SUCCESS;
154 dispose_command (global_command);
155 global_command = (COMMAND *)NULL;
156 }
157 else if (current_command = global_command)
158 {
159 global_command = (COMMAND *)NULL;
160 current_command_number++;
161
162 executing = 1;
d166f048 163 stdin_redir = 0;
a0c0a00f
CR
164
165 /* If the shell is interactive, expand and display $PS0 after reading a
166 command (possibly a list or pipeline) and before executing it. */
167 if (interactive && ps0_prompt)
168 {
169 char *ps0_string;
170
171 ps0_string = decode_prompt_string (ps0_prompt);
172 if (ps0_string && *ps0_string)
173 {
174 fprintf (stderr, "%s", ps0_string);
175 fflush (stderr);
176 }
177 free (ps0_string);
178 }
179
ccc6cda3
JA
180 execute_command (current_command);
181
182 exec_done:
95732b49
JA
183 QUIT;
184
ccc6cda3 185 if (current_command)
28ef6c31 186 {
ccc6cda3
JA
187 dispose_command (current_command);
188 current_command = (COMMAND *)NULL;
28ef6c31 189 }
ccc6cda3
JA
190 }
191 }
192 else
193 {
194 /* Parse error, maybe discard rest of stream if not interactive. */
195 if (interactive == 0)
196 EOF_Reached = EOF;
197 }
198 if (just_one_command)
199 EOF_Reached = EOF;
200 }
201 indirection_level--;
202 return (last_command_exit_value);
203}
204
205static sighandler
206alrm_catcher(i)
207 int i;
208{
b80f6443 209 printf (_("\007timed out waiting for input: auto-logout\n"));
3185942a 210 fflush (stdout);
b80f6443 211 bash_logout (); /* run ~/.bash_logout if this is a login shell */
ccc6cda3
JA
212 jump_to_top_level (EXITPROG);
213 SIGRETURN (0);
214}
215
216/* Send an escape sequence to emacs term mode to tell it the
217 current working directory. */
218static void
219send_pwd_to_eterm ()
220{
ac50fbac 221 char *pwd, *f;
ccc6cda3 222
ac50fbac 223 f = 0;
ccc6cda3
JA
224 pwd = get_string_value ("PWD");
225 if (pwd == 0)
ac50fbac 226 f = pwd = get_working_directory ("eterm");
ccc6cda3 227 fprintf (stderr, "\032/%s\n", pwd);
ac50fbac 228 free (f);
ccc6cda3
JA
229}
230
231/* Call the YACC-generated parser and return the status of the parse.
232 Input is read from the current input stream (bash_input). yyparse
233 leaves the parsed command in the global variable GLOBAL_COMMAND.
234 This is where PROMPT_COMMAND is executed. */
235int
236parse_command ()
237{
238 int r;
239 char *command_to_execute;
240
241 need_here_doc = 0;
242 run_pending_traps ();
243
244 /* Allow the execution of a random command just before the printing
245 of each primary prompt. If the shell variable PROMPT_COMMAND
246 is set then the value of it is the command to execute. */
a0c0a00f
CR
247 /* The tests are a combination of SHOULD_PROMPT() and prompt_again()
248 from parse.y, which are the conditions under which the prompt is
249 actually printed. */
250 if (interactive && bash_input.type != st_string && parser_expanding_alias() == 0)
ccc6cda3
JA
251 {
252 command_to_execute = get_string_value ("PROMPT_COMMAND");
253 if (command_to_execute)
0628567a 254 execute_variable_command (command_to_execute, "PROMPT_COMMAND");
ccc6cda3
JA
255
256 if (running_under_emacs == 2)
257 send_pwd_to_eterm (); /* Yuck */
258 }
259
260 current_command_line_count = 0;
261 r = yyparse ();
262
263 if (need_here_doc)
264 gather_here_documents ();
265
266 return (r);
267}
268
269/* Read and parse a command, returning the status of the parse. The command
270 is left in the globval variable GLOBAL_COMMAND for use by reader_loop.
271 This is where the shell timeout code is executed. */
272int
273read_command ()
274{
275 SHELL_VAR *tmout_var;
276 int tmout_len, result;
277 SigHandler *old_alrm;
278
bb70624e 279 set_current_prompt_level (1);
ccc6cda3
JA
280 global_command = (COMMAND *)NULL;
281
282 /* Only do timeouts if interactive. */
283 tmout_var = (SHELL_VAR *)NULL;
284 tmout_len = 0;
f73dda09 285 old_alrm = (SigHandler *)NULL;
ccc6cda3
JA
286
287 if (interactive)
288 {
289 tmout_var = find_variable ("TMOUT");
ccc6cda3 290
7117c2d2 291 if (tmout_var && var_isset (tmout_var))
ccc6cda3 292 {
7117c2d2 293 tmout_len = atoi (value_cell (tmout_var));
ccc6cda3
JA
294 if (tmout_len > 0)
295 {
296 old_alrm = set_signal_handler (SIGALRM, alrm_catcher);
297 alarm (tmout_len);
298 }
299 }
300 }
301
302 QUIT;
303
304 current_command_line_count = 0;
305 result = parse_command ();
306
307 if (interactive && tmout_var && (tmout_len > 0))
308 {
309 alarm(0);
310 set_signal_handler (SIGALRM, old_alrm);
311 }
312
313 return (result);
314}