]>
Commit | Line | Data |
---|---|---|
726f6388 JA |
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, 1989, 1991 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 | |
bb70624e | 10 | Software Foundation; either version 2, or (at your option) any later |
726f6388 JA |
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 | |
bb70624e | 20 | Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. |
726f6388 JA |
21 | |
22 | $PRODUCES source.c | |
23 | ||
24 | $BUILTIN source | |
25 | $FUNCTION source_builtin | |
26 | $SHORT_DOC source filename | |
27 | Read and execute commands from FILENAME and return. The pathnames | |
28 | in $PATH are used to find the directory containing FILENAME. | |
29 | $END | |
30 | $BUILTIN . | |
31 | $DOCNAME dot | |
32 | $FUNCTION source_builtin | |
33 | $SHORT_DOC . filename | |
34 | Read and execute commands from FILENAME and return. The pathnames | |
35 | in $PATH are used to find the directory containing FILENAME. | |
36 | $END | |
37 | /* source.c - Implements the `.' and `source' builtins. */ | |
38 | ||
ccc6cda3 JA |
39 | #include <config.h> |
40 | ||
41 | #include "../bashtypes.h" | |
bb70624e JA |
42 | #include "posixstat.h" |
43 | #include "filecntl.h" | |
cce855bc JA |
44 | #ifndef _MINIX |
45 | # include <sys/file.h> | |
46 | #endif | |
726f6388 JA |
47 | #include <errno.h> |
48 | ||
ccc6cda3 JA |
49 | #if defined (HAVE_UNISTD_H) |
50 | # include <unistd.h> | |
51 | #endif | |
52 | ||
53 | #include "../bashansi.h" | |
726f6388 JA |
54 | |
55 | #include "../shell.h" | |
cce855bc | 56 | #include "../findcmd.h" |
ccc6cda3 | 57 | #include "common.h" |
726f6388 | 58 | |
726f6388 JA |
59 | #if !defined (errno) |
60 | extern int errno; | |
61 | #endif /* !errno */ | |
62 | ||
ccc6cda3 JA |
63 | #if defined (RESTRICTED_SHELL) |
64 | extern int restricted; | |
65 | #endif | |
726f6388 | 66 | |
ccc6cda3 JA |
67 | /* If non-zero, `.' uses $PATH to look up the script to be sourced. */ |
68 | int source_uses_path = 1; | |
726f6388 | 69 | |
28ef6c31 JA |
70 | /* If non-zero, `.' looks in the current directory if the filename argument |
71 | is not found in the $PATH. */ | |
72 | int source_searches_cwd = 1; | |
73 | ||
726f6388 JA |
74 | /* If this . script is supplied arguments, we save the dollar vars and |
75 | replace them with the script arguments for the duration of the script's | |
76 | execution. If the script does not change the dollar vars, we restore | |
28ef6c31 JA |
77 | what we saved. If the dollar vars are changed in the script, and we are |
78 | not executing a shell function, we leave the new values alone and free | |
79 | the saved values. */ | |
726f6388 JA |
80 | static void |
81 | maybe_pop_dollar_vars () | |
82 | { | |
28ef6c31 | 83 | if (variable_context == 0 && dollar_vars_changed ()) |
726f6388 JA |
84 | { |
85 | dispose_saved_dollar_vars (); | |
86 | set_dollar_vars_unchanged (); | |
87 | } | |
88 | else | |
89 | pop_dollar_vars (); | |
90 | } | |
91 | ||
92 | /* Read and execute commands from the file passed as argument. Guess what. | |
93 | This cannot be done in a subshell, since things like variable assignments | |
94 | take place in there. So, I open the file, place it into a large string, | |
95 | close the file, and then execute the string. */ | |
ccc6cda3 | 96 | int |
726f6388 JA |
97 | source_builtin (list) |
98 | WORD_LIST *list; | |
99 | { | |
ccc6cda3 JA |
100 | int result; |
101 | char *filename; | |
726f6388 | 102 | |
ccc6cda3 | 103 | if (list == 0) |
726f6388 | 104 | { |
ccc6cda3 JA |
105 | builtin_error ("filename argument required"); |
106 | builtin_usage (); | |
107 | return (EX_USAGE); | |
108 | } | |
726f6388 | 109 | |
ccc6cda3 JA |
110 | if (no_options (list)) |
111 | return (EX_USAGE); | |
726f6388 | 112 | |
ccc6cda3 JA |
113 | #if defined (RESTRICTED_SHELL) |
114 | if (restricted && strchr (list->word->word, '/')) | |
115 | { | |
116 | builtin_error ("%s: restricted", list->word->word); | |
117 | return (EXECUTION_FAILURE); | |
118 | } | |
119 | #endif | |
726f6388 | 120 | |
ccc6cda3 JA |
121 | filename = (char *)NULL; |
122 | if (source_uses_path) | |
123 | filename = find_path_file (list->word->word); | |
124 | if (filename == 0) | |
28ef6c31 JA |
125 | { |
126 | if (source_searches_cwd == 0) | |
127 | { | |
128 | builtin_error ("%s: file not found", list->word->word); | |
129 | return (EXECUTION_FAILURE); | |
130 | } | |
131 | else | |
132 | filename = savestring (list->word->word); | |
133 | } | |
726f6388 | 134 | |
ccc6cda3 JA |
135 | begin_unwind_frame ("source"); |
136 | add_unwind_protect ((Function *)xfree, filename); | |
726f6388 | 137 | |
ccc6cda3 | 138 | if (list->next) |
726f6388 | 139 | { |
ccc6cda3 JA |
140 | push_dollar_vars (); |
141 | add_unwind_protect ((Function *)maybe_pop_dollar_vars, (char *)NULL); | |
142 | remember_args (list->next, 1); | |
726f6388 | 143 | } |
ccc6cda3 JA |
144 | set_dollar_vars_unchanged (); |
145 | ||
146 | result = source_file (filename); | |
147 | ||
148 | run_unwind_frame ("source"); | |
149 | ||
726f6388 JA |
150 | return (result); |
151 | } |