1 /* Copyright (C) 1996 Free Software Foundation, Inc.
3 This file is part of GNU Bash, the Bourne Again SHell.
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 2, or (at your option) any later
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
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, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
21 #if defined (HAVE_UNISTD_H)
25 #include "../bashtypes.h"
26 #include "posixstat.h"
33 #include "../bashansi.h"
37 #include "../builtins.h"
40 #include "../execute_cmd.h"
43 # include "../bashhist.h"
52 /* Flags for _evalfile() */
53 #define FEVAL_ENOENTOK 0x001
54 #define FEVAL_BUILTIN 0x002
55 #define FEVAL_UNWINDPROT 0x004
56 #define FEVAL_NONINT 0x008
57 #define FEVAL_LONGJMP 0x010
58 #define FEVAL_HISTORY 0x020
59 #define FEVAL_CHECKBINARY 0x040
60 #define FEVAL_REGFILE 0x080
62 extern int posixly_correct;
63 extern int indirection_level, startup_state, subshell_environment;
64 extern int return_catch_flag, return_catch_value;
65 extern int last_command_exit_value;
67 /* How many `levels' of sourced files we have. */
71 _evalfile (filename, flags)
75 volatile int old_interactive;
76 procenv_t old_return_catch;
77 int return_val, fd, result, pflags;
81 sh_vmsg_func_t *errfunc;
85 fd = open (filename, O_RDONLY);
87 if (fd < 0 || (fstat (fd, &finfo) == -1))
90 if (((flags & FEVAL_ENOENTOK) == 0) || errno != ENOENT)
91 file_error (filename);
93 if (flags & FEVAL_LONGJMP)
95 last_command_exit_value = 1;
96 jump_to_top_level (EXITPROG);
99 return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE
100 : ((errno == ENOENT) ? 0 : -1));
103 errfunc = ((flags & FEVAL_BUILTIN) ? builtin_error : internal_error);
105 if (S_ISDIR (finfo.st_mode))
107 (*errfunc) ("%s: is a directory", filename);
108 return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
110 else if ((flags & FEVAL_REGFILE) && S_ISREG (finfo.st_mode) == 0)
112 (*errfunc) ("%s: not a regular file", filename);
113 return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
116 file_size = (size_t)finfo.st_size;
117 /* Check for overflow with large files. */
118 if (file_size != finfo.st_size || file_size + 1 < file_size)
120 (*errfunc) ("%s: file is too large", filename);
121 return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
124 #if defined (__CYGWIN__) && defined (O_TEXT)
125 setmode (fd, O_TEXT);
128 string = (char *)xmalloc (1 + file_size);
129 result = read (fd, string, file_size);
130 string[result] = '\0';
136 if (result < 0) /* XXX was != file_size, not < 0 */
139 goto file_error_and_exit;
145 return ((flags & FEVAL_BUILTIN) ? EXECUTION_SUCCESS : 1);
148 if ((flags & FEVAL_CHECKBINARY) &&
149 check_binary_file (string, (result > 80) ? 80 : result))
152 (*errfunc) ("%s: cannot execute binary file", filename);
153 return ((flags & FEVAL_BUILTIN) ? EX_BINARY_FILE : -1);
156 if (flags & FEVAL_UNWINDPROT)
158 begin_unwind_frame ("_evalfile");
160 unwind_protect_int (return_catch_flag);
161 unwind_protect_jmp_buf (return_catch);
162 if (flags & FEVAL_NONINT)
163 unwind_protect_int (interactive);
164 unwind_protect_int (sourcelevel);
168 COPY_PROCENV (return_catch, old_return_catch);
169 if (flags & FEVAL_NONINT)
170 old_interactive = interactive;
173 if (flags & FEVAL_NONINT)
179 /* set the flags to be passed to parse_and_execute */
180 pflags = (flags & FEVAL_HISTORY) ? 0 : SEVAL_NOHIST;
182 if (flags & FEVAL_BUILTIN)
183 result = EXECUTION_SUCCESS;
185 return_val = setjmp (return_catch);
187 /* If `return' was seen outside of a function, but in the script, then
188 force parse_and_execute () to clean up. */
191 parse_and_execute_cleanup ();
192 result = return_catch_value;
195 result = parse_and_execute (string, filename, pflags);
197 if (flags & FEVAL_UNWINDPROT)
198 run_unwind_frame ("_evalfile");
201 if (flags & FEVAL_NONINT)
202 interactive = old_interactive;
205 COPY_PROCENV (old_return_catch, return_catch);
208 return ((flags & FEVAL_BUILTIN) ? result : 1);
212 maybe_execute_file (fname, force_noninteractive)
214 int force_noninteractive;
219 filename = bash_tilde_expand (fname);
220 flags = FEVAL_ENOENTOK;
221 if (force_noninteractive)
222 flags |= FEVAL_NONINT;
223 result = _evalfile (filename, flags);
228 #if defined (HISTORY)
230 fc_execute_file (filename)
231 const char *filename;
235 /* We want these commands to show up in the history list if
236 remember_on_history is set. */
237 flags = FEVAL_ENOENTOK|FEVAL_HISTORY|FEVAL_REGFILE;
238 return (_evalfile (filename, flags));
243 source_file (filename)
244 const char *filename;
248 flags = FEVAL_BUILTIN|FEVAL_UNWINDPROT|FEVAL_NONINT;
249 /* POSIX shells exit if non-interactive and file error. */
250 if (posixly_correct && !interactive_shell)
251 flags |= FEVAL_LONGJMP;
252 return (_evalfile (filename, flags));