]> git.ipfire.org Git - thirdparty/bash.git/blame - builtins/setattr.def
Imported from ../bash-2.05.tar.gz.
[thirdparty/bash.git] / builtins / setattr.def
CommitLineData
726f6388
JA
1This file is setattr.def, from which is created setattr.c.
2It implements the builtins "export" and "readonly", in Bash.
3
4Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
5
6This file is part of GNU Bash, the Bourne Again SHell.
7
8Bash is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
bb70624e 10Software Foundation; either version 2, or (at your option) any later
726f6388
JA
11version.
12
13Bash is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License along
19with Bash; see the file COPYING. If not, write to the Free Software
bb70624e 20Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
726f6388
JA
21
22$PRODUCES setattr.c
23
ccc6cda3
JA
24#include <config.h>
25
26#if defined (HAVE_UNISTD_H)
cce855bc
JA
27# ifdef _MINIX
28# include <sys/types.h>
29# endif
ccc6cda3
JA
30# include <unistd.h>
31#endif
32
33#include <stdio.h>
34#include "../bashansi.h"
35
726f6388
JA
36#include "../shell.h"
37#include "common.h"
38#include "bashgetopt.h"
39
d166f048 40extern int posixly_correct;
726f6388
JA
41extern int array_needs_making;
42extern char *this_command_name;
d166f048
JA
43extern Function *this_shell_builtin;
44
45#ifdef ARRAY_VARS
46extern int declare_builtin ();
47#endif
48
49#define READONLY_OR_EXPORT \
50 (this_shell_builtin == readonly_builtin || this_shell_builtin == export_builtin)
726f6388
JA
51
52$BUILTIN export
53$FUNCTION export_builtin
ccc6cda3 54$SHORT_DOC export [-nf] [name ...] or export -p
726f6388
JA
55NAMEs are marked for automatic export to the environment of
56subsequently executed commands. If the -f option is given,
57the NAMEs refer to functions. If no NAMEs are given, or if `-p'
58is given, a list of all names that are exported in this shell is
59printed. An argument of `-n' says to remove the export property
60from subsequent NAMEs. An argument of `--' disables further option
61processing.
62$END
63
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. */
ccc6cda3 69int
726f6388
JA
70export_builtin (list)
71 register WORD_LIST *list;
72{
ccc6cda3 73 return (set_or_show_attributes (list, att_exported, 0));
726f6388
JA
74}
75
76$BUILTIN readonly
77$FUNCTION readonly_builtin
ccc6cda3 78$SHORT_DOC readonly [-anf] [name ...] or readonly -p
726f6388
JA
79The given NAMEs are marked readonly and the values of these NAMEs may
80not be changed by subsequent assignment. If the -f option is given,
81then functions corresponding to the NAMEs are so marked. If no
82arguments are given, or if `-p' is given, a list of all readonly names
83is printed. An argument of `-n' says to remove the readonly property
ccc6cda3
JA
84from subsequent NAMEs. The `-a' option means to treat each NAME as
85an array variable. An argument of `--' disables further option
726f6388
JA
86processing.
87$END
88
89/* For each variable name in LIST, make that variable readonly. Given an
90 empty LIST, print out all existing readonly variables. */
ccc6cda3 91int
726f6388
JA
92readonly_builtin (list)
93 register WORD_LIST *list;
94{
ccc6cda3 95 return (set_or_show_attributes (list, att_readonly, 0));
726f6388
JA
96}
97
98/* For each variable name in LIST, make that variable have the specified
99 ATTRIBUTE. An arg of `-n' says to remove the attribute from the the
100 remaining names in LIST. */
101int
ccc6cda3 102set_or_show_attributes (list, attribute, nodefs)
726f6388 103 register WORD_LIST *list;
ccc6cda3 104 int attribute, nodefs;
726f6388
JA
105{
106 register SHELL_VAR *var;
ccc6cda3
JA
107 int assign, undo, functions_only, arrays_only, any_failed, assign_error, opt;
108 char *name;
d166f048
JA
109#if defined (ARRAY_VARS)
110 WORD_LIST *nlist, *tlist;
111 WORD_DESC *w;
112#endif
726f6388 113
ccc6cda3 114 undo = functions_only = arrays_only = any_failed = assign_error = 0;
726f6388
JA
115 /* Read arguments from the front of the list. */
116 reset_internal_getopt ();
ccc6cda3 117 while ((opt = internal_getopt (list, "anfp")) != -1)
726f6388
JA
118 {
119 switch (opt)
120 {
121 case 'n':
122 undo = 1;
123 break;
124 case 'f':
125 functions_only = 1;
126 break;
ccc6cda3
JA
127#if defined (ARRAY_VARS)
128 case 'a':
129 arrays_only = 1;
130 break;
131#endif
726f6388
JA
132 case 'p':
133 break;
134 default:
ccc6cda3 135 builtin_usage ();
726f6388
JA
136 return (EX_USAGE);
137 }
138 }
139 list = loptend;
140
141 if (list)
142 {
143 if (attribute & att_exported)
144 array_needs_making = 1;
145
ccc6cda3 146 /* Cannot undo readonly status, silently disallowed. */
726f6388
JA
147 if (undo && (attribute & att_readonly))
148 attribute &= ~att_readonly;
149
150 while (list)
151 {
ccc6cda3 152 name = list->word->word;
726f6388 153
ccc6cda3 154 if (functions_only) /* xxx -f name */
726f6388
JA
155 {
156 var = find_function (name);
ccc6cda3 157 if (var == 0)
726f6388
JA
158 {
159 builtin_error ("%s: not a function", name);
160 any_failed++;
161 }
162 else
ccc6cda3
JA
163 SETVARATTR (var, attribute, undo);
164
726f6388 165 list = list->next;
726f6388
JA
166 continue;
167 }
168
ccc6cda3 169 /* xxx [-np] name[=value] */
726f6388
JA
170 assign = assignment (name);
171
28ef6c31 172 if (assign)
726f6388 173 name[assign] = '\0';
ccc6cda3 174
726f6388
JA
175 if (legal_identifier (name) == 0)
176 {
ccc6cda3 177 builtin_error ("`%s': not a valid identifier", name);
d166f048
JA
178 if (assign)
179 assign_error++;
180 else
181 any_failed++;
726f6388
JA
182 list = list->next;
183 continue;
184 }
185
ccc6cda3 186 if (assign) /* xxx [-np] name=value */
726f6388
JA
187 {
188 name[assign] = '=';
d166f048
JA
189#if defined (ARRAY_VARS)
190 /* Let's try something here. Turn readonly -a xxx=yyy into
191 declare -ra xxx=yyy and see what that gets us. */
192 if (arrays_only)
193 {
194 tlist = list->next;
195 list->next = (WORD_LIST *)NULL;
196 w = make_word ("-ra");
197 nlist = make_word_list (w, list);
198 opt = declare_builtin (nlist);
199 if (opt != EXECUTION_SUCCESS)
200 assign_error++;
201 list->next = tlist;
202 dispose_word (w);
203 free (nlist);
204 }
205 else
206#endif
726f6388
JA
207 /* This word has already been expanded once with command
208 and parameter expansion. Call do_assignment_no_expand (),
ccc6cda3
JA
209 which does not do command or parameter substitution. If
210 the assignment is not performed correctly, flag an error. */
211 if (do_assignment_no_expand (name) == 0)
212 assign_error++;
726f6388
JA
213 name[assign] = '\0';
214 }
215
ccc6cda3 216 set_var_attribute (name, attribute, undo);
726f6388
JA
217 list = list->next;
218 }
219 }
220 else
221 {
222 SHELL_VAR **variable_list;
223 register int i;
224
225 if ((attribute & att_function) || functions_only)
226 {
227 variable_list = all_shell_functions ();
228 if (attribute != att_function)
229 attribute &= ~att_function; /* so declare -xf works, for example */
230 }
231 else
232 variable_list = all_shell_variables ();
233
ccc6cda3
JA
234#if defined (ARRAY_VARS)
235 if (attribute & att_array)
28ef6c31
JA
236 {
237 arrays_only++;
238 if (attribute != att_array)
ccc6cda3 239 attribute &= ~att_array;
28ef6c31 240 }
ccc6cda3
JA
241#endif
242
726f6388
JA
243 if (variable_list)
244 {
245 for (i = 0; var = variable_list[i]; i++)
246 {
ccc6cda3
JA
247#if defined (ARRAY_VARS)
248 if (arrays_only && array_p (var) == 0)
28ef6c31 249 continue;
ccc6cda3
JA
250#endif
251 if ((var->attributes & attribute) && invisible_p (var) == 0)
d166f048 252 show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
ccc6cda3
JA
253 }
254 free (variable_list);
255 }
256 }
257
258 return (assign_error ? EX_BADASSIGN
259 : ((any_failed == 0) ? EXECUTION_SUCCESS
260 : EXECUTION_FAILURE));
261}
262
d166f048
JA
263/* Show the attributes for shell variable VAR. If NODEFS is non-zero,
264 don't show function definitions along with the name. If PATTR is
265 non-zero, it indicates we're being called from `export' or `readonly'.
266 In POSIX mode, this prints the name of the calling builtin (`export'
267 or `readonly') instead of `declare', and doesn't print function defs
268 when called by `export' or `readonly'. */
ccc6cda3 269int
d166f048 270show_var_attributes (var, pattr, nodefs)
ccc6cda3 271 SHELL_VAR *var;
d166f048 272 int pattr, nodefs;
ccc6cda3
JA
273{
274 char flags[6], *x;
275 int i;
726f6388 276
ccc6cda3 277 i = 0;
726f6388 278
d166f048
JA
279 /* pattr == 0 means we are called from `declare'. */
280 if (pattr == 0 || posixly_correct == 0)
281 {
ccc6cda3 282#if defined (ARRAY_VARS)
d166f048
JA
283 if (array_p (var))
284 flags[i++] = 'a';
ccc6cda3 285#endif
726f6388 286
d166f048 287 if (function_p (var))
28ef6c31 288 flags[i++] = 'f';
726f6388 289
d166f048 290 if (integer_p (var))
28ef6c31 291 flags[i++] = 'i';
726f6388 292
d166f048 293 if (readonly_p (var))
28ef6c31 294 flags[i++] = 'r';
726f6388 295
d166f048 296 if (exported_p (var))
28ef6c31 297 flags[i++] = 'x';
d166f048
JA
298 }
299 else
300 {
301#if defined (ARRAY_VARS)
302 if (array_p (var))
303 flags[i++] = 'a';
304#endif
305
306 if (function_p (var))
28ef6c31 307 flags[i++] = 'f';
d166f048 308 }
726f6388 309
ccc6cda3 310 flags[i] = '\0';
726f6388 311
d166f048
JA
312 if (pattr == 0 || posixly_correct == 0)
313 printf ("declare -%s ", i ? flags : "-");
314 else if (i)
315 printf ("%s -%s ", this_command_name, flags);
316 else
317 printf ("%s ", this_command_name);
ccc6cda3
JA
318
319#if defined (ARRAY_VARS)
320 if (array_p (var))
321 print_array_assignment (var, 1);
322 else
323#endif
d166f048
JA
324 /* force `readline' and `export' to not print out function definitions
325 when in POSIX mode. */
326 if (nodefs || (function_p (var) && pattr != 0 && posixly_correct))
ccc6cda3
JA
327 printf ("%s\n", var->name);
328 else if (function_p (var))
329 printf ("%s\n", named_function_string (var->name, function_cell (var), 1));
330 else
331 {
28ef6c31 332 x = sh_double_quote (value_cell (var) ? value_cell (var) : "");
ccc6cda3
JA
333 printf ("%s=%s\n", var->name, x);
334 free (x);
335 }
336 return (0);
337}
338
339int
340show_name_attributes (name, nodefs)
341 char *name;
342 int nodefs;
343{
344 SHELL_VAR *var;
cce855bc 345 int ret;
ccc6cda3
JA
346
347 var = find_tempenv_variable (name);
348 if (var == 0)
349 var = find_variable (name);
350
351 if (var && invisible_p (var) == 0)
352 {
d166f048 353 show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
cce855bc
JA
354 if (tempvar_p (var))
355 dispose_variable (var);
ccc6cda3
JA
356 return (0);
357 }
358 else
359 return (1);
360}
361
362void
363set_var_attribute (name, attribute, undo)
364 char *name;
365 int attribute, undo;
366{
367 SHELL_VAR *var, *tv;
368
369 if (undo)
370 var = find_variable (name);
371 else
372 {
373 if (tv = find_tempenv_variable (name))
374 {
e8ce775d 375 var = bind_variable (tv->name, tv->value ? tv->value : "");
ccc6cda3
JA
376 dispose_variable (tv);
377 }
378 else
379 var = find_variable (name);
380
381 if (var == 0)
382 {
383 var = bind_variable (name, (char *)NULL);
bb70624e 384 VSETATTR (var, att_invisible);
726f6388
JA
385 }
386 }
ccc6cda3
JA
387
388 if (var)
389 SETVARATTR (var, attribute, undo);
390
bb70624e 391 if (var && (exported_p (var) || (attribute & att_exported)))
ccc6cda3 392 array_needs_making++; /* XXX */
726f6388 393}