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