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