]> git.ipfire.org Git - thirdparty/bash.git/blame - eval.c
Imported from ../bash-3.2.48.tar.gz.
[thirdparty/bash.git] / eval.c
CommitLineData
bb70624e 1/* eval.c -- reading and evaluating commands. */
ccc6cda3 2
bb70624e 3/* Copyright (C) 1996 Free Software Foundation, Inc.
ccc6cda3 4
bb70624e 5 This file is part of GNU Bash, the Bourne Again SHell.
ccc6cda3 6
bb70624e
JA
7 Bash is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
ccc6cda3 11
bb70624e
JA
12 Bash is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
ccc6cda3 16
bb70624e
JA
17 You should have received a copy of the GNU General Public License
18 along with Bash; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
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
7117c2d2
JA
57static void send_pwd_to_eterm __P((void));
58static sighandler alrm_catcher __P((int));
59
ccc6cda3
JA
60/* Read and execute commands until EOF is reached. This assumes that
61 the input source has already been initialized. */
62int
63reader_loop ()
64{
65 int our_indirection_level;
95732b49 66 COMMAND * volatile current_command;
ccc6cda3 67
95732b49 68 current_command = (COMMAND *)NULL;
f73dda09
JA
69 USE_VAR(current_command);
70
ccc6cda3
JA
71 our_indirection_level = ++indirection_level;
72
73 while (EOF_Reached == 0)
74 {
75 int code;
76
77 code = setjmp (top_level);
78
79#if defined (PROCESS_SUBSTITUTION)
80 unlink_fifo_list ();
81#endif /* PROCESS_SUBSTITUTION */
82
83 if (interactive_shell && signal_is_ignored (SIGINT) == 0)
84 set_signal_handler (SIGINT, sigint_sighandler);
85
86 if (code != NOT_JUMPED)
87 {
88 indirection_level = our_indirection_level;
89
90 switch (code)
91 {
92 /* Some kind of throw to top_level has occured. */
93 case FORCE_EOF:
b80f6443 94 case ERREXIT:
ccc6cda3
JA
95 case EXITPROG:
96 current_command = (COMMAND *)NULL;
bb70624e
JA
97 if (exit_immediately_on_error)
98 variable_context = 0; /* not in a function */
ccc6cda3
JA
99 EOF_Reached = EOF;
100 goto exec_done;
101
102 case DISCARD:
103 last_command_exit_value = 1;
104 if (subshell_environment)
105 {
106 current_command = (COMMAND *)NULL;
107 EOF_Reached = EOF;
108 goto exec_done;
109 }
110 /* Obstack free command elements, etc. */
111 if (current_command)
112 {
113 dispose_command (current_command);
114 current_command = (COMMAND *)NULL;
115 }
116 break;
117
118 default:
b72432fd 119 command_error ("reader_loop", CMDERR_BADJUMP, code, 0);
ccc6cda3
JA
120 }
121 }
122
123 executing = 0;
7117c2d2
JA
124 if (temporary_env)
125 dispose_used_env_vars ();
ccc6cda3
JA
126
127#if (defined (ultrix) && defined (mips)) || defined (C_ALLOCA)
128 /* Attempt to reclaim memory allocated with alloca (). */
129 (void) alloca (0);
130#endif
131
132 if (read_command () == 0)
133 {
134 if (interactive_shell == 0 && read_but_dont_execute)
135 {
136 last_command_exit_value = EXECUTION_SUCCESS;
137 dispose_command (global_command);
138 global_command = (COMMAND *)NULL;
139 }
140 else if (current_command = global_command)
141 {
142 global_command = (COMMAND *)NULL;
143 current_command_number++;
144
145 executing = 1;
d166f048 146 stdin_redir = 0;
ccc6cda3
JA
147 execute_command (current_command);
148
149 exec_done:
95732b49
JA
150 QUIT;
151
ccc6cda3 152 if (current_command)
28ef6c31 153 {
ccc6cda3
JA
154 dispose_command (current_command);
155 current_command = (COMMAND *)NULL;
28ef6c31 156 }
ccc6cda3
JA
157 }
158 }
159 else
160 {
161 /* Parse error, maybe discard rest of stream if not interactive. */
162 if (interactive == 0)
163 EOF_Reached = EOF;
164 }
165 if (just_one_command)
166 EOF_Reached = EOF;
167 }
168 indirection_level--;
169 return (last_command_exit_value);
170}
171
172static sighandler
173alrm_catcher(i)
174 int i;
175{
b80f6443
JA
176 printf (_("\007timed out waiting for input: auto-logout\n"));
177 bash_logout (); /* run ~/.bash_logout if this is a login shell */
ccc6cda3
JA
178 jump_to_top_level (EXITPROG);
179 SIGRETURN (0);
180}
181
182/* Send an escape sequence to emacs term mode to tell it the
183 current working directory. */
184static void
185send_pwd_to_eterm ()
186{
187 char *pwd;
188
189 pwd = get_string_value ("PWD");
190 if (pwd == 0)
191 pwd = get_working_directory ("eterm");
192 fprintf (stderr, "\032/%s\n", pwd);
193}
194
195/* Call the YACC-generated parser and return the status of the parse.
196 Input is read from the current input stream (bash_input). yyparse
197 leaves the parsed command in the global variable GLOBAL_COMMAND.
198 This is where PROMPT_COMMAND is executed. */
199int
200parse_command ()
201{
202 int r;
203 char *command_to_execute;
204
205 need_here_doc = 0;
206 run_pending_traps ();
207
208 /* Allow the execution of a random command just before the printing
209 of each primary prompt. If the shell variable PROMPT_COMMAND
210 is set then the value of it is the command to execute. */
211 if (interactive && bash_input.type != st_string)
212 {
213 command_to_execute = get_string_value ("PROMPT_COMMAND");
214 if (command_to_execute)
0628567a 215 execute_variable_command (command_to_execute, "PROMPT_COMMAND");
ccc6cda3
JA
216
217 if (running_under_emacs == 2)
218 send_pwd_to_eterm (); /* Yuck */
219 }
220
221 current_command_line_count = 0;
222 r = yyparse ();
223
224 if (need_here_doc)
225 gather_here_documents ();
226
227 return (r);
228}
229
230/* Read and parse a command, returning the status of the parse. The command
231 is left in the globval variable GLOBAL_COMMAND for use by reader_loop.
232 This is where the shell timeout code is executed. */
233int
234read_command ()
235{
236 SHELL_VAR *tmout_var;
237 int tmout_len, result;
238 SigHandler *old_alrm;
239
bb70624e 240 set_current_prompt_level (1);
ccc6cda3
JA
241 global_command = (COMMAND *)NULL;
242
243 /* Only do timeouts if interactive. */
244 tmout_var = (SHELL_VAR *)NULL;
245 tmout_len = 0;
f73dda09 246 old_alrm = (SigHandler *)NULL;
ccc6cda3
JA
247
248 if (interactive)
249 {
250 tmout_var = find_variable ("TMOUT");
ccc6cda3 251
7117c2d2 252 if (tmout_var && var_isset (tmout_var))
ccc6cda3 253 {
7117c2d2 254 tmout_len = atoi (value_cell (tmout_var));
ccc6cda3
JA
255 if (tmout_len > 0)
256 {
257 old_alrm = set_signal_handler (SIGALRM, alrm_catcher);
258 alarm (tmout_len);
259 }
260 }
261 }
262
263 QUIT;
264
265 current_command_line_count = 0;
266 result = parse_command ();
267
268 if (interactive && tmout_var && (tmout_len > 0))
269 {
270 alarm(0);
271 set_signal_handler (SIGALRM, old_alrm);
272 }
273
274 return (result);
275}