Imported from ../bash-3.0.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 #if defined (RESTRICTED_SHELL)
72 extern int restricted;
73 #endif
74
75 /* If non-zero, `.' uses $PATH to look up the script to be sourced. */
76 int source_uses_path = 1;
77
78 /* If non-zero, `.' looks in the current directory if the filename argument
79    is not found in the $PATH. */
80 int source_searches_cwd = 1;
81
82 /* If this . script is supplied arguments, we save the dollar vars and
83    replace them with the script arguments for the duration of the script's
84    execution.  If the script does not change the dollar vars, we restore
85    what we saved.  If the dollar vars are changed in the script, and we are
86    not executing a shell function, we leave the new values alone and free
87    the saved values. */
88 static void
89 maybe_pop_dollar_vars ()
90 {
91   if (variable_context == 0 && (dollar_vars_changed () & ARGS_SETBLTIN))
92     dispose_saved_dollar_vars ();
93   else
94     pop_dollar_vars ();
95   if (debugging_mode)
96     pop_args ();        /* restore BASH_ARGC and BASH_ARGV */
97   set_dollar_vars_unchanged ();
98 }
99
100 /* Read and execute commands from the file passed as argument.  Guess what.
101    This cannot be done in a subshell, since things like variable assignments
102    take place in there.  So, I open the file, place it into a large string,
103    close the file, and then execute the string. */
104 int
105 source_builtin (list)
106      WORD_LIST *list;
107 {
108   int result;
109   char *filename, *debug_trap;
110
111   if (no_options (list))
112     return (EX_USAGE);
113   list = loptend;
114
115   if (list == 0)
116     {
117       builtin_error (_("filename argument required"));
118       builtin_usage ();
119       return (EX_USAGE);
120     }
121
122 #if defined (RESTRICTED_SHELL)
123   if (restricted && strchr (list->word->word, '/'))
124     {
125       sh_restricted (list->word->word);
126       return (EXECUTION_FAILURE);
127     }
128 #endif
129
130   filename = (char *)NULL;
131   if (source_uses_path)
132     filename = find_path_file (list->word->word);
133   if (filename == 0)
134     {
135       if (source_searches_cwd == 0)
136         {
137           builtin_error (_("%s: file not found"), list->word->word);
138           return (EXECUTION_FAILURE);
139         }
140       else
141         filename = savestring (list->word->word);
142     }
143
144   begin_unwind_frame ("source");
145   add_unwind_protect ((Function *)xfree, filename);
146
147   if (list->next)
148     {
149       push_dollar_vars ();
150       add_unwind_protect ((Function *)maybe_pop_dollar_vars, (char *)NULL);
151       remember_args (list->next, 1);
152       if (debugging_mode)
153         push_args (list->next); /* Update BASH_ARGV and BASH_ARGC */
154     }
155   set_dollar_vars_unchanged ();
156
157   /* Don't inherit the DEBUG trap unless function_trace_mode (overloaded)
158      is set.  XXX - should sourced files inherit the RETURN trap?  Functions
159      don't. */
160   debug_trap = TRAP_STRING (DEBUG_TRAP);
161   if (debug_trap && function_trace_mode == 0)
162     {
163       debug_trap = savestring (debug_trap);
164       add_unwind_protect (xfree, debug_trap);
165       add_unwind_protect (set_debug_trap, debug_trap);
166       restore_default_signal (DEBUG_TRAP);
167     }
168
169   result = source_file (filename, (list && list->next));
170
171   run_unwind_frame ("source");
172
173   return (result);
174 }