]> git.ipfire.org Git - thirdparty/bash.git/blob - builtins/setattr.def
Imported from ../bash-2.0.tar.gz.
[thirdparty/bash.git] / builtins / setattr.def
1 This file is setattr.def, from which is created setattr.c.
2 It implements the builtins "export" and "readonly", 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
10 Software Foundation; either version 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA.
21
22 $PRODUCES setattr.c
23
24 #include <config.h>
25
26 #if defined (HAVE_UNISTD_H)
27 # include <unistd.h>
28 #endif
29
30 #include <stdio.h>
31 #include "../bashansi.h"
32
33 #include "../shell.h"
34 #include "common.h"
35 #include "bashgetopt.h"
36
37 extern int array_needs_making;
38 extern char *this_command_name;
39
40 $BUILTIN export
41 $FUNCTION export_builtin
42 $SHORT_DOC export [-nf] [name ...] or export -p
43 NAMEs are marked for automatic export to the environment of
44 subsequently executed commands. If the -f option is given,
45 the NAMEs refer to functions. If no NAMEs are given, or if `-p'
46 is given, a list of all names that are exported in this shell is
47 printed. An argument of `-n' says to remove the export property
48 from subsequent NAMEs. An argument of `--' disables further option
49 processing.
50 $END
51
52 /* For each variable name in LIST, make that variable appear in the
53 environment passed to simple commands. If there is no LIST, then
54 print all such variables. An argument of `-n' says to remove the
55 exported attribute from variables named in LIST. An argument of
56 -f indicates that the names present in LIST refer to functions. */
57 int
58 export_builtin (list)
59 register WORD_LIST *list;
60 {
61 return (set_or_show_attributes (list, att_exported, 0));
62 }
63
64 $BUILTIN readonly
65 $FUNCTION readonly_builtin
66 $SHORT_DOC readonly [-anf] [name ...] or readonly -p
67 The given NAMEs are marked readonly and the values of these NAMEs may
68 not be changed by subsequent assignment. If the -f option is given,
69 then functions corresponding to the NAMEs are so marked. If no
70 arguments are given, or if `-p' is given, a list of all readonly names
71 is printed. An argument of `-n' says to remove the readonly property
72 from subsequent NAMEs. The `-a' option means to treat each NAME as
73 an array variable. An argument of `--' disables further option
74 processing.
75 $END
76
77 /* For each variable name in LIST, make that variable readonly. Given an
78 empty LIST, print out all existing readonly variables. */
79 int
80 readonly_builtin (list)
81 register WORD_LIST *list;
82 {
83 return (set_or_show_attributes (list, att_readonly, 0));
84 }
85
86 /* For each variable name in LIST, make that variable have the specified
87 ATTRIBUTE. An arg of `-n' says to remove the attribute from the the
88 remaining names in LIST. */
89 int
90 set_or_show_attributes (list, attribute, nodefs)
91 register WORD_LIST *list;
92 int attribute, nodefs;
93 {
94 register SHELL_VAR *var;
95 int assign, undo, functions_only, arrays_only, any_failed, assign_error, opt;
96 char *name;
97
98 undo = functions_only = arrays_only = any_failed = assign_error = 0;
99 /* Read arguments from the front of the list. */
100 reset_internal_getopt ();
101 while ((opt = internal_getopt (list, "anfp")) != -1)
102 {
103 switch (opt)
104 {
105 case 'n':
106 undo = 1;
107 break;
108 case 'f':
109 functions_only = 1;
110 break;
111 #if defined (ARRAY_VARS)
112 case 'a':
113 arrays_only = 1;
114 break;
115 #endif
116 case 'p':
117 break;
118 default:
119 builtin_usage ();
120 return (EX_USAGE);
121 }
122 }
123 list = loptend;
124
125 if (list)
126 {
127 if (attribute & att_exported)
128 array_needs_making = 1;
129
130 /* Cannot undo readonly status, silently disallowed. */
131 if (undo && (attribute & att_readonly))
132 attribute &= ~att_readonly;
133
134 while (list)
135 {
136 name = list->word->word;
137
138 if (functions_only) /* xxx -f name */
139 {
140 var = find_function (name);
141 if (var == 0)
142 {
143 builtin_error ("%s: not a function", name);
144 any_failed++;
145 }
146 else
147 SETVARATTR (var, attribute, undo);
148
149 list = list->next;
150 continue;
151 }
152
153 /* xxx [-np] name[=value] */
154 assign = assignment (name);
155
156 if (assign)
157 name[assign] = '\0';
158
159 if (legal_identifier (name) == 0)
160 {
161 builtin_error ("`%s': not a valid identifier", name);
162 assign_error++;
163 list = list->next;
164 continue;
165 }
166
167 if (assign) /* xxx [-np] name=value */
168 {
169 name[assign] = '=';
170 /* This word has already been expanded once with command
171 and parameter expansion. Call do_assignment_no_expand (),
172 which does not do command or parameter substitution. If
173 the assignment is not performed correctly, flag an error. */
174 if (do_assignment_no_expand (name) == 0)
175 assign_error++;
176 name[assign] = '\0';
177 }
178
179 set_var_attribute (name, attribute, undo);
180 list = list->next;
181 }
182 }
183 else
184 {
185 SHELL_VAR **variable_list;
186 register int i;
187
188 if ((attribute & att_function) || functions_only)
189 {
190 variable_list = all_shell_functions ();
191 if (attribute != att_function)
192 attribute &= ~att_function; /* so declare -xf works, for example */
193 }
194 else
195 variable_list = all_shell_variables ();
196
197 #if defined (ARRAY_VARS)
198 if (attribute & att_array)
199 {
200 arrays_only++;
201 if (attribute != att_array)
202 attribute &= ~att_array;
203 }
204 #endif
205
206 if (variable_list)
207 {
208 for (i = 0; var = variable_list[i]; i++)
209 {
210 #if defined (ARRAY_VARS)
211 if (arrays_only && array_p (var) == 0)
212 continue;
213 #endif
214 if ((var->attributes & attribute) && invisible_p (var) == 0)
215 show_var_attributes (var, nodefs);
216 }
217 free (variable_list);
218 }
219 }
220
221 return (assign_error ? EX_BADASSIGN
222 : ((any_failed == 0) ? EXECUTION_SUCCESS
223 : EXECUTION_FAILURE));
224 }
225
226 int
227 show_var_attributes (var, nodefs)
228 SHELL_VAR *var;
229 int nodefs;
230 {
231 char flags[6], *x;
232 int i;
233
234 i = 0;
235
236 #if defined (ARRAY_VARS)
237 if (array_p (var))
238 flags[i++] = 'a';
239 #endif
240
241 if (function_p (var))
242 flags[i++] = 'f';
243
244 if (integer_p (var))
245 flags[i++] = 'i';
246
247 if (readonly_p (var))
248 flags[i++] = 'r';
249
250 if (exported_p (var))
251 flags[i++] = 'x';
252
253 flags[i] = '\0';
254
255 printf ("declare -%s ", i ? flags : "-");
256
257 #if defined (ARRAY_VARS)
258 if (array_p (var))
259 print_array_assignment (var, 1);
260 else
261 #endif
262 if (nodefs)
263 printf ("%s\n", var->name);
264 else if (function_p (var))
265 printf ("%s\n", named_function_string (var->name, function_cell (var), 1));
266 else
267 {
268 x = double_quote (value_cell (var));
269 printf ("%s=%s\n", var->name, x);
270 free (x);
271 }
272 return (0);
273 }
274
275 int
276 show_name_attributes (name, nodefs)
277 char *name;
278 int nodefs;
279 {
280 SHELL_VAR *var;
281
282 var = find_tempenv_variable (name);
283 if (var == 0)
284 var = find_variable (name);
285
286 if (var && invisible_p (var) == 0)
287 {
288 show_var_attributes (var, nodefs);
289 return (0);
290 }
291 else
292 return (1);
293 }
294
295 void
296 set_var_attribute (name, attribute, undo)
297 char *name;
298 int attribute, undo;
299 {
300 SHELL_VAR *var, *tv;
301
302 if (undo)
303 var = find_variable (name);
304 else
305 {
306 if (tv = find_tempenv_variable (name))
307 {
308 var = bind_variable (tv->name, tv->value);
309 dispose_variable (tv);
310 }
311 else
312 var = find_variable (name);
313
314 if (var == 0)
315 {
316 var = bind_variable (name, (char *)NULL);
317 var->attributes |= att_invisible;
318 }
319 }
320
321 if (var)
322 SETVARATTR (var, attribute, undo);
323
324 if (var && ((var->attributes & att_exported) || (attribute & att_exported)))
325 array_needs_making++; /* XXX */
326 }