Imported from ../bash-3.2.tar.gz.
[platform/upstream/bash.git] / builtins / source.def
1 This file is source.def, from which is created source.c.
2 It implements the builtins "." and  "source" in Bash.
3
4 Copyright (C) 1987-2003 Free Software Foundation, Inc.
5
6 This file is part of GNU Bash, the Bourne Again SHell.
7
8 Bash is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
12
13 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with Bash; see the file COPYING.  If not, write to the Free Software
20 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
21
22 $PRODUCES source.c
23
24 $BUILTIN source
25 $FUNCTION source_builtin
26 $SHORT_DOC source filename [arguments]
27 Read and execute commands from FILENAME and return.  The pathnames
28 in $PATH are used to find the directory containing FILENAME.  If any
29 ARGUMENTS are supplied, they become the positional parameters when
30 FILENAME is executed.
31 $END
32 $BUILTIN .
33 $DOCNAME dot
34 $FUNCTION source_builtin
35 $SHORT_DOC . filename [arguments]
36 Read and execute commands from FILENAME and return.  The pathnames
37 in $PATH are used to find the directory containing FILENAME.  If any
38 ARGUMENTS are supplied, they become the positional parameters when
39 FILENAME is executed.
40 $END
41 /* source.c - Implements the `.' and `source' builtins. */
42
43 #include <config.h>
44
45 #include "../bashtypes.h"
46 #include "posixstat.h"
47 #include "filecntl.h"
48 #if ! defined(_MINIX) && defined (HAVE_SYS_FILE_H)
49 #  include <sys/file.h>
50 #endif
51 #include <errno.h>
52
53 #if defined (HAVE_UNISTD_H)
54 #  include <unistd.h>
55 #endif
56
57 #include "../bashansi.h"
58 #include "../bashintl.h"
59
60 #include "../shell.h"
61 #include "../flags.h"
62 #include "../findcmd.h"
63 #include "common.h"
64 #include "bashgetopt.h"
65 #include "../trap.h"
66
67 #if !defined (errno)
68 extern int errno;
69 #endif /* !errno */
70
71 static void maybe_pop_dollar_vars __P((void));
72
73 /* If non-zero, `.' uses $PATH to look up the script to be sourced. */
74 int source_uses_path = 1;
75
76 /* If non-zero, `.' looks in the current directory if the filename argument
77    is not found in the $PATH. */
78 int source_searches_cwd = 1;
79
80 /* If this . script is supplied arguments, we save the dollar vars and
81    replace them with the script arguments for the duration of the script's
82    execution.  If the script does not change the dollar vars, we restore
83    what we saved.  If the dollar vars are changed in the script, and we are
84    not executing a shell function, we leave the new values alone and free
85    the saved values. */
86 static void
87 maybe_pop_dollar_vars ()
88 {
89   if (variable_context == 0 && (dollar_vars_changed () & ARGS_SETBLTIN))
90     dispose_saved_dollar_vars ();
91   else
92     pop_dollar_vars ();
93   if (debugging_mode)
94     pop_args ();        /* restore BASH_ARGC and BASH_ARGV */
95   set_dollar_vars_unchanged ();
96 }
97
98 /* Read and execute commands from the file passed as argument.  Guess what.
99    This cannot be done in a subshell, since things like variable assignments
100    take place in there.  So, I open the file, place it into a large string,
101    close the file, and then execute the string. */
102 int
103 source_builtin (list)
104      WORD_LIST *list;
105 {
106   int result;
107   char *filename, *debug_trap;
108
109   if (no_options (list))
110     return (EX_USAGE);
111   list = loptend;
112
113   if (list == 0)
114     {
115       builtin_error (_("filename argument required"));
116       builtin_usage ();
117       return (EX_USAGE);
118     }
119
120 #if defined (RESTRICTED_SHELL)
121   if (restricted && strchr (list->word->word, '/'))
122     {
123       sh_restricted (list->word->word);
124       return (EXECUTION_FAILURE);
125     }
126 #endif
127
128   filename = (char *)NULL;
129   if (source_uses_path)
130     filename = find_path_file (list->word->word);
131   if (filename == 0)
132     {
133       if (source_searches_cwd == 0)
134         {
135           builtin_error (_("%s: file not found"), list->word->word);
136           return (EXECUTION_FAILURE);
137         }
138       else
139         filename = savestring (list->word->word);
140     }
141
142   begin_unwind_frame ("source");
143   add_unwind_protect ((Function *)xfree, filename);
144
145   if (list->next)
146     {
147       push_dollar_vars ();
148       add_unwind_protect ((Function *)maybe_pop_dollar_vars, (char *)NULL);
149       remember_args (list->next, 1);
150       if (debugging_mode)
151         push_args (list->next); /* Update BASH_ARGV and BASH_ARGC */
152     }
153   set_dollar_vars_unchanged ();
154
155   /* Don't inherit the DEBUG trap unless function_trace_mode (overloaded)
156      is set.  XXX - should sourced files inherit the RETURN trap?  Functions
157      don't. */
158   debug_trap = TRAP_STRING (DEBUG_TRAP);
159   if (debug_trap && function_trace_mode == 0)
160     {
161       debug_trap = savestring (debug_trap);
162       add_unwind_protect (xfree, debug_trap);
163       add_unwind_protect (set_debug_trap, debug_trap);
164       restore_default_signal (DEBUG_TRAP);
165     }
166
167   result = source_file (filename, (list && list->next));
168
169   run_unwind_frame ("source");
170
171   return (result);
172 }