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