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)
32 #include "../bashansi.h"
37 #include "bashgetopt.h"
39 #if defined (READLINE)
40 # include "../input.h"
41 # include "../bashline.h"
42 # include <readline/readline.h>
46 # include "../bashhist.h"
49 extern int interactive;
50 extern int noclobber, posixly_correct, ignoreeof, eof_encountered_limit;
51 #if defined (READLINE)
52 extern int rl_editing_mode, no_line_editing;
57 $SHORT_DOC set [--abefhkmnptuvxBCHP] [-o option] [arg ...]
58 -a Mark variables which are modified or created for export.
59 -b Notify of job termination immediately.
60 -e Exit immediately if a command exits with a non-zero status.
61 -f Disable file name generation (globbing).
62 -h Remember the location of commands as they are looked up.
63 -i Force the shell to be an "interactive" one. Interactive shells
64 always read `~/.bashrc' on startup.
65 -k All assignment arguments are placed in the environment for a
66 command, not just those that precede the command name.
67 -m Job control is enabled.
68 -n Read commands but do not execute them.
70 Set the variable corresponding to option-name:
72 braceexpand same as -B
73 #if defined (READLINE)
74 emacs use an emacs-style line editing interface
78 #if defined (BANG_HISTORY)
80 #endif /* BANG_HISTORY */
81 ignoreeof the shell will not exit upon reading EOF
83 allow comments to appear in interactive commands
93 posix change the behavior of bash where the default
94 operation differs from the 1003.2 standard to
98 #if defined (READLINE)
99 vi use a vi-style line editing interface
100 #endif /* READLINE */
102 -p Turned on whenever the real and effective user ids do not match.
103 Disables processing of the $ENV file and importing of shell
104 functions. Turning this option off causes the effective uid and
105 gid to be set to the real uid and gid.
106 -t Exit after reading and executing one command.
107 -u Treat unset variables as an error when substituting.
108 -v Print shell input lines as they are read.
109 -x Print commands and their arguments as they are executed.
110 #if defined (BRACE_EXPANSION)
111 -B the shell will perform brace expansion
112 #endif /* BRACE_EXPANSION */
113 #if defined (BANG_HISTORY)
114 -H Enable ! style history substitution. This flag is on
116 #endif /* BANG_HISTORY */
117 -C If set, disallow existing regular files to be overwritten
118 by redirection of output.
119 -P If set, do not follow symbolic links when executing commands
120 such as cd which change the current directory.
122 Using + rather than - causes these flags to be turned off. The
123 flags can also be used upon invocation of the shell. The current
124 set of flags may be found in $-. The remaining n ARGs are positional
125 parameters and are assigned, in order, to $1, $2, .. $n. If no
126 ARGs are given, all shell variables are printed.
129 static int set_ignoreeof ();
131 #if defined (READLINE)
132 static int set_edit_mode ();
133 static int get_edit_mode ();
136 #if defined (HISTORY)
137 static int bash_set_history ();
140 static char *on = "on";
141 static char *off = "off";
143 /* An a-list used to match long options for set -o to the corresponding
149 { "allexport", 'a' },
150 #if defined (BRACE_EXPANSION)
151 { "braceexpand",'B' },
155 #if defined (BANG_HISTORY)
156 { "histexpand", 'H' },
157 #endif /* BANG_HISTORY */
160 { "noclobber", 'C' },
163 #if defined (JOB_CONTROL)
165 #endif /* JOB_CONTROL */
169 { "privileged", 'p' },
180 } binary_o_options[] = {
181 #if defined (HISTORY)
182 { "history", &remember_on_history, bash_set_history, (Function *)NULL },
184 { "ignoreeof", &ignoreeof, set_ignoreeof, (Function *)NULL },
185 { "interactive-comments", &interactive_comments, (Function *)NULL, (Function *)NULL },
186 { "posix", &posixly_correct, (Function *)NULL, (Function *)NULL },
187 #if defined (READLINE)
188 { "emacs", (int *)NULL, set_edit_mode, get_edit_mode },
189 { "vi", (int *)NULL, set_edit_mode, get_edit_mode },
191 { (char *)NULL, (int *)NULL }
194 #define GET_BINARY_O_OPTION_VALUE(i, name) \
195 ((binary_o_options[i].get_func) ? (*binary_o_options[i].get_func) (name) \
196 : (*binary_o_options[i].variable))
198 #define SET_BINARY_O_OPTION_VALUE(i, onoff, name) \
199 ((binary_o_options[i].set_func) ? (*binary_o_options[i].set_func) (onoff, name) \
200 : (*binary_o_options[i].variable = (onoff == FLAG_ON)))
203 minus_o_option_value (name)
209 for (i = 0; o_options[i].name; i++)
211 if (STREQ (name, o_options[i].name))
213 on_or_off = find_flag (o_options[i].letter);
214 return ((on_or_off == FLAG_UNKNOWN) ? -1 : *on_or_off);
217 for (i = 0; binary_o_options[i].name; i++)
219 if (STREQ (name, binary_o_options[i].name))
220 return (GET_BINARY_O_OPTION_VALUE (i, name));
226 #define MINUS_O_FORMAT "%-15s\t%s\n"
229 list_minus_o_opts (mode)
233 int *on_or_off, value;
235 for (value = i = 0; o_options[i].name; i++)
237 on_or_off = find_flag (o_options[i].letter);
238 if (on_or_off == FLAG_UNKNOWN)
240 if (mode == -1 || mode == *on_or_off)
241 printf (MINUS_O_FORMAT, o_options[i].name, *on_or_off ? on : off);
243 for (i = 0; binary_o_options[i].name; i++)
245 value = GET_BINARY_O_OPTION_VALUE (i, binary_o_options[i].name);
246 if (mode == -1 || mode == value)
247 printf (MINUS_O_FORMAT, binary_o_options[i].name, value ? on : off);
252 minus_o_option_commands ()
255 int *on_or_off, value;
257 for (value = i = 0; o_options[i].name; i++)
259 on_or_off = find_flag (o_options[i].letter);
260 if (on_or_off == FLAG_UNKNOWN)
262 printf ("set %co %s\n", *on_or_off ? '-' : '+', o_options[i].name);
264 for (i = 0; binary_o_options[i].name; i++)
266 value = GET_BINARY_O_OPTION_VALUE (i, binary_o_options[i].name);
267 printf ("set %co %s\n", value ? '-' : '+', binary_o_options[i].name);
272 set_ignoreeof (on_or_off, option_name)
276 ignoreeof = on_or_off == FLAG_ON;
277 unbind_variable ("ignoreeof");
279 bind_variable ("IGNOREEOF", "10");
281 unbind_variable ("IGNOREEOF");
282 sv_ignoreeof ("IGNOREEOF");
286 #if defined (READLINE)
287 /* Magic. This code `knows' how readline handles rl_editing_mode. */
289 set_edit_mode (on_or_off, option_name)
295 if (on_or_off == FLAG_ON)
297 rl_variable_bind ("editing-mode", option_name);
300 with_input_from_stdin ();
305 isemacs = rl_editing_mode == 1;
306 if ((isemacs && *option_name == 'e') || (!isemacs && *option_name == 'v'))
309 with_input_from_stream (stdin, "stdin");
313 return 1-no_line_editing;
320 return (*name == 'e' ? no_line_editing == 0 && rl_editing_mode == 1
321 : no_line_editing == 0 && rl_editing_mode == 0);
323 #endif /* READLINE */
325 #if defined (HISTORY)
327 bash_set_history (on_or_off, option_name)
331 if (on_or_off == FLAG_ON)
333 bash_history_enable ();
334 if (history_lines_this_session == 0)
338 bash_history_disable ();
339 return (1 - remember_on_history);
344 set_minus_o_option (on_or_off, option_name)
352 for (i = 0; binary_o_options[i].name; i++)
354 if (STREQ (option_name, binary_o_options[i].name))
356 SET_BINARY_O_OPTION_VALUE (i, on_or_off, option_name);
357 return (EXECUTION_SUCCESS);
361 for (i = 0, option_char = -1, set_func = 0; o_options[i].name; i++)
363 if (STREQ (option_name, o_options[i].name))
365 option_char = o_options[i].letter;
369 if (option_char == -1)
371 builtin_error ("%s: unknown option name", option_name);
372 return (EXECUTION_FAILURE);
374 if (change_flag (option_char, on_or_off) == FLAG_ERROR)
376 bad_option (option_name);
377 return (EXECUTION_FAILURE);
379 return (EXECUTION_SUCCESS);
383 print_all_shell_variables ()
387 vars = all_shell_variables ();
390 print_var_list (vars);
394 vars = all_shell_functions ();
397 print_var_list (vars);
406 int vsize, i, vptr, *ip;
409 for (vsize = i = 0; o_options[i].name; i++)
411 ip = find_flag (o_options[i].letter);
413 vsize += strlen (o_options[i].name) + 1;
415 for (i = 0; binary_o_options[i].name; i++)
416 if (GET_BINARY_O_OPTION_VALUE (i, binary_o_options[i].name))
417 vsize += strlen (binary_o_options[i].name) + 1;
419 value = xmalloc (vsize + 1);
421 for (i = vptr = 0; o_options[i].name; i++)
423 ip = find_flag (o_options[i].letter);
426 strcpy (value + vptr, o_options[i].name);
427 vptr += strlen (o_options[i].name);
431 for (i = 0; binary_o_options[i].name; i++)
432 if (GET_BINARY_O_OPTION_VALUE (i, binary_o_options[i].name))
434 strcpy (value + vptr, binary_o_options[i].name);
435 vptr += strlen (binary_o_options[i].name);
438 value[--vptr] = '\0'; /* cut off trailing colon */
440 v = find_variable ("SHELLOPTS");
442 v->attributes &= ~att_readonly;
443 v = bind_variable ("SHELLOPTS", value);
444 v->attributes |= att_readonly;
450 parse_shellopts (value)
457 while (vname = extract_colon_unit (value, &vptr))
459 set_minus_o_option (FLAG_ON, vname);
465 initialize_shell_options ()
469 /* set up any shell options we may have inherited. */
470 if (temp = get_string_value ("SHELLOPTS"))
471 parse_shellopts (temp);
473 /* Set up the $SHELLOPTS variable. */
477 /* Set some flags from the word values in the input list. If LIST is empty,
478 then print out the values of the variables instead. If LIST contains
479 non-flags, then set $1 - $9 to the successive words of LIST. */
484 int on_or_off, flag_name, force_assignment, opts_changed;
490 print_all_shell_variables ();
491 return (EXECUTION_SUCCESS);
494 /* Check validity of flag arguments. */
495 if (*list->word->word == '-' || *list->word->word == '+')
497 for (l = list; l && (arg = l->word->word); l = l->next)
501 if (arg[0] != '-' && arg[0] != '+')
504 /* `-' or `--' signifies end of flag arguments. */
505 if (arg[0] == '-' && (!arg[1] || (arg[1] == '-' && !arg[2])))
510 if (find_flag (c) == FLAG_UNKNOWN && c != 'o')
513 s[0] = c; s[1] = '\0';
517 return (c == '?' ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
523 /* Do the set command. While the list consists of words starting with
524 '-' or '+' treat them as flags, otherwise, start assigning them to
526 for (force_assignment = opts_changed = 0; list; )
528 arg = list->word->word;
530 /* If the argument is `--' or `-' then signal the end of the list
531 and remember the remaining arguments. */
532 if (arg[0] == '-' && (!arg[1] || (arg[1] == '-' && !arg[2])))
536 /* `set --' unsets the positional parameters. */
538 force_assignment = 1;
540 /* Until told differently, the old shell behaviour of
541 `set - [arg ...]' being equivalent to `set +xv [arg ...]'
542 stands. Posix.2 says the behaviour is marked as obsolescent. */
545 change_flag ('x', '+');
546 change_flag ('v', '+');
553 if ((on_or_off = *arg) && (on_or_off == '-' || on_or_off == '+'))
555 while (flag_name = *++arg)
557 if (flag_name == '?')
560 return (EXECUTION_SUCCESS);
562 else if (flag_name == 'o') /* -+o option-name */
571 if (on_or_off == '-')
572 list_minus_o_opts (-1);
574 minus_o_option_commands ();
578 option_name = opt->word->word;
580 if (option_name == 0 || *option_name == '\0' ||
581 *option_name == '-' || *option_name == '+')
583 if (on_or_off == '-')
584 list_minus_o_opts (-1);
586 minus_o_option_commands ();
589 list = list->next; /* Skip over option name. */
592 if (set_minus_o_option (on_or_off, option_name) != EXECUTION_SUCCESS)
595 return (EXECUTION_FAILURE);
598 else if (change_flag (flag_name, on_or_off) == FLAG_ERROR)
607 return (EXECUTION_FAILURE);
619 /* Assigning $1 ... $n */
620 if (list || force_assignment)
621 remember_args (list, 1);
622 /* Set up new value of $SHELLOPTS */
625 return (EXECUTION_SUCCESS);
629 $FUNCTION unset_builtin
630 $SHORT_DOC unset [-f] [-v] [name ...]
631 For each NAME, remove the corresponding variable or function. Given
632 the `-v', unset will only act on variables. Given the `-f' flag,
633 unset will only act on functions. With neither flag, unset first
634 tries to unset a variable, and if that fails, then tries to unset a
635 function. Some variables (such as PATH and IFS) cannot be unset; also
639 #define NEXT_VARIABLE() any_failed++; list = list->next; continue;
645 int unset_function, unset_variable, unset_array, opt, any_failed;
648 unset_function = unset_variable = unset_array = any_failed = 0;
650 reset_internal_getopt ();
651 while ((opt = internal_getopt (list, "fv")) != -1)
669 if (unset_function && unset_variable)
671 builtin_error ("cannot simultaneously unset a function and a variable");
672 return (EXECUTION_FAILURE);
679 #if defined (ARRAY_VARS)
683 name = list->word->word;
685 #if defined (ARRAY_VARS)
686 if (!unset_function && valid_array_reference (name))
688 t = strchr (name, '[');
694 var = unset_function ? find_function (name) : find_variable (name);
696 if (var && !unset_function && non_unsettable_p (var))
698 builtin_error ("%s: cannot unset", name);
702 /* Posix.2 says that unsetting readonly variables is an error. */
703 if (var && readonly_p (var))
705 builtin_error ("%s: cannot unset: readonly %s",
706 name, unset_function ? "function" : "variable");
710 /* Unless the -f option is supplied, the name refers to a variable. */
711 #if defined (ARRAY_VARS)
712 if (var && unset_array)
714 if (array_p (var) == 0)
716 builtin_error ("%s: not an array variable", name);
720 tem = unbind_array_element (var, t);
723 #endif /* ARRAY_VARS */
724 tem = makunbound (name, unset_function ? shell_functions : shell_variables);
726 /* This is what Posix.2 draft 11+ says. ``If neither -f nor -v
727 is specified, the name refers to a variable; if a variable by
728 that name does not exist, a function by that name, if any,
730 if (tem == -1 && !unset_function && !unset_variable)
731 tem = makunbound (name, shell_functions);
735 else if (!unset_function)
736 stupidly_hack_special_variables (name);
741 return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS);