]> git.ipfire.org Git - thirdparty/bash.git/blob - builtins/set.def
Imported from ../bash-1.14.7.tar.gz.
[thirdparty/bash.git] / builtins / set.def
1 This file is set.def, from which is created set.c.
2 It implements the "set" and "unset" builtins 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 set.c
23
24 #include <stdio.h>
25 #include "../shell.h"
26 #include "../flags.h"
27
28 #include "bashgetopt.h"
29
30 extern int interactive;
31 extern int noclobber, no_brace_expansion, posixly_correct;
32 #if defined (READLINE)
33 extern int rl_editing_mode, no_line_editing;
34 #endif /* READLINE */
35
36 #define USAGE_STRING "set [--abefhknotuvxldHCP] [-o option] [arg ...]"
37
38 $BUILTIN set
39 $FUNCTION set_builtin
40 $SHORT_DOC set [--abefhknotuvxldHCP] [-o option] [arg ...]
41 -a Mark variables which are modified or created for export.
42 -b Notify of job termination immediately.
43 -e Exit immediately if a command exits with a non-zero status.
44 -f Disable file name generation (globbing).
45 -h Locate and remember function commands as functions are
46 defined. Function commands are normally looked up when
47 the function is executed.
48 -i Force the shell to be an "interactive" one. Interactive shells
49 always read `~/.bashrc' on startup.
50 -k All keyword arguments are placed in the environment for a
51 command, not just those that precede the command name.
52 -m Job control is enabled.
53 -n Read commands but do not execute them.
54 -o option-name
55 Set the variable corresponding to option-name:
56 allexport same as -a
57 braceexpand the shell will perform brace expansion
58 #if defined (READLINE)
59 emacs use an emacs-style line editing interface
60 #endif /* READLINE */
61 errexit same as -e
62 #if defined (BANG_HISTORY)
63 histexpand same as -H
64 #endif /* BANG_HISTORY */
65 ignoreeof the shell will not exit upon reading EOF
66 interactive-comments
67 allow comments to appear in interactive commands
68 monitor same as -m
69 noclobber disallow redirection to existing files
70 noexec same as -n
71 noglob same as -f
72 nohash same as -d
73 notify save as -b
74 nounset same as -u
75 physical same as -P
76 posix change the behavior of bash where the default
77 operation differs from the 1003.2 standard to
78 match the standard
79 privileged same as -p
80 verbose same as -v
81 #if defined (READLINE)
82 vi use a vi-style line editing interface
83 #endif /* READLINE */
84 xtrace same as -x
85 -p Turned on whenever the real and effective user ids do not match.
86 Disables processing of the $ENV file and importing of shell
87 functions. Turning this option off causes the effective uid and
88 gid to be set to the real uid and gid.
89 -t Exit after reading and executing one command.
90 -u Treat unset variables as an error when substituting.
91 -v Print shell input lines as they are read.
92 -x Print commands and their arguments as they are executed.
93 -l Save and restore the binding of the NAME in a FOR command.
94 -d Disable the hashing of commands that are looked up for execution.
95 Normally, commands are remembered in a hash table, and once
96 found, do not have to be looked up again.
97 #if defined (BANG_HISTORY)
98 -H Enable ! style history substitution. This flag is on
99 by default.
100 #endif /* BANG_HISTORY */
101 -C If set, disallow existing regular files to be overwritten
102 by redirection of output.
103 -P If set, do not follow symbolic links when executing commands
104 such as cd which change the current directory.
105
106 Using + rather than - causes these flags to be turned off. The
107 flags can also be used upon invocation of the shell. The current
108 set of flags may be found in $-. The remaining n ARGs are positional
109 parameters and are assigned, in order, to $1, $2, .. $n. If no
110 ARGs are given, all shell variables are printed.
111 $END
112
113 /* An a-list used to match long options for set -o to the corresponding
114 option letter. */
115 struct {
116 char *name;
117 int letter;
118 } o_options[] = {
119 { "allexport", 'a' },
120 { "errexit", 'e' },
121 #if defined (BANG_HISTORY)
122 { "histexpand", 'H' },
123 #endif /* BANG_HISTORY */
124 { "monitor", 'm' },
125 { "noexec", 'n' },
126 { "noglob", 'f' },
127 { "nohash", 'd' },
128 #if defined (JOB_CONTROL)
129 { "notify", 'b' },
130 #endif /* JOB_CONTROL */
131 {"nounset", 'u' },
132 {"physical", 'P' },
133 {"privileged", 'p' },
134 {"verbose", 'v' },
135 {"xtrace", 'x' },
136 {(char *)NULL, 0},
137 };
138
139 #define MINUS_O_FORMAT "%-15s\t%s\n"
140
141 void
142 list_minus_o_opts ()
143 {
144 register int i;
145 char *on = "on", *off = "off";
146
147 printf (MINUS_O_FORMAT, "braceexpand", (no_brace_expansion == 0) ? on : off);
148 printf (MINUS_O_FORMAT, "noclobber", (noclobber == 1) ? on : off);
149
150 if (find_variable ("ignoreeof") || find_variable ("IGNOREEOF"))
151 printf (MINUS_O_FORMAT, "ignoreeof", on);
152 else
153 printf (MINUS_O_FORMAT, "ignoreeof", off);
154
155 printf (MINUS_O_FORMAT, "interactive-comments",
156 interactive_comments ? on : off);
157
158 printf (MINUS_O_FORMAT, "posix", posixly_correct ? on : off);
159
160 #if defined (READLINE)
161 if (no_line_editing)
162 {
163 printf (MINUS_O_FORMAT, "emacs", off);
164 printf (MINUS_O_FORMAT, "vi", off);
165 }
166 else
167 {
168 /* Magic. This code `knows' how readline handles rl_editing_mode. */
169 printf (MINUS_O_FORMAT, "emacs", (rl_editing_mode == 1) ? on : off);
170 printf (MINUS_O_FORMAT, "vi", (rl_editing_mode == 0) ? on : off);
171 }
172 #endif /* READLINE */
173
174 for (i = 0; o_options[i].name; i++)
175 {
176 int *on_or_off, zero = 0;
177
178 on_or_off = find_flag (o_options[i].letter);
179 if (on_or_off == FLAG_UNKNOWN)
180 on_or_off = &zero;
181 printf (MINUS_O_FORMAT, o_options[i].name, (*on_or_off == 1) ? on : off);
182 }
183 }
184
185 set_minus_o_option (on_or_off, option_name)
186 int on_or_off;
187 char *option_name;
188 {
189 int option_char = -1;
190
191 if (STREQ (option_name, "braceexpand"))
192 {
193 if (on_or_off == FLAG_ON)
194 no_brace_expansion = 0;
195 else
196 no_brace_expansion = 1;
197 }
198 else if (STREQ (option_name, "noclobber"))
199 {
200 if (on_or_off == FLAG_ON)
201 bind_variable ("noclobber", "");
202 else
203 unbind_variable ("noclobber");
204 stupidly_hack_special_variables ("noclobber");
205 }
206 else if (STREQ (option_name, "ignoreeof"))
207 {
208 unbind_variable ("ignoreeof");
209 unbind_variable ("IGNOREEOF");
210 if (on_or_off == FLAG_ON)
211 bind_variable ("IGNOREEOF", "10");
212 stupidly_hack_special_variables ("IGNOREEOF");
213 }
214
215 #if defined (READLINE)
216 else if ((STREQ (option_name, "emacs")) || (STREQ (option_name, "vi")))
217 {
218 if (on_or_off == FLAG_ON)
219 {
220 rl_variable_bind ("editing-mode", option_name);
221
222 if (interactive)
223 with_input_from_stdin ();
224 no_line_editing = 0;
225 }
226 else
227 {
228 int isemacs = (rl_editing_mode == 1);
229 if ((isemacs && STREQ (option_name, "emacs")) ||
230 (!isemacs && STREQ (option_name, "vi")))
231 {
232 if (interactive)
233 with_input_from_stream (stdin, "stdin");
234 no_line_editing = 1;
235 }
236 else
237 builtin_error ("not in %s editing mode", option_name);
238 }
239 }
240 #endif /* READLINE */
241 else if (STREQ (option_name, "interactive-comments"))
242 interactive_comments = (on_or_off == FLAG_ON);
243 else if (STREQ (option_name, "posix"))
244 {
245 posixly_correct = (on_or_off == FLAG_ON);
246 unbind_variable ("POSIXLY_CORRECT");
247 unbind_variable ("POSIX_PEDANTIC");
248 if (on_or_off == FLAG_ON)
249 {
250 bind_variable ("POSIXLY_CORRECT", "");
251 stupidly_hack_special_variables ("POSIXLY_CORRECT");
252 }
253 }
254 else
255 {
256 register int i;
257 for (i = 0; o_options[i].name; i++)
258 {
259 if (STREQ (option_name, o_options[i].name))
260 {
261 option_char = o_options[i].letter;
262 break;
263 }
264 }
265 if (option_char == -1)
266 {
267 builtin_error ("%s: unknown option name", option_name);
268 return (EXECUTION_FAILURE);
269 }
270 if (change_flag (option_char, on_or_off) == FLAG_ERROR)
271 {
272 bad_option (option_name);
273 return (EXECUTION_FAILURE);
274 }
275 }
276 return (EXECUTION_SUCCESS);
277 }
278
279 /* Set some flags from the word values in the input list. If LIST is empty,
280 then print out the values of the variables instead. If LIST contains
281 non-flags, then set $1 - $9 to the successive words of LIST. */
282 set_builtin (list)
283 WORD_LIST *list;
284 {
285 int on_or_off, flag_name, force_assignment = 0;
286
287 if (!list)
288 {
289 SHELL_VAR **vars;
290
291 vars = all_shell_variables ();
292 if (vars)
293 {
294 print_var_list (vars);
295 free (vars);
296 }
297
298 vars = all_shell_functions ();
299 if (vars)
300 {
301 print_var_list (vars);
302 free (vars);
303 }
304
305 return (EXECUTION_SUCCESS);
306 }
307
308 /* Check validity of flag arguments. */
309 if (*list->word->word == '-' || *list->word->word == '+')
310 {
311 register char *arg;
312 WORD_LIST *save_list = list;
313
314 while (list && (arg = list->word->word))
315 {
316 char c;
317
318 if (arg[0] != '-' && arg[0] != '+')
319 break;
320
321 /* `-' or `--' signifies end of flag arguments. */
322 if (arg[0] == '-' &&
323 (!arg[1] || (arg[1] == '-' && !arg[2])))
324 break;
325
326 while (c = *++arg)
327 {
328 if (find_flag (c) == FLAG_UNKNOWN && c != 'o')
329 {
330 char s[2];
331 s[0] = c; s[1] = '\0';
332 bad_option (s);
333 if (c == '?')
334 printf ("usage: %s\n", USAGE_STRING);
335 return (c == '?' ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
336 }
337 }
338 list = list->next;
339 }
340 list = save_list;
341 }
342
343 /* Do the set command. While the list consists of words starting with
344 '-' or '+' treat them as flags, otherwise, start assigning them to
345 $1 ... $n. */
346 while (list)
347 {
348 char *string = list->word->word;
349
350 /* If the argument is `--' or `-' then signal the end of the list
351 and remember the remaining arguments. */
352 if (string[0] == '-' && (!string[1] || (string[1] == '-' && !string[2])))
353 {
354 list = list->next;
355
356 /* `set --' unsets the positional parameters. */
357 if (string[1] == '-')
358 force_assignment = 1;
359
360 /* Until told differently, the old shell behaviour of
361 `set - [arg ...]' being equivalent to `set +xv [arg ...]'
362 stands. Posix.2 says the behaviour is marked as obsolescent. */
363 else
364 {
365 change_flag ('x', '+');
366 change_flag ('v', '+');
367 }
368
369 break;
370 }
371
372 if ((on_or_off = *string) &&
373 (on_or_off == '-' || on_or_off == '+'))
374 {
375 int i = 1;
376 while (flag_name = string[i++])
377 {
378 if (flag_name == '?')
379 {
380 printf ("usage: %s\n", USAGE_STRING);
381 return (EXECUTION_SUCCESS);
382 }
383 else if (flag_name == 'o') /* -+o option-name */
384 {
385 char *option_name;
386 WORD_LIST *opt;
387
388 opt = list->next;
389
390 if (!opt)
391 {
392 list_minus_o_opts ();
393 continue;
394 }
395
396 option_name = opt->word->word;
397
398 if (!option_name || !*option_name || (*option_name == '-'))
399 {
400 list_minus_o_opts ();
401 continue;
402 }
403 list = list->next; /* Skip over option name. */
404
405 if (set_minus_o_option (on_or_off, option_name) != EXECUTION_SUCCESS)
406 return (EXECUTION_FAILURE);
407 }
408 else
409 {
410 if (change_flag (flag_name, on_or_off) == FLAG_ERROR)
411 {
412 char opt[3];
413 opt[0] = on_or_off;
414 opt[1] = flag_name;
415 opt[2] = '\0';
416 bad_option (opt);
417 return (EXECUTION_FAILURE);
418 }
419 }
420 }
421 }
422 else
423 {
424 break;
425 }
426 list = list->next;
427 }
428
429 /* Assigning $1 ... $n */
430 if (list || force_assignment)
431 remember_args (list, 1);
432 return (EXECUTION_SUCCESS);
433 }
434
435 $BUILTIN unset
436 $FUNCTION unset_builtin
437 $SHORT_DOC unset [-f] [-v] [name ...]
438 For each NAME, remove the corresponding variable or function. Given
439 the `-v', unset will only act on variables. Given the `-f' flag,
440 unset will only act on functions. With neither flag, unset first
441 tries to unset a variable, and if that fails, then tries to unset a
442 function. Some variables (such as PATH and IFS) cannot be unset; also
443 see readonly.
444 $END
445
446 unset_builtin (list)
447 WORD_LIST *list;
448 {
449 int unset_function = 0, unset_variable = 0, opt;
450 int any_failed = 0;
451 char *name;
452
453 reset_internal_getopt ();
454 while ((opt = internal_getopt (list, "fv")) != -1)
455 {
456 switch (opt)
457 {
458 case 'f':
459 unset_function = 1;
460 break;
461 case 'v':
462 unset_variable = 1;
463 break;
464 default:
465 return (EXECUTION_FAILURE);
466 }
467 }
468
469 list = loptend;
470
471 if (unset_function && unset_variable)
472 {
473 builtin_error ("cannot simultaneously unset a function and a variable");
474 return (EXECUTION_FAILURE);
475 }
476
477 while (list)
478 {
479 name = list->word->word;
480
481 if (!unset_function &&
482 find_name_in_list (name, non_unsettable_vars) > -1)
483 {
484 builtin_error ("%s: cannot unset", name);
485 any_failed++;
486 }
487 else
488 {
489 SHELL_VAR *var;
490 int tem;
491
492 var = unset_function ? find_function (name) : find_variable (name);
493
494 /* Posix.2 says that unsetting readonly variables is an error. */
495 if (var && readonly_p (var))
496 {
497 builtin_error ("%s: cannot unset: readonly %s",
498 name, unset_function ? "function" : "variable");
499 any_failed++;
500 list = list->next;
501 continue;
502 }
503
504 /* Unless the -f option is supplied, the name refers to a
505 variable. */
506 tem = makunbound
507 (name, unset_function ? shell_functions : shell_variables);
508
509 /* This is what Posix.2 draft 11+ says. ``If neither -f nor -v
510 is specified, the name refers to a variable; if a variable by
511 that name does not exist, a function by that name, if any,
512 shall be unset.'' */
513 if ((tem == -1) && !unset_function && !unset_variable)
514 tem = makunbound (name, shell_functions);
515
516 if (tem == -1)
517 any_failed++;
518 else if (!unset_function)
519 stupidly_hack_special_variables (name);
520 }
521 list = list->next;
522 }
523
524 if (any_failed)
525 return (EXECUTION_FAILURE);
526 else
527 return (EXECUTION_SUCCESS);
528 }