0063b711ed85755c66394195f0de0728475de76c
[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 #  ifdef _MINIX
23 #    include <sys/types.h>
24 #  endif
25 #  include <unistd.h>
26 #endif
27
28 #include <stdio.h>
29 #include <signal.h>
30
31 #include <errno.h>
32
33 #include "../filecntl.h"
34 #include "../bashansi.h"
35
36 #include "../shell.h"
37 #include "../jobs.h"
38 #include "../builtins.h"
39 #include "../flags.h"
40 #include "../input.h"
41 #include "../execute_cmd.h"
42 #include "../redir.h"
43
44 #if defined (HISTORY)
45 #  include "../bashhist.h"
46 #endif
47
48 #include "common.h"
49
50 #if !defined (errno)
51 extern int errno;
52 #endif
53
54 extern void run_trap_cleanup ();
55
56 extern int interactive, interactive_shell;
57 extern int indirection_level, startup_state, subshell_environment;
58 extern int line_number;
59 extern int last_command_exit_value;
60 extern int running_trap;
61 extern int posixly_correct;
62 extern COMMAND *global_command;
63
64 int parse_and_execute_level = 0;
65
66 static int cat_file ();
67
68 /* How to force parse_and_execute () to clean up after itself. */
69 void
70 parse_and_execute_cleanup ()
71 {
72   if (running_trap)
73     {
74       run_trap_cleanup (running_trap - 1);
75       unfreeze_jobs_list ();
76     }
77   run_unwind_frame ("parse_and_execute_top");
78 }
79
80 /* Parse and execute the commands in STRING.  Returns whatever
81    execute_command () returns.  This frees STRING.  FLAGS is a
82    flags word; look in common.h for the possible values.  Actions
83    are:
84         (flags & SEVAL_NONINT) -> interactive = 0;
85         (flags & SEVAL_INTERACT) -> interactive = 1;
86         (flags & SEVAL_NOHIST) -> call bash_history_disable ()
87 */
88
89 int
90 parse_and_execute (string, from_file, flags)
91      char *string;
92      char *from_file;
93      int flags;
94 {
95   int code;
96   volatile int should_jump_to_top_level, last_result;
97   char *orig_string;
98   COMMAND *volatile command;
99
100   orig_string = string;
101   /* Unwind protect this invocation of parse_and_execute (). */
102   begin_unwind_frame ("parse_and_execute_top");
103   unwind_protect_int (parse_and_execute_level);
104   unwind_protect_jmp_buf (top_level);
105   unwind_protect_int (indirection_level);
106   unwind_protect_int (line_number);
107   if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
108     unwind_protect_int (interactive);
109
110 #if defined (HISTORY)
111   unwind_protect_int (remember_on_history);     /* can be used in scripts */
112 #  if defined (BANG_HISTORY)
113   if (interactive_shell)
114     {
115       unwind_protect_int (history_expansion_inhibited);
116     }
117 #  endif /* BANG_HISTORY */
118 #endif /* HISTORY */
119
120   add_unwind_protect (pop_stream, (char *)NULL);
121   if (orig_string)
122     add_unwind_protect (xfree, orig_string);
123   end_unwind_frame ();
124
125   parse_and_execute_level++;
126   push_stream (1);      /* reset the line number */
127   indirection_level++;
128   if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
129     interactive = (flags & SEVAL_NONINT) ? 0 : 1;
130
131 #if defined (HISTORY)
132   if (flags & SEVAL_NOHIST)
133     bash_history_disable ();
134 #endif /* HISTORY */
135
136   code = should_jump_to_top_level = 0;
137   last_result = EXECUTION_SUCCESS;
138   command = (COMMAND *)NULL;
139
140   with_input_from_string (string, from_file);
141   while (*(bash_input.location.string))
142     {
143       if (interrupt_state)
144         {
145           last_result = EXECUTION_FAILURE;
146           break;
147         }
148
149       /* Provide a location for functions which `longjmp (top_level)' to
150          jump to.  This prevents errors in substitution from restarting
151          the reader loop directly, for example. */
152       code = setjmp (top_level);
153
154       if (code)
155         {
156           should_jump_to_top_level = 0;
157           switch (code)
158             {
159             case FORCE_EOF:
160             case EXITPROG:
161               run_unwind_frame ("pe_dispose");
162               /* Remember to call longjmp (top_level) after the old
163                  value for it is restored. */
164               should_jump_to_top_level = 1;
165               goto out;
166
167             case DISCARD:
168               run_unwind_frame ("pe_dispose");
169               last_command_exit_value = 1;      /* XXX */
170               if (subshell_environment)
171                 {
172                   should_jump_to_top_level = 1;
173                   goto out;
174                 }
175               else
176                 {
177 #if 0
178                   dispose_command (command);    /* pe_dispose does this */
179 #endif
180                   continue;
181                 }
182
183             default:
184               programming_error ("parse_and_execute: bad jump: code %d", code);
185               break;
186             }
187         }
188           
189       if (parse_command () == 0)
190         {
191           if (interactive_shell == 0 && read_but_dont_execute)
192             {
193               last_result = EXECUTION_SUCCESS;
194               dispose_command (global_command);
195               global_command = (COMMAND *)NULL;
196             }
197           else if (command = global_command)
198             {
199               struct fd_bitmap *bitmap;
200
201               bitmap = new_fd_bitmap (FD_BITMAP_SIZE);
202               begin_unwind_frame ("pe_dispose");
203               add_unwind_protect (dispose_fd_bitmap, bitmap);
204               add_unwind_protect (dispose_command, command);    /* XXX */
205
206               global_command = (COMMAND *)NULL;
207
208 #if defined (ONESHOT)
209               if (startup_state == 2 && *bash_input.location.string == '\0' &&
210                   command->type == cm_simple && !command->redirects &&
211                   !command->value.Simple->redirects &&
212                   ((command->flags & CMD_TIME_PIPELINE) == 0))
213                 {
214                   command->flags |= CMD_NO_FORK;
215                   command->value.Simple->flags |= CMD_NO_FORK;
216                 }
217 #endif /* ONESHOT */
218
219               /* See if this is a candidate for $( <file ). */
220               if (startup_state == 2 &&
221                   subshell_environment == SUBSHELL_COMSUB &&
222                   *bash_input.location.string == '\0' &&
223                   command->type == cm_simple && !command->redirects &&
224                   (command->flags & CMD_TIME_PIPELINE) == 0 &&
225                   command->value.Simple->words == 0 &&
226                   command->value.Simple->redirects &&
227                   command->value.Simple->redirects->next == 0 &&
228                   command->value.Simple->redirects->instruction == r_input_direction)
229                 {
230                   int r;
231                   r = cat_file (command->value.Simple->redirects);
232                   last_result = (r < 0) ? EXECUTION_FAILURE : EXECUTION_SUCCESS;
233                 }
234               else
235                 last_result = execute_command_internal
236                                 (command, 0, NO_PIPE, NO_PIPE, bitmap);
237
238               dispose_command (command);
239               dispose_fd_bitmap (bitmap);
240               discard_unwind_frame ("pe_dispose");
241             }
242         }
243       else
244         {
245           last_result = EXECUTION_FAILURE;
246
247           /* Since we are shell compatible, syntax errors in a script
248              abort the execution of the script.  Right? */
249           break;
250         }
251     }
252
253  out:
254
255   run_unwind_frame ("parse_and_execute_top");
256
257   if (interrupt_state && parse_and_execute_level == 0)
258     {
259       /* An interrupt during non-interactive execution in an
260          interactive shell (e.g. via $PROMPT_COMMAND) should
261          not cause the shell to exit. */
262       interactive = interactive_shell;
263       throw_to_top_level ();
264     }
265
266   if (should_jump_to_top_level)
267     jump_to_top_level (code);
268
269   return (last_result);
270 }
271
272 /* Write NB bytes from BUF to file descriptor FD, retrying the write if
273    it is interrupted.  We retry three times if we get a zero-length
274    write.  Any other signal causes this function to return prematurely. */
275 static int
276 zwrite (fd, buf, nb)
277      int fd;
278      unsigned char *buf;
279      int nb;
280 {
281   int n, i, nt;
282
283   for (n = nb, nt = 0;;)
284     {
285       i = write (fd, buf, n);
286       if (i > 0)
287         {
288           n -= i;
289           if (n <= 0)
290             return nb;
291         }
292       else if (i == 0)
293         {
294           if (++nt > 3)
295             return (nb - n);
296         }
297       else if (errno != EINTR)
298         return -1;
299     }
300 }
301
302 /* Handle a $( < file ) command substitution.  This expands the filename,
303    returning errors as appropriate, then just cats the file to the standard
304    output. */
305 static int
306 cat_file (r)
307      REDIRECT *r;
308 {
309   char lbuf[128], *fn;
310   int nr, fd, rval;
311
312   if (r->instruction != r_input_direction)
313     return -1;
314
315   /* Get the filename. */
316   if (posixly_correct && !interactive_shell)
317     disallow_filename_globbing++;
318   fn = redirection_expand (r->redirectee.filename);
319   if (posixly_correct && !interactive_shell)
320     disallow_filename_globbing--;
321
322   if (fn == 0)
323     {
324       redirection_error (r, AMBIGUOUS_REDIRECT);
325       return -1;
326     }
327
328   fd = open(fn, O_RDONLY);
329   if (fd < 0)
330     {
331       file_error (fn);
332       free (fn);
333       return -1;
334     }
335
336   rval = 0;
337   while (1)
338     {
339       /* Retry the reads on EINTR.  Any other error causes a break from the
340          loop. */
341       while ((nr = read (fd, lbuf, sizeof(lbuf))) < 0 && errno == EINTR)
342         ;
343       if (nr == 0)
344         break;
345       else if (nr < 0)
346         {
347           rval = -1;
348           break;
349         }
350       if (zwrite (1, lbuf, nr) < 0)
351         {
352           rval = -1;
353           break;
354         }
355     }
356
357   free (fn);
358   close (fd);
359
360   return (0);  
361 }