aboutsummaryrefslogtreecommitdiffstats
path: root/builtins/source.def
diff options
context:
space:
mode:
authorJari Aalto <jari.aalto@cante.net>1996-08-26 18:22:31 +0000
committerJari Aalto <jari.aalto@cante.net>2009-09-12 16:46:49 +0000
commit726f63884db0132f01745f1fb4465e6621088ccf (patch)
tree6c2f7765a890a97e0e513cb539df43283a8f7c4d /builtins/source.def
downloadandroid_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.def186
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);
+}