No specific user configuration
[platform/upstream/bash.git] / builtins / evalfile.c
1 /* evalfile.c - read and evaluate commands from a file or file descriptor */
2
3 /* Copyright (C) 1996-2009 Free Software Foundation, Inc.
4
5    This file is part of GNU Bash, the Bourne Again SHell.
6
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.
11
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.
16
17    You should have received a copy of the GNU General Public License
18    along with Bash.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include <config.h>
22
23 #if defined (HAVE_UNISTD_H)
24 #  include <unistd.h>
25 #endif
26
27 #include "../bashtypes.h"
28 #include "posixstat.h"
29 #include "filecntl.h"
30
31 #include <stdio.h>
32 #include <signal.h>
33 #include <errno.h>
34
35 #include "../bashansi.h"
36 #include "../bashintl.h"
37
38 #include "../shell.h"
39 #include "../jobs.h"
40 #include "../builtins.h"
41 #include "../flags.h"
42 #include "../input.h"
43 #include "../execute_cmd.h"
44 #include "../trap.h"
45
46 #if defined (HISTORY)
47 #  include "../bashhist.h"
48 #endif
49
50 #include <typemax.h>
51
52 #include "common.h"
53
54 #if !defined (errno)
55 extern int errno;
56 #endif
57
58 /* Flags for _evalfile() */
59 #define FEVAL_ENOENTOK          0x001
60 #define FEVAL_BUILTIN           0x002
61 #define FEVAL_UNWINDPROT        0x004
62 #define FEVAL_NONINT            0x008
63 #define FEVAL_LONGJMP           0x010
64 #define FEVAL_HISTORY           0x020
65 #define FEVAL_CHECKBINARY       0x040
66 #define FEVAL_REGFILE           0x080
67 #define FEVAL_NOPUSHARGS        0x100
68
69 extern int posixly_correct;
70 extern int indirection_level, subshell_environment;
71 extern int return_catch_flag, return_catch_value;
72 extern int last_command_exit_value;
73 extern int executing_command_builtin;
74
75 /* How many `levels' of sourced files we have. */
76 int sourcelevel = 0;
77
78 static int
79 _evalfile (filename, flags)
80      const char *filename;
81      int flags;
82 {
83   volatile int old_interactive;
84   procenv_t old_return_catch;
85   int return_val, fd, result, pflags, i, nnull;
86   ssize_t nr;                   /* return value from read(2) */
87   char *string;
88   struct stat finfo;
89   size_t file_size;
90   sh_vmsg_func_t *errfunc;
91 #if defined (ARRAY_VARS)
92   SHELL_VAR *funcname_v, *nfv, *bash_source_v, *bash_lineno_v;
93   ARRAY *funcname_a, *bash_source_a, *bash_lineno_a;
94 #  if defined (DEBUGGER)
95   SHELL_VAR *bash_argv_v, *bash_argc_v;
96   ARRAY *bash_argv_a, *bash_argc_a;
97 #  endif
98   char *t, tt[2];
99 #endif
100
101   USE_VAR(pflags);
102
103 #if defined (ARRAY_VARS)
104   GET_ARRAY_FROM_VAR ("FUNCNAME", funcname_v, funcname_a);
105   GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a);
106   GET_ARRAY_FROM_VAR ("BASH_LINENO", bash_lineno_v, bash_lineno_a);
107 #  if defined (DEBUGGER)
108   GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a);
109   GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
110 #  endif
111 #endif
112
113   fd = open (filename, O_RDONLY);
114
115   if (fd < 0 || (fstat (fd, &finfo) == -1))
116     {
117       i = errno;
118       if (fd >= 0)
119         close (fd);
120       errno = i;
121
122 file_error_and_exit:
123       if (((flags & FEVAL_ENOENTOK) == 0) || errno != ENOENT)
124         file_error (filename);
125
126       if (flags & FEVAL_LONGJMP)
127         {
128           last_command_exit_value = 1;
129           jump_to_top_level (EXITPROG);
130         }
131
132       return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE
133                                       : ((errno == ENOENT) ? 0 : -1));
134     }
135
136   errfunc = ((flags & FEVAL_BUILTIN) ? builtin_error : internal_error);
137
138   if (S_ISDIR (finfo.st_mode))
139     {
140       (*errfunc) (_("%s: is a directory"), filename);
141       close (fd);
142       return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
143     }
144   else if ((flags & FEVAL_REGFILE) && S_ISREG (finfo.st_mode) == 0)
145     {
146       (*errfunc) (_("%s: not a regular file"), filename);
147       close (fd);
148       return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
149     }
150
151   file_size = (size_t)finfo.st_size;
152   /* Check for overflow with large files. */
153   if (file_size != finfo.st_size || file_size + 1 < file_size)
154     {
155       (*errfunc) (_("%s: file is too large"), filename);
156       close (fd);
157       return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
158     }      
159
160   if (S_ISREG (finfo.st_mode) && file_size <= SSIZE_MAX)
161     {
162       string = (char *)xmalloc (1 + file_size);
163       nr = read (fd, string, file_size);
164       if (nr >= 0)
165         string[nr] = '\0';
166     }
167   else
168     nr = zmapfd (fd, &string, 0);
169
170   return_val = errno;
171   close (fd);
172   errno = return_val;
173
174   if (nr < 0)           /* XXX was != file_size, not < 0 */
175     {
176       free (string);
177       goto file_error_and_exit;
178     }
179
180   if (nr == 0)
181     {
182       free (string);
183       return ((flags & FEVAL_BUILTIN) ? EXECUTION_SUCCESS : 1);
184     }
185       
186   if ((flags & FEVAL_CHECKBINARY) && 
187       check_binary_file (string, (nr > 80) ? 80 : nr))
188     {
189       free (string);
190       (*errfunc) (_("%s: cannot execute binary file"), filename);
191       return ((flags & FEVAL_BUILTIN) ? EX_BINARY_FILE : -1);
192     }
193
194   i = strlen (string);
195   if (i < nr)
196     {
197       for (nnull = i = 0; i < nr; i++)
198         if (string[i] == '\0')
199           {
200             memmove (string+i, string+i+1, nr - i);
201             nr--;
202             /* Even if the `check binary' flag is not set, we want to avoid
203                sourcing files with more than 256 null characters -- that
204                probably indicates a binary file. */
205             if ((flags & FEVAL_BUILTIN) && ++nnull > 256)
206               {
207                 free (string);
208                 (*errfunc) (_("%s: cannot execute binary file"), filename);
209                 return ((flags & FEVAL_BUILTIN) ? EX_BINARY_FILE : -1);
210               }
211           }
212     }
213
214   if (flags & FEVAL_UNWINDPROT)
215     {
216       begin_unwind_frame ("_evalfile");
217
218       unwind_protect_int (return_catch_flag);
219       unwind_protect_jmp_buf (return_catch);
220       if (flags & FEVAL_NONINT)
221         unwind_protect_int (interactive);
222       unwind_protect_int (sourcelevel);
223     }
224   else
225     {
226       COPY_PROCENV (return_catch, old_return_catch);
227       if (flags & FEVAL_NONINT)
228         old_interactive = interactive;
229     }
230
231   if (flags & FEVAL_NONINT)
232     interactive = 0;
233
234   return_catch_flag++;
235   sourcelevel++;
236
237 #if defined (ARRAY_VARS)
238   array_push (bash_source_a, (char *)filename);
239   t = itos (executing_line_number ());
240   array_push (bash_lineno_a, t);
241   free (t);
242   array_push (funcname_a, "source");    /* not exactly right */
243 #  if defined (DEBUGGER)
244   /* Have to figure out a better way to do this when `source' is supplied
245      arguments */
246   if ((flags & FEVAL_NOPUSHARGS) == 0)
247     {
248       array_push (bash_argv_a, (char *)filename);
249       tt[0] = '1'; tt[1] = '\0';
250       array_push (bash_argc_a, tt);
251     }
252 #  endif
253 #endif
254
255   /* set the flags to be passed to parse_and_execute */
256   pflags = SEVAL_RESETLINE;
257   pflags |= (flags & FEVAL_HISTORY) ? 0 : SEVAL_NOHIST;
258
259   if (flags & FEVAL_BUILTIN)
260     result = EXECUTION_SUCCESS;
261
262   return_val = setjmp_nosigs (return_catch);
263
264   /* If `return' was seen outside of a function, but in the script, then
265      force parse_and_execute () to clean up. */
266   if (return_val)
267     {
268       parse_and_execute_cleanup ();
269       result = return_catch_value;
270     }
271   else
272     result = parse_and_execute (string, filename, pflags);
273
274   if (flags & FEVAL_UNWINDPROT)
275     run_unwind_frame ("_evalfile");
276   else
277     {
278       if (flags & FEVAL_NONINT)
279         interactive = old_interactive;
280       return_catch_flag--;
281       sourcelevel--;
282       COPY_PROCENV (old_return_catch, return_catch);
283     }
284
285 #if defined (ARRAY_VARS)
286   /* These two variables cannot be unset, and cannot be affected by the
287      sourced file. */
288   array_pop (bash_source_a);
289   array_pop (bash_lineno_a);
290
291   /* FUNCNAME can be unset, and so can potentially be changed by the
292      sourced file. */
293   GET_ARRAY_FROM_VAR ("FUNCNAME", nfv, funcname_a);
294   if (nfv == funcname_v)
295     array_pop (funcname_a);
296 #  if defined (DEBUGGER)
297   if ((flags & FEVAL_NOPUSHARGS) == 0)
298     {
299       array_pop (bash_argc_a);
300       array_pop (bash_argv_a);
301     }
302 #  endif
303 #endif
304
305   return ((flags & FEVAL_BUILTIN) ? result : 1);
306 }
307
308 int
309 maybe_execute_file (fname, force_noninteractive)
310      const char *fname;
311      int force_noninteractive;
312 {
313   char *filename;
314   int result, flags;
315
316   filename = bash_tilde_expand (fname, 0);
317   flags = FEVAL_ENOENTOK;
318   if (force_noninteractive)
319     flags |= FEVAL_NONINT;
320   result = _evalfile (filename, flags);
321   free (filename);
322   return result;
323 }
324
325 #if defined (HISTORY)
326 int
327 fc_execute_file (filename)
328      const char *filename;
329 {
330   int flags;
331
332   /* We want these commands to show up in the history list if
333      remember_on_history is set. */
334   flags = FEVAL_ENOENTOK|FEVAL_HISTORY|FEVAL_REGFILE;
335   return (_evalfile (filename, flags));
336 }
337 #endif /* HISTORY */
338
339 int
340 source_file (filename, sflags)
341      const char *filename;
342      int sflags;
343 {
344   int flags, rval;
345
346   flags = FEVAL_BUILTIN|FEVAL_UNWINDPROT|FEVAL_NONINT;
347   if (sflags)
348     flags |= FEVAL_NOPUSHARGS;
349   /* POSIX shells exit if non-interactive and file error. */
350   if (posixly_correct && interactive_shell == 0 && executing_command_builtin == 0)
351     flags |= FEVAL_LONGJMP;
352   rval = _evalfile (filename, flags);
353
354   run_return_trap ();
355   return rval;
356 }