1 This file is set.def, from which is created set.c.
2 It implements the "set" and "unset" builtins in Bash.
4 Copyright (C) 1987, 1989, 1991 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA.
26 #if defined (HAVE_UNISTD_H)
28 # include <sys/types.h>
35 #include "../bashansi.h"
40 #include "bashgetopt.h"
42 #if defined (READLINE)
43 # include "../input.h"
44 # include "../bashline.h"
45 # include <readline/readline.h>
49 # include "../bashhist.h"
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;
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.
73 Set the variable corresponding to option-name:
75 braceexpand same as -B
76 #if defined (READLINE)
77 emacs use an emacs-style line editing interface
81 #if defined (BANG_HISTORY)
83 #endif /* BANG_HISTORY */
85 history enable command history
87 ignoreeof the shell will not exit upon reading EOF
89 allow comments to appear in interactive commands
99 posix change the behavior of bash where the default
100 operation differs from the 1003.2 standard to
102 privileged same as -p
104 #if defined (READLINE)
105 vi use a vi-style line editing interface
106 #endif /* READLINE */
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
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.
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.
135 static int set_ignoreeof ();
136 static int set_posix_mode ();
138 #if defined (READLINE)
139 static int set_edit_mode ();
140 static int get_edit_mode ();
143 #if defined (HISTORY)
144 static int bash_set_history ();
147 static char *on = "on";
148 static char *off = "off";
150 /* An a-list used to match long options for set -o to the corresponding
156 { "allexport", 'a' },
157 #if defined (BRACE_EXPANSION)
158 { "braceexpand",'B' },
162 #if defined (BANG_HISTORY)
163 { "histexpand", 'H' },
164 #endif /* BANG_HISTORY */
167 { "noclobber", 'C' },
170 #if defined (JOB_CONTROL)
172 #endif /* JOB_CONTROL */
176 { "privileged", 'p' },
187 } binary_o_options[] = {
188 #if defined (HISTORY)
189 { "history", &remember_on_history, bash_set_history, (Function *)NULL },
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 },
198 { (char *)NULL, (int *)NULL }
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))
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)))
210 minus_o_option_value (name)
216 for (i = 0; o_options[i].name; i++)
218 if (STREQ (name, o_options[i].name))
220 on_or_off = find_flag (o_options[i].letter);
221 return ((on_or_off == FLAG_UNKNOWN) ? -1 : *on_or_off);
224 for (i = 0; binary_o_options[i].name; i++)
226 if (STREQ (name, binary_o_options[i].name))
227 return (GET_BINARY_O_OPTION_VALUE (i, name));
233 #define MINUS_O_FORMAT "%-15s\t%s\n"
236 print_minus_o_option (name, value, pflag)
241 printf (MINUS_O_FORMAT, name, value ? on : off);
243 printf ("set %co %s\n", value ? '-' : '+', name);
247 list_minus_o_opts (mode, reusable)
251 int *on_or_off, value;
253 for (value = i = 0; o_options[i].name; i++)
255 on_or_off = find_flag (o_options[i].letter);
256 if (on_or_off == FLAG_UNKNOWN)
258 if (mode == -1 || mode == *on_or_off)
259 print_minus_o_option (o_options[i].name, *on_or_off, reusable);
261 for (i = 0; binary_o_options[i].name; i++)
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);
270 set_ignoreeof (on_or_off, option_name)
274 ignoreeof = on_or_off == FLAG_ON;
275 unbind_variable ("ignoreeof");
277 bind_variable ("IGNOREEOF", "10");
279 unbind_variable ("IGNOREEOF");
280 sv_ignoreeof ("IGNOREEOF");
285 set_posix_mode (on_or_off, option_name)
289 posixly_correct = on_or_off == FLAG_ON;
290 if (posixly_correct == 0)
291 unbind_variable ("POSIXLY_CORRECT");
293 bind_variable ("POSIXLY_CORRECT", "y");
294 sv_strict_posix ("POSIXLY_CORRECT");
298 #if defined (READLINE)
299 /* Magic. This code `knows' how readline handles rl_editing_mode. */
301 set_edit_mode (on_or_off, option_name)
307 if (on_or_off == FLAG_ON)
309 rl_variable_bind ("editing-mode", option_name);
312 with_input_from_stdin ();
317 isemacs = rl_editing_mode == 1;
318 if ((isemacs && *option_name == 'e') || (!isemacs && *option_name == 'v'))
321 with_input_from_stream (stdin, "stdin");
325 return 1-no_line_editing;
332 return (*name == 'e' ? no_line_editing == 0 && rl_editing_mode == 1
333 : no_line_editing == 0 && rl_editing_mode == 0);
335 #endif /* READLINE */
337 #if defined (HISTORY)
339 bash_set_history (on_or_off, option_name)
343 if (on_or_off == FLAG_ON)
345 bash_history_enable ();
346 if (history_lines_this_session == 0)
350 bash_history_disable ();
351 return (1 - remember_on_history);
356 set_minus_o_option (on_or_off, option_name)
364 for (i = 0; binary_o_options[i].name; i++)
366 if (STREQ (option_name, binary_o_options[i].name))
368 SET_BINARY_O_OPTION_VALUE (i, on_or_off, option_name);
369 return (EXECUTION_SUCCESS);
373 for (i = 0, option_char = -1, set_func = 0; o_options[i].name; i++)
375 if (STREQ (option_name, o_options[i].name))
377 option_char = o_options[i].letter;
381 if (option_char == -1)
383 builtin_error ("%s: unknown option name", option_name);
384 return (EXECUTION_FAILURE);
386 if (change_flag (option_char, on_or_off) == FLAG_ERROR)
388 bad_option (option_name);
389 return (EXECUTION_FAILURE);
391 return (EXECUTION_SUCCESS);
395 print_all_shell_variables ()
399 vars = all_shell_variables ();
402 print_var_list (vars);
406 vars = all_shell_functions ();
409 print_var_list (vars);
418 int vsize, i, vptr, *ip, exported;
421 for (vsize = i = 0; o_options[i].name; i++)
423 ip = find_flag (o_options[i].letter);
425 vsize += strlen (o_options[i].name) + 1;
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;
431 value = xmalloc (vsize + 1);
433 for (i = vptr = 0; o_options[i].name; i++)
435 ip = find_flag (o_options[i].letter);
438 strcpy (value + vptr, o_options[i].name);
439 vptr += strlen (o_options[i].name);
443 for (i = 0; binary_o_options[i].name; i++)
444 if (GET_BINARY_O_OPTION_VALUE (i, binary_o_options[i].name))
446 strcpy (value + vptr, binary_o_options[i].name);
447 vptr += strlen (binary_o_options[i].name);
451 vptr--; /* cut off trailing colon */
454 v = find_variable ("SHELLOPTS");
456 /* Turn off the read-only attribute so we can bind the new value, and
457 note whether or not the variable was exported. */
460 v->attributes &= ~att_readonly;
461 exported = exported_p (v);
466 v = bind_variable ("SHELLOPTS", value);
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;
479 parse_shellopts (value)
486 while (vname = extract_colon_unit (value, &vptr))
488 set_minus_o_option (FLAG_ON, vname);
494 initialize_shell_options (no_shellopts)
500 if (no_shellopts == 0)
502 var = find_variable ("SHELLOPTS");
503 /* set up any shell options we may have inherited. */
504 if (var && imported_p (var))
506 temp = (array_p (var)) ? (char *)NULL : savestring (value_cell (var));
509 parse_shellopts (temp);
515 /* Set up the $SHELLOPTS variable. */
519 /* Reset the values of the -o options that are not also shell flags. */
521 reset_shell_options ()
523 #if defined (HISTORY)
524 remember_on_history = 1;
526 ignoreeof = posixly_correct = 0;
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. */
536 int on_or_off, flag_name, force_assignment, opts_changed;
542 print_all_shell_variables ();
543 return (EXECUTION_SUCCESS);
546 /* Check validity of flag arguments. */
547 if (*list->word->word == '-' || *list->word->word == '+')
549 for (l = list; l && (arg = l->word->word); l = l->next)
553 if (arg[0] != '-' && arg[0] != '+')
556 /* `-' or `--' signifies end of flag arguments. */
557 if (arg[0] == '-' && (!arg[1] || (arg[1] == '-' && !arg[2])))
562 if (find_flag (c) == FLAG_UNKNOWN && c != 'o')
565 s[0] = c; s[1] = '\0';
569 return (c == '?' ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
575 /* Do the set command. While the list consists of words starting with
576 '-' or '+' treat them as flags, otherwise, start assigning them to
578 for (force_assignment = opts_changed = 0; list; )
580 arg = list->word->word;
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])))
588 /* `set --' unsets the positional parameters. */
590 force_assignment = 1;
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. */
597 change_flag ('x', '+');
598 change_flag ('v', '+');
605 if ((on_or_off = *arg) && (on_or_off == '-' || on_or_off == '+'))
607 while (flag_name = *++arg)
609 if (flag_name == '?')
612 return (EXECUTION_SUCCESS);
614 else if (flag_name == 'o') /* -+o option-name */
623 list_minus_o_opts (-1, (on_or_off == '+'));
627 option_name = opt->word->word;
629 if (option_name == 0 || *option_name == '\0' ||
630 *option_name == '-' || *option_name == '+')
632 list_minus_o_opts (-1, (on_or_off == '+'));
635 list = list->next; /* Skip over option name. */
638 if (set_minus_o_option (on_or_off, option_name) != EXECUTION_SUCCESS)
641 return (EXECUTION_FAILURE);
644 else if (change_flag (flag_name, on_or_off) == FLAG_ERROR)
653 return (EXECUTION_FAILURE);
665 /* Assigning $1 ... $n */
666 if (list || force_assignment)
667 remember_args (list, 1);
668 /* Set up new value of $SHELLOPTS */
671 return (EXECUTION_SUCCESS);
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
685 #define NEXT_VARIABLE() any_failed++; list = list->next; continue;
691 int unset_function, unset_variable, unset_array, opt, any_failed;
694 unset_function = unset_variable = unset_array = any_failed = 0;
696 reset_internal_getopt ();
697 while ((opt = internal_getopt (list, "fv")) != -1)
715 if (unset_function && unset_variable)
717 builtin_error ("cannot simultaneously unset a function and a variable");
718 return (EXECUTION_FAILURE);
725 #if defined (ARRAY_VARS)
729 name = list->word->word;
731 #if defined (ARRAY_VARS)
732 if (!unset_function && valid_array_reference (name))
734 t = strchr (name, '[');
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)
745 builtin_error ("`%s': not a valid identifier", name);
749 var = unset_function ? find_function (name) : find_variable (name);
751 if (var && !unset_function && non_unsettable_p (var))
753 builtin_error ("%s: cannot unset", name);
757 /* Posix.2 says that unsetting readonly variables is an error. */
758 if (var && readonly_p (var))
760 builtin_error ("%s: cannot unset: readonly %s",
761 name, unset_function ? "function" : "variable");
765 /* Unless the -f option is supplied, the name refers to a variable. */
766 #if defined (ARRAY_VARS)
767 if (var && unset_array)
769 if (array_p (var) == 0)
771 builtin_error ("%s: not an array variable", name);
775 tem = unbind_array_element (var, t);
778 #endif /* ARRAY_VARS */
779 tem = makunbound (name, unset_function ? shell_functions : shell_variables);
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,
785 if (tem == -1 && !unset_function && !unset_variable)
786 tem = makunbound (name, shell_functions);
790 else if (!unset_function)
791 stupidly_hack_special_variables (name);
796 return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS);