a97168c493620d313c94eb6928e07825b3777b20
[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 <stdio.h>
25 #include "../shell.h"
26 #include "../flags.h"
27
28 #include "bashgetopt.h"
29
30 extern int interactive;
31 extern int noclobber, no_brace_expansion, posixly_correct;
32 #if defined (READLINE)
33 extern int rl_editing_mode, no_line_editing;
34 #endif /* READLINE */
35
36 #define USAGE_STRING "set [--abefhknotuvxldHCP] [-o option] [arg ...]"
37
38 $BUILTIN set
39 $FUNCTION set_builtin
40 $SHORT_DOC set [--abefhknotuvxldHCP] [-o option] [arg ...]
41     -a  Mark variables which are modified or created for export.
42     -b  Notify of job termination immediately.
43     -e  Exit immediately if a command exits with a non-zero status.
44     -f  Disable file name generation (globbing).
45     -h  Locate and remember function commands as functions are
46         defined.  Function commands are normally looked up when
47         the function is executed.
48     -i  Force the shell to be an "interactive" one.  Interactive shells
49         always read `~/.bashrc' on startup.
50     -k  All keyword arguments are placed in the environment for a
51         command, not just those that precede the command name.
52     -m  Job control is enabled.
53     -n  Read commands but do not execute them.
54     -o option-name
55         Set the variable corresponding to option-name:
56             allexport    same as -a
57             braceexpand  the shell will perform brace expansion
58 #if defined (READLINE)
59             emacs        use an emacs-style line editing interface
60 #endif /* READLINE */
61             errexit      same as -e
62 #if defined (BANG_HISTORY)
63             histexpand   same as -H
64 #endif /* BANG_HISTORY */
65             ignoreeof    the shell will not exit upon reading EOF
66             interactive-comments
67                          allow comments to appear in interactive commands
68             monitor      same as -m
69             noclobber    disallow redirection to existing files
70             noexec       same as -n
71             noglob       same as -f
72             nohash       same as -d
73             notify       save as -b
74             nounset      same as -u
75             physical     same as -P
76             posix        change the behavior of bash where the default
77                          operation differs from the 1003.2 standard to
78                          match the standard
79             privileged   same as -p
80             verbose      same as -v
81 #if defined (READLINE)
82             vi           use a vi-style line editing interface
83 #endif /* READLINE */
84             xtrace       same as -x
85     -p  Turned on whenever the real and effective user ids do not match.
86         Disables processing of the $ENV file and importing of shell
87         functions.  Turning this option off causes the effective uid and
88         gid to be set to the real uid and gid.
89     -t  Exit after reading and executing one command.
90     -u  Treat unset variables as an error when substituting.
91     -v  Print shell input lines as they are read.
92     -x  Print commands and their arguments as they are executed.
93     -l  Save and restore the binding of the NAME in a FOR command.
94     -d  Disable the hashing of commands that are looked up for execution.
95         Normally, commands are remembered in a hash table, and once
96         found, do not have to be looked up again.
97 #if defined (BANG_HISTORY)
98     -H  Enable ! style history substitution.  This flag is on
99         by default.
100 #endif /* BANG_HISTORY */
101     -C  If set, disallow existing regular files to be overwritten
102         by redirection of output.
103     -P  If set, do not follow symbolic links when executing commands
104         such as cd which change the current directory.
105
106 Using + rather than - causes these flags to be turned off.  The
107 flags can also be used upon invocation of the shell.  The current
108 set of flags may be found in $-.  The remaining n ARGs are positional
109 parameters and are assigned, in order, to $1, $2, .. $n.  If no
110 ARGs are given, all shell variables are printed.
111 $END
112
113 /* An a-list used to match long options for set -o to the corresponding
114    option letter. */
115 struct {
116   char *name;
117   int letter;
118 } o_options[] = {
119   { "allexport",  'a' },
120   { "errexit",    'e' },
121 #if defined (BANG_HISTORY)
122   { "histexpand", 'H' },
123 #endif /* BANG_HISTORY */
124   { "monitor",    'm' },
125   { "noexec",     'n' },
126   { "noglob",     'f' },
127   { "nohash",     'd' },
128 #if defined (JOB_CONTROL)
129   { "notify",     'b' },
130 #endif /* JOB_CONTROL */
131   {"nounset",     'u' },
132   {"physical",    'P' },
133   {"privileged",  'p' },
134   {"verbose",     'v' },
135   {"xtrace",      'x' },
136   {(char *)NULL, 0},
137 };
138
139 #define MINUS_O_FORMAT "%-15s\t%s\n"
140
141 void
142 list_minus_o_opts ()
143 {
144   register int  i;
145   char *on = "on", *off = "off";
146
147   printf (MINUS_O_FORMAT, "braceexpand", (no_brace_expansion == 0) ? on : off);
148   printf (MINUS_O_FORMAT, "noclobber", (noclobber == 1) ? on : off);
149
150   if (find_variable ("ignoreeof") || find_variable ("IGNOREEOF"))
151     printf (MINUS_O_FORMAT, "ignoreeof", on);
152   else
153     printf (MINUS_O_FORMAT, "ignoreeof", off);
154
155   printf (MINUS_O_FORMAT, "interactive-comments",
156           interactive_comments ? on : off);
157
158   printf (MINUS_O_FORMAT, "posix", posixly_correct ? on : off);
159
160 #if defined (READLINE)
161   if (no_line_editing)
162     {
163       printf (MINUS_O_FORMAT, "emacs", off);
164       printf (MINUS_O_FORMAT, "vi", off);
165     }
166   else
167     {
168       /* Magic.  This code `knows' how readline handles rl_editing_mode. */
169       printf (MINUS_O_FORMAT, "emacs", (rl_editing_mode == 1) ? on : off);
170       printf (MINUS_O_FORMAT, "vi", (rl_editing_mode == 0) ? on : off);
171     }
172 #endif /* READLINE */
173
174   for (i = 0; o_options[i].name; i++)
175     {
176       int *on_or_off, zero = 0;
177
178       on_or_off = find_flag (o_options[i].letter);
179       if (on_or_off == FLAG_UNKNOWN)
180         on_or_off = &zero;
181       printf (MINUS_O_FORMAT, o_options[i].name, (*on_or_off == 1) ? on : off);
182     }
183 }
184
185 set_minus_o_option (on_or_off, option_name)
186      int on_or_off;
187      char *option_name;
188 {
189   int option_char = -1;
190
191   if (STREQ (option_name, "braceexpand"))
192     {
193       if (on_or_off == FLAG_ON)
194         no_brace_expansion = 0;
195       else
196         no_brace_expansion = 1;
197     }
198   else if (STREQ (option_name, "noclobber"))
199     {
200       if (on_or_off == FLAG_ON)
201         bind_variable ("noclobber", "");
202       else
203         unbind_variable ("noclobber");
204       stupidly_hack_special_variables ("noclobber");
205     }
206   else if (STREQ (option_name, "ignoreeof"))
207     {
208       unbind_variable ("ignoreeof");
209       unbind_variable ("IGNOREEOF");
210       if (on_or_off == FLAG_ON)
211         bind_variable ("IGNOREEOF", "10");
212       stupidly_hack_special_variables ("IGNOREEOF");
213     }
214   
215 #if defined (READLINE)
216   else if ((STREQ (option_name, "emacs")) || (STREQ (option_name, "vi")))
217     {
218       if (on_or_off == FLAG_ON)
219         {
220           rl_variable_bind ("editing-mode", option_name);
221
222           if (interactive)
223             with_input_from_stdin ();
224           no_line_editing = 0;
225         }
226       else
227         {
228           int isemacs = (rl_editing_mode == 1);
229           if ((isemacs && STREQ (option_name, "emacs")) ||
230               (!isemacs && STREQ (option_name, "vi")))
231             {
232               if (interactive)
233                 with_input_from_stream (stdin, "stdin");
234               no_line_editing = 1;
235             }
236           else
237             builtin_error ("not in %s editing mode", option_name);
238         }
239     }
240 #endif /* READLINE */
241   else if (STREQ (option_name, "interactive-comments"))
242     interactive_comments = (on_or_off == FLAG_ON);
243   else if (STREQ (option_name, "posix"))
244     {
245       posixly_correct = (on_or_off == FLAG_ON);
246       unbind_variable ("POSIXLY_CORRECT");
247       unbind_variable ("POSIX_PEDANTIC");
248       if (on_or_off == FLAG_ON)
249         {
250           bind_variable ("POSIXLY_CORRECT", "");
251           stupidly_hack_special_variables ("POSIXLY_CORRECT");
252         }
253     }
254   else
255     {
256       register int i;
257       for (i = 0; o_options[i].name; i++)
258         {
259           if (STREQ (option_name, o_options[i].name))
260             {
261               option_char = o_options[i].letter;
262               break;
263             }
264         }
265       if (option_char == -1)
266         {
267           builtin_error ("%s: unknown option name", option_name);
268           return (EXECUTION_FAILURE);
269         }
270       if (change_flag (option_char, on_or_off) == FLAG_ERROR)
271         {
272           bad_option (option_name);
273           return (EXECUTION_FAILURE);
274         }
275     }
276   return (EXECUTION_SUCCESS);
277 }
278
279 /* Set some flags from the word values in the input list.  If LIST is empty,
280    then print out the values of the variables instead.  If LIST contains
281    non-flags, then set $1 - $9 to the successive words of LIST. */
282 set_builtin (list)
283      WORD_LIST *list;
284 {
285   int on_or_off, flag_name, force_assignment = 0;
286
287   if (!list)
288     {
289       SHELL_VAR **vars;
290
291       vars = all_shell_variables ();
292       if (vars)
293         {
294           print_var_list (vars);
295           free (vars);
296         }
297
298       vars = all_shell_functions ();
299       if (vars)
300         {
301           print_var_list (vars);
302           free (vars);
303         }
304
305       return (EXECUTION_SUCCESS);
306     }
307
308   /* Check validity of flag arguments. */
309   if (*list->word->word == '-' || *list->word->word == '+')
310     {
311       register char *arg;
312       WORD_LIST *save_list = list;
313
314       while (list && (arg = list->word->word))
315         {
316           char c;
317
318           if (arg[0] != '-' && arg[0] != '+')
319             break;
320
321           /* `-' or `--' signifies end of flag arguments. */
322           if (arg[0] == '-' &&
323               (!arg[1] || (arg[1] == '-' && !arg[2])))
324             break;
325
326           while (c = *++arg)
327             {
328               if (find_flag (c) == FLAG_UNKNOWN && c != 'o')
329                 {
330                   char s[2];
331                   s[0] = c; s[1] = '\0';
332                   bad_option (s);
333                   if (c == '?')
334                     printf ("usage: %s\n", USAGE_STRING);
335                   return (c == '?' ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
336                 }
337             }
338           list = list->next;
339         }
340       list = save_list;
341     }
342
343   /* Do the set command.  While the list consists of words starting with
344      '-' or '+' treat them as flags, otherwise, start assigning them to
345      $1 ... $n. */
346   while (list)
347     {
348       char *string = list->word->word;
349
350       /* If the argument is `--' or `-' then signal the end of the list
351          and remember the remaining arguments. */
352       if (string[0] == '-' && (!string[1] || (string[1] == '-' && !string[2])))
353         {
354           list = list->next;
355
356           /* `set --' unsets the positional parameters. */
357           if (string[1] == '-')
358             force_assignment = 1;
359
360           /* Until told differently, the old shell behaviour of
361              `set - [arg ...]' being equivalent to `set +xv [arg ...]'
362              stands.  Posix.2 says the behaviour is marked as obsolescent. */
363           else
364             {
365               change_flag ('x', '+');
366               change_flag ('v', '+');
367             }
368
369           break;
370         }
371
372       if ((on_or_off = *string) &&
373           (on_or_off == '-' || on_or_off == '+'))
374         {
375           int i = 1;
376           while (flag_name = string[i++])
377             {
378               if (flag_name == '?')
379                 {
380                   printf ("usage: %s\n", USAGE_STRING);
381                   return (EXECUTION_SUCCESS);
382                 }
383               else if (flag_name == 'o') /* -+o option-name */
384                 {
385                   char *option_name;
386                   WORD_LIST *opt;
387
388                   opt = list->next;
389
390                   if (!opt)
391                     {
392                       list_minus_o_opts ();
393                       continue;
394                     }
395
396                   option_name = opt->word->word;
397
398                   if (!option_name || !*option_name || (*option_name == '-'))
399                     {
400                       list_minus_o_opts ();
401                       continue;
402                     }
403                   list = list->next; /* Skip over option name. */
404
405                   if (set_minus_o_option (on_or_off, option_name) != EXECUTION_SUCCESS)
406                     return (EXECUTION_FAILURE);
407                 }
408               else
409                 {
410                   if (change_flag (flag_name, on_or_off) == FLAG_ERROR)
411                     {
412                       char opt[3];
413                       opt[0] = on_or_off;
414                       opt[1] = flag_name;
415                       opt[2] = '\0';
416                       bad_option (opt);
417                       return (EXECUTION_FAILURE);
418                     }
419                 }
420             }
421         }
422       else
423         {
424           break;
425         }
426       list = list->next;
427     }
428
429   /* Assigning $1 ... $n */
430   if (list || force_assignment)
431     remember_args (list, 1);
432   return (EXECUTION_SUCCESS);
433 }
434
435 $BUILTIN unset
436 $FUNCTION unset_builtin
437 $SHORT_DOC unset [-f] [-v] [name ...]
438 For each NAME, remove the corresponding variable or function.  Given
439 the `-v', unset will only act on variables.  Given the `-f' flag,
440 unset will only act on functions.  With neither flag, unset first
441 tries to unset a variable, and if that fails, then tries to unset a
442 function.  Some variables (such as PATH and IFS) cannot be unset; also
443 see readonly.
444 $END
445
446 unset_builtin (list)
447   WORD_LIST *list;
448 {
449   int unset_function = 0, unset_variable = 0, opt;
450   int any_failed = 0;
451   char *name;
452
453   reset_internal_getopt ();
454   while ((opt = internal_getopt (list, "fv")) != -1)
455     {
456       switch (opt)
457         {
458         case 'f':
459           unset_function = 1;
460           break;
461         case 'v':
462           unset_variable = 1;
463           break;
464         default:
465           return (EXECUTION_FAILURE);
466         }
467     }
468
469   list = loptend;
470
471   if (unset_function && unset_variable)
472     {
473       builtin_error ("cannot simultaneously unset a function and a variable");
474       return (EXECUTION_FAILURE);
475     }
476
477   while (list)
478     {
479       name = list->word->word;
480
481       if (!unset_function &&
482           find_name_in_list (name, non_unsettable_vars) > -1)
483         {
484           builtin_error ("%s: cannot unset", name);
485           any_failed++;
486         }
487       else
488         {
489           SHELL_VAR *var;
490           int tem;
491
492           var = unset_function ? find_function (name) : find_variable (name);
493
494           /* Posix.2 says that unsetting readonly variables is an error. */
495           if (var && readonly_p (var))
496             {
497               builtin_error ("%s: cannot unset: readonly %s",
498                              name, unset_function ? "function" : "variable");
499               any_failed++;
500               list = list->next;
501               continue;
502             }
503
504           /* Unless the -f option is supplied, the name refers to a
505              variable. */
506           tem = makunbound
507             (name, unset_function ? shell_functions : shell_variables);
508
509           /* This is what Posix.2 draft 11+ says.  ``If neither -f nor -v
510              is specified, the name refers to a variable; if a variable by
511              that name does not exist, a function by that name, if any,
512              shall be unset.'' */
513           if ((tem == -1) && !unset_function && !unset_variable)
514             tem = makunbound (name, shell_functions);
515
516           if (tem == -1)
517             any_failed++;
518           else if (!unset_function)
519             stupidly_hack_special_variables (name);
520         }
521       list = list->next;
522     }
523
524   if (any_failed)
525     return (EXECUTION_FAILURE);
526   else
527     return (EXECUTION_SUCCESS);
528 }