diff options
author | Jari Aalto <jari.aalto@cante.net> | 1996-08-26 18:22:31 +0000 |
---|---|---|
committer | Jari Aalto <jari.aalto@cante.net> | 2009-09-12 16:46:49 +0000 |
commit | 726f63884db0132f01745f1fb4465e6621088ccf (patch) | |
tree | 6c2f7765a890a97e0e513cb539df43283a8f7c4d /builtins/source.def | |
download | android_external_bash-726f63884db0132f01745f1fb4465e6621088ccf.tar.gz android_external_bash-726f63884db0132f01745f1fb4465e6621088ccf.tar.bz2 android_external_bash-726f63884db0132f01745f1fb4465e6621088ccf.zip |
Imported from ../bash-1.14.7.tar.gz.
Diffstat (limited to 'builtins/source.def')
-rw-r--r-- | builtins/source.def | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/builtins/source.def b/builtins/source.def new file mode 100644 index 0000000..895e98b --- /dev/null +++ b/builtins/source.def @@ -0,0 +1,186 @@ +This file is source.def, from which is created source.c. +It implements the builtins "." and "source" in Bash. + +Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. + +This file is part of GNU Bash, the Bourne Again SHell. + +Bash is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 1, or (at your option) any later +version. + +Bash is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License along +with Bash; see the file COPYING. If not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +$PRODUCES source.c + +$BUILTIN source +$FUNCTION source_builtin +$SHORT_DOC source filename +Read and execute commands from FILENAME and return. The pathnames +in $PATH are used to find the directory containing FILENAME. +$END +$BUILTIN . +$DOCNAME dot +$FUNCTION source_builtin +$SHORT_DOC . filename +Read and execute commands from FILENAME and return. The pathnames +in $PATH are used to find the directory containing FILENAME. +$END +/* source.c - Implements the `.' and `source' builtins. */ + +#include <sys/types.h> +#include <sys/file.h> +#include <errno.h> + +#if defined (HAVE_STRING_H) +# include <string.h> +#else /* !HAVE_STRING_H */ +# include <strings.h> +#endif /* !HAVE_STRING_H */ + +#include "../shell.h" +#include "../posixstat.h" +#include "../filecntl.h" +#include "../execute_cmd.h" + +/* Not all systems declare ERRNO in errno.h... and some systems #define it! */ +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +/* Variables used here but defined in other files. */ +extern int return_catch_flag, return_catch_value; +extern jmp_buf return_catch; +extern int posixly_correct; +extern int interactive, interactive_shell, last_command_exit_value; + +/* How many `levels' of sourced files we have. */ +int sourcelevel = 0; + +/* If this . script is supplied arguments, we save the dollar vars and + replace them with the script arguments for the duration of the script's + execution. If the script does not change the dollar vars, we restore + what we saved. If the dollar vars are changed in the script, we leave + the new values alone and free the saved values. */ +static void +maybe_pop_dollar_vars () +{ + if (dollar_vars_changed ()) + { + dispose_saved_dollar_vars (); + set_dollar_vars_unchanged (); + } + else + pop_dollar_vars (); +} + +/* Read and execute commands from the file passed as argument. Guess what. + This cannot be done in a subshell, since things like variable assignments + take place in there. So, I open the file, place it into a large string, + close the file, and then execute the string. */ +source_builtin (list) + WORD_LIST *list; +{ + int result, return_val; + + /* Assume the best. */ + result = EXECUTION_SUCCESS; + + if (list) + { + char *string, *filename; + struct stat finfo; + int fd, tt; + + filename = find_path_file (list->word->word); + if (!filename) + filename = savestring (list->word->word); + + if (((fd = open (filename, O_RDONLY)) < 0) || (fstat (fd, &finfo) < 0)) + goto file_error_exit; + + string = (char *)xmalloc (1 + (int)finfo.st_size); + tt = read (fd, string, finfo.st_size); + string[finfo.st_size] = '\0'; + + /* Close the open file, preserving the state of errno. */ + { int temp = errno; close (fd); errno = temp; } + + if (tt != finfo.st_size) + { + free (string); + + file_error_exit: + file_error (filename); + free (filename); + + /* POSIX shells exit if non-interactive and file error. */ + if (posixly_correct && !interactive_shell) + { + last_command_exit_value = 1; + longjmp (top_level, EXITPROG); + } + + return (EXECUTION_FAILURE); + } + + if (tt > 80) + tt = 80; + + if (check_binary_file ((unsigned char *)string, tt)) + { + free (string); + builtin_error ("%s: cannot execute binary file", filename); + free (filename); + return (EX_BINARY_FILE); + } + + begin_unwind_frame ("File Sourcing"); + + if (list->next) + { + push_dollar_vars (); + add_unwind_protect ((Function *)maybe_pop_dollar_vars, (char *)NULL); + remember_args (list->next, 1); + } + + unwind_protect_int (return_catch_flag); + unwind_protect_jmp_buf (return_catch); + unwind_protect_int (interactive); + unwind_protect_int (sourcelevel); + add_unwind_protect ((Function *)xfree, filename); + interactive = 0; + sourcelevel++; + + set_dollar_vars_unchanged (); + + return_catch_flag++; + return_val = setjmp (return_catch); + + if (return_val) + parse_and_execute_cleanup (); + else + result = parse_and_execute (string, filename, -1); + + run_unwind_frame ("File Sourcing"); + + /* If RETURN_VAL is non-zero, then we return the value given + to return_builtin (), since that is how we got here. */ + if (return_val) + result = return_catch_value; + } + else + { + builtin_error ("filename argument required"); + result = EXECUTION_FAILURE; + } + return (result); +} |