| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | This file is source.def, from which is created source.c. | 
					
						
							|  |  |  | It implements the builtins "." and  "source" in Bash. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  | Copyright (C) 1987-2009 Free Software Foundation, Inc. | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | This file is part of GNU Bash, the Bourne Again SHell. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  | 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 3 of the License, or | 
					
						
							|  |  |  | (at your option) any later version. | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  | 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. | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  | You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  | along with Bash.  If not, see <http://www.gnu.org/licenses/>. | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | $PRODUCES source.c | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | $BUILTIN source | 
					
						
							|  |  |  | $FUNCTION source_builtin | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  | $SHORT_DOC source filename [arguments] | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  | Execute commands from a file in the current shell. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Read and execute commands from FILENAME in the current shell.  The | 
					
						
							|  |  |  | entries in $PATH are used to find the directory containing FILENAME. | 
					
						
							|  |  |  | If any ARGUMENTS are supplied, they become the positional parameters | 
					
						
							|  |  |  | when FILENAME is executed. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Exit Status: | 
					
						
							|  |  |  | Returns the status of the last command executed in FILENAME; fails if | 
					
						
							|  |  |  | FILENAME cannot be read. | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | $END | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | $BUILTIN . | 
					
						
							|  |  |  | $DOCNAME dot | 
					
						
							|  |  |  | $FUNCTION source_builtin | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  | $SHORT_DOC . filename [arguments] | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  | Execute commands from a file in the current shell. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Read and execute commands from FILENAME in the current shell.  The | 
					
						
							|  |  |  | entries in $PATH are used to find the directory containing FILENAME. | 
					
						
							|  |  |  | If any ARGUMENTS are supplied, they become the positional parameters | 
					
						
							|  |  |  | when FILENAME is executed. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Exit Status: | 
					
						
							|  |  |  | Returns the status of the last command executed in FILENAME; fails if | 
					
						
							|  |  |  | FILENAME cannot be read. | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | $END | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #include <config.h> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "../bashtypes.h" | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | #include "posixstat.h" | 
					
						
							|  |  |  | #include "filecntl.h" | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  | #if ! defined(_MINIX) && defined (HAVE_SYS_FILE_H) | 
					
						
							| 
									
										
										
										
											1998-04-17 19:52:44 +00:00
										 |  |  | #  include <sys/file.h> | 
					
						
							|  |  |  | #endif | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | #include <errno.h> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #if defined (HAVE_UNISTD_H) | 
					
						
							|  |  |  | #  include <unistd.h> | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "../bashansi.h" | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  | #include "../bashintl.h" | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "../shell.h" | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  | #include "../flags.h" | 
					
						
							| 
									
										
										
										
											1998-04-17 19:52:44 +00:00
										 |  |  | #include "../findcmd.h" | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #include "common.h" | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | #include "bashgetopt.h" | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  | #include "../trap.h" | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if !defined (errno) | 
					
						
							|  |  |  | extern int errno; | 
					
						
							|  |  |  | #endif /* !errno */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  | extern int posixly_correct; | 
					
						
							| 
									
										
										
										
											2011-11-22 19:11:26 -05:00
										 |  |  | extern int last_command_exit_value; | 
					
						
							|  |  |  | extern int executing_command_builtin; | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-10 14:15:34 +00:00
										 |  |  | static void maybe_pop_dollar_vars __P((void)); | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | /* If non-zero, `.' uses $PATH to look up the script to be sourced. */ | 
					
						
							|  |  |  | int source_uses_path = 1; | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | /* If non-zero, `.' looks in the current directory if the filename argument | 
					
						
							|  |  |  |    is not found in the $PATH. */ | 
					
						
							|  |  |  | int source_searches_cwd = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | /* 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 | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |    what we saved.  If the dollar vars are changed in the script, and we are | 
					
						
							|  |  |  |    not executing a shell function, we leave the new values alone and free | 
					
						
							|  |  |  |    the saved values. */ | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | static void | 
					
						
							|  |  |  | maybe_pop_dollar_vars () | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |   if (variable_context == 0 && (dollar_vars_changed () & ARGS_SETBLTIN)) | 
					
						
							|  |  |  |     dispose_saved_dollar_vars (); | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  |   else | 
					
						
							|  |  |  |     pop_dollar_vars (); | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  |   if (debugging_mode) | 
					
						
							|  |  |  |     pop_args ();	/* restore BASH_ARGC and BASH_ARGV */ | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |   set_dollar_vars_unchanged (); | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* 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. */ | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | int | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | source_builtin (list) | 
					
						
							|  |  |  |      WORD_LIST *list; | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   int result; | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  |   char *filename, *debug_trap; | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |   if (no_options (list)) | 
					
						
							|  |  |  |     return (EX_USAGE); | 
					
						
							|  |  |  |   list = loptend; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   if (list == 0) | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  |       builtin_error (_("filename argument required")); | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |       builtin_usage (); | 
					
						
							|  |  |  |       return (EX_USAGE); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #if defined (RESTRICTED_SHELL) | 
					
						
							|  |  |  |   if (restricted && strchr (list->word->word, '/')) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |       sh_restricted (list->word->word); | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |       return (EXECUTION_FAILURE); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   filename = (char *)NULL; | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |   /* XXX -- should this be absolute_pathname? */ | 
					
						
							|  |  |  |   if (posixly_correct && strchr (list->word->word, '/')) | 
					
						
							|  |  |  |     filename = savestring (list->word->word); | 
					
						
							|  |  |  |   else if (absolute_pathname (list->word->word)) | 
					
						
							|  |  |  |     filename = savestring (list->word->word); | 
					
						
							|  |  |  |   else if (source_uses_path) | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |     filename = find_path_file (list->word->word); | 
					
						
							|  |  |  |   if (filename == 0) | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |     { | 
					
						
							|  |  |  |       if (source_searches_cwd == 0) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  | 	  builtin_error (_("%s: file not found"), list->word->word); | 
					
						
							| 
									
										
										
										
											2011-11-22 19:11:26 -05:00
										 |  |  | 	  if (posixly_correct && interactive_shell == 0 && executing_command_builtin == 0) | 
					
						
							|  |  |  | 	    { | 
					
						
							|  |  |  | 	      last_command_exit_value = 1; | 
					
						
							|  |  |  | 	      jump_to_top_level (EXITPROG); | 
					
						
							|  |  |  | 	    } | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | 	  return (EXECUTION_FAILURE); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  | 	filename = savestring (list->word->word); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   begin_unwind_frame ("source"); | 
					
						
							|  |  |  |   add_unwind_protect ((Function *)xfree, filename); | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   if (list->next) | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |       push_dollar_vars (); | 
					
						
							|  |  |  |       add_unwind_protect ((Function *)maybe_pop_dollar_vars, (char *)NULL); | 
					
						
							|  |  |  |       remember_args (list->next, 1); | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  |       if (debugging_mode) | 
					
						
							|  |  |  | 	push_args (list->next);	/* Update BASH_ARGV and BASH_ARGC */ | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   set_dollar_vars_unchanged (); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  |   /* Don't inherit the DEBUG trap unless function_trace_mode (overloaded) | 
					
						
							|  |  |  |      is set.  XXX - should sourced files inherit the RETURN trap?  Functions | 
					
						
							|  |  |  |      don't. */ | 
					
						
							|  |  |  |   debug_trap = TRAP_STRING (DEBUG_TRAP); | 
					
						
							|  |  |  |   if (debug_trap && function_trace_mode == 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       debug_trap = savestring (debug_trap); | 
					
						
							|  |  |  |       add_unwind_protect (xfree, debug_trap); | 
					
						
							|  |  |  |       add_unwind_protect (set_debug_trap, debug_trap); | 
					
						
							|  |  |  |       restore_default_signal (DEBUG_TRAP); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   result = source_file (filename, (list && list->next)); | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   run_unwind_frame ("source"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  |   return (result); | 
					
						
							|  |  |  | } |