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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
21 #if defined (HAVE_UNISTD_H)
25 #include "../bashtypes.h"
26 #include "../posixstat.h"
27 #include "../filecntl.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
60 extern int interactive
, interactive_shell
, posixly_correct
;
61 extern int indirection_level
, startup_state
, subshell_environment
;
62 extern int return_catch_flag
, return_catch_value
;
63 extern int last_command_exit_value
;
65 /* How many `levels' of sourced files we have. */
69 _evalfile (filename
, flags
)
73 volatile int old_interactive
;
74 procenv_t old_return_catch
;
75 int return_val
, fd
, result
, pflags
;
80 fd
= open (filename
, O_RDONLY
);
82 if (fd
< 0 || (fstat (fd
, &finfo
) == -1))
85 if (((flags
& FEVAL_ENOENTOK
) == 0) || errno
!= ENOENT
)
86 file_error (filename
);
88 if (flags
& FEVAL_LONGJMP
)
90 last_command_exit_value
= 1;
91 jump_to_top_level (EXITPROG
);
94 return ((flags
& FEVAL_BUILTIN
) ? EXECUTION_FAILURE
95 : ((errno
== ENOENT
) ? 0 : -1));
98 errfunc
= (VFunction
*)((flags
& FEVAL_BUILTIN
) ? builtin_error
: internal_error
);
100 if (S_ISDIR (finfo
.st_mode
))
102 (*errfunc
) ("%s: is a directory", filename
);
103 return ((flags
& FEVAL_BUILTIN
) ? EXECUTION_FAILURE
: -1);
105 else if (S_ISREG (finfo
.st_mode
) == 0)
107 (*errfunc
) ("%s: not a regular file", filename
);
108 return ((flags
& FEVAL_BUILTIN
) ? EXECUTION_FAILURE
: -1);
111 string
= xmalloc (1 + (int)finfo
.st_size
);
112 result
= read (fd
, string
, finfo
.st_size
);
113 string
[result
] = '\0';
119 if (result
!= (int)finfo
.st_size
)
122 goto file_error_and_exit
;
125 if (check_binary_file ((unsigned char *)string
, (result
> 80) ? 80 : result
))
128 (*errfunc
) ("%s: cannot execute binary file", filename
);
129 return ((flags
& FEVAL_BUILTIN
) ? EX_BINARY_FILE
: -1);
132 if (flags
& FEVAL_UNWINDPROT
)
134 begin_unwind_frame ("_evalfile");
136 unwind_protect_int (return_catch_flag
);
137 unwind_protect_jmp_buf (return_catch
);
138 if (flags
& FEVAL_NONINT
)
139 unwind_protect_int (interactive
);
140 unwind_protect_int (sourcelevel
);
144 COPY_PROCENV (return_catch
, old_return_catch
);
145 if (flags
& FEVAL_NONINT
)
146 old_interactive
= interactive
;
149 if (flags
& FEVAL_NONINT
)
155 /* set the flags to be passed to parse_and_execute */
156 pflags
= (flags
& FEVAL_HISTORY
) ? 0 : SEVAL_NOHIST
;
158 if (flags
& FEVAL_BUILTIN
)
159 result
= EXECUTION_SUCCESS
;
161 return_val
= setjmp (return_catch
);
163 /* If `return' was seen outside of a function, but in the script, then
164 force parse_and_execute () to clean up. */
167 parse_and_execute_cleanup ();
168 result
= return_catch_value
;
171 result
= parse_and_execute (string
, filename
, pflags
);
173 if (flags
& FEVAL_UNWINDPROT
)
174 run_unwind_frame ("_evalfile");
177 if (flags
& FEVAL_NONINT
)
178 interactive
= old_interactive
;
181 COPY_PROCENV (old_return_catch
, return_catch
);
184 return ((flags
& FEVAL_BUILTIN
) ? result
: 1);
188 maybe_execute_file (fname
, force_noninteractive
)
190 int force_noninteractive
;
195 filename
= bash_tilde_expand (fname
);
196 flags
= FEVAL_ENOENTOK
;
197 if (force_noninteractive
)
198 flags
|= FEVAL_NONINT
;
199 result
= _evalfile (filename
, flags
);
204 #if defined (HISTORY)
206 fc_execute_file (filename
)
211 /* We want these commands to show up in the history list if
212 remember_on_history is set. */
213 flags
= FEVAL_ENOENTOK
|FEVAL_HISTORY
;
214 return (_evalfile (filename
, flags
));
219 source_file (filename
)
224 flags
= FEVAL_BUILTIN
|FEVAL_UNWINDPROT
|FEVAL_NONINT
;
225 /* POSIX shells exit if non-interactive and file error. */
226 if (posixly_correct
&& !interactive_shell
)
227 flags
|= FEVAL_LONGJMP
;
228 return (_evalfile (filename
, flags
));