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
61 extern int interactive
, interactive_shell
, posixly_correct
;
62 extern int indirection_level
, startup_state
, subshell_environment
;
63 extern int return_catch_flag
, return_catch_value
;
64 extern int last_command_exit_value
;
66 /* How many `levels' of sourced files we have. */
70 _evalfile (filename
, flags
)
74 volatile int old_interactive
;
75 procenv_t old_return_catch
;
76 int return_val
, fd
, result
, pflags
;
82 fd
= open (filename
, O_RDONLY
);
84 if (fd
< 0 || (fstat (fd
, &finfo
) == -1))
87 if (((flags
& FEVAL_ENOENTOK
) == 0) || errno
!= ENOENT
)
88 file_error (filename
);
90 if (flags
& FEVAL_LONGJMP
)
92 last_command_exit_value
= 1;
93 jump_to_top_level (EXITPROG
);
96 return ((flags
& FEVAL_BUILTIN
) ? EXECUTION_FAILURE
97 : ((errno
== ENOENT
) ? 0 : -1));
100 errfunc
= (VFunction
*)((flags
& FEVAL_BUILTIN
) ? builtin_error
: internal_error
);
102 if (S_ISDIR (finfo
.st_mode
))
104 (*errfunc
) ("%s: is a directory", filename
);
105 return ((flags
& FEVAL_BUILTIN
) ? EXECUTION_FAILURE
: -1);
107 else if (S_ISREG (finfo
.st_mode
) == 0)
109 (*errfunc
) ("%s: not a regular file", filename
);
110 return ((flags
& FEVAL_BUILTIN
) ? EXECUTION_FAILURE
: -1);
113 file_size
= (size_t)finfo
.st_size
;
114 /* Check for overflow with large files. */
115 if (file_size
!= finfo
.st_size
|| file_size
+ 1 < file_size
)
117 (*errfunc
) ("%s: file is too large", filename
);
118 return ((flags
& FEVAL_BUILTIN
) ? EXECUTION_FAILURE
: -1);
121 #if defined (__CYGWIN__) && defined (O_TEXT)
122 setmode (fd
, O_TEXT
);
125 string
= xmalloc (1 + file_size
);
126 result
= read (fd
, string
, file_size
);
127 string
[result
] = '\0';
133 if (result
< 0) /* XXX was != file_size, not < 0 */
136 goto file_error_and_exit
;
142 return ((flags
& FEVAL_BUILTIN
) ? EXECUTION_SUCCESS
: 1);
145 if ((flags
& FEVAL_CHECKBINARY
) &&
146 check_binary_file ((unsigned char *)string
, (result
> 80) ? 80 : result
))
149 (*errfunc
) ("%s: cannot execute binary file", filename
);
150 return ((flags
& FEVAL_BUILTIN
) ? EX_BINARY_FILE
: -1);
153 if (flags
& FEVAL_UNWINDPROT
)
155 begin_unwind_frame ("_evalfile");
157 unwind_protect_int (return_catch_flag
);
158 unwind_protect_jmp_buf (return_catch
);
159 if (flags
& FEVAL_NONINT
)
160 unwind_protect_int (interactive
);
161 unwind_protect_int (sourcelevel
);
165 COPY_PROCENV (return_catch
, old_return_catch
);
166 if (flags
& FEVAL_NONINT
)
167 old_interactive
= interactive
;
170 if (flags
& FEVAL_NONINT
)
176 /* set the flags to be passed to parse_and_execute */
177 pflags
= (flags
& FEVAL_HISTORY
) ? 0 : SEVAL_NOHIST
;
179 if (flags
& FEVAL_BUILTIN
)
180 result
= EXECUTION_SUCCESS
;
182 return_val
= setjmp (return_catch
);
184 /* If `return' was seen outside of a function, but in the script, then
185 force parse_and_execute () to clean up. */
188 parse_and_execute_cleanup ();
189 result
= return_catch_value
;
192 result
= parse_and_execute (string
, filename
, pflags
);
194 if (flags
& FEVAL_UNWINDPROT
)
195 run_unwind_frame ("_evalfile");
198 if (flags
& FEVAL_NONINT
)
199 interactive
= old_interactive
;
202 COPY_PROCENV (old_return_catch
, return_catch
);
205 return ((flags
& FEVAL_BUILTIN
) ? result
: 1);
209 maybe_execute_file (fname
, force_noninteractive
)
211 int force_noninteractive
;
216 filename
= bash_tilde_expand (fname
);
217 flags
= FEVAL_ENOENTOK
;
218 if (force_noninteractive
)
219 flags
|= FEVAL_NONINT
;
220 result
= _evalfile (filename
, flags
);
225 #if defined (HISTORY)
227 fc_execute_file (filename
)
232 /* We want these commands to show up in the history list if
233 remember_on_history is set. */
234 flags
= FEVAL_ENOENTOK
|FEVAL_HISTORY
;
235 return (_evalfile (filename
, flags
));
240 source_file (filename
)
245 flags
= FEVAL_BUILTIN
|FEVAL_UNWINDPROT
|FEVAL_NONINT
;
246 /* POSIX shells exit if non-interactive and file error. */
247 if (posixly_correct
&& !interactive_shell
)
248 flags
|= FEVAL_LONGJMP
;
249 return (_evalfile (filename
, flags
));