2e8406855ce2abc4473972d4533d535ea603df31
[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 int interactive, interactive_shell;
44 extern int indirection_level, startup_state, subshell_environment;
45 extern int line_number;
46 extern int last_command_exit_value;
47 extern int running_trap;
48 extern COMMAND *global_command;
49
50 int parse_and_execute_level = 0;
51
52 /* How to force parse_and_execute () to clean up after itself. */
53 void
54 parse_and_execute_cleanup ()
55 {
56   if (running_trap)
57     {
58       run_trap_cleanup (running_trap - 1);
59       unfreeze_jobs_list ();
60     }
61   run_unwind_frame ("parse_and_execute_top");
62 }
63
64 /* Parse and execute the commands in STRING.  Returns whatever
65    execute_command () returns.  This frees STRING.  INTERACT is
66    the new value for `interactive' while the commands are being
67    executed.  A value of -1 means don't change it. */
68 int
69 parse_and_execute (string, from_file, interact)
70      char *string;
71      char *from_file;
72      int interact;
73 {
74   int code;
75   volatile int should_jump_to_top_level, last_result;
76   char *orig_string;
77   COMMAND *volatile command;
78
79   orig_string = string;
80   /* Unwind protect this invocation of parse_and_execute (). */
81   begin_unwind_frame ("parse_and_execute_top");
82   unwind_protect_int (parse_and_execute_level);
83   unwind_protect_jmp_buf (top_level);
84   unwind_protect_int (indirection_level);
85   unwind_protect_int (line_number);
86   if (interact != -1 && interactive != interact)
87     unwind_protect_int (interactive);
88
89 #if defined (HISTORY)
90   if (interactive_shell)
91     {
92       unwind_protect_int (remember_on_history);
93 #  if defined (BANG_HISTORY)
94       unwind_protect_int (history_expansion_inhibited);
95 #  endif /* BANG_HISTORY */
96     }
97 #endif /* HISTORY */
98
99   add_unwind_protect (pop_stream, (char *)NULL);
100   if (orig_string)
101     add_unwind_protect (xfree, orig_string);
102   end_unwind_frame ();
103
104   parse_and_execute_level++;
105   push_stream (1);      /* reset the line number */
106   indirection_level++;
107   if (interact != -1)
108     interactive = interact;
109
110 #if defined (HISTORY)
111   bash_history_disable ();
112 #endif /* HISTORY */
113
114   code = should_jump_to_top_level = 0;
115   last_result = EXECUTION_SUCCESS;
116   command = (COMMAND *)NULL;
117
118   with_input_from_string (string, from_file);
119   while (*(bash_input.location.string))
120     {
121       if (interrupt_state)
122         {
123           last_result = EXECUTION_FAILURE;
124           break;
125         }
126
127       /* Provide a location for functions which `longjmp (top_level)' to
128          jump to.  This prevents errors in substitution from restarting
129          the reader loop directly, for example. */
130       code = setjmp (top_level);
131
132       if (code)
133         {
134           should_jump_to_top_level = 0;
135           switch (code)
136             {
137             case FORCE_EOF:
138             case EXITPROG:
139               run_unwind_frame ("pe_dispose");
140               /* Remember to call longjmp (top_level) after the old
141                  value for it is restored. */
142               should_jump_to_top_level = 1;
143               goto out;
144
145             case DISCARD:
146               run_unwind_frame ("pe_dispose");
147               last_command_exit_value = 1;      /* XXX */
148               if (subshell_environment)
149                 {
150                   should_jump_to_top_level = 1;
151                   goto out;
152                 }
153               else
154                 {
155                   dispose_command (command);    /* XXX */
156                   continue;
157                 }
158
159             default:
160               programming_error ("parse_and_execute: bad jump: code %d", code);
161               break;
162             }
163         }
164           
165       if (parse_command () == 0)
166         {
167           if (interactive_shell == 0 && read_but_dont_execute)
168             {
169               last_result = EXECUTION_SUCCESS;
170               dispose_command (global_command);
171               global_command = (COMMAND *)NULL;
172             }
173           else if (command = global_command)
174             {
175               struct fd_bitmap *bitmap;
176
177               bitmap = new_fd_bitmap (FD_BITMAP_SIZE);
178               begin_unwind_frame ("pe_dispose");
179               add_unwind_protect (dispose_fd_bitmap, bitmap);
180
181               global_command = (COMMAND *)NULL;
182
183 #if defined (ONESHOT)
184               if (startup_state == 2 && *bash_input.location.string == '\0' &&
185                   command->type == cm_simple && !command->redirects &&
186                   !command->value.Simple->redirects)
187                 {
188                   command->flags |= CMD_NO_FORK;
189                   command->value.Simple->flags |= CMD_NO_FORK;
190                 }
191 #endif /* ONESHOT */
192
193               last_result = execute_command_internal
194                                 (command, 0, NO_PIPE, NO_PIPE, bitmap);
195
196               dispose_command (command);
197               dispose_fd_bitmap (bitmap);
198               discard_unwind_frame ("pe_dispose");
199             }
200         }
201       else
202         {
203           last_result = EXECUTION_FAILURE;
204
205           /* Since we are shell compatible, syntax errors in a script
206              abort the execution of the script.  Right? */
207           break;
208         }
209     }
210
211  out:
212
213   run_unwind_frame ("parse_and_execute_top");
214
215   if (interrupt_state && parse_and_execute_level == 0)
216     {
217       /* An interrupt during non-interactive execution in an
218          interactive shell (e.g. via $PROMPT_COMMAND) should
219          not cause the shell to exit. */
220       interactive = interactive_shell;
221       throw_to_top_level ();
222     }
223
224   if (should_jump_to_top_level)
225     jump_to_top_level (code);
226
227   return (last_result);
228 }