]> git.ipfire.org Git - thirdparty/bash.git/blob - builtins/set.def
423a0671294c590a0d5abf90c6e6ecdadd81e33b
[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 <config.h>
25
26 #if defined (HAVE_UNISTD_H)
27 # ifdef _MINIX
28 # include <sys/types.h>
29 # endif
30 # include <unistd.h>
31 #endif
32
33 #include <stdio.h>
34
35 #include "../bashansi.h"
36
37 #include "../shell.h"
38 #include "../flags.h"
39 #include "common.h"
40 #include "bashgetopt.h"
41
42 #if defined (READLINE)
43 # include "../input.h"
44 # include "../bashline.h"
45 # include <readline/readline.h>
46 #endif
47
48 #if defined (HISTORY)
49 # include "../bashhist.h"
50 #endif
51
52 extern int interactive;
53 extern int noclobber, posixly_correct, ignoreeof, eof_encountered_limit;
54 #if defined (READLINE)
55 extern int rl_editing_mode, no_line_editing;
56 #endif /* READLINE */
57
58 $BUILTIN set
59 $FUNCTION set_builtin
60 $SHORT_DOC set [--abefhkmnptuvxBCHP] [-o option] [arg ...]
61 -a Mark variables which are modified or created for export.
62 -b Notify of job termination immediately.
63 -e Exit immediately if a command exits with a non-zero status.
64 -f Disable file name generation (globbing).
65 -h Remember the location of commands as they are looked up.
66 -i Force the shell to be an "interactive" one. Interactive shells
67 always read `~/.bashrc' on startup.
68 -k All assignment arguments are placed in the environment for a
69 command, not just those that precede the command name.
70 -m Job control is enabled.
71 -n Read commands but do not execute them.
72 -o option-name
73 Set the variable corresponding to option-name:
74 allexport same as -a
75 braceexpand same as -B
76 #if defined (READLINE)
77 emacs use an emacs-style line editing interface
78 #endif /* READLINE */
79 errexit same as -e
80 hashall same as -h
81 #if defined (BANG_HISTORY)
82 histexpand same as -H
83 #endif /* BANG_HISTORY */
84 #if defined (HISTORY)
85 history enable command history
86 #endif
87 ignoreeof the shell will not exit upon reading EOF
88 interactive-comments
89 allow comments to appear in interactive commands
90 keyword same as -k
91 monitor same as -m
92 noclobber same as -C
93 noexec same as -n
94 noglob same as -f
95 notify same as -b
96 nounset same as -u
97 onecmd same as -t
98 physical same as -P
99 posix change the behavior of bash where the default
100 operation differs from the 1003.2 standard to
101 match the standard
102 privileged same as -p
103 verbose same as -v
104 #if defined (READLINE)
105 vi use a vi-style line editing interface
106 #endif /* READLINE */
107 xtrace same as -x
108 -p Turned on whenever the real and effective user ids do not match.
109 Disables processing of the $ENV file and importing of shell
110 functions. Turning this option off causes the effective uid and
111 gid to be set to the real uid and gid.
112 -t Exit after reading and executing one command.
113 -u Treat unset variables as an error when substituting.
114 -v Print shell input lines as they are read.
115 -x Print commands and their arguments as they are executed.
116 #if defined (BRACE_EXPANSION)
117 -B the shell will perform brace expansion
118 #endif /* BRACE_EXPANSION */
119 -C If set, disallow existing regular files to be overwritten
120 by redirection of output.
121 #if defined (BANG_HISTORY)
122 -H Enable ! style history substitution. This flag is on
123 by default.
124 #endif /* BANG_HISTORY */
125 -P If set, do not follow symbolic links when executing commands
126 such as cd which change the current directory.
127
128 Using + rather than - causes these flags to be turned off. The
129 flags can also be used upon invocation of the shell. The current
130 set of flags may be found in $-. The remaining n ARGs are positional
131 parameters and are assigned, in order, to $1, $2, .. $n. If no
132 ARGs are given, all shell variables are printed.
133 $END
134
135 static int set_ignoreeof ();
136 static int set_posix_mode ();
137
138 #if defined (READLINE)
139 static int set_edit_mode ();
140 static int get_edit_mode ();
141 #endif
142
143 #if defined (HISTORY)
144 static int bash_set_history ();
145 #endif
146
147 static char *on = "on";
148 static char *off = "off";
149
150 /* An a-list used to match long options for set -o to the corresponding
151 option letter. */
152 struct {
153 char *name;
154 int letter;
155 } o_options[] = {
156 { "allexport", 'a' },
157 #if defined (BRACE_EXPANSION)
158 { "braceexpand",'B' },
159 #endif
160 { "errexit", 'e' },
161 { "hashall", 'h' },
162 #if defined (BANG_HISTORY)
163 { "histexpand", 'H' },
164 #endif /* BANG_HISTORY */
165 { "keyword", 'k' },
166 { "monitor", 'm' },
167 { "noclobber", 'C' },
168 { "noexec", 'n' },
169 { "noglob", 'f' },
170 #if defined (JOB_CONTROL)
171 { "notify", 'b' },
172 #endif /* JOB_CONTROL */
173 { "nounset", 'u' },
174 { "onecmd", 't' },
175 { "physical", 'P' },
176 { "privileged", 'p' },
177 { "verbose", 'v' },
178 { "xtrace", 'x' },
179 {(char *)NULL, 0 },
180 };
181
182 struct {
183 char *name;
184 int *variable;
185 Function *set_func;
186 Function *get_func;
187 } binary_o_options[] = {
188 #if defined (HISTORY)
189 { "history", &remember_on_history, bash_set_history, (Function *)NULL },
190 #endif
191 { "ignoreeof", &ignoreeof, set_ignoreeof, (Function *)NULL },
192 { "interactive-comments", &interactive_comments, (Function *)NULL, (Function *)NULL },
193 { "posix", &posixly_correct, set_posix_mode, (Function *)NULL },
194 #if defined (READLINE)
195 { "emacs", (int *)NULL, set_edit_mode, get_edit_mode },
196 { "vi", (int *)NULL, set_edit_mode, get_edit_mode },
197 #endif
198 { (char *)NULL, (int *)NULL }
199 };
200
201 #define GET_BINARY_O_OPTION_VALUE(i, name) \
202 ((binary_o_options[i].get_func) ? (*binary_o_options[i].get_func) (name) \
203 : (*binary_o_options[i].variable))
204
205 #define SET_BINARY_O_OPTION_VALUE(i, onoff, name) \
206 ((binary_o_options[i].set_func) ? (*binary_o_options[i].set_func) (onoff, name) \
207 : (*binary_o_options[i].variable = (onoff == FLAG_ON)))
208
209 int
210 minus_o_option_value (name)
211 char *name;
212 {
213 register int i;
214 int *on_or_off;
215
216 for (i = 0; o_options[i].name; i++)
217 {
218 if (STREQ (name, o_options[i].name))
219 {
220 on_or_off = find_flag (o_options[i].letter);
221 return ((on_or_off == FLAG_UNKNOWN) ? -1 : *on_or_off);
222 }
223 }
224 for (i = 0; binary_o_options[i].name; i++)
225 {
226 if (STREQ (name, binary_o_options[i].name))
227 return (GET_BINARY_O_OPTION_VALUE (i, name));
228 }
229
230 return (-1);
231 }
232
233 #define MINUS_O_FORMAT "%-15s\t%s\n"
234
235 static void
236 print_minus_o_option (name, value, pflag)
237 char *name;
238 int value, pflag;
239 {
240 if (pflag == 0)
241 printf (MINUS_O_FORMAT, name, value ? on : off);
242 else
243 printf ("set %co %s\n", value ? '-' : '+', name);
244 }
245
246 void
247 list_minus_o_opts (mode, reusable)
248 int mode, reusable;
249 {
250 register int i;
251 int *on_or_off, value;
252
253 for (value = i = 0; o_options[i].name; i++)
254 {
255 on_or_off = find_flag (o_options[i].letter);
256 if (on_or_off == FLAG_UNKNOWN)
257 on_or_off = &value;
258 if (mode == -1 || mode == *on_or_off)
259 print_minus_o_option (o_options[i].name, *on_or_off, reusable);
260 }
261 for (i = 0; binary_o_options[i].name; i++)
262 {
263 value = GET_BINARY_O_OPTION_VALUE (i, binary_o_options[i].name);
264 if (mode == -1 || mode == value)
265 print_minus_o_option (binary_o_options[i].name, value, reusable);
266 }
267 }
268
269 static int
270 set_ignoreeof (on_or_off, option_name)
271 int on_or_off;
272 char *option_name;
273 {
274 ignoreeof = on_or_off == FLAG_ON;
275 unbind_variable ("ignoreeof");
276 if (ignoreeof)
277 bind_variable ("IGNOREEOF", "10");
278 else
279 unbind_variable ("IGNOREEOF");
280 sv_ignoreeof ("IGNOREEOF");
281 return 0;
282 }
283
284 static int
285 set_posix_mode (on_or_off, option_name)
286 int on_or_off;
287 char *option_name;
288 {
289 posixly_correct = on_or_off == FLAG_ON;
290 if (posixly_correct == 0)
291 unbind_variable ("POSIXLY_CORRECT");
292 else
293 bind_variable ("POSIXLY_CORRECT", "y");
294 sv_strict_posix ("POSIXLY_CORRECT");
295 return (0);
296 }
297
298 #if defined (READLINE)
299 /* Magic. This code `knows' how readline handles rl_editing_mode. */
300 static int
301 set_edit_mode (on_or_off, option_name)
302 int on_or_off;
303 char *option_name;
304 {
305 int isemacs;
306
307 if (on_or_off == FLAG_ON)
308 {
309 rl_variable_bind ("editing-mode", option_name);
310
311 if (interactive)
312 with_input_from_stdin ();
313 no_line_editing = 0;
314 }
315 else
316 {
317 isemacs = rl_editing_mode == 1;
318 if ((isemacs && *option_name == 'e') || (!isemacs && *option_name == 'v'))
319 {
320 if (interactive)
321 with_input_from_stream (stdin, "stdin");
322 no_line_editing = 1;
323 }
324 }
325 return 1-no_line_editing;
326 }
327
328 static int
329 get_edit_mode (name)
330 char *name;
331 {
332 return (*name == 'e' ? no_line_editing == 0 && rl_editing_mode == 1
333 : no_line_editing == 0 && rl_editing_mode == 0);
334 }
335 #endif /* READLINE */
336
337 #if defined (HISTORY)
338 static int
339 bash_set_history (on_or_off, option_name)
340 int on_or_off;
341 char *option_name;
342 {
343 if (on_or_off == FLAG_ON)
344 {
345 bash_history_enable ();
346 if (history_lines_this_session == 0)
347 load_history ();
348 }
349 else
350 bash_history_disable ();
351 return (1 - remember_on_history);
352 }
353 #endif
354
355 int
356 set_minus_o_option (on_or_off, option_name)
357 int on_or_off;
358 char *option_name;
359 {
360 int option_char;
361 VFunction *set_func;
362 register int i;
363
364 for (i = 0; binary_o_options[i].name; i++)
365 {
366 if (STREQ (option_name, binary_o_options[i].name))
367 {
368 SET_BINARY_O_OPTION_VALUE (i, on_or_off, option_name);
369 return (EXECUTION_SUCCESS);
370 }
371 }
372
373 for (i = 0, option_char = -1, set_func = 0; o_options[i].name; i++)
374 {
375 if (STREQ (option_name, o_options[i].name))
376 {
377 option_char = o_options[i].letter;
378 break;
379 }
380 }
381 if (option_char == -1)
382 {
383 builtin_error ("%s: unknown option name", option_name);
384 return (EXECUTION_FAILURE);
385 }
386 if (change_flag (option_char, on_or_off) == FLAG_ERROR)
387 {
388 bad_option (option_name);
389 return (EXECUTION_FAILURE);
390 }
391 return (EXECUTION_SUCCESS);
392 }
393
394 static void
395 print_all_shell_variables ()
396 {
397 SHELL_VAR **vars;
398
399 vars = all_shell_variables ();
400 if (vars)
401 {
402 print_var_list (vars);
403 free (vars);
404 }
405
406 vars = all_shell_functions ();
407 if (vars)
408 {
409 print_var_list (vars);
410 free (vars);
411 }
412 }
413
414 void
415 set_shellopts ()
416 {
417 char *value;
418 int vsize, i, vptr, *ip, exported;
419 SHELL_VAR *v;
420
421 for (vsize = i = 0; o_options[i].name; i++)
422 {
423 ip = find_flag (o_options[i].letter);
424 if (ip && *ip)
425 vsize += strlen (o_options[i].name) + 1;
426 }
427 for (i = 0; binary_o_options[i].name; i++)
428 if (GET_BINARY_O_OPTION_VALUE (i, binary_o_options[i].name))
429 vsize += strlen (binary_o_options[i].name) + 1;
430
431 value = xmalloc (vsize + 1);
432
433 for (i = vptr = 0; o_options[i].name; i++)
434 {
435 ip = find_flag (o_options[i].letter);
436 if (ip && *ip)
437 {
438 strcpy (value + vptr, o_options[i].name);
439 vptr += strlen (o_options[i].name);
440 value[vptr++] = ':';
441 }
442 }
443 for (i = 0; binary_o_options[i].name; i++)
444 if (GET_BINARY_O_OPTION_VALUE (i, binary_o_options[i].name))
445 {
446 strcpy (value + vptr, binary_o_options[i].name);
447 vptr += strlen (binary_o_options[i].name);
448 value[vptr++] = ':';
449 }
450 if (vptr)
451 vptr--; /* cut off trailing colon */
452 value[vptr] = '\0';
453
454 v = find_variable ("SHELLOPTS");
455
456 /* Turn off the read-only attribute so we can bind the new value, and
457 note whether or not the variable was exported. */
458 if (v)
459 {
460 v->attributes &= ~att_readonly;
461 exported = exported_p (v);
462 }
463 else
464 exported = 0;
465
466 v = bind_variable ("SHELLOPTS", value);
467
468 /* Turn the read-only attribute back on, and turn off the export attribute
469 if it was set implicitly by mark_modified_vars and SHELLOPTS was not
470 exported before we bound the new value. */
471 v->attributes |= att_readonly;
472 if (mark_modified_vars && exported == 0 && exported_p (v))
473 v->attributes &= ~att_exported;
474
475 free (value);
476 }
477
478 void
479 parse_shellopts (value)
480 char *value;
481 {
482 char *vname;
483 int vptr;
484
485 vptr = 0;
486 while (vname = extract_colon_unit (value, &vptr))
487 {
488 set_minus_o_option (FLAG_ON, vname);
489 free (vname);
490 }
491 }
492
493 void
494 initialize_shell_options (no_shellopts)
495 int no_shellopts;
496 {
497 char *temp;
498 SHELL_VAR *var;
499
500 if (no_shellopts == 0)
501 {
502 var = find_variable ("SHELLOPTS");
503 /* set up any shell options we may have inherited. */
504 if (var && imported_p (var))
505 {
506 temp = (array_p (var)) ? (char *)NULL : savestring (value_cell (var));
507 if (temp)
508 {
509 parse_shellopts (temp);
510 free (temp);
511 }
512 }
513 }
514
515 /* Set up the $SHELLOPTS variable. */
516 set_shellopts ();
517 }
518
519 /* Reset the values of the -o options that are not also shell flags. */
520 void
521 reset_shell_options ()
522 {
523 #if defined (HISTORY)
524 remember_on_history = 1;
525 #endif
526 ignoreeof = posixly_correct = 0;
527 }
528
529 /* Set some flags from the word values in the input list. If LIST is empty,
530 then print out the values of the variables instead. If LIST contains
531 non-flags, then set $1 - $9 to the successive words of LIST. */
532 int
533 set_builtin (list)
534 WORD_LIST *list;
535 {
536 int on_or_off, flag_name, force_assignment, opts_changed;
537 WORD_LIST *l;
538 register char *arg;
539
540 if (list == 0)
541 {
542 print_all_shell_variables ();
543 return (EXECUTION_SUCCESS);
544 }
545
546 /* Check validity of flag arguments. */
547 if (*list->word->word == '-' || *list->word->word == '+')
548 {
549 for (l = list; l && (arg = l->word->word); l = l->next)
550 {
551 char c;
552
553 if (arg[0] != '-' && arg[0] != '+')
554 break;
555
556 /* `-' or `--' signifies end of flag arguments. */
557 if (arg[0] == '-' && (!arg[1] || (arg[1] == '-' && !arg[2])))
558 break;
559
560 while (c = *++arg)
561 {
562 if (find_flag (c) == FLAG_UNKNOWN && c != 'o')
563 {
564 char s[2];
565 s[0] = c; s[1] = '\0';
566 bad_option (s);
567 if (c == '?')
568 builtin_usage ();
569 return (c == '?' ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
570 }
571 }
572 }
573 }
574
575 /* Do the set command. While the list consists of words starting with
576 '-' or '+' treat them as flags, otherwise, start assigning them to
577 $1 ... $n. */
578 for (force_assignment = opts_changed = 0; list; )
579 {
580 arg = list->word->word;
581
582 /* If the argument is `--' or `-' then signal the end of the list
583 and remember the remaining arguments. */
584 if (arg[0] == '-' && (!arg[1] || (arg[1] == '-' && !arg[2])))
585 {
586 list = list->next;
587
588 /* `set --' unsets the positional parameters. */
589 if (arg[1] == '-')
590 force_assignment = 1;
591
592 /* Until told differently, the old shell behaviour of
593 `set - [arg ...]' being equivalent to `set +xv [arg ...]'
594 stands. Posix.2 says the behaviour is marked as obsolescent. */
595 else
596 {
597 change_flag ('x', '+');
598 change_flag ('v', '+');
599 opts_changed = 1;
600 }
601
602 break;
603 }
604
605 if ((on_or_off = *arg) && (on_or_off == '-' || on_or_off == '+'))
606 {
607 while (flag_name = *++arg)
608 {
609 if (flag_name == '?')
610 {
611 builtin_usage ();
612 return (EXECUTION_SUCCESS);
613 }
614 else if (flag_name == 'o') /* -+o option-name */
615 {
616 char *option_name;
617 WORD_LIST *opt;
618
619 opt = list->next;
620
621 if (opt == 0)
622 {
623 list_minus_o_opts (-1, (on_or_off == '+'));
624 continue;
625 }
626
627 option_name = opt->word->word;
628
629 if (option_name == 0 || *option_name == '\0' ||
630 *option_name == '-' || *option_name == '+')
631 {
632 list_minus_o_opts (-1, (on_or_off == '+'));
633 continue;
634 }
635 list = list->next; /* Skip over option name. */
636
637 opts_changed = 1;
638 if (set_minus_o_option (on_or_off, option_name) != EXECUTION_SUCCESS)
639 {
640 set_shellopts ();
641 return (EXECUTION_FAILURE);
642 }
643 }
644 else if (change_flag (flag_name, on_or_off) == FLAG_ERROR)
645 {
646 char opt[3];
647 opt[0] = on_or_off;
648 opt[1] = flag_name;
649 opt[2] = '\0';
650 bad_option (opt);
651 builtin_usage ();
652 set_shellopts ();
653 return (EXECUTION_FAILURE);
654 }
655 opts_changed = 1;
656 }
657 }
658 else
659 {
660 break;
661 }
662 list = list->next;
663 }
664
665 /* Assigning $1 ... $n */
666 if (list || force_assignment)
667 remember_args (list, 1);
668 /* Set up new value of $SHELLOPTS */
669 if (opts_changed)
670 set_shellopts ();
671 return (EXECUTION_SUCCESS);
672 }
673
674 $BUILTIN unset
675 $FUNCTION unset_builtin
676 $SHORT_DOC unset [-f] [-v] [name ...]
677 For each NAME, remove the corresponding variable or function. Given
678 the `-v', unset will only act on variables. Given the `-f' flag,
679 unset will only act on functions. With neither flag, unset first
680 tries to unset a variable, and if that fails, then tries to unset a
681 function. Some variables (such as PATH and IFS) cannot be unset; also
682 see readonly.
683 $END
684
685 #define NEXT_VARIABLE() any_failed++; list = list->next; continue;
686
687 int
688 unset_builtin (list)
689 WORD_LIST *list;
690 {
691 int unset_function, unset_variable, unset_array, opt, any_failed;
692 char *name;
693
694 unset_function = unset_variable = unset_array = any_failed = 0;
695
696 reset_internal_getopt ();
697 while ((opt = internal_getopt (list, "fv")) != -1)
698 {
699 switch (opt)
700 {
701 case 'f':
702 unset_function = 1;
703 break;
704 case 'v':
705 unset_variable = 1;
706 break;
707 default:
708 builtin_usage ();
709 return (EX_USAGE);
710 }
711 }
712
713 list = loptend;
714
715 if (unset_function && unset_variable)
716 {
717 builtin_error ("cannot simultaneously unset a function and a variable");
718 return (EXECUTION_FAILURE);
719 }
720
721 while (list)
722 {
723 SHELL_VAR *var;
724 int tem;
725 #if defined (ARRAY_VARS)
726 char *t;
727 #endif
728
729 name = list->word->word;
730
731 #if defined (ARRAY_VARS)
732 if (!unset_function && valid_array_reference (name))
733 {
734 t = strchr (name, '[');
735 *t++ = '\0';
736 unset_array++;
737 }
738 #endif
739
740 /* Bash allows functions with names which are not valid identifiers
741 to be created when not in posix mode, so check only when in posix
742 mode when unsetting a function. */
743 if (((unset_function && posixly_correct) || !unset_function) && legal_identifier (name) == 0)
744 {
745 builtin_error ("`%s': not a valid identifier", name);
746 NEXT_VARIABLE ();
747 }
748
749 var = unset_function ? find_function (name) : find_variable (name);
750
751 if (var && !unset_function && non_unsettable_p (var))
752 {
753 builtin_error ("%s: cannot unset", name);
754 NEXT_VARIABLE ();
755 }
756
757 /* Posix.2 says that unsetting readonly variables is an error. */
758 if (var && readonly_p (var))
759 {
760 builtin_error ("%s: cannot unset: readonly %s",
761 name, unset_function ? "function" : "variable");
762 NEXT_VARIABLE ();
763 }
764
765 /* Unless the -f option is supplied, the name refers to a variable. */
766 #if defined (ARRAY_VARS)
767 if (var && unset_array)
768 {
769 if (array_p (var) == 0)
770 {
771 builtin_error ("%s: not an array variable", name);
772 NEXT_VARIABLE ();
773 }
774 else
775 tem = unbind_array_element (var, t);
776 }
777 else
778 #endif /* ARRAY_VARS */
779 tem = makunbound (name, unset_function ? shell_functions : shell_variables);
780
781 /* This is what Posix.2 draft 11+ says. ``If neither -f nor -v
782 is specified, the name refers to a variable; if a variable by
783 that name does not exist, a function by that name, if any,
784 shall be unset.'' */
785 if (tem == -1 && !unset_function && !unset_variable)
786 tem = makunbound (name, shell_functions);
787
788 if (tem == -1)
789 any_failed++;
790 else if (!unset_function)
791 stupidly_hack_special_variables (name);
792
793 list = list->next;
794 }
795
796 return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
797 }