b5ac83b4018ec0c26fcd202075b7eb9052096916
[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 #  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 rl_editing_mode, 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       save 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 static int
270 set_ignoreeof (on_or_off, option_name)
271      int on_or_off;
272      char *option_name;
273 {
274   ignoreeof = on_or_off == FLAG_ON;
275   unbind_variable ("ignoreeof");
276   if (ignoreeof)
277     bind_variable ("IGNOREEOF", "10"); 
278   else
279     unbind_variable ("IGNOREEOF");
280   sv_ignoreeof ("IGNOREEOF");
281   return 0;
282 }
283
284 static int
285 set_posix_mode (on_or_off, option_name)
286      int on_or_off;
287      char *option_name;
288 {
289   posixly_correct = on_or_off == FLAG_ON;
290   if (posixly_correct == 0)
291     unbind_variable ("POSIXLY_CORRECT");
292   else
293     bind_variable ("POSIXLY_CORRECT", "y");
294   sv_strict_posix ("POSIXLY_CORRECT");
295   return (0);
296 }
297
298 #if defined (READLINE)
299 /* Magic.  This code `knows' how readline handles rl_editing_mode. */
300 static int
301 set_edit_mode (on_or_off, option_name)
302      int on_or_off;
303      char *option_name;
304 {
305   int isemacs;
306
307   if (on_or_off == FLAG_ON)
308     {
309       rl_variable_bind ("editing-mode", option_name);
310
311       if (interactive)
312         with_input_from_stdin ();
313       no_line_editing = 0;
314     }
315   else
316     {
317       isemacs = rl_editing_mode == 1;
318       if ((isemacs && *option_name == 'e') || (!isemacs && *option_name == 'v'))
319         {
320           if (interactive)
321             with_input_from_stream (stdin, "stdin");
322           no_line_editing = 1;
323         }
324     }
325   return 1-no_line_editing;
326 }
327
328 static int
329 get_edit_mode (name)
330      char *name;
331 {
332   return (*name == 'e' ? no_line_editing == 0 && rl_editing_mode == 1
333                        : no_line_editing == 0 && rl_editing_mode == 0);
334 }
335 #endif /* READLINE */
336
337 #if defined (HISTORY)
338 static int
339 bash_set_history (on_or_off, option_name)
340      int on_or_off;
341      char *option_name;
342 {
343   if (on_or_off == FLAG_ON)
344     {
345       bash_history_enable ();
346       if (history_lines_this_session == 0)
347         load_history ();
348     }
349   else
350     bash_history_disable ();
351   return (1 - remember_on_history);
352 }
353 #endif
354
355 int
356 set_minus_o_option (on_or_off, option_name)
357      int on_or_off;
358      char *option_name;
359 {
360   int option_char;
361   VFunction *set_func;
362   register int i;
363
364   for (i = 0; binary_o_options[i].name; i++)
365     {
366       if (STREQ (option_name, binary_o_options[i].name))
367         {
368           SET_BINARY_O_OPTION_VALUE (i, on_or_off, option_name);
369           return (EXECUTION_SUCCESS);
370         }
371     }
372
373   for (i = 0, option_char = -1, set_func = 0; o_options[i].name; i++)
374     {
375       if (STREQ (option_name, o_options[i].name))
376         {
377           option_char = o_options[i].letter;
378           break;
379         }
380     }
381   if (option_char == -1)
382     {
383       builtin_error ("%s: unknown option name", option_name);
384       return (EXECUTION_FAILURE);
385     }
386  if (change_flag (option_char, on_or_off) == FLAG_ERROR)
387     {
388       bad_option (option_name);
389       return (EXECUTION_FAILURE);
390     }
391   return (EXECUTION_SUCCESS);
392 }
393
394 static void
395 print_all_shell_variables ()
396 {
397   SHELL_VAR **vars;
398
399   vars = all_shell_variables ();
400   if (vars)
401     {
402       print_var_list (vars);
403       free (vars);
404     }
405
406   vars = all_shell_functions ();
407   if (vars)
408     {
409       print_var_list (vars);
410       free (vars);
411     }
412 }
413
414 void
415 set_shellopts ()
416 {
417   char *value;
418   int vsize, i, vptr, *ip, exported;
419   SHELL_VAR *v;
420
421   for (vsize = i = 0; o_options[i].name; i++)
422     {
423       ip = find_flag (o_options[i].letter);
424       if (ip && *ip)
425         vsize += strlen (o_options[i].name) + 1;
426     }
427   for (i = 0; binary_o_options[i].name; i++)
428     if (GET_BINARY_O_OPTION_VALUE (i, binary_o_options[i].name))
429       vsize += strlen (binary_o_options[i].name) + 1;
430
431   value = xmalloc (vsize + 1);
432
433   for (i = vptr = 0; o_options[i].name; i++)
434     {
435       ip = find_flag (o_options[i].letter);
436       if (ip && *ip)
437         {
438           strcpy (value + vptr, o_options[i].name);
439           vptr += strlen (o_options[i].name);
440           value[vptr++] = ':';
441         }
442     }
443   for (i = 0; binary_o_options[i].name; i++)
444     if (GET_BINARY_O_OPTION_VALUE (i, binary_o_options[i].name))
445       {
446         strcpy (value + vptr, binary_o_options[i].name);
447         vptr += strlen (binary_o_options[i].name);
448         value[vptr++] = ':';
449       }
450   if (vptr)
451     vptr--;                     /* cut off trailing colon */
452   value[vptr] = '\0';
453
454   v = find_variable ("SHELLOPTS");
455
456   /* Turn off the read-only attribute so we can bind the new value, and
457      note whether or not the variable was exported. */
458   if (v)
459     {
460       v->attributes &= ~att_readonly;
461       exported = exported_p (v);
462     }
463   else
464     exported = 0;
465
466   v = bind_variable ("SHELLOPTS", value);
467
468   /* Turn the read-only attribute back on, and turn off the export attribute
469      if it was set implicitly by mark_modified_vars and SHELLOPTS was not
470      exported before we bound the new value. */
471   v->attributes |= att_readonly;
472   if (mark_modified_vars && exported == 0 && exported_p (v))
473     v->attributes &= ~att_exported;
474
475   free (value);
476 }
477
478 void
479 parse_shellopts (value)
480      char *value;
481 {
482   char *vname;
483   int vptr;
484
485   vptr = 0;
486   while (vname = extract_colon_unit (value, &vptr))
487     {
488       set_minus_o_option (FLAG_ON, vname);
489       free (vname);
490     }
491 }
492
493 void
494 initialize_shell_options (no_shellopts)
495      int no_shellopts;
496 {
497   char *temp;
498   SHELL_VAR *var;
499
500   if (no_shellopts == 0)
501     {
502       var = find_variable ("SHELLOPTS");
503       /* set up any shell options we may have inherited. */
504       if (var && imported_p (var))
505         {
506           temp = (array_p (var)) ? (char *)NULL : savestring (value_cell (var));
507           if (temp)
508             {
509               parse_shellopts (temp);
510               free (temp);
511             }
512         }
513     }
514
515   /* Set up the $SHELLOPTS variable. */
516   set_shellopts ();
517 }
518
519 /* Reset the values of the -o options that are not also shell flags. */
520 void
521 reset_shell_options ()
522 {
523 #if defined (HISTORY)
524   remember_on_history = 1;
525 #endif
526   ignoreeof = posixly_correct = 0;
527 }
528
529 /* Set some flags from the word values in the input list.  If LIST is empty,
530    then print out the values of the variables instead.  If LIST contains
531    non-flags, then set $1 - $9 to the successive words of LIST. */
532 int
533 set_builtin (list)
534      WORD_LIST *list;
535 {
536   int on_or_off, flag_name, force_assignment, opts_changed;
537   WORD_LIST *l;
538   register char *arg;
539
540   if (list == 0)
541     {
542       print_all_shell_variables ();
543       return (EXECUTION_SUCCESS);
544     }
545
546   /* Check validity of flag arguments. */
547   if (*list->word->word == '-' || *list->word->word == '+')
548     {
549       for (l = list; l && (arg = l->word->word); l = l->next)
550         {
551           char c;
552
553           if (arg[0] != '-' && arg[0] != '+')
554             break;
555
556           /* `-' or `--' signifies end of flag arguments. */
557           if (arg[0] == '-' && (!arg[1] || (arg[1] == '-' && !arg[2])))
558             break;
559
560           while (c = *++arg)
561             {
562               if (find_flag (c) == FLAG_UNKNOWN && c != 'o')
563                 {
564                   char s[2];
565                   s[0] = c; s[1] = '\0';
566                   bad_option (s);
567                   if (c == '?')
568                     builtin_usage ();
569                   return (c == '?' ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
570                 }
571             }
572         }
573     }
574
575   /* Do the set command.  While the list consists of words starting with
576      '-' or '+' treat them as flags, otherwise, start assigning them to
577      $1 ... $n. */
578   for (force_assignment = opts_changed = 0; list; )
579     {
580       arg = list->word->word;
581
582       /* If the argument is `--' or `-' then signal the end of the list
583          and remember the remaining arguments. */
584       if (arg[0] == '-' && (!arg[1] || (arg[1] == '-' && !arg[2])))
585         {
586           list = list->next;
587
588           /* `set --' unsets the positional parameters. */
589           if (arg[1] == '-')
590             force_assignment = 1;
591
592           /* Until told differently, the old shell behaviour of
593              `set - [arg ...]' being equivalent to `set +xv [arg ...]'
594              stands.  Posix.2 says the behaviour is marked as obsolescent. */
595           else
596             {
597               change_flag ('x', '+');
598               change_flag ('v', '+');
599               opts_changed = 1;
600             }
601
602           break;
603         }
604
605       if ((on_or_off = *arg) && (on_or_off == '-' || on_or_off == '+'))
606         {
607           while (flag_name = *++arg)
608             {
609               if (flag_name == '?')
610                 {
611                   builtin_usage ();
612                   return (EXECUTION_SUCCESS);
613                 }
614               else if (flag_name == 'o') /* -+o option-name */
615                 {
616                   char *option_name;
617                   WORD_LIST *opt;
618
619                   opt = list->next;
620
621                   if (opt == 0)
622                     {
623                       list_minus_o_opts (-1, (on_or_off == '+'));
624                       continue;
625                     }
626
627                   option_name = opt->word->word;
628
629                   if (option_name == 0 || *option_name == '\0' ||
630                       *option_name == '-' || *option_name == '+')
631                     {
632                       list_minus_o_opts (-1, (on_or_off == '+'));
633                       continue;
634                     }
635                   list = list->next; /* Skip over option name. */
636
637                   opts_changed = 1;
638                   if (set_minus_o_option (on_or_off, option_name) != EXECUTION_SUCCESS)
639                     {
640                       set_shellopts ();
641                       return (EXECUTION_FAILURE);
642                     }
643                 }
644               else if (change_flag (flag_name, on_or_off) == FLAG_ERROR)
645                 {
646                   char opt[3];
647                   opt[0] = on_or_off;
648                   opt[1] = flag_name;
649                   opt[2] = '\0';
650                   bad_option (opt);
651                   builtin_usage ();
652                   set_shellopts ();
653                   return (EXECUTION_FAILURE);
654                 }
655               opts_changed = 1;
656             }
657         }
658       else
659         {
660           break;
661         }
662       list = list->next;
663     }
664
665   /* Assigning $1 ... $n */
666   if (list || force_assignment)
667     remember_args (list, 1);
668   /* Set up new value of $SHELLOPTS */
669   if (opts_changed)
670     set_shellopts ();
671   return (EXECUTION_SUCCESS);
672 }
673
674 $BUILTIN unset
675 $FUNCTION unset_builtin
676 $SHORT_DOC unset [-f] [-v] [name ...]
677 For each NAME, remove the corresponding variable or function.  Given
678 the `-v', unset will only act on variables.  Given the `-f' flag,
679 unset will only act on functions.  With neither flag, unset first
680 tries to unset a variable, and if that fails, then tries to unset a
681 function.  Some variables (such as PATH and IFS) cannot be unset; also
682 see readonly.
683 $END
684
685 #define NEXT_VARIABLE() any_failed++; list = list->next; continue;
686
687 int
688 unset_builtin (list)
689   WORD_LIST *list;
690 {
691   int unset_function, unset_variable, unset_array, opt, any_failed;
692   char *name;
693
694   unset_function = unset_variable = unset_array = any_failed = 0;
695
696   reset_internal_getopt ();
697   while ((opt = internal_getopt (list, "fv")) != -1)
698     {
699       switch (opt)
700         {
701         case 'f':
702           unset_function = 1;
703           break;
704         case 'v':
705           unset_variable = 1;
706           break;
707         default:
708           builtin_usage ();
709           return (EX_USAGE);
710         }
711     }
712
713   list = loptend;
714
715   if (unset_function && unset_variable)
716     {
717       builtin_error ("cannot simultaneously unset a function and a variable");
718       return (EXECUTION_FAILURE);
719     }
720
721   while (list)
722     {
723       SHELL_VAR *var;
724       int tem;
725 #if defined (ARRAY_VARS)
726       char *t;
727 #endif
728
729       name = list->word->word;
730
731 #if defined (ARRAY_VARS)
732       if (!unset_function && valid_array_reference (name))
733         {
734           t = strchr (name, '[');
735           *t++ = '\0';
736           unset_array++;
737         }
738 #endif
739
740       /* Bash allows functions with names which are not valid identifiers
741          to be created when not in posix mode, so check only when in posix
742          mode when unsetting a function. */
743       if (((unset_function && posixly_correct) || !unset_function) && legal_identifier (name) == 0)
744         {
745           builtin_error ("`%s': not a valid identifier", name);
746           NEXT_VARIABLE ();
747         }
748
749       var = unset_function ? find_function (name) : find_variable (name);
750
751       if (var && !unset_function && non_unsettable_p (var))
752         {
753           builtin_error ("%s: cannot unset", name);
754           NEXT_VARIABLE ();
755         }
756
757       /* Posix.2 says that unsetting readonly variables is an error. */
758       if (var && readonly_p (var))
759         {
760           builtin_error ("%s: cannot unset: readonly %s",
761                          name, unset_function ? "function" : "variable");
762           NEXT_VARIABLE ();
763         }
764
765       /* Unless the -f option is supplied, the name refers to a variable. */
766 #if defined (ARRAY_VARS)
767       if (var && unset_array)
768         {
769           if (array_p (var) == 0)
770             {
771               builtin_error ("%s: not an array variable", name);
772               NEXT_VARIABLE ();
773             }
774           else
775             tem = unbind_array_element (var, t);
776         }
777       else
778 #endif /* ARRAY_VARS */
779       tem = makunbound (name, unset_function ? shell_functions : shell_variables);
780
781       /* This is what Posix.2 draft 11+ says.  ``If neither -f nor -v
782          is specified, the name refers to a variable; if a variable by
783          that name does not exist, a function by that name, if any,
784          shall be unset.'' */
785       if (tem == -1 && !unset_function && !unset_variable)
786         tem = makunbound (name, shell_functions);
787
788       if (tem == -1)
789         any_failed++;
790       else if (!unset_function)
791         stupidly_hack_special_variables (name);
792
793       list = list->next;
794     }
795
796   return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
797 }