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