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