bf4a8a5b311489136e088ad07501fc7c78d2e1c0
[platform/upstream/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                   dispose_command (command);    /* XXX */
164                   continue;
165                 }
166
167             default:
168               programming_error ("parse_and_execute: bad jump: code %d", code);
169               break;
170             }
171         }
172           
173       if (parse_command () == 0)
174         {
175           if (interactive_shell == 0 && read_but_dont_execute)
176             {
177               last_result = EXECUTION_SUCCESS;
178               dispose_command (global_command);
179               global_command = (COMMAND *)NULL;
180             }
181           else if (command = global_command)
182             {
183               struct fd_bitmap *bitmap;
184
185               bitmap = new_fd_bitmap (FD_BITMAP_SIZE);
186               begin_unwind_frame ("pe_dispose");
187               add_unwind_protect (dispose_fd_bitmap, bitmap);
188               add_unwind_protect (dispose_command, command);    /* XXX */
189
190               global_command = (COMMAND *)NULL;
191
192 #if defined (ONESHOT)
193               if (startup_state == 2 && *bash_input.location.string == '\0' &&
194                   command->type == cm_simple && !command->redirects &&
195                   !command->value.Simple->redirects)
196                 {
197                   command->flags |= CMD_NO_FORK;
198                   command->value.Simple->flags |= CMD_NO_FORK;
199                 }
200 #endif /* ONESHOT */
201
202               last_result = execute_command_internal
203                                 (command, 0, NO_PIPE, NO_PIPE, bitmap);
204
205               dispose_command (command);
206               dispose_fd_bitmap (bitmap);
207               discard_unwind_frame ("pe_dispose");
208             }
209         }
210       else
211         {
212           last_result = EXECUTION_FAILURE;
213
214           /* Since we are shell compatible, syntax errors in a script
215              abort the execution of the script.  Right? */
216           break;
217         }
218     }
219
220  out:
221
222   run_unwind_frame ("parse_and_execute_top");
223
224   if (interrupt_state && parse_and_execute_level == 0)
225     {
226       /* An interrupt during non-interactive execution in an
227          interactive shell (e.g. via $PROMPT_COMMAND) should
228          not cause the shell to exit. */
229       interactive = interactive_shell;
230       throw_to_top_level ();
231     }
232
233   if (should_jump_to_top_level)
234     jump_to_top_level (code);
235
236   return (last_result);
237 }