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
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"
35 #include
"../bashintl.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
;
47 extern int declare_builtin
__P((WORD_LIST *)
);
50 #define READONLY_OR_EXPORT \
51 (this_shell_builtin
== readonly_builtin || this_shell_builtin
== export_builtin
)
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
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.
*/
72 register WORD_LIST
*list
;
74 return (set_or_show_attributes (list
, att_exported
, 0));
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
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 (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;
116 #if defined (ARRAY_VARS)
117 WORD_LIST *nlist, *tlist;
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)
134 #if defined (ARRAY_VARS)
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;
159 name = list->word->word;
161 if (functions_only) /* xxx -f name */
163 var = find_function (name);
166 builtin_error (_("%s: not a function"), name);
170 SETVARATTR (var, attribute, undo);
176 /* xxx [-np] name[=value] */
177 assign = assignment (name, 0);
183 if (name[assign - 1] == '+')
185 aflags |= ASS_APPEND;
186 name[assign - 1] = '\
0';
190 if (legal_identifier (name) == 0)
201 if (assign) /* xxx [-np] name=value */
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.
*/
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
)
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)
231 if (aflags
& ASS_APPEND
)
232 name
[assign
- 1] = '\0';
235 set_var_attribute (name
, attribute
, undo
);
241 SHELL_VAR
**variable_list
;
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
*/
251 variable_list
= all_shell_variables ();
253 #if
defined (ARRAY_VARS
)
254 if (attribute
& att_array
)
257 if (attribute
!= att_array
)
258 attribute
&= ~att_array
;
264 for (i
= 0; var
= variable_list
[i
]; i
++)
266 #if
defined (ARRAY_VARS
)
267 if (arrays_only
&& array_p (var
) == 0)
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
)
298 /* pattr
== 0 means we are called from `declare
'. */
299 if (pattr == 0 || posixly_correct == 0)
301 #if defined (ARRAY_VARS)
306 if (function_p (var))
312 if (readonly_p (var))
318 if (exported_p (var))
323 #if defined (ARRAY_VARS)
328 if (function_p (var))
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));
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 : "-");
348 printf ("%s -%s ", this_command_name, flags);
350 printf ("%s ", this_command_name);
352 #if defined (ARRAY_VARS)
354 print_array_assignment (var, 1);
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);
367 x = sh_double_quote (var_isset (var) ? value_cell (var) : "");
368 printf ("%s=%s\n", var->name, x);
375 show_name_attributes (name, nodefs)
381 var = find_variable_internal (name, 1);
383 if (var && invisible_p (var) == 0)
385 show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
393 set_var_attribute (name, attribute, undo)
401 var = find_variable (name);
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);
425 var = find_variable_internal (name, 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);
437 SETVARATTR (var, attribute, undo);
439 if (var && (exported_p (var) || (attribute & att_exported)))
440 array_needs_making++; /* XXX */