1 This file is set.def
, from which is created set.c.
2 It implements the
"set" and
"unset" builtins in Bush.
4 Copyright (C
) 1987-2020 Free Software Foundation
, Inc.
6 This file is part of GNU Bush
, the Bourne Again SHell.
8 Bush 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 Bush 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 Bush. If not
, see
<http
://www.gnu.org
/licenses
/>.
25 #if
defined (HAVE_UNISTD_H
)
27 # include
<sys
/types.h
>
34 #include
"../src/bushansi.h"
35 #include
"../src/bushintl.h"
37 #include
"../src/shell.h"
38 #include
"../src/lxrgmr/parser.h"
39 #include
"../src/flags.h"
41 #include
"bushgetopt.h"
43 #if
defined (READLINE
)
44 # include
"../src/input/input.h"
45 # include
"../src/input/bushline.h"
46 # include
<readline
/readline.h
>
50 # include
"../src/bushhist.h"
55 $SHORT_DOC set
[-abdefhkmnptuvxBCHP
] [-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 -d same as
-x
, but only effect on current function.
66 -f Disable file name
generation (globbing
).
67 -h Remember the location of commands as they are looked up.
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
83 #if
defined (BANG_HISTORY
)
85 #endif
/* BANG_HISTORY
*/
87 history enable command history
89 ignoreeof the shell will not exit upon reading EOF
91 allow comments to appear in interactive commands
93 #if
defined (JOB_CONTROL
)
99 nolog currently accepted but ignored
100 #if
defined (JOB_CONTROL
)
106 pipefail the return value of a pipeline is the status of
107 the last command to exit with a non
-zero status
,
108 or zero if no command exited with a non
-zero status
109 posix change the behavior of bush where the default
110 operation differs from the Posix standard to
112 privileged same as
-p
114 #if
defined (READLINE
)
115 vi use a vi
-style line editing interface
116 #endif
/* READLINE
*/
119 -p Turned on whenever the real and effective user ids do not match.
120 Disables processing of the $ENV file and importing of shell
121 functions. Turning this option off causes the effective uid and
122 gid to be set to the real uid and gid.
123 -t Exit after reading and executing one command.
124 -u Treat unset variables as an error when substituting.
125 -v Print shell input lines as they are read.
126 -x Print commands and their arguments as they are executed.
127 #if
defined (BRACE_EXPANSION
)
128 -B the shell will perform brace expansion
129 #endif
/* BRACE_EXPANSION
*/
130 -C If set
, disallow existing regular files to be overwritten
131 by redirection of output.
132 -E If set
, the ERR trap is inherited by shell functions.
133 #if
defined (BANG_HISTORY
)
134 -H Enable
! style history substitution. This flag is on
135 by default when the shell is interactive.
136 #endif
/* BANG_HISTORY
*/
137 -P If set
, do not resolve symbolic links when executing commands
138 such as cd which change the current directory.
139 -T If set
, the DEBUG and
RETURN traps are inherited by shell functions.
140 -- Assign any remaining arguments to the positional parameters.
141 If there are no remaining arguments
, the positional parameters
143 - Assign any remaining arguments to the positional parameters.
144 The
-x and
-v options are turned off.
146 Using
+ rather than
- causes these flags to be turned off. The
147 flags can also be used upon invocation of the shell. The current
148 set of flags may be found in $
-. The remaining n ARGs are positional
149 parameters and are assigned
, in order
, to $
1, $
2, .. $n. If no
150 ARGs are given
, all shell variables are printed.
153 Returns success unless an invalid option is given.
156 typedef int setopt_set_func_t
PARAMS((int
, char *)
);
157 typedef int setopt_get_func_t
PARAMS((char *)
);
159 static int find_minus_o_option
PARAMS((char *)
);
161 static void print_minus_o_option
PARAMS((char
*, int
, int
));
162 static void print_all_shell_variables
PARAMS((void
));
164 static int set_ignoreeof
PARAMS((int
, char *)
);
165 static int set_posix_mode
PARAMS((int
, char *)
);
167 #if
defined (READLINE
)
168 static int set_edit_mode
PARAMS((int
, char *)
);
169 static int get_edit_mode
PARAMS((char *)
);
172 #if
defined (HISTORY
)
173 static int bush_set_history
PARAMS((int
, char *)
);
176 static const char
* const on
= "on";
177 static const char
* const off
= "off";
179 static int previous_option_value
;
181 /* A struct used to match long options for set
-o to the corresponding
182 option letter or internal variable. The functions can be called to
183 dynamically generate values. If you add a new variable name here
184 that doesn
't have a corresponding single-character option letter, make
185 sure to set the value appropriately in reset_shell_options. */
190 setopt_set_func_t *set_func;
191 setopt_get_func_t *get_func;
193 { "allexport", 'a
', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
194 #if defined (BRACE_EXPANSION)
195 { "braceexpand",'B
', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
197 #if defined (READLINE)
198 { "emacs", '\
0', (int *)NULL, set_edit_mode, get_edit_mode },
200 { "errexit", 'e
', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
201 { "errtrace", 'E
', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
202 { "functrace", 'T
', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
203 { "hashall", 'h
', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
204 #if defined (BANG_HISTORY)
205 { "histexpand", 'H
', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
206 #endif /* BANG_HISTORY */
207 #if defined (HISTORY)
208 { "history", '\
0', &enable_history_list, bush_set_history, (setopt_get_func_t *)NULL },
210 { "ignoreeof", '\
0', &ignoreeof, set_ignoreeof, (setopt_get_func_t *)NULL },
211 { "interactive-comments", '\
0', &interactive_comments, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
212 { "keyword", 'k
', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
213 #if defined (JOB_CONTROL)
214 { "monitor", 'm
', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
216 { "noclobber", 'C
', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
217 { "noexec", 'n
', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
218 { "noglob", 'f
', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
219 #if defined (HISTORY)
220 { "nolog", '\
0', &dont_save_function_defs, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
222 #if defined (JOB_CONTROL)
223 { "notify", 'b
', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
224 #endif /* JOB_CONTROL */
225 { "nounset", 'u
', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
226 { "onecmd", 't
', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
227 { "physical", 'P
', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
228 { "pipefail", '\
0', &pipefail_opt, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
229 { "posix", '\
0', &posixly_correct, set_posix_mode, (setopt_get_func_t *)NULL },
230 { "privileged", 'p
', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
231 { "verbose", 'v
', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
232 #if defined (READLINE)
233 { "vi", '\
0', (int *)NULL, set_edit_mode, get_edit_mode },
235 { "xtrace", 'x
', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
236 { "dbginfo", 'd
', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
237 {(char *)NULL, 0 , (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
240 #define N_O_OPTIONS (sizeof (o_options) / sizeof (o_options[0]))
242 #define GET_BINARY_O_OPTION_VALUE(i, name) \
243 ((o_options[i].get_func) ? (*o_options[i].get_func) (name) \
244 : (*o_options[i].variable))
246 #define SET_BINARY_O_OPTION_VALUE(i, onoff, name) \
247 ((o_options[i].set_func) ? (*o_options[i].set_func) (onoff, name) \
248 : (*o_options[i].variable = (onoff == FLAG_ON)))
251 find_minus_o_option (name)
256 for (i = 0; o_options[i].name; i++)
257 if (STREQ (name, o_options[i].name))
263 minus_o_option_value (name)
269 i = find_minus_o_option (name);
273 if (o_options[i].letter)
275 on_or_off = find_flag (o_options[i].letter);
276 return ((on_or_off == FLAG_UNKNOWN) ? -1 : *on_or_off);
279 return (GET_BINARY_O_OPTION_VALUE (i, name));
282 #define MINUS_O_FORMAT "%-15s\t%s\n"
285 print_minus_o_option (name, value, pflag)
290 printf (MINUS_O_FORMAT, name, value ? on : off);
292 printf ("set %co %s\n", value ? '-' : '+', name);
296 list_minus_o_opts (mode, reusable)
300 int *on_or_off, value;
302 for (i = 0; o_options[i].name; i++)
304 if (o_options[i].letter)
307 on_or_off = find_flag (o_options[i].letter);
308 if (on_or_off == FLAG_UNKNOWN)
310 if (mode == -1 || mode == *on_or_off)
311 print_minus_o_option (o_options[i].name, *on_or_off, reusable);
315 value = GET_BINARY_O_OPTION_VALUE (i, o_options[i].name);
316 if (mode == -1 || mode == value)
317 print_minus_o_option (o_options[i].name, value, reusable);
328 ret = strvec_create (N_O_OPTIONS + 1);
329 for (i = 0; o_options[i].name; i++)
330 ret[i] = o_options[i].name;
331 ret[i] = (char *)NULL;
336 get_current_options ()
341 posixopts = num_posix_options (); /* shopts modified by posix mode */
342 /* Make the buffer big enough to hold the set -o options and the shopt
343 options modified by posix mode. */
344 temp = (char *)xmalloc (1 + N_O_OPTIONS + posixopts);
345 for (i = 0; o_options[i].name; i++)
347 if (o_options[i].letter)
348 temp[i] = *(find_flag (o_options[i].letter));
350 temp[i] = GET_BINARY_O_OPTION_VALUE (i, o_options[i].name);
353 /* Add the shell options that are modified by posix mode to the end of the
354 bitmap. They will be handled in set_current_options() */
355 get_posix_options (temp+i);
356 temp[i+posixopts] = '\
0';
361 set_current_options (bitmap)
364 int i, v, cv, *on_or_off;
369 for (i = 0; o_options[i].name; i++)
371 v = bitmap[i] ? FLAG_ON : FLAG_OFF;
372 if (o_options[i].letter)
374 /* We should not get FLAG_UNKNOWN here */
375 on_or_off = find_flag (o_options[i].letter);
376 cv = *on_or_off ? FLAG_ON : FLAG_OFF;
378 change_flag (o_options[i].letter, v);
382 cv = GET_BINARY_O_OPTION_VALUE (i, o_options[i].name);
383 cv = cv ? FLAG_ON : FLAG_OFF;
385 SET_BINARY_O_OPTION_VALUE (i, v, o_options[i].name);
389 /* Now reset the variables changed by posix mode */
390 set_posix_options (bitmap+i);
394 set_ignoreeof (on_or_off, option_name)
398 ignoreeof = on_or_off == FLAG_ON;
399 unbind_variable_noref ("ignoreeof");
401 bind_variable ("IGNOREEOF", "10", 0);
403 unbind_variable_noref ("IGNOREEOF");
404 sv_ignoreeof ("IGNOREEOF");
409 set_posix_mode (on_or_off, option_name)
413 /* short-circuit on no-op */
414 if ((on_or_off == FLAG_ON && posixly_correct) ||
415 (on_or_off == FLAG_OFF && posixly_correct == 0))
418 posixly_correct = on_or_off == FLAG_ON;
419 if (posixly_correct == 0)
420 unbind_variable_noref ("POSIXLY_CORRECT");
422 bind_variable ("POSIXLY_CORRECT", "y", 0);
423 sv_strict_posix ("POSIXLY_CORRECT");
427 #if defined (READLINE)
428 /* Magic. This code `knows' how readline handles rl_editing_mode.
*/
430 set_edit_mode (on_or_off
, option_name
)
436 if (on_or_off
== FLAG_ON
)
438 rl_variable_bind ("editing-mode", option_name
);
441 with_input_from_stdin ();
446 isemacs
= rl_editing_mode
== 1;
447 if ((isemacs
&& *option_name
== 'e') ||
(!isemacs
&& *option_name
== 'v'))
450 with_input_from_stream (stdin
, "stdin");
454 return
1-no_line_editing
;
461 return (*name == 'e' ? no_line_editing == 0 && rl_editing_mode == 1
462 : no_line_editing == 0 && rl_editing_mode == 0);
464 #endif /* READLINE */
466 #if defined (HISTORY)
468 bush_set_history (on_or_off, option_name)
472 if (on_or_off == FLAG_ON)
474 enable_history_list = 1;
475 bush_history_enable ();
476 if (history_lines_this_session == 0)
481 enable_history_list = 0;
482 bush_history_disable ();
484 return (1 - enable_history_list);
489 set_minus_o_option (on_or_off, option_name)
495 i = find_minus_o_option (option_name);
498 sh_invalidoptname (option_name);
502 if (o_options[i].letter == 0)
504 previous_option_value = GET_BINARY_O_OPTION_VALUE (i, o_options[i].name);
505 SET_BINARY_O_OPTION_VALUE (i, on_or_off, option_name);
506 return (EXECUTION_SUCCESS);
510 if ((previous_option_value = change_flag (o_options[i].letter, on_or_off)) == FLAG_ERROR)
512 sh_invalidoptname (option_name);
513 return (EXECUTION_FAILURE);
516 return (EXECUTION_SUCCESS);
521 print_all_shell_variables ()
525 vars = all_shell_variables ();
528 print_var_list (vars);
532 /* POSIX.2 does not allow function names and definitions to be output when
533 `set' is invoked without options (PASC Interp #202). */
534 if (posixly_correct == 0)
536 vars = all_shell_functions ();
539 print_func_list (vars);
549 char tflag[N_O_OPTIONS];
550 int vsize, i, vptr, *ip, exported;
553 for (vsize = i = 0; o_options[i].name; i++)
556 if (o_options[i].letter)
558 ip = find_flag (o_options[i].letter);
561 vsize += strlen (o_options[i].name) + 1;
565 else if (GET_BINARY_O_OPTION_VALUE (i, o_options[i].name))
567 vsize += strlen (o_options[i].name) + 1;
572 value = (char *)xmalloc (vsize
+ 1);
574 for (i
= vptr
= 0; o_options
[i
].name
; i
++)
578 strcpy (value
+ vptr
, o_options
[i
].name
);
579 vptr
+= strlen (o_options
[i
].name
);
585 vptr
--; /* cut off trailing colon
*/
588 v
= find_variable ("SHELLOPTS");
590 /* Turn off the read
-only attribute so we can bind the new value
, and
591 note whether or not the variable was exported.
*/
594 VUNSETATTR (v
, att_readonly
);
595 exported
= exported_p (v
);
600 v
= bind_variable ("SHELLOPTS", value
, 0);
602 /* Turn the read
-only attribute back on
, and turn off the export attribute
603 if it was set implicitly by mark_modified_vars and SHELLOPTS was not
604 exported before we bound the new value.
*/
605 VSETATTR (v
, att_readonly
);
606 if (mark_modified_vars
&& exported
== 0 && exported_p (v
))
607 VUNSETATTR (v
, att_exported
);
613 parse_shellopts (value
)
620 while (vname
= extract_colon_unit (value
, &vptr
))
622 set_minus_o_option (FLAG_ON
, vname
);
628 initialize_shell_options (no_shellopts
)
634 if (no_shellopts
== 0)
636 var
= find_variable ("SHELLOPTS");
637 /* set up any shell options we may have inherited.
*/
638 if (var
&& imported_p (var
))
640 temp
= (array_p (var
) ||
assoc_p (var
)) ?
(char *)NULL
: savestring (value_cell (var
));
643 parse_shellopts (temp
);
649 /* Set up the $SHELLOPTS variable.
*/
653 /* Reset the values of the
-o options that are not also shell flags. This is
654 called from execute_cmd.c
:initialize_subshell() when setting up a subshell
655 to run an executable shell script without a leading `#
!'. */
657 reset_shell_options ()
662 #if defined (STRICT_POSIX)
667 #if defined (HISTORY)
668 dont_save_function_defs = 0;
669 remember_on_history = enable_history_list = 1; /* XXX */
673 /* Set some flags from the word values in the input list. If LIST is empty,
674 then print out the values of the variables instead. If LIST contains
675 non-flags, then set $1 - $9 to the successive words of LIST. */
680 int on_or_off, flag_name, force_assignment, opts_changed, rv, r;
686 print_all_shell_variables ();
687 return (sh_chkwrite (EXECUTION_SUCCESS));
690 /* Check validity of flag arguments. */
691 rv = EXECUTION_SUCCESS;
692 reset_internal_getopt ();
693 while ((flag_name = internal_getopt (list, optflags)) != -1)
695 printf("flag_name = %c\n", flag_name);
698 case 'i
': /* don't allow set
-i
*/
708 return (list_optopt
== '?' ? EXECUTION_SUCCESS
: EX_USAGE
);
714 /* Do the set command. While the list consists of words starting with
715 '-' or
'+' treat them as flags
, otherwise
, start assigning them to
717 for (force_assignment
= opts_changed
= 0; list
; )
719 arg
= list
->word
->word
;
721 /* If the argument is `
--' or `-' then signal the end of the list
722 and remember the remaining arguments.
*/
723 if (arg
[0] == '-' && (!arg
[1] ||
(arg
[1] == '-' && !arg
[2])))
727 /* `set
--' unsets the positional parameters. */
729 force_assignment = 1;
731 /* Until told differently, the old shell behaviour of
732 `set - [arg ...]' being equivalent to `set
+xv
[arg ...
]'
733 stands. Posix.2 says the behaviour is marked as obsolescent. */
736 change_flag ('x
', '+');
737 change_flag ('d
', '+');
738 change_flag ('v
', '+');
745 if ((on_or_off = *arg) && (on_or_off == '-' || on_or_off == '+'))
747 while (flag_name = *++arg)
749 if (flag_name == '?
')
752 return (EXECUTION_SUCCESS);
754 else if (flag_name == 'o
') /* -+o option-name */
763 list_minus_o_opts (-1, (on_or_off == '+'));
764 rv = sh_chkwrite (rv);
768 option_name = opt->word->word;
770 if (option_name == 0 || *option_name == '\
0' ||
771 *option_name == '-' || *option_name == '+')
773 list_minus_o_opts (-1, (on_or_off == '+'));
776 list = list->next; /* Skip over option name. */
779 if ((r = set_minus_o_option (on_or_off, option_name)) != EXECUTION_SUCCESS)
785 else if (change_flag (flag_name, on_or_off) == FLAG_ERROR)
793 return (EXECUTION_FAILURE);
805 /* Assigning $1 ... $n */
806 if (list || force_assignment)
807 remember_args (list, 1);
808 /* Set up new value of $SHELLOPTS */
816 $FUNCTION unset_builtin
817 $SHORT_DOC unset [-f] [-v] [-n] [name ...]
818 Unset values and attributes of shell variables and functions.
820 For each NAME, remove the corresponding variable or function.
823 -f treat each NAME as a shell function
824 -v treat each NAME as a shell variable
825 -n treat each NAME as a name reference and unset the variable itself
826 rather than the variable it references
828 Without options, unset first tries to unset a variable, and if that fails,
829 tries to unset a function.
831 Some variables cannot be unset; also see `readonly'.
834 Returns success unless an invalid option is given or a NAME is read
-only.
837 #define
NEXT_VARIABLE() any_failed
++; list
= list
->next
; continue
;
843 int unset_function
, unset_variable
, unset_array
, opt
, nameref
, any_failed
;
844 int global_unset_func
, global_unset_var
, vflags
, valid_id
;
847 unset_function
= unset_variable
= unset_array
= nameref
= any_failed
= 0;
848 global_unset_func
= global_unset_var
= 0;
850 reset_internal_getopt ();
851 while ((opt
= internal_getopt (list
, "fnv")) != -1)
856 global_unset_func
= 1;
859 global_unset_var
= 1;
873 if (global_unset_func
&& global_unset_var
)
875 builtin_error (_("cannot simultaneously unset a function and a variable"));
876 return (EXECUTION_FAILURE
);
878 else
if (unset_function
&& nameref
)
881 #if
defined (ARRAY_VARS
)
882 vflags
= assoc_expand_once ?
(VA_NOEXPAND|VA_ONEWORD
) : 0;
889 #if
defined (ARRAY_VARS
)
893 name
= list
->word
->word
;
895 unset_function
= global_unset_func
;
896 unset_variable
= global_unset_var
;
898 #if
defined (ARRAY_VARS
)
900 /* XXX valid array reference second arg was
0 */
901 if (!unset_function
&& nameref
== 0 && valid_array_reference (name
, vflags
))
903 t
= strchr (name
, '[');
908 /* Get error checking out of the way first. The low
-level functions
909 just perform the unset
, relying on the caller to verify.
*/
910 valid_id
= legal_identifier (name
);
912 /* Whether or not we are in posix mode
, if neither
-f nor
-v appears
,
913 skip over trying to unset variables with invalid names and just
914 treat them as potential shell function names.
*/
915 if (global_unset_func
== 0 && global_unset_var
== 0 && valid_id
== 0)
917 unset_variable
= unset_array
= 0;
921 /* Bush allows functions with names which are not valid identifiers
922 to be created when not in posix mode
, so check only when in posix
923 mode when unsetting a function.
*/
924 if (unset_function
== 0 && valid_id
== 0)
930 /* Search for functions here if
-f supplied or if NAME cannot be a
932 var
= unset_function ?
find_function (name
)
933 : (nameref ?
find_variable_last_nameref (name
, 0) : find_variable (name
));
935 /* Some
variables (but not functions yet
) cannot be unset
, period.
*/
936 if (var
&& unset_function
== 0 && non_unsettable_p (var
))
938 builtin_error (_("%s: cannot unset"), name
);
942 /* if we have a nameref we want to use it
*/
943 if (var
&& unset_function
== 0 && nameref
== 0 && STREQ (name
, name_cell(var
)) == 0)
944 name
= name_cell (var
);
946 /* Posix
.2 says try variables first
, then functions. If we would
947 find a function after unsuccessfully searching for a variable
,
948 note that we
're acting on a function now as if -f were
949 supplied. The readonly check below takes care of it. */
950 if (var == 0 && nameref == 0 && unset_variable == 0 && unset_function == 0)
952 if (var = find_function (name))
956 /* Posix.2 says that unsetting readonly variables is an error. */
957 if (var && readonly_p (var))
959 builtin_error (_("%s: cannot unset: readonly %s"),
960 var->name, unset_function ? "function" : "variable");
964 /* Unless the -f option is supplied, the name refers to a variable. */
965 #if defined (ARRAY_VARS)
966 if (var && unset_array)
968 /* Let unbind_array_element decide what to do with non-array vars */
969 tem = unbind_array_element (var, t, vflags); /* XXX new third arg */
970 if (tem == -2 && array_p (var) == 0 && assoc_p (var) == 0)
972 builtin_error (_("%s: not an array variable"), var->name);
979 #endif /* ARRAY_VARS */
980 /* If we're trying to unset a nameref variable whose value isn
't a set
981 variable, make sure we still try to unset the nameref's value
*/
982 if (var
== 0 && nameref
== 0 && unset_function
== 0)
984 var
= find_variable_last_nameref (name
, 0);
985 if (var
&& nameref_p (var
))
987 #if
defined (ARRAY_VARS
)
988 if (valid_array_reference (nameref_cell (var
), 0))
990 tname
= savestring (nameref_cell (var
));
991 if (var
= array_variable_part (tname
, 0, &t
, (int *)
0))
992 tem
= unbind_array_element (var
, t
, vflags
); /* XXX new third arg
*/
997 tem
= unbind_variable (nameref_cell (var
));
1000 tem
= unbind_variable (name
);
1003 tem
= unset_function ?
unbind_func (name
) : (nameref ?
unbind_nameref (name
) : unbind_variable (name
));
1005 /* This is what Posix
.2 says
: ``If neither
-f nor
-v
1006 is specified
, the name refers to a variable
; if a variable by
1007 that name does not exist
, a function by that name
, if any
,
1008 shall be unset.
'' */
1009 if (tem
== -1 && nameref
== 0 && unset_function
== 0 && unset_variable
== 0)
1010 tem
= unbind_func (name
);
1012 name
= list
->word
->word
; /* reset above for namerefs
*/
1014 /* SUSv3
, POSIX
.1-2001 say
: ``Unsetting a variable or function that
1015 was not previously set shall not be considered an error.
'' */
1017 if (unset_function
== 0)
1018 stupidly_hack_special_variables (name
);
1023 return (any_failed ? EXECUTION_FAILURE
: EXECUTION_SUCCESS
);