]> git.ipfire.org Git - thirdparty/bash.git/blame - builtins/set.def
Bash-4.4 patch 19
[thirdparty/bash.git] / builtins / set.def
CommitLineData
726f6388
JA
1This file is set.def, from which is created set.c.
2It implements the "set" and "unset" builtins in Bash.
3
a0c0a00f 4Copyright (C) 1987-2015 Free Software Foundation, Inc.
726f6388
JA
5
6This file is part of GNU Bash, the Bourne Again SHell.
7
3185942a
JA
8Bash is free software: you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation, either version 3 of the License, or
11(at your option) any later version.
726f6388 12
3185942a
JA
13Bash is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
726f6388 17
3185942a
JA
18You should have received a copy of the GNU General Public License
19along with Bash. If not, see <http://www.gnu.org/licenses/>.
726f6388
JA
20
21$PRODUCES set.c
22
ccc6cda3
JA
23#include <config.h>
24
25#if defined (HAVE_UNISTD_H)
cce855bc
JA
26# ifdef _MINIX
27# include <sys/types.h>
28# endif
ccc6cda3
JA
29# include <unistd.h>
30#endif
31
726f6388 32#include <stdio.h>
ccc6cda3
JA
33
34#include "../bashansi.h"
b80f6443 35#include "../bashintl.h"
ccc6cda3 36
726f6388
JA
37#include "../shell.h"
38#include "../flags.h"
ccc6cda3 39#include "common.h"
726f6388
JA
40#include "bashgetopt.h"
41
ccc6cda3
JA
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
7117c2d2 52extern int posixly_correct, ignoreeof, eof_encountered_limit;
f73dda09
JA
53#if defined (HISTORY)
54extern int dont_save_function_defs;
55#endif
726f6388 56#if defined (READLINE)
28ef6c31 57extern int no_line_editing;
726f6388
JA
58#endif /* READLINE */
59
726f6388
JA
60$BUILTIN set
61$FUNCTION set_builtin
495aee44 62$SHORT_DOC set [-abefhkmnptuvxBCHP] [-o option-name] [--] [arg ...]
3185942a
JA
63Set or unset values of shell options and positional parameters.
64
65Change the value of shell attributes and positional parameters, or
66display the names and values of shell variables.
67
68Options:
69 -a Mark variables which are modified or created for export.
70 -b Notify of job termination immediately.
71 -e Exit immediately if a command exits with a non-zero status.
72 -f Disable file name generation (globbing).
73 -h Remember the location of commands as they are looked up.
74 -k All assignment arguments are placed in the environment for a
75 command, not just those that precede the command name.
76 -m Job control is enabled.
77 -n Read commands but do not execute them.
78 -o option-name
79 Set the variable corresponding to option-name:
80 allexport same as -a
81 braceexpand same as -B
726f6388 82#if defined (READLINE)
3185942a 83 emacs use an emacs-style line editing interface
726f6388 84#endif /* READLINE */
3185942a
JA
85 errexit same as -e
86 errtrace same as -E
87 functrace same as -T
88 hashall same as -h
726f6388 89#if defined (BANG_HISTORY)
3185942a 90 histexpand same as -H
726f6388 91#endif /* BANG_HISTORY */
d166f048 92#if defined (HISTORY)
3185942a 93 history enable command history
d166f048 94#endif
3185942a
JA
95 ignoreeof the shell will not exit upon reading EOF
96 interactive-comments
97 allow comments to appear in interactive commands
98 keyword same as -k
ac50fbac 99#if defined (JOB_CONTROL)
3185942a 100 monitor same as -m
ac50fbac 101#endif
3185942a
JA
102 noclobber same as -C
103 noexec same as -n
104 noglob same as -f
105 nolog currently accepted but ignored
ac50fbac 106#if defined (JOB_CONTROL)
3185942a 107 notify same as -b
ac50fbac 108#endif
3185942a
JA
109 nounset same as -u
110 onecmd same as -t
111 physical same as -P
112 pipefail the return value of a pipeline is the status of
113 the last command to exit with a non-zero status,
114 or zero if no command exited with a non-zero status
115 posix change the behavior of bash where the default
116 operation differs from the Posix standard to
117 match the standard
118 privileged same as -p
119 verbose same as -v
726f6388 120#if defined (READLINE)
3185942a 121 vi use a vi-style line editing interface
726f6388 122#endif /* READLINE */
3185942a
JA
123 xtrace same as -x
124 -p Turned on whenever the real and effective user ids do not match.
125 Disables processing of the $ENV file and importing of shell
126 functions. Turning this option off causes the effective uid and
127 gid to be set to the real uid and gid.
128 -t Exit after reading and executing one command.
129 -u Treat unset variables as an error when substituting.
130 -v Print shell input lines as they are read.
131 -x Print commands and their arguments as they are executed.
ccc6cda3 132#if defined (BRACE_EXPANSION)
3185942a 133 -B the shell will perform brace expansion
ccc6cda3 134#endif /* BRACE_EXPANSION */
3185942a
JA
135 -C If set, disallow existing regular files to be overwritten
136 by redirection of output.
137 -E If set, the ERR trap is inherited by shell functions.
726f6388 138#if defined (BANG_HISTORY)
3185942a
JA
139 -H Enable ! style history substitution. This flag is on
140 by default when the shell is interactive.
726f6388 141#endif /* BANG_HISTORY */
ac50fbac 142 -P If set, do not resolve symbolic links when executing commands
3185942a 143 such as cd which change the current directory.
a0c0a00f 144 -T If set, the DEBUG and RETURN traps are inherited by shell functions.
495aee44
CR
145 -- Assign any remaining arguments to the positional parameters.
146 If there are no remaining arguments, the positional parameters
147 are unset.
3185942a
JA
148 - Assign any remaining arguments to the positional parameters.
149 The -x and -v options are turned off.
726f6388
JA
150
151Using + rather than - causes these flags to be turned off. The
152flags can also be used upon invocation of the shell. The current
153set of flags may be found in $-. The remaining n ARGs are positional
154parameters and are assigned, in order, to $1, $2, .. $n. If no
155ARGs are given, all shell variables are printed.
3185942a
JA
156
157Exit Status:
158Returns success unless an invalid option is given.
726f6388
JA
159$END
160
7117c2d2
JA
161typedef int setopt_set_func_t __P((int, char *));
162typedef int setopt_get_func_t __P((char *));
163
f73dda09
JA
164static void print_minus_o_option __P((char *, int, int));
165static void print_all_shell_variables __P((void));
166
167static int set_ignoreeof __P((int, char *));
168static int set_posix_mode __P((int, char *));
ccc6cda3
JA
169
170#if defined (READLINE)
f73dda09
JA
171static int set_edit_mode __P((int, char *));
172static int get_edit_mode __P((char *));
ccc6cda3
JA
173#endif
174
175#if defined (HISTORY)
f73dda09 176static int bash_set_history __P((int, char *));
ccc6cda3
JA
177#endif
178
3185942a
JA
179static const char * const on = "on";
180static const char * const off = "off";
ccc6cda3 181
a0c0a00f
CR
182static int previous_option_value;
183
7117c2d2
JA
184/* A struct used to match long options for set -o to the corresponding
185 option letter or internal variable. The functions can be called to
a0c0a00f
CR
186 dynamically generate values. If you add a new variable name here
187 that doesn't have a corresponding single-character option letter, make
188 sure to set the value appropriately in reset_shell_options. */
3185942a 189const struct {
726f6388
JA
190 char *name;
191 int letter;
7117c2d2
JA
192 int *variable;
193 setopt_set_func_t *set_func;
194 setopt_get_func_t *get_func;
726f6388 195} o_options[] = {
7117c2d2 196 { "allexport", 'a', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
ccc6cda3 197#if defined (BRACE_EXPANSION)
7117c2d2 198 { "braceexpand",'B', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
ccc6cda3 199#endif
7117c2d2
JA
200#if defined (READLINE)
201 { "emacs", '\0', (int *)NULL, set_edit_mode, get_edit_mode },
202#endif
203 { "errexit", 'e', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
b80f6443
JA
204 { "errtrace", 'E', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
205 { "functrace", 'T', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
7117c2d2 206 { "hashall", 'h', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
726f6388 207#if defined (BANG_HISTORY)
7117c2d2 208 { "histexpand", 'H', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
726f6388 209#endif /* BANG_HISTORY */
ccc6cda3 210#if defined (HISTORY)
f1be666c 211 { "history", '\0', &enable_history_list, bash_set_history, (setopt_get_func_t *)NULL },
f73dda09 212#endif
7117c2d2
JA
213 { "ignoreeof", '\0', &ignoreeof, set_ignoreeof, (setopt_get_func_t *)NULL },
214 { "interactive-comments", '\0', &interactive_comments, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
215 { "keyword", 'k', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
ac50fbac 216#if defined (JOB_CONTROL)
7117c2d2 217 { "monitor", 'm', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
ac50fbac 218#endif
7117c2d2
JA
219 { "noclobber", 'C', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
220 { "noexec", 'n', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
221 { "noglob", 'f', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
f73dda09 222#if defined (HISTORY)
7117c2d2 223 { "nolog", '\0', &dont_save_function_defs, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
ccc6cda3 224#endif
7117c2d2
JA
225#if defined (JOB_CONTROL)
226 { "notify", 'b', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
227#endif /* JOB_CONTROL */
228 { "nounset", 'u', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
229 { "onecmd", 't', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
230 { "physical", 'P', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
b80f6443 231 { "pipefail", '\0', &pipefail_opt, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
7117c2d2
JA
232 { "posix", '\0', &posixly_correct, set_posix_mode, (setopt_get_func_t *)NULL },
233 { "privileged", 'p', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
234 { "verbose", 'v', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
ccc6cda3 235#if defined (READLINE)
7117c2d2 236 { "vi", '\0', (int *)NULL, set_edit_mode, get_edit_mode },
ccc6cda3 237#endif
7117c2d2
JA
238 { "xtrace", 'x', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
239 {(char *)NULL, 0 , (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
726f6388
JA
240};
241
7117c2d2
JA
242#define N_O_OPTIONS (sizeof (o_options) / sizeof (o_options[0]))
243
ccc6cda3 244#define GET_BINARY_O_OPTION_VALUE(i, name) \
7117c2d2
JA
245 ((o_options[i].get_func) ? (*o_options[i].get_func) (name) \
246 : (*o_options[i].variable))
ccc6cda3
JA
247
248#define SET_BINARY_O_OPTION_VALUE(i, onoff, name) \
7117c2d2
JA
249 ((o_options[i].set_func) ? (*o_options[i].set_func) (onoff, name) \
250 : (*o_options[i].variable = (onoff == FLAG_ON)))
ccc6cda3
JA
251
252int
253minus_o_option_value (name)
254 char *name;
255{
256 register int i;
257 int *on_or_off;
258
259 for (i = 0; o_options[i].name; i++)
260 {
261 if (STREQ (name, o_options[i].name))
262 {
7117c2d2
JA
263 if (o_options[i].letter)
264 {
265 on_or_off = find_flag (o_options[i].letter);
266 return ((on_or_off == FLAG_UNKNOWN) ? -1 : *on_or_off);
267 }
268 else
269 return (GET_BINARY_O_OPTION_VALUE (i, name));
ccc6cda3
JA
270 }
271 }
28ef6c31 272
ccc6cda3
JA
273 return (-1);
274}
275
726f6388
JA
276#define MINUS_O_FORMAT "%-15s\t%s\n"
277
cce855bc
JA
278static void
279print_minus_o_option (name, value, pflag)
280 char *name;
281 int value, pflag;
726f6388 282{
cce855bc
JA
283 if (pflag == 0)
284 printf (MINUS_O_FORMAT, name, value ? on : off);
285 else
286 printf ("set %co %s\n", value ? '-' : '+', name);
ccc6cda3 287}
726f6388 288
cce855bc
JA
289void
290list_minus_o_opts (mode, reusable)
291 int mode, reusable;
ccc6cda3
JA
292{
293 register int i;
294 int *on_or_off, value;
726f6388 295
7117c2d2 296 for (i = 0; o_options[i].name; i++)
ccc6cda3 297 {
7117c2d2
JA
298 if (o_options[i].letter)
299 {
300 value = 0;
301 on_or_off = find_flag (o_options[i].letter);
302 if (on_or_off == FLAG_UNKNOWN)
303 on_or_off = &value;
304 if (mode == -1 || mode == *on_or_off)
305 print_minus_o_option (o_options[i].name, *on_or_off, reusable);
306 }
307 else
308 {
309 value = GET_BINARY_O_OPTION_VALUE (i, o_options[i].name);
310 if (mode == -1 || mode == value)
311 print_minus_o_option (o_options[i].name, value, reusable);
312 }
ccc6cda3
JA
313 }
314}
726f6388 315
bb70624e
JA
316char **
317get_minus_o_opts ()
318{
319 char **ret;
7117c2d2
JA
320 int i;
321
322 ret = strvec_create (N_O_OPTIONS + 1);
323 for (i = 0; o_options[i].name; i++)
324 ret[i] = o_options[i].name;
325 ret[i] = (char *)NULL;
bb70624e
JA
326 return ret;
327}
328
a0c0a00f
CR
329char *
330get_current_options ()
331{
332 char *temp;
333 int i;
334
335 temp = (char *)xmalloc (1 + N_O_OPTIONS);
336 for (i = 0; o_options[i].name; i++)
337 {
338 if (o_options[i].letter)
339 temp[i] = *(find_flag (o_options[i].letter));
340 else
341 temp[i] = GET_BINARY_O_OPTION_VALUE (i, o_options[i].name);
342 }
343 temp[i] = '\0';
344 return (temp);
345}
346
347void
348set_current_options (bitmap)
349 const char *bitmap;
350{
351 int i;
352
353 if (bitmap == 0)
354 return;
355 for (i = 0; o_options[i].name; i++)
356 {
357 if (o_options[i].letter)
358 change_flag (o_options[i].letter, bitmap[i] ? FLAG_ON : FLAG_OFF);
359 else
360 SET_BINARY_O_OPTION_VALUE (i, bitmap[i] ? FLAG_ON : FLAG_OFF, o_options[i].name);
361 }
362}
363
ccc6cda3
JA
364static int
365set_ignoreeof (on_or_off, option_name)
366 int on_or_off;
367 char *option_name;
368{
369 ignoreeof = on_or_off == FLAG_ON;
a0c0a00f 370 unbind_variable_noref ("ignoreeof");
ccc6cda3 371 if (ignoreeof)
95732b49 372 bind_variable ("IGNOREEOF", "10", 0);
ccc6cda3 373 else
a0c0a00f 374 unbind_variable_noref ("IGNOREEOF");
ccc6cda3
JA
375 sv_ignoreeof ("IGNOREEOF");
376 return 0;
377}
726f6388 378
d166f048
JA
379static int
380set_posix_mode (on_or_off, option_name)
381 int on_or_off;
382 char *option_name;
383{
384 posixly_correct = on_or_off == FLAG_ON;
385 if (posixly_correct == 0)
a0c0a00f 386 unbind_variable_noref ("POSIXLY_CORRECT");
d166f048 387 else
95732b49 388 bind_variable ("POSIXLY_CORRECT", "y", 0);
d166f048
JA
389 sv_strict_posix ("POSIXLY_CORRECT");
390 return (0);
391}
392
726f6388 393#if defined (READLINE)
ccc6cda3
JA
394/* Magic. This code `knows' how readline handles rl_editing_mode. */
395static int
396set_edit_mode (on_or_off, option_name)
397 int on_or_off;
398 char *option_name;
399{
400 int isemacs;
401
402 if (on_or_off == FLAG_ON)
726f6388 403 {
ccc6cda3
JA
404 rl_variable_bind ("editing-mode", option_name);
405
406 if (interactive)
407 with_input_from_stdin ();
408 no_line_editing = 0;
726f6388
JA
409 }
410 else
411 {
ccc6cda3
JA
412 isemacs = rl_editing_mode == 1;
413 if ((isemacs && *option_name == 'e') || (!isemacs && *option_name == 'v'))
414 {
415 if (interactive)
416 with_input_from_stream (stdin, "stdin");
417 no_line_editing = 1;
418 }
726f6388 419 }
ccc6cda3
JA
420 return 1-no_line_editing;
421}
422
423static int
424get_edit_mode (name)
425 char *name;
426{
427 return (*name == 'e' ? no_line_editing == 0 && rl_editing_mode == 1
428 : no_line_editing == 0 && rl_editing_mode == 0);
429}
726f6388
JA
430#endif /* READLINE */
431
ccc6cda3
JA
432#if defined (HISTORY)
433static int
434bash_set_history (on_or_off, option_name)
435 int on_or_off;
436 char *option_name;
437{
438 if (on_or_off == FLAG_ON)
726f6388 439 {
f1be666c 440 enable_history_list = 1;
ccc6cda3
JA
441 bash_history_enable ();
442 if (history_lines_this_session == 0)
443 load_history ();
726f6388 444 }
ccc6cda3 445 else
f1be666c
JA
446 {
447 enable_history_list = 0;
448 bash_history_disable ();
449 }
450 return (1 - enable_history_list);
726f6388 451}
ccc6cda3 452#endif
726f6388 453
ccc6cda3 454int
726f6388
JA
455set_minus_o_option (on_or_off, option_name)
456 int on_or_off;
457 char *option_name;
458{
ccc6cda3 459 register int i;
726f6388 460
7117c2d2 461 for (i = 0; o_options[i].name; i++)
726f6388 462 {
ccc6cda3 463 if (STREQ (option_name, o_options[i].name))
28ef6c31 464 {
7117c2d2
JA
465 if (o_options[i].letter == 0)
466 {
a0c0a00f 467 previous_option_value = GET_BINARY_O_OPTION_VALUE (i, o_options[i].name);
7117c2d2
JA
468 SET_BINARY_O_OPTION_VALUE (i, on_or_off, option_name);
469 return (EXECUTION_SUCCESS);
470 }
471 else
472 {
a0c0a00f 473 if ((previous_option_value = change_flag (o_options[i].letter, on_or_off)) == FLAG_ERROR)
7117c2d2
JA
474 {
475 sh_invalidoptname (option_name);
476 return (EXECUTION_FAILURE);
477 }
478 else
479 return (EXECUTION_SUCCESS);
480 }
481
28ef6c31 482 }
726f6388 483 }
7117c2d2
JA
484
485 sh_invalidoptname (option_name);
3185942a 486 return (EX_USAGE);
ccc6cda3 487}
726f6388 488
ccc6cda3
JA
489static void
490print_all_shell_variables ()
491{
492 SHELL_VAR **vars;
493
494 vars = all_shell_variables ();
495 if (vars)
496 {
497 print_var_list (vars);
498 free (vars);
726f6388 499 }
ccc6cda3 500
28ef6c31
JA
501 /* POSIX.2 does not allow function names and definitions to be output when
502 `set' is invoked without options (PASC Interp #202). */
503 if (posixly_correct == 0)
726f6388 504 {
28ef6c31
JA
505 vars = all_shell_functions ();
506 if (vars)
507 {
508 print_func_list (vars);
509 free (vars);
510 }
726f6388 511 }
ccc6cda3
JA
512}
513
514void
515set_shellopts ()
516{
517 char *value;
7117c2d2 518 char tflag[N_O_OPTIONS];
cce855bc 519 int vsize, i, vptr, *ip, exported;
ccc6cda3
JA
520 SHELL_VAR *v;
521
522 for (vsize = i = 0; o_options[i].name; i++)
726f6388 523 {
7117c2d2
JA
524 tflag[i] = 0;
525 if (o_options[i].letter)
526 {
527 ip = find_flag (o_options[i].letter);
528 if (ip && *ip)
529 {
530 vsize += strlen (o_options[i].name) + 1;
531 tflag[i] = 1;
532 }
533 }
534 else if (GET_BINARY_O_OPTION_VALUE (i, o_options[i].name))
535 {
536 vsize += strlen (o_options[i].name) + 1;
537 tflag[i] = 1;
538 }
ccc6cda3 539 }
ccc6cda3 540
f73dda09 541 value = (char *)xmalloc (vsize + 1);
ccc6cda3
JA
542
543 for (i = vptr = 0; o_options[i].name; i++)
544 {
7117c2d2 545 if (tflag[i])
726f6388 546 {
ccc6cda3
JA
547 strcpy (value + vptr, o_options[i].name);
548 vptr += strlen (o_options[i].name);
549 value[vptr++] = ':';
726f6388
JA
550 }
551 }
7117c2d2 552
d166f048
JA
553 if (vptr)
554 vptr--; /* cut off trailing colon */
555 value[vptr] = '\0';
ccc6cda3
JA
556
557 v = find_variable ("SHELLOPTS");
cce855bc
JA
558
559 /* Turn off the read-only attribute so we can bind the new value, and
560 note whether or not the variable was exported. */
ccc6cda3 561 if (v)
cce855bc 562 {
bb70624e 563 VUNSETATTR (v, att_readonly);
cce855bc
JA
564 exported = exported_p (v);
565 }
566 else
567 exported = 0;
568
95732b49 569 v = bind_variable ("SHELLOPTS", value, 0);
cce855bc
JA
570
571 /* Turn the read-only attribute back on, and turn off the export attribute
572 if it was set implicitly by mark_modified_vars and SHELLOPTS was not
573 exported before we bound the new value. */
bb70624e 574 VSETATTR (v, att_readonly);
cce855bc 575 if (mark_modified_vars && exported == 0 && exported_p (v))
bb70624e 576 VUNSETATTR (v, att_exported);
ccc6cda3
JA
577
578 free (value);
579}
580
581void
582parse_shellopts (value)
583 char *value;
584{
585 char *vname;
586 int vptr;
587
588 vptr = 0;
589 while (vname = extract_colon_unit (value, &vptr))
590 {
591 set_minus_o_option (FLAG_ON, vname);
592 free (vname);
593 }
594}
595
596void
cce855bc
JA
597initialize_shell_options (no_shellopts)
598 int no_shellopts;
ccc6cda3
JA
599{
600 char *temp;
d166f048 601 SHELL_VAR *var;
ccc6cda3 602
cce855bc 603 if (no_shellopts == 0)
d166f048 604 {
cce855bc
JA
605 var = find_variable ("SHELLOPTS");
606 /* set up any shell options we may have inherited. */
607 if (var && imported_p (var))
d166f048 608 {
3185942a 609 temp = (array_p (var) || assoc_p (var)) ? (char *)NULL : savestring (value_cell (var));
cce855bc
JA
610 if (temp)
611 {
612 parse_shellopts (temp);
613 free (temp);
614 }
d166f048
JA
615 }
616 }
ccc6cda3
JA
617
618 /* Set up the $SHELLOPTS variable. */
619 set_shellopts ();
726f6388
JA
620}
621
28ef6c31
JA
622/* Reset the values of the -o options that are not also shell flags. This is
623 called from execute_cmd.c:initialize_subshell() when setting up a subshell
624 to run an executable shell script without a leading `#!'. */
d166f048
JA
625void
626reset_shell_options ()
627{
a0c0a00f
CR
628 pipefail_opt = 0;
629 ignoreeof = 0;
630
631#if defined (STRICT_POSIX)
632 posixly_correct = 1;
633#else
634 posixly_correct = 0;
635#endif
d166f048 636#if defined (HISTORY)
a0c0a00f 637 dont_save_function_defs = 0;
f1be666c 638 remember_on_history = enable_history_list = 1;
d166f048 639#endif
d166f048
JA
640}
641
726f6388
JA
642/* Set some flags from the word values in the input list. If LIST is empty,
643 then print out the values of the variables instead. If LIST contains
644 non-flags, then set $1 - $9 to the successive words of LIST. */
ccc6cda3 645int
726f6388
JA
646set_builtin (list)
647 WORD_LIST *list;
648{
3185942a 649 int on_or_off, flag_name, force_assignment, opts_changed, rv, r;
ccc6cda3 650 register char *arg;
7117c2d2 651 char s[3];
726f6388 652
ccc6cda3 653 if (list == 0)
726f6388 654 {
ccc6cda3 655 print_all_shell_variables ();
3185942a 656 return (sh_chkwrite (EXECUTION_SUCCESS));
726f6388
JA
657 }
658
659 /* Check validity of flag arguments. */
3185942a 660 rv = EXECUTION_SUCCESS;
7117c2d2
JA
661 reset_internal_getopt ();
662 while ((flag_name = internal_getopt (list, optflags)) != -1)
726f6388 663 {
7117c2d2 664 switch (flag_name)
726f6388 665 {
a0c0a00f
CR
666 case 'i': /* don't allow set -i */
667 s[0] = list_opttype;
668 s[1] = 'i';
669 s[2] = '\0';
670 sh_invalidopt (s);
671 builtin_usage ();
672 return (EX_USAGE);
673 CASE_HELPOPT;
7117c2d2
JA
674 case '?':
675 builtin_usage ();
676 return (list_optopt == '?' ? EXECUTION_SUCCESS : EX_USAGE);
677 default:
726f6388 678 break;
726f6388 679 }
726f6388 680 }
7117c2d2 681
726f6388
JA
682 /* Do the set command. While the list consists of words starting with
683 '-' or '+' treat them as flags, otherwise, start assigning them to
684 $1 ... $n. */
ccc6cda3 685 for (force_assignment = opts_changed = 0; list; )
726f6388 686 {
ccc6cda3 687 arg = list->word->word;
726f6388
JA
688
689 /* If the argument is `--' or `-' then signal the end of the list
690 and remember the remaining arguments. */
ccc6cda3 691 if (arg[0] == '-' && (!arg[1] || (arg[1] == '-' && !arg[2])))
726f6388
JA
692 {
693 list = list->next;
694
695 /* `set --' unsets the positional parameters. */
ccc6cda3 696 if (arg[1] == '-')
726f6388
JA
697 force_assignment = 1;
698
699 /* Until told differently, the old shell behaviour of
700 `set - [arg ...]' being equivalent to `set +xv [arg ...]'
701 stands. Posix.2 says the behaviour is marked as obsolescent. */
702 else
703 {
704 change_flag ('x', '+');
705 change_flag ('v', '+');
ccc6cda3 706 opts_changed = 1;
726f6388
JA
707 }
708
709 break;
710 }
711
ccc6cda3 712 if ((on_or_off = *arg) && (on_or_off == '-' || on_or_off == '+'))
726f6388 713 {
ccc6cda3 714 while (flag_name = *++arg)
726f6388
JA
715 {
716 if (flag_name == '?')
717 {
ccc6cda3 718 builtin_usage ();
726f6388
JA
719 return (EXECUTION_SUCCESS);
720 }
721 else if (flag_name == 'o') /* -+o option-name */
722 {
723 char *option_name;
724 WORD_LIST *opt;
725
726 opt = list->next;
727
ccc6cda3 728 if (opt == 0)
726f6388 729 {
cce855bc 730 list_minus_o_opts (-1, (on_or_off == '+'));
3185942a 731 rv = sh_chkwrite (rv);
726f6388
JA
732 continue;
733 }
734
735 option_name = opt->word->word;
736
ccc6cda3
JA
737 if (option_name == 0 || *option_name == '\0' ||
738 *option_name == '-' || *option_name == '+')
726f6388 739 {
cce855bc 740 list_minus_o_opts (-1, (on_or_off == '+'));
726f6388
JA
741 continue;
742 }
743 list = list->next; /* Skip over option name. */
744
ccc6cda3 745 opts_changed = 1;
3185942a 746 if ((r = set_minus_o_option (on_or_off, option_name)) != EXECUTION_SUCCESS)
726f6388 747 {
ccc6cda3 748 set_shellopts ();
3185942a 749 return (r);
726f6388
JA
750 }
751 }
ccc6cda3
JA
752 else if (change_flag (flag_name, on_or_off) == FLAG_ERROR)
753 {
7117c2d2
JA
754 s[0] = on_or_off;
755 s[1] = flag_name;
756 s[2] = '\0';
757 sh_invalidopt (s);
ccc6cda3
JA
758 builtin_usage ();
759 set_shellopts ();
760 return (EXECUTION_FAILURE);
761 }
762 opts_changed = 1;
726f6388
JA
763 }
764 }
765 else
766 {
767 break;
768 }
769 list = list->next;
770 }
771
772 /* Assigning $1 ... $n */
773 if (list || force_assignment)
774 remember_args (list, 1);
ccc6cda3
JA
775 /* Set up new value of $SHELLOPTS */
776 if (opts_changed)
777 set_shellopts ();
3185942a 778 return (rv);
726f6388
JA
779}
780
781$BUILTIN unset
782$FUNCTION unset_builtin
ac50fbac 783$SHORT_DOC unset [-f] [-v] [-n] [name ...]
3185942a
JA
784Unset values and attributes of shell variables and functions.
785
786For each NAME, remove the corresponding variable or function.
787
788Options:
789 -f treat each NAME as a shell function
790 -v treat each NAME as a shell variable
ac50fbac 791 -n treat each NAME as a name reference and unset the variable itself
a0c0a00f 792 rather than the variable it references
3185942a
JA
793
794Without options, unset first tries to unset a variable, and if that fails,
795tries to unset a function.
796
797Some variables cannot be unset; also see `readonly'.
798
799Exit Status:
800Returns success unless an invalid option is given or a NAME is read-only.
726f6388
JA
801$END
802
ccc6cda3
JA
803#define NEXT_VARIABLE() any_failed++; list = list->next; continue;
804
805int
726f6388
JA
806unset_builtin (list)
807 WORD_LIST *list;
808{
ac50fbac 809 int unset_function, unset_variable, unset_array, opt, nameref, any_failed;
8daea13b 810 int global_unset_func, global_unset_var;
a0c0a00f 811 char *name, *tname;
726f6388 812
ac50fbac 813 unset_function = unset_variable = unset_array = nameref = any_failed = 0;
8daea13b 814 global_unset_func = global_unset_var = 0;
ccc6cda3 815
726f6388 816 reset_internal_getopt ();
ac50fbac 817 while ((opt = internal_getopt (list, "fnv")) != -1)
726f6388
JA
818 {
819 switch (opt)
820 {
821 case 'f':
8daea13b 822 global_unset_func = 1;
726f6388
JA
823 break;
824 case 'v':
8daea13b 825 global_unset_var = 1;
726f6388 826 break;
ac50fbac
CR
827 case 'n':
828 nameref = 1;
829 break;
a0c0a00f 830 CASE_HELPOPT;
726f6388 831 default:
ccc6cda3
JA
832 builtin_usage ();
833 return (EX_USAGE);
726f6388
JA
834 }
835 }
836
837 list = loptend;
838
8daea13b 839 if (global_unset_func && global_unset_var)
726f6388 840 {
b80f6443 841 builtin_error (_("cannot simultaneously unset a function and a variable"));
726f6388
JA
842 return (EXECUTION_FAILURE);
843 }
ac50fbac
CR
844 else if (unset_function && nameref)
845 nameref = 0;
726f6388
JA
846
847 while (list)
848 {
ccc6cda3
JA
849 SHELL_VAR *var;
850 int tem;
851#if defined (ARRAY_VARS)
852 char *t;
853#endif
854
726f6388
JA
855 name = list->word->word;
856
8daea13b
CR
857 unset_function = global_unset_func;
858 unset_variable = global_unset_var;
859
ccc6cda3 860#if defined (ARRAY_VARS)
f73dda09 861 unset_array = 0;
a0c0a00f 862 if (!unset_function && nameref == 0 && valid_array_reference (name, 0))
726f6388 863 {
ccc6cda3
JA
864 t = strchr (name, '[');
865 *t++ = '\0';
866 unset_array++;
726f6388 867 }
ccc6cda3 868#endif
ac50fbac
CR
869 /* Get error checking out of the way first. The low-level functions
870 just perform the unset, relying on the caller to verify. */
ccc6cda3 871
cce855bc
JA
872 /* Bash allows functions with names which are not valid identifiers
873 to be created when not in posix mode, so check only when in posix
874 mode when unsetting a function. */
875 if (((unset_function && posixly_correct) || !unset_function) && legal_identifier (name) == 0)
28ef6c31 876 {
7117c2d2 877 sh_invalidid (name);
28ef6c31
JA
878 NEXT_VARIABLE ();
879 }
d166f048 880
ac50fbac
CR
881 /* Only search for functions here if -f supplied. */
882 var = unset_function ? find_function (name)
a0c0a00f 883 : (nameref ? find_variable_last_nameref (name, 0) : find_variable (name));
ccc6cda3 884
ac50fbac
CR
885 /* Some variables (but not functions yet) cannot be unset, period. */
886 if (var && unset_function == 0 && non_unsettable_p (var))
726f6388 887 {
b80f6443 888 builtin_error (_("%s: cannot unset"), name);
ccc6cda3
JA
889 NEXT_VARIABLE ();
890 }
726f6388 891
a0c0a00f
CR
892 /* if we have a nameref we want to use it */
893 if (var && unset_function == 0 && nameref == 0 && STREQ (name, name_cell(var)) == 0)
894 name = name_cell (var);
895
ac50fbac
CR
896 /* Posix.2 says try variables first, then functions. If we would
897 find a function after unsuccessfully searching for a variable,
898 note that we're acting on a function now as if -f were
899 supplied. The readonly check below takes care of it. */
a0c0a00f 900 if (var == 0 && nameref == 0 && unset_variable == 0 && unset_function == 0)
ac50fbac
CR
901 {
902 if (var = find_function (name))
903 unset_function = 1;
904 }
905
ccc6cda3
JA
906 /* Posix.2 says that unsetting readonly variables is an error. */
907 if (var && readonly_p (var))
908 {
b80f6443 909 builtin_error (_("%s: cannot unset: readonly %s"),
ac50fbac 910 var->name, unset_function ? "function" : "variable");
ccc6cda3
JA
911 NEXT_VARIABLE ();
912 }
726f6388 913
ccc6cda3
JA
914 /* Unless the -f option is supplied, the name refers to a variable. */
915#if defined (ARRAY_VARS)
916 if (var && unset_array)
917 {
a0c0a00f
CR
918 /* Let unbind_array_element decide what to do with non-array vars */
919 tem = unbind_array_element (var, t);
920 if (tem == -2 && array_p (var) == 0 && assoc_p (var) == 0)
726f6388 921 {
ac50fbac 922 builtin_error (_("%s: not an array variable"), var->name);
ccc6cda3 923 NEXT_VARIABLE ();
726f6388 924 }
a0c0a00f
CR
925 else if (tem < 0)
926 any_failed++;
927 }
928 else
929#endif /* ARRAY_VARS */
930 /* If we're trying to unset a nameref variable whose value isn't a set
931 variable, make sure we still try to unset the nameref's value */
932 if (var == 0 && nameref == 0 && unset_function == 0)
933 {
934 var = find_variable_last_nameref (name, 0);
935 if (var && nameref_p (var))
7117c2d2 936 {
a0c0a00f
CR
937#if defined (ARRAY_VARS)
938 if (valid_array_reference (nameref_cell (var), 0))
939 {
940 tname = savestring (nameref_cell (var));
941 if (var = array_variable_part (tname, &t, 0))
942 tem = unbind_array_element (var, t);
943 free (tname);
944 }
945 else
946#endif
947 tem = unbind_variable (nameref_cell (var));
7117c2d2 948 }
a0c0a00f
CR
949 else
950 tem = unbind_variable (name);
726f6388 951 }
ccc6cda3 952 else
a0c0a00f 953 tem = unset_function ? unbind_func (name) : (nameref ? unbind_nameref (name) : unbind_variable (name));
ccc6cda3 954
ac50fbac 955 /* This is what Posix.2 says: ``If neither -f nor -v
ccc6cda3
JA
956 is specified, the name refers to a variable; if a variable by
957 that name does not exist, a function by that name, if any,
958 shall be unset.'' */
a0c0a00f 959 if (tem == -1 && nameref == 0 && unset_function == 0 && unset_variable == 0)
7117c2d2
JA
960 tem = unbind_func (name);
961
a0c0a00f
CR
962 name = list->word->word; /* reset above for namerefs */
963
7117c2d2
JA
964 /* SUSv3, POSIX.1-2001 say: ``Unsetting a variable or function that
965 was not previously set shall not be considered an error.'' */
ccc6cda3 966
7117c2d2 967 if (unset_function == 0)
ccc6cda3
JA
968 stupidly_hack_special_variables (name);
969
726f6388
JA
970 list = list->next;
971 }
972
ccc6cda3 973 return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
726f6388 974}