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-2021 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
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 Bash is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with Bash. If not, see <http://www.gnu.org/licenses/>.
25 #if defined (HAVE_UNISTD_H)
27 # include <sys/types.h>
34 #include "../bashansi.h"
35 #include "../bashintl.h"
38 #include "../parser.h"
41 #include "bashgetopt.h"
43 #if defined (READLINE)
44 # include "../input.h"
45 # include "../bashline.h"
46 # include <readline/readline.h>
50 # include "../bashhist.h"
55 $SHORT_DOC set [-abefhkmnptuvxBCEHPT] [-o option-name] [--] [-] [arg ...]
56 Set or unset values of shell options and positional parameters.
58 Change the value of shell attributes and positional parameters, or
59 display the names and values of shell variables.
62 -a Mark variables which are modified or created for export.
63 -b Notify of job termination immediately.
64 -e Exit immediately if a command exits with a non-zero status.
65 -f Disable file name generation (globbing).
66 -h Remember the location of commands as they are looked up.
67 -k All assignment arguments are placed in the environment for a
68 command, not just those that precede the command name.
69 -m Job control is enabled.
70 -n Read commands but do not execute them.
72 Set the variable corresponding to option-name:
74 braceexpand same as -B
75 #if defined (READLINE)
76 emacs use an emacs-style line editing interface
82 #if defined (BANG_HISTORY)
84 #endif /* BANG_HISTORY */
86 history enable command history
88 ignoreeof the shell will not exit upon reading EOF
90 allow comments to appear in interactive commands
92 #if defined (JOB_CONTROL)
98 nolog currently accepted but ignored
99 #if defined (JOB_CONTROL)
105 pipefail the return value of a pipeline is the status of
106 the last command to exit with a non-zero status,
107 or zero if no command exited with a non-zero status
108 posix change the behavior of bash where the default
109 operation differs from the Posix standard to
111 privileged same as -p
113 #if defined (READLINE)
114 vi use a vi-style line editing interface
115 #endif /* READLINE */
117 -p Turned on whenever the real and effective user ids do not match.
118 Disables processing of the $ENV file and importing of shell
119 functions. Turning this option off causes the effective uid and
120 gid to be set to the real uid and gid.
121 -t Exit after reading and executing one command.
122 -u Treat unset variables as an error when substituting.
123 -v Print shell input lines as they are read.
124 -x Print commands and their arguments as they are executed.
125 #if defined (BRACE_EXPANSION)
126 -B the shell will perform brace expansion
127 #endif /* BRACE_EXPANSION */
128 -C If set, disallow existing regular files to be overwritten
129 by redirection of output.
130 -E If set, the ERR trap is inherited by shell functions.
131 #if defined (BANG_HISTORY)
132 -H Enable ! style history substitution. This flag is on
133 by default when the shell is interactive.
134 #endif /* BANG_HISTORY */
135 -P If set, do not resolve symbolic links when executing commands
136 such as cd which change the current directory.
137 -T If set, the DEBUG and RETURN traps are inherited by shell functions.
138 -- Assign any remaining arguments to the positional parameters.
139 If there are no remaining arguments, the positional parameters
141 - Assign any remaining arguments to the positional parameters.
142 The -x and -v options are turned off.
144 Using + rather than - causes these flags to be turned off. The
145 flags can also be used upon invocation of the shell. The current
146 set of flags may be found in $-. The remaining n ARGs are positional
147 parameters and are assigned, in order, to $1, $2, .. $n. If no
148 ARGs are given, all shell variables are printed.
151 Returns success unless an invalid option is given.
154 typedef int setopt_set_func_t PARAMS((int, char *));
155 typedef int setopt_get_func_t PARAMS((char *));
157 static int find_minus_o_option PARAMS((char *));
159 static void print_minus_o_option PARAMS((char *, int, int));
160 static void print_all_shell_variables PARAMS((void));
162 static int set_ignoreeof PARAMS((int, char *));
163 static int set_posix_mode PARAMS((int, char *));
165 #if defined (READLINE)
166 static int set_edit_mode PARAMS((int, char *));
167 static int get_edit_mode PARAMS((char *));
170 #if defined (HISTORY)
171 static int bash_set_history PARAMS((int, char *));
174 static const char * const on = "on";
175 static const char * const off = "off";
177 static int previous_option_value;
179 /* A struct used to match long options for set -o to the corresponding
180 option letter or internal variable. The functions can be called to
181 dynamically generate values. If you add a new variable name here
182 that doesn't have a corresponding single-character option letter, make
183 sure to set the value appropriately in reset_shell_options. */
188 setopt_set_func_t *set_func;
189 setopt_get_func_t *get_func;
191 { "allexport", 'a', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
192 #if defined (BRACE_EXPANSION)
193 { "braceexpand",'B', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
195 #if defined (READLINE)
196 { "emacs", '\0', (int *)NULL, set_edit_mode, get_edit_mode },
198 { "errexit", 'e', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
199 { "errtrace", 'E', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
200 { "functrace", 'T', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
201 { "hashall", 'h', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
202 #if defined (BANG_HISTORY)
203 { "histexpand", 'H', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
204 #endif /* BANG_HISTORY */
205 #if defined (HISTORY)
206 { "history", '\0', &enable_history_list, bash_set_history, (setopt_get_func_t *)NULL },
208 { "ignoreeof", '\0', &ignoreeof, set_ignoreeof, (setopt_get_func_t *)NULL },
209 { "interactive-comments", '\0', &interactive_comments, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
210 { "keyword", 'k', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
211 #if defined (JOB_CONTROL)
212 { "monitor", 'm', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
214 { "noclobber", 'C', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
215 { "noexec", 'n', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
216 { "noglob", 'f', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
217 #if defined (HISTORY)
218 { "nolog", '\0', &dont_save_function_defs, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
220 #if defined (JOB_CONTROL)
221 { "notify", 'b', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
222 #endif /* JOB_CONTROL */
223 { "nounset", 'u', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
224 { "onecmd", 't', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
225 { "physical", 'P', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
226 { "pipefail", '\0', &pipefail_opt, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
227 { "posix", '\0', &posixly_correct, set_posix_mode, (setopt_get_func_t *)NULL },
228 { "privileged", 'p', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
229 { "verbose", 'v', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
230 #if defined (READLINE)
231 { "vi", '\0', (int *)NULL, set_edit_mode, get_edit_mode },
233 { "xtrace", 'x', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
234 {(char *)NULL, 0 , (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
237 #define N_O_OPTIONS (sizeof (o_options) / sizeof (o_options[0]))
239 #define GET_BINARY_O_OPTION_VALUE(i, name) \
240 ((o_options[i].get_func) ? (*o_options[i].get_func) (name) \
241 : (*o_options[i].variable))
243 #define SET_BINARY_O_OPTION_VALUE(i, onoff, name) \
244 ((o_options[i].set_func) ? (*o_options[i].set_func) (onoff, name) \
245 : (*o_options[i].variable = (onoff == FLAG_ON)))
248 find_minus_o_option (name)
253 for (i = 0; o_options[i].name; i++)
254 if (STREQ (name, o_options[i].name))
260 minus_o_option_value (name)
266 i = find_minus_o_option (name);
270 if (o_options[i].letter)
272 on_or_off = find_flag (o_options[i].letter);
273 return ((on_or_off == FLAG_UNKNOWN) ? -1 : *on_or_off);
276 return (GET_BINARY_O_OPTION_VALUE (i, name));
279 #define MINUS_O_FORMAT "%-15s\t%s\n"
282 print_minus_o_option (name, value, pflag)
287 printf (MINUS_O_FORMAT, name, value ? on : off);
289 printf ("set %co %s\n", value ? '-' : '+', name);
293 list_minus_o_opts (mode, reusable)
297 int *on_or_off, value;
299 for (i = 0; o_options[i].name; i++)
301 if (o_options[i].letter)
304 on_or_off = find_flag (o_options[i].letter);
305 if (on_or_off == FLAG_UNKNOWN)
307 if (mode == -1 || mode == *on_or_off)
308 print_minus_o_option (o_options[i].name, *on_or_off, reusable);
312 value = GET_BINARY_O_OPTION_VALUE (i, o_options[i].name);
313 if (mode == -1 || mode == value)
314 print_minus_o_option (o_options[i].name, value, reusable);
325 ret = strvec_create (N_O_OPTIONS + 1);
326 for (i = 0; o_options[i].name; i++)
327 ret[i] = o_options[i].name;
328 ret[i] = (char *)NULL;
333 get_current_options ()
338 posixopts = num_posix_options (); /* shopts modified by posix mode */
339 /* Make the buffer big enough to hold the set -o options and the shopt
340 options modified by posix mode. */
341 temp = (char *)xmalloc (1 + N_O_OPTIONS + posixopts);
342 for (i = 0; o_options[i].name; i++)
344 if (o_options[i].letter)
345 temp[i] = *(find_flag (o_options[i].letter));
347 temp[i] = GET_BINARY_O_OPTION_VALUE (i, o_options[i].name);
350 /* Add the shell options that are modified by posix mode to the end of the
351 bitmap. They will be handled in set_current_options() */
352 get_posix_options (temp+i);
353 temp[i+posixopts] = '\0';
358 set_current_options (bitmap)
361 int i, v, cv, *on_or_off;
366 for (i = 0; o_options[i].name; i++)
368 v = bitmap[i] ? FLAG_ON : FLAG_OFF;
369 if (o_options[i].letter)
371 /* We should not get FLAG_UNKNOWN here */
372 on_or_off = find_flag (o_options[i].letter);
373 cv = *on_or_off ? FLAG_ON : FLAG_OFF;
375 change_flag (o_options[i].letter, v);
379 cv = GET_BINARY_O_OPTION_VALUE (i, o_options[i].name);
380 cv = cv ? FLAG_ON : FLAG_OFF;
382 SET_BINARY_O_OPTION_VALUE (i, v, o_options[i].name);
386 /* Now reset the variables changed by posix mode */
387 set_posix_options (bitmap+i);
391 set_ignoreeof (on_or_off, option_name)
395 ignoreeof = on_or_off == FLAG_ON;
396 unbind_variable_noref ("ignoreeof");
398 bind_variable ("IGNOREEOF", "10", 0);
400 unbind_variable_noref ("IGNOREEOF");
401 sv_ignoreeof ("IGNOREEOF");
406 set_posix_mode (on_or_off, option_name)
410 /* short-circuit on no-op */
411 if ((on_or_off == FLAG_ON && posixly_correct) ||
412 (on_or_off == FLAG_OFF && posixly_correct == 0))
415 posixly_correct = on_or_off == FLAG_ON;
416 if (posixly_correct == 0)
417 unbind_variable_noref ("POSIXLY_CORRECT");
419 bind_variable ("POSIXLY_CORRECT", "y", 0);
420 sv_strict_posix ("POSIXLY_CORRECT");
424 #if defined (READLINE)
425 /* Magic. This code `knows' how readline handles rl_editing_mode. */
427 set_edit_mode (on_or_off, option_name)
433 if (on_or_off == FLAG_ON)
435 rl_variable_bind ("editing-mode", option_name);
438 with_input_from_stdin ();
443 isemacs = rl_editing_mode == 1;
444 if ((isemacs && *option_name == 'e') || (!isemacs && *option_name == 'v'))
447 with_input_from_stream (stdin, "stdin");
451 return 1-no_line_editing;
458 return (*name == 'e' ? no_line_editing == 0 && rl_editing_mode == 1
459 : no_line_editing == 0 && rl_editing_mode == 0);
461 #endif /* READLINE */
463 #if defined (HISTORY)
465 bash_set_history (on_or_off, option_name)
469 if (on_or_off == FLAG_ON)
471 enable_history_list = 1;
472 bash_history_enable ();
473 if (history_lines_this_session == 0)
478 enable_history_list = 0;
479 bash_history_disable ();
481 return (1 - enable_history_list);
486 set_minus_o_option (on_or_off, option_name)
492 i = find_minus_o_option (option_name);
495 sh_invalidoptname (option_name);
499 if (o_options[i].letter == 0)
501 previous_option_value = GET_BINARY_O_OPTION_VALUE (i, o_options[i].name);
502 SET_BINARY_O_OPTION_VALUE (i, on_or_off, option_name);
503 return (EXECUTION_SUCCESS);
507 if ((previous_option_value = change_flag (o_options[i].letter, on_or_off)) == FLAG_ERROR)
509 sh_invalidoptname (option_name);
510 return (EXECUTION_FAILURE);
513 return (EXECUTION_SUCCESS);
518 print_all_shell_variables ()
522 vars = all_shell_variables ();
525 print_var_list (vars);
529 /* POSIX.2 does not allow function names and definitions to be output when
530 `set' is invoked without options (PASC Interp #202). */
531 if (posixly_correct == 0)
533 vars = all_shell_functions ();
536 print_func_list (vars);
546 char tflag[N_O_OPTIONS];
547 int vsize, i, vptr, *ip, exported;
550 for (vsize = i = 0; o_options[i].name; i++)
553 if (o_options[i].letter)
555 ip = find_flag (o_options[i].letter);
558 vsize += strlen (o_options[i].name) + 1;
562 else if (GET_BINARY_O_OPTION_VALUE (i, o_options[i].name))
564 vsize += strlen (o_options[i].name) + 1;
569 value = (char *)xmalloc (vsize + 1);
571 for (i = vptr = 0; o_options[i].name; i++)
575 strcpy (value + vptr, o_options[i].name);
576 vptr += strlen (o_options[i].name);
582 vptr--; /* cut off trailing colon */
585 v = find_variable ("SHELLOPTS");
587 /* Turn off the read-only attribute so we can bind the new value, and
588 note whether or not the variable was exported. */
591 VUNSETATTR (v, att_readonly);
592 exported = exported_p (v);
597 v = bind_variable ("SHELLOPTS", value, 0);
599 /* Turn the read-only attribute back on, and turn off the export attribute
600 if it was set implicitly by mark_modified_vars and SHELLOPTS was not
601 exported before we bound the new value. */
602 VSETATTR (v, att_readonly);
603 if (mark_modified_vars && exported == 0 && exported_p (v))
604 VUNSETATTR (v, att_exported);
610 parse_shellopts (value)
617 while (vname = extract_colon_unit (value, &vptr))
619 set_minus_o_option (FLAG_ON, vname);
625 initialize_shell_options (no_shellopts)
631 if (no_shellopts == 0)
633 var = find_variable ("SHELLOPTS");
634 /* set up any shell options we may have inherited. */
635 if (var && imported_p (var))
637 temp = (array_p (var) || assoc_p (var)) ? (char *)NULL : savestring (value_cell (var));
640 parse_shellopts (temp);
646 /* Set up the $SHELLOPTS variable. */
650 /* Reset the values of the -o options that are not also shell flags. This is
651 called from execute_cmd.c:initialize_subshell() when setting up a subshell
652 to run an executable shell script without a leading `#!'. */
654 reset_shell_options ()
659 #if defined (STRICT_POSIX)
664 #if defined (HISTORY)
665 dont_save_function_defs = 0;
666 remember_on_history = enable_history_list = 1; /* XXX */
670 /* Set some flags from the word values in the input list. If LIST is empty,
671 then print out the values of the variables instead. If LIST contains
672 non-flags, then set $1 - $9 to the successive words of LIST. */
677 int on_or_off, flag_name, force_assignment, opts_changed, rv, r;
683 print_all_shell_variables ();
684 return (sh_chkwrite (EXECUTION_SUCCESS));
687 /* Check validity of flag arguments. */
688 rv = EXECUTION_SUCCESS;
689 reset_internal_getopt ();
690 while ((flag_name = internal_getopt (list, optflags)) != -1)
694 case 'i': /* don't allow set -i */
704 return (list_optopt == '?' ? EXECUTION_SUCCESS : EX_USAGE);
710 /* Do the set command. While the list consists of words starting with
711 '-' or '+' treat them as flags, otherwise, start assigning them to
713 for (force_assignment = opts_changed = 0; list; )
715 arg = list->word->word;
717 /* If the argument is `--' or `-' then signal the end of the list
718 and remember the remaining arguments. */
719 if (arg[0] == '-' && (!arg[1] || (arg[1] == '-' && !arg[2])))
723 /* `set --' unsets the positional parameters. */
725 force_assignment = 1;
727 /* Until told differently, the old shell behaviour of
728 `set - [arg ...]' being equivalent to `set +xv [arg ...]'
729 stands. Posix.2 says the behaviour is marked as obsolescent. */
732 change_flag ('x', '+');
733 change_flag ('v', '+');
740 if ((on_or_off = *arg) && (on_or_off == '-' || on_or_off == '+'))
742 while (flag_name = *++arg)
744 if (flag_name == '?')
747 return (EXECUTION_SUCCESS);
749 else if (flag_name == 'o') /* -+o option-name */
758 list_minus_o_opts (-1, (on_or_off == '+'));
759 rv = sh_chkwrite (rv);
763 option_name = opt->word->word;
765 if (option_name == 0 || *option_name == '\0' ||
766 *option_name == '-' || *option_name == '+')
768 list_minus_o_opts (-1, (on_or_off == '+'));
771 list = list->next; /* Skip over option name. */
774 if ((r = set_minus_o_option (on_or_off, option_name)) != EXECUTION_SUCCESS)
780 else if (change_flag (flag_name, on_or_off) == FLAG_ERROR)
788 return (EXECUTION_FAILURE);
800 /* Assigning $1 ... $n */
801 if (list || force_assignment)
802 remember_args (list, 1);
803 /* Set up new value of $SHELLOPTS */
810 $FUNCTION unset_builtin
811 $SHORT_DOC unset [-f] [-v] [-n] [name ...]
812 Unset values and attributes of shell variables and functions.
814 For each NAME, remove the corresponding variable or function.
817 -f treat each NAME as a shell function
818 -v treat each NAME as a shell variable
819 -n treat each NAME as a name reference and unset the variable itself
820 rather than the variable it references
822 Without options, unset first tries to unset a variable, and if that fails,
823 tries to unset a function.
825 Some variables cannot be unset; also see `readonly'.
828 Returns success unless an invalid option is given or a NAME is read-only.
831 #define NEXT_VARIABLE() any_failed++; list = list->next; continue;
837 int unset_function, unset_variable, unset_array, opt, nameref, any_failed;
838 int global_unset_func, global_unset_var, vflags, base_vflags, valid_id;
841 unset_function = unset_variable = unset_array = nameref = any_failed = 0;
842 global_unset_func = global_unset_var = 0;
844 reset_internal_getopt ();
845 while ((opt = internal_getopt (list, "fnv")) != -1)
850 global_unset_func = 1;
853 global_unset_var = 1;
867 if (global_unset_func && global_unset_var)
869 builtin_error (_("cannot simultaneously unset a function and a variable"));
870 return (EXECUTION_FAILURE);
872 else if (unset_function && nameref)
875 #if defined (ARRAY_VARS)
876 base_vflags = assoc_expand_once ? VA_NOEXPAND : 0;
883 #if defined (ARRAY_VARS)
887 name = list->word->word;
889 unset_function = global_unset_func;
890 unset_variable = global_unset_var;
892 #if defined (ARRAY_VARS)
893 vflags = builtin_arrayref_flags (list->word, base_vflags);
896 #if defined (ARRAY_VARS)
898 /* XXX valid array reference second arg was 0 */
899 if (!unset_function && nameref == 0 && tokenize_array_reference (name, vflags, &t))
902 /* Get error checking out of the way first. The low-level functions
903 just perform the unset, relying on the caller to verify. */
904 valid_id = legal_identifier (name);
906 /* Whether or not we are in posix mode, if neither -f nor -v appears,
907 skip over trying to unset variables with invalid names and just
908 treat them as potential shell function names. */
909 if (global_unset_func == 0 && global_unset_var == 0 && valid_id == 0)
911 unset_variable = unset_array = 0;
915 /* Bash allows functions with names which are not valid identifiers
916 to be created when not in posix mode, so check only when in posix
917 mode when unsetting a function. */
918 if (unset_function == 0 && valid_id == 0)
924 /* Search for functions here if -f supplied or if NAME cannot be a
926 var = unset_function ? find_function (name)
927 : (nameref ? find_variable_last_nameref (name, 0) : find_variable (name));
929 /* Some variables (but not functions yet) cannot be unset, period. */
930 if (var && unset_function == 0 && non_unsettable_p (var))
932 builtin_error (_("%s: cannot unset"), name);
936 /* if we have a nameref we want to use it */
937 if (var && unset_function == 0 && nameref == 0 && STREQ (name, name_cell(var)) == 0)
938 name = name_cell (var);
940 /* Posix.2 says try variables first, then functions. If we would
941 find a function after unsuccessfully searching for a variable,
942 note that we're acting on a function now as if -f were
943 supplied. The readonly check below takes care of it. */
944 if (var == 0 && nameref == 0 && unset_variable == 0 && unset_function == 0)
946 if (var = find_function (name))
950 /* Posix.2 says that unsetting readonly variables is an error. */
951 if (var && readonly_p (var))
953 builtin_error (_("%s: cannot unset: readonly %s"),
954 var->name, unset_function ? "function" : "variable");
958 /* Unless the -f option is supplied, the name refers to a variable. */
959 #if defined (ARRAY_VARS)
960 if (var && unset_array)
962 if (shell_compatibility_level <= 51)
963 vflags |= VA_ALLOWALL;
965 /* Let unbind_array_element decide what to do with non-array vars */
966 tem = unbind_array_element (var, t, vflags); /* XXX new third arg */
967 if (tem == -2 && array_p (var) == 0 && assoc_p (var) == 0)
969 builtin_error (_("%s: not an array variable"), var->name);
976 #endif /* ARRAY_VARS */
977 /* If we're trying to unset a nameref variable whose value isn't a set
978 variable, make sure we still try to unset the nameref's value */
979 if (var == 0 && nameref == 0 && unset_function == 0)
981 var = find_variable_last_nameref (name, 0);
982 if (var && nameref_p (var))
984 #if defined (ARRAY_VARS)
985 if (valid_array_reference (nameref_cell (var), 0))
989 tname = savestring (nameref_cell (var));
990 if (var = array_variable_part (tname, 0, &t, &len))
992 /* change to what unbind_array_element now expects */
993 if (t[len - 1] == ']')
995 tem = unbind_array_element (var, t, vflags); /* XXX new third arg */
1001 tem = unbind_variable (nameref_cell (var));
1004 tem = unbind_variable (name);
1007 tem = unset_function ? unbind_func (name) : (nameref ? unbind_nameref (name) : unbind_variable (name));
1009 /* This is what Posix.2 says: ``If neither -f nor -v
1010 is specified, the name refers to a variable; if a variable by
1011 that name does not exist, a function by that name, if any,
1012 shall be unset.'' */
1013 if (tem == -1 && nameref == 0 && unset_function == 0 && unset_variable == 0)
1014 tem = unbind_func (name);
1016 name = list->word->word; /* reset above for namerefs */
1018 /* SUSv3, POSIX.1-2001 say: ``Unsetting a variable or function that
1019 was not previously set shall not be considered an error.'' */
1021 if (unset_function == 0)
1022 stupidly_hack_special_variables (name);
1027 return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS);