Patch-ID: bash32-017
[bash.git] / builtins / setattr.def
blob28102bc472ffdcbc1ec93bca9e63e533370d0672
1 This file is setattr.def, from which is created setattr.c.
2 It implements the builtins "export" and "readonly", in Bash.
4 Copyright (C) 1987-2004 Free Software Foundation, Inc.
6 This file is part of GNU Bash, the Bourne Again SHell.
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.
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.
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.
22 $PRODUCES setattr.c
24 #include <config.h>
26 #if defined (HAVE_UNISTD_H)
27 # ifdef _MINIX
28 # include <sys/types.h>
29 # endif
30 # include <unistd.h>
31 #endif
33 #include <stdio.h>
34 #include "../bashansi.h"
35 #include "../bashintl.h"
37 #include "../shell.h"
38 #include "common.h"
39 #include "bashgetopt.h"
41 extern int posixly_correct;
42 extern int array_needs_making;
43 extern char *this_command_name;
44 extern sh_builtin_func_t *this_shell_builtin;
46 #ifdef ARRAY_VARS
47 extern int declare_builtin __P((WORD_LIST *));
48 #endif
50 #define READONLY_OR_EXPORT \
51 (this_shell_builtin == readonly_builtin || this_shell_builtin == export_builtin)
53 $BUILTIN export
54 $FUNCTION export_builtin
55 $SHORT_DOC export [-nf] [name[=value] ...] or export -p
56 NAMEs are marked for automatic export to the environment of
57 subsequently executed commands. If the -f option is given,
58 the NAMEs refer to functions. If no NAMEs are given, or if `-p'
59 is given, a list of all names that are exported in this shell is
60 printed. An argument of `-n' says to remove the export property
61 from subsequent NAMEs. An argument of `--' disables further option
62 processing.
63 $END
65 /* For each variable name in LIST, make that variable appear in the
66 environment passed to simple commands. If there is no LIST, then
67 print all such variables. An argument of `-n' says to remove the
68 exported attribute from variables named in LIST. An argument of
69 -f indicates that the names present in LIST refer to functions. */
70 int
71 export_builtin (list)
72 register WORD_LIST *list;
74 return (set_or_show_attributes (list, att_exported, 0));
77 $BUILTIN readonly
78 $FUNCTION readonly_builtin
79 $SHORT_DOC readonly [-af] [name[=value] ...] or readonly -p
80 The given NAMEs are marked readonly and the values of these NAMEs may
81 not be changed by subsequent assignment. If the -f option is given,
82 then functions corresponding to the NAMEs are so marked. If no
83 arguments are given, or if `-p' is given, a list of all readonly names
84 is printed. The `-a' option means to treat each NAME as
85 an array variable. An argument of `--' disables further option
86 processing.
87 $END
89 /* For each variable name in LIST, make that variable readonly. Given an
90 empty LIST, print out all existing readonly variables. */
91 int
92 readonly_builtin (list)
93 register WORD_LIST *list;
95 return (set_or_show_attributes (list, att_readonly, 0));
98 #if defined (ARRAY_VARS)
99 # define ATTROPTS "afnp"
100 #else
101 # define ATTROPTS "fnp"
102 #endif
104 /* For each variable name in LIST, make that variable have the specified
105 ATTRIBUTE. An arg of `-n' says to remove the attribute from the the
106 remaining names in LIST (doesn't work for readonly). */
108 set_or_show_attributes (list, attribute, nodefs)
109 register WORD_LIST *list;
110 int attribute, nodefs;
112 register SHELL_VAR *var;
113 int assign, undo, functions_only, arrays_only, any_failed, assign_error, opt;
114 int aflags;
115 char *name;
116 #if defined (ARRAY_VARS)
117 WORD_LIST *nlist, *tlist;
118 WORD_DESC *w;
119 #endif
121 undo = functions_only = arrays_only = any_failed = assign_error = 0;
122 /* Read arguments from the front of the list. */
123 reset_internal_getopt ();
124 while ((opt = internal_getopt (list, ATTROPTS)) != -1)
126 switch (opt)
128 case 'n':
129 undo = 1;
130 break;
131 case 'f':
132 functions_only = 1;
133 break;
134 #if defined (ARRAY_VARS)
135 case 'a':
136 arrays_only = 1;
137 break;
138 #endif
139 case 'p':
140 break;
141 default:
142 builtin_usage ();
143 return (EX_USAGE);
146 list = loptend;
148 if (list)
150 if (attribute & att_exported)
151 array_needs_making = 1;
153 /* Cannot undo readonly status, silently disallowed. */
154 if (undo && (attribute & att_readonly))
155 attribute &= ~att_readonly;
157 while (list)
159 name = list->word->word;
161 if (functions_only) /* xxx -f name */
163 var = find_function (name);
164 if (var == 0)
166 builtin_error (_("%s: not a function"), name);
167 any_failed++;
169 else
170 SETVARATTR (var, attribute, undo);
172 list = list->next;
173 continue;
176 /* xxx [-np] name[=value] */
177 assign = assignment (name, 0);
179 aflags = 0;
180 if (assign)
182 name[assign] = '\0';
183 if (name[assign - 1] == '+')
185 aflags |= ASS_APPEND;
186 name[assign - 1] = '\0';
190 if (legal_identifier (name) == 0)
192 sh_invalidid (name);
193 if (assign)
194 assign_error++;
195 else
196 any_failed++;
197 list = list->next;
198 continue;
201 if (assign) /* xxx [-np] name=value */
203 name[assign] = '=';
204 if (aflags & ASS_APPEND)
205 name[assign - 1] = '+';
206 #if defined (ARRAY_VARS)
207 /* Let's try something here. Turn readonly -a xxx=yyy into
208 declare -ra xxx=yyy and see what that gets us. */
209 if (arrays_only)
211 tlist = list->next;
212 list->next = (WORD_LIST *)NULL;
213 w = make_word ("-ra");
214 nlist = make_word_list (w, list);
215 opt = declare_builtin (nlist);
216 if (opt != EXECUTION_SUCCESS)
217 assign_error++;
218 list->next = tlist;
219 dispose_word (w);
220 free (nlist);
222 else
223 #endif
224 /* This word has already been expanded once with command
225 and parameter expansion. Call do_assignment_no_expand (),
226 which does not do command or parameter substitution. If
227 the assignment is not performed correctly, flag an error. */
228 if (do_assignment_no_expand (name) == 0)
229 assign_error++;
230 name[assign] = '\0';
231 if (aflags & ASS_APPEND)
232 name[assign - 1] = '\0';
235 set_var_attribute (name, attribute, undo);
236 list = list->next;
239 else
241 SHELL_VAR **variable_list;
242 register int i;
244 if ((attribute & att_function) || functions_only)
246 variable_list = all_shell_functions ();
247 if (attribute != att_function)
248 attribute &= ~att_function; /* so declare -xf works, for example */
250 else
251 variable_list = all_shell_variables ();
253 #if defined (ARRAY_VARS)
254 if (attribute & att_array)
256 arrays_only++;
257 if (attribute != att_array)
258 attribute &= ~att_array;
260 #endif
262 if (variable_list)
264 for (i = 0; var = variable_list[i]; i++)
266 #if defined (ARRAY_VARS)
267 if (arrays_only && array_p (var) == 0)
268 continue;
269 #endif
270 if ((var->attributes & attribute))
271 show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
273 free (variable_list);
277 return (assign_error ? EX_BADASSIGN
278 : ((any_failed == 0) ? EXECUTION_SUCCESS
279 : EXECUTION_FAILURE));
282 /* Show the attributes for shell variable VAR. If NODEFS is non-zero,
283 don't show function definitions along with the name. If PATTR is
284 non-zero, it indicates we're being called from `export' or `readonly'.
285 In POSIX mode, this prints the name of the calling builtin (`export'
286 or `readonly') instead of `declare', and doesn't print function defs
287 when called by `export' or `readonly'. */
289 show_var_attributes (var, pattr, nodefs)
290 SHELL_VAR *var;
291 int pattr, nodefs;
293 char flags[8], *x;
294 int i;
296 i = 0;
298 /* pattr == 0 means we are called from `declare'. */
299 if (pattr == 0 || posixly_correct == 0)
301 #if defined (ARRAY_VARS)
302 if (array_p (var))
303 flags[i++] = 'a';
304 #endif
306 if (function_p (var))
307 flags[i++] = 'f';
309 if (integer_p (var))
310 flags[i++] = 'i';
312 if (readonly_p (var))
313 flags[i++] = 'r';
315 if (trace_p (var))
316 flags[i++] = 't';
318 if (exported_p (var))
319 flags[i++] = 'x';
321 else
323 #if defined (ARRAY_VARS)
324 if (array_p (var))
325 flags[i++] = 'a';
326 #endif
328 if (function_p (var))
329 flags[i++] = 'f';
332 flags[i] = '\0';
334 /* If we're printing functions with definitions, print the function def
335 first, then the attributes, instead of printing output that can't be
336 reused as input to recreate the current state. */
337 if (function_p (var) && nodefs == 0 && (pattr == 0 || posixly_correct == 0))
339 printf ("%s\n", named_function_string (var->name, function_cell (var), 1));
340 nodefs++;
341 if (pattr == 0 && i == 1 && flags[0] == 'f')
342 return 0; /* don't print `declare -f name' */
345 if (pattr == 0 || posixly_correct == 0)
346 printf ("declare -%s ", i ? flags : "-");
347 else if (i)
348 printf ("%s -%s ", this_command_name, flags);
349 else
350 printf ("%s ", this_command_name);
352 #if defined (ARRAY_VARS)
353 if (array_p (var))
354 print_array_assignment (var, 1);
355 else
356 #endif
357 /* force `readonly' and `export' to not print out function definitions
358 when in POSIX mode. */
359 if (nodefs || (function_p (var) && pattr != 0 && posixly_correct))
360 printf ("%s\n", var->name);
361 else if (function_p (var))
362 printf ("%s\n", named_function_string (var->name, function_cell (var), 1));
363 else if (invisible_p (var))
364 printf ("%s\n", var->name);
365 else
367 x = sh_double_quote (var_isset (var) ? value_cell (var) : "");
368 printf ("%s=%s\n", var->name, x);
369 free (x);
371 return (0);
375 show_name_attributes (name, nodefs)
376 char *name;
377 int nodefs;
379 SHELL_VAR *var;
381 var = find_variable_internal (name, 1);
383 if (var && invisible_p (var) == 0)
385 show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
386 return (0);
388 else
389 return (1);
392 void
393 set_var_attribute (name, attribute, undo)
394 char *name;
395 int attribute, undo;
397 SHELL_VAR *var, *tv;
398 char *tvalue;
400 if (undo)
401 var = find_variable (name);
402 else
404 tv = find_tempenv_variable (name);
405 /* XXX -- need to handle case where tv is a temp variable in a
406 function-scope context, since function_env has been merged into
407 the local variables table. */
408 if (tv && tempvar_p (tv))
410 tvalue = var_isset (tv) ? savestring (value_cell (tv)) : savestring ("");
412 var = bind_variable (tv->name, tvalue, 0);
413 var->attributes |= tv->attributes & ~att_tempvar;
414 VSETATTR (tv, att_propagate);
415 if (var->context != 0)
416 VSETATTR (var, att_propagate);
417 SETVARATTR (tv, attribute, undo); /* XXX */
419 stupidly_hack_special_variables (tv->name);
421 free (tvalue);
423 else
425 var = find_variable_internal (name, 0);
426 if (var == 0)
428 var = bind_variable (name, (char *)NULL, 0);
429 VSETATTR (var, att_invisible);
431 else if (var->context != 0)
432 VSETATTR (var, att_propagate);
436 if (var)
437 SETVARATTR (var, attribute, undo);
439 if (var && (exported_p (var) || (attribute & att_exported)))
440 array_needs_making++; /* XXX */