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-2002 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
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
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.
26 #if defined (HAVE_UNISTD_H)
28 # include <sys/types.h>
34 #include "../bashansi.h"
38 #include "bashgetopt.h"
40 extern int posixly_correct;
41 extern int array_needs_making;
42 extern char *this_command_name;
43 extern sh_builtin_func_t *this_shell_builtin;
46 extern int declare_builtin __P((WORD_LIST *));
49 #define READONLY_OR_EXPORT \
50 (this_shell_builtin == readonly_builtin || this_shell_builtin == export_builtin)
53 $FUNCTION export_builtin
54 $SHORT_DOC export [-nf] [name[=value] ...] or export -p
55 NAMEs are marked for automatic export to the environment of
56 subsequently executed commands. If the -f option is given,
57 the NAMEs refer to functions. If no NAMEs are given, or if `-p'
58 is given, a list of all names that are exported in this shell is
59 printed. An argument of `-n' says to remove the export property
60 from subsequent NAMEs. An argument of `--' disables further option
64 /* For each variable name in LIST, make that variable appear in the
65 environment passed to simple commands. If there is no LIST, then
66 print all such variables. An argument of `-n' says to remove the
67 exported attribute from variables named in LIST. An argument of
68 -f indicates that the names present in LIST refer to functions. */
71 register WORD_LIST *list;
73 return (set_or_show_attributes (list, att_exported, 0));
77 $FUNCTION readonly_builtin
78 $SHORT_DOC readonly [-anf] [name[=value] ...] or readonly -p
79 The given NAMEs are marked readonly and the values of these NAMEs may
80 not be changed by subsequent assignment. If the -f option is given,
81 then functions corresponding to the NAMEs are so marked. If no
82 arguments are given, or if `-p' is given, a list of all readonly names
83 is printed. An argument of `-n' says to remove the readonly property
84 from subsequent NAMEs. The `-a' option means to treat each NAME as
85 an array variable. An argument of `--' disables further option
89 /* For each variable name in LIST, make that variable readonly. Given an
90 empty LIST, print out all existing readonly variables. */
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"
101 # define ATTROPTS "fnp"
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. */
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;
115 #if defined (ARRAY_VARS)
116 WORD_LIST *nlist, *tlist;
120 undo = functions_only = arrays_only = any_failed = assign_error = 0;
121 /* Read arguments from the front of the list. */
122 reset_internal_getopt ();
123 while ((opt = internal_getopt (list, ATTROPTS)) != -1)
133 #if defined (ARRAY_VARS)
149 if (attribute & att_exported)
150 array_needs_making = 1;
152 /* Cannot undo readonly status, silently disallowed. */
153 if (undo && (attribute & att_readonly))
154 attribute &= ~att_readonly;
158 name = list->word->word;
160 if (functions_only) /* xxx -f name */
162 var = find_function (name);
165 builtin_error ("%s: not a function", name);
169 SETVARATTR (var, attribute, undo);
175 /* xxx [-np] name[=value] */
176 assign = assignment (name);
181 if (legal_identifier (name) == 0)
192 if (assign) /* xxx [-np] name=value */
195 #if defined (ARRAY_VARS)
196 /* Let's try something here. Turn readonly -a xxx=yyy into
197 declare -ra xxx=yyy and see what that gets us. */
201 list->next = (WORD_LIST *)NULL;
202 w = make_word ("-ra");
203 nlist = make_word_list (w, list);
204 opt = declare_builtin (nlist);
205 if (opt != EXECUTION_SUCCESS)
213 /* This word has already been expanded once with command
214 and parameter expansion. Call do_assignment_no_expand (),
215 which does not do command or parameter substitution. If
216 the assignment is not performed correctly, flag an error. */
217 if (do_assignment_no_expand (name) == 0)
222 set_var_attribute (name, attribute, undo);
228 SHELL_VAR **variable_list;
231 if ((attribute & att_function) || functions_only)
233 variable_list = all_shell_functions ();
234 if (attribute != att_function)
235 attribute &= ~att_function; /* so declare -xf works, for example */
238 variable_list = all_shell_variables ();
240 #if defined (ARRAY_VARS)
241 if (attribute & att_array)
244 if (attribute != att_array)
245 attribute &= ~att_array;
251 for (i = 0; var = variable_list[i]; i++)
253 #if defined (ARRAY_VARS)
254 if (arrays_only && array_p (var) == 0)
257 if ((var->attributes & attribute))
258 show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
260 free (variable_list);
264 return (assign_error ? EX_BADASSIGN
265 : ((any_failed == 0) ? EXECUTION_SUCCESS
266 : EXECUTION_FAILURE));
269 /* Show the attributes for shell variable VAR. If NODEFS is non-zero,
270 don't show function definitions along with the name. If PATTR is
271 non-zero, it indicates we're being called from `export' or `readonly'.
272 In POSIX mode, this prints the name of the calling builtin (`export'
273 or `readonly') instead of `declare', and doesn't print function defs
274 when called by `export' or `readonly'. */
276 show_var_attributes (var, pattr, nodefs)
285 /* pattr == 0 means we are called from `declare'. */
286 if (pattr == 0 || posixly_correct == 0)
288 #if defined (ARRAY_VARS)
293 if (function_p (var))
299 if (readonly_p (var))
305 if (exported_p (var))
310 #if defined (ARRAY_VARS)
315 if (function_p (var))
321 /* If we're printing functions with definitions, print the function def
322 first, then the attributes, instead of printing output that can't be
323 reused as input to recreate the current state. */
324 if (function_p (var) && nodefs == 0 && (pattr == 0 || posixly_correct == 0))
326 printf ("%s\n", named_function_string (var->name, function_cell (var), 1));
328 if (pattr == 0 && i == 1 && flags[0] == 'f')
329 return 0; /* don't print `declare -f name' */
332 if (pattr == 0 || posixly_correct == 0)
333 printf ("declare -%s ", i ? flags : "-");
335 printf ("%s -%s ", this_command_name, flags);
337 printf ("%s ", this_command_name);
339 #if defined (ARRAY_VARS)
341 print_array_assignment (var, 1);
344 /* force `readonly' and `export' to not print out function definitions
345 when in POSIX mode. */
346 if (nodefs || (function_p (var) && pattr != 0 && posixly_correct))
347 printf ("%s\n", var->name);
348 else if (function_p (var))
349 printf ("%s\n", named_function_string (var->name, function_cell (var), 1));
350 else if (invisible_p (var))
351 printf ("%s\n", var->name);
354 x = sh_double_quote (var_isset (var) ? value_cell (var) : "");
355 printf ("%s=%s\n", var->name, x);
362 show_name_attributes (name, nodefs)
368 var = find_variable_internal (name, 1);
370 if (var && invisible_p (var) == 0)
372 show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
380 set_var_attribute (name, attribute, undo)
388 var = find_variable (name);
391 tv = find_tempenv_variable (name);
392 /* XXX -- need to handle case where tv is a temp variable in a
393 function-scope context, since function_env has been merged into
394 the local variables table. */
395 if (tv && tempvar_p (tv))
397 tvalue = var_isset (tv) ? savestring (value_cell (tv)) : savestring ("");
399 var = bind_variable (tv->name, tvalue);
400 var->attributes |= tv->attributes & ~att_tempvar;
401 VSETATTR (tv, att_propagate);
402 if (var->context != 0)
403 VSETATTR (var, att_propagate);
404 SETVARATTR (tv, attribute, undo); /* XXX */
410 var = find_variable_internal (name, 0);
413 var = bind_variable (name, (char *)NULL);
414 VSETATTR (var, att_invisible);
416 else if (var->context != 0)
417 VSETATTR (var, att_propagate);
422 SETVARATTR (var, attribute, undo);
424 if (var && (exported_p (var) || (attribute & att_exported)))
425 array_needs_making++; /* XXX */