blob: 9fbbca14b65838d29c2531794f4eee5438ce1c32 [file] [log] [blame]
Jari Aalto726f6381996-08-26 18:22:31 +00001This file is set.def, from which is created set.c.
2It implements the "set" and "unset" builtins in Bash.
3
Chet Rameyac50fba2014-02-26 09:36:43 -05004Copyright (C) 1987-2012 Free Software Foundation, Inc.
Jari Aalto726f6381996-08-26 18:22:31 +00005
6This file is part of GNU Bash, the Bourne Again SHell.
7
Jari Aalto31859422009-01-12 13:36:28 +00008Bash 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.
Jari Aalto726f6381996-08-26 18:22:31 +000012
Jari Aalto31859422009-01-12 13:36:28 +000013Bash 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.
Jari Aalto726f6381996-08-26 18:22:31 +000017
Jari Aalto31859422009-01-12 13:36:28 +000018You should have received a copy of the GNU General Public License
19along with Bash. If not, see <http://www.gnu.org/licenses/>.
Jari Aalto726f6381996-08-26 18:22:31 +000020
21$PRODUCES set.c
22
Jari Aaltoccc6cda1996-12-23 17:02:34 +000023#include <config.h>
24
25#if defined (HAVE_UNISTD_H)
Jari Aaltocce855b1998-04-17 19:52:44 +000026# ifdef _MINIX
27# include <sys/types.h>
28# endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +000029# include <unistd.h>
30#endif
31
Jari Aalto726f6381996-08-26 18:22:31 +000032#include <stdio.h>
Jari Aaltoccc6cda1996-12-23 17:02:34 +000033
34#include "../bashansi.h"
Jari Aaltob80f6442004-07-27 13:29:18 +000035#include "../bashintl.h"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000036
Jari Aalto726f6381996-08-26 18:22:31 +000037#include "../shell.h"
38#include "../flags.h"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000039#include "common.h"
Jari Aalto726f6381996-08-26 18:22:31 +000040#include "bashgetopt.h"
41
Jari Aaltoccc6cda1996-12-23 17:02:34 +000042#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
Jari Aalto7117c2d2002-07-17 14:10:11 +000052extern int posixly_correct, ignoreeof, eof_encountered_limit;
Jari Aaltof73dda02001-11-13 17:56:06 +000053#if defined (HISTORY)
54extern int dont_save_function_defs;
55#endif
Jari Aalto726f6381996-08-26 18:22:31 +000056#if defined (READLINE)
Jari Aalto28ef6c32001-04-06 19:14:31 +000057extern int no_line_editing;
Jari Aalto726f6381996-08-26 18:22:31 +000058#endif /* READLINE */
59
Jari Aalto726f6381996-08-26 18:22:31 +000060$BUILTIN set
61$FUNCTION set_builtin
Chet Ramey495aee42011-11-22 19:11:26 -050062$SHORT_DOC set [-abefhkmnptuvxBCHP] [-o option-name] [--] [arg ...]
Jari Aalto31859422009-01-12 13:36:28 +000063Set 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
Jari Aalto726f6381996-08-26 18:22:31 +000082#if defined (READLINE)
Jari Aalto31859422009-01-12 13:36:28 +000083 emacs use an emacs-style line editing interface
Jari Aalto726f6381996-08-26 18:22:31 +000084#endif /* READLINE */
Jari Aalto31859422009-01-12 13:36:28 +000085 errexit same as -e
86 errtrace same as -E
87 functrace same as -T
88 hashall same as -h
Jari Aalto726f6381996-08-26 18:22:31 +000089#if defined (BANG_HISTORY)
Jari Aalto31859422009-01-12 13:36:28 +000090 histexpand same as -H
Jari Aalto726f6381996-08-26 18:22:31 +000091#endif /* BANG_HISTORY */
Jari Aaltod166f041997-06-05 14:59:13 +000092#if defined (HISTORY)
Jari Aalto31859422009-01-12 13:36:28 +000093 history enable command history
Jari Aaltod166f041997-06-05 14:59:13 +000094#endif
Jari Aalto31859422009-01-12 13:36:28 +000095 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
Chet Rameyac50fba2014-02-26 09:36:43 -050099#if defined (JOB_CONTROL)
Jari Aalto31859422009-01-12 13:36:28 +0000100 monitor same as -m
Chet Rameyac50fba2014-02-26 09:36:43 -0500101#endif
Jari Aalto31859422009-01-12 13:36:28 +0000102 noclobber same as -C
103 noexec same as -n
104 noglob same as -f
105 nolog currently accepted but ignored
Chet Rameyac50fba2014-02-26 09:36:43 -0500106#if defined (JOB_CONTROL)
Jari Aalto31859422009-01-12 13:36:28 +0000107 notify same as -b
Chet Rameyac50fba2014-02-26 09:36:43 -0500108#endif
Jari Aalto31859422009-01-12 13:36:28 +0000109 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
Jari Aalto726f6381996-08-26 18:22:31 +0000120#if defined (READLINE)
Jari Aalto31859422009-01-12 13:36:28 +0000121 vi use a vi-style line editing interface
Jari Aalto726f6381996-08-26 18:22:31 +0000122#endif /* READLINE */
Jari Aalto31859422009-01-12 13:36:28 +0000123 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.
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000132#if defined (BRACE_EXPANSION)
Jari Aalto31859422009-01-12 13:36:28 +0000133 -B the shell will perform brace expansion
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000134#endif /* BRACE_EXPANSION */
Jari Aalto31859422009-01-12 13:36:28 +0000135 -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.
Jari Aalto726f6381996-08-26 18:22:31 +0000138#if defined (BANG_HISTORY)
Jari Aalto31859422009-01-12 13:36:28 +0000139 -H Enable ! style history substitution. This flag is on
140 by default when the shell is interactive.
Jari Aalto726f6381996-08-26 18:22:31 +0000141#endif /* BANG_HISTORY */
Chet Rameyac50fba2014-02-26 09:36:43 -0500142 -P If set, do not resolve symbolic links when executing commands
Jari Aalto31859422009-01-12 13:36:28 +0000143 such as cd which change the current directory.
144 -T If set, the DEBUG trap is inherited by shell functions.
Chet Ramey495aee42011-11-22 19:11:26 -0500145 -- Assign any remaining arguments to the positional parameters.
146 If there are no remaining arguments, the positional parameters
147 are unset.
Jari Aalto31859422009-01-12 13:36:28 +0000148 - Assign any remaining arguments to the positional parameters.
149 The -x and -v options are turned off.
Jari Aalto726f6381996-08-26 18:22:31 +0000150
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.
Jari Aalto31859422009-01-12 13:36:28 +0000156
157Exit Status:
158Returns success unless an invalid option is given.
Jari Aalto726f6381996-08-26 18:22:31 +0000159$END
160
Jari Aalto7117c2d2002-07-17 14:10:11 +0000161typedef int setopt_set_func_t __P((int, char *));
162typedef int setopt_get_func_t __P((char *));
163
Jari Aaltof73dda02001-11-13 17:56:06 +0000164static 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 *));
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000169
170#if defined (READLINE)
Jari Aaltof73dda02001-11-13 17:56:06 +0000171static int set_edit_mode __P((int, char *));
172static int get_edit_mode __P((char *));
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000173#endif
174
175#if defined (HISTORY)
Jari Aaltof73dda02001-11-13 17:56:06 +0000176static int bash_set_history __P((int, char *));
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000177#endif
178
Jari Aalto31859422009-01-12 13:36:28 +0000179static const char * const on = "on";
180static const char * const off = "off";
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000181
Jari Aalto7117c2d2002-07-17 14:10:11 +0000182/* A struct used to match long options for set -o to the corresponding
183 option letter or internal variable. The functions can be called to
184 dynamically generate values. */
Jari Aalto31859422009-01-12 13:36:28 +0000185const struct {
Jari Aalto726f6381996-08-26 18:22:31 +0000186 char *name;
187 int letter;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000188 int *variable;
Jari Aaltof73dda02001-11-13 17:56:06 +0000189 setopt_set_func_t *set_func;
190 setopt_get_func_t *get_func;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000191} o_options[] = {
192 { "allexport", 'a', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
193#if defined (BRACE_EXPANSION)
194 { "braceexpand",'B', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000195#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000196#if defined (READLINE)
Jari Aalto7117c2d2002-07-17 14:10:11 +0000197 { "emacs", '\0', (int *)NULL, set_edit_mode, get_edit_mode },
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000198#endif
Jari Aalto7117c2d2002-07-17 14:10:11 +0000199 { "errexit", 'e', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
Jari Aaltob80f6442004-07-27 13:29:18 +0000200 { "errtrace", 'E', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
201 { "functrace", 'T', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
Jari Aalto7117c2d2002-07-17 14:10:11 +0000202 { "hashall", 'h', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
203#if defined (BANG_HISTORY)
204 { "histexpand", 'H', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
205#endif /* BANG_HISTORY */
206#if defined (HISTORY)
Jari Aaltof1be6662008-11-18 13:15:12 +0000207 { "history", '\0', &enable_history_list, bash_set_history, (setopt_get_func_t *)NULL },
Jari Aalto7117c2d2002-07-17 14:10:11 +0000208#endif
209 { "ignoreeof", '\0', &ignoreeof, set_ignoreeof, (setopt_get_func_t *)NULL },
210 { "interactive-comments", '\0', &interactive_comments, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
211 { "keyword", 'k', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
Chet Rameyac50fba2014-02-26 09:36:43 -0500212#if defined (JOB_CONTROL)
Jari Aalto7117c2d2002-07-17 14:10:11 +0000213 { "monitor", 'm', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
Chet Rameyac50fba2014-02-26 09:36:43 -0500214#endif
Jari Aalto7117c2d2002-07-17 14:10:11 +0000215 { "noclobber", 'C', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
216 { "noexec", 'n', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
217 { "noglob", 'f', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
218#if defined (HISTORY)
219 { "nolog", '\0', &dont_save_function_defs, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
220#endif
221#if defined (JOB_CONTROL)
222 { "notify", 'b', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
223#endif /* JOB_CONTROL */
224 { "nounset", 'u', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
225 { "onecmd", 't', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
226 { "physical", 'P', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
Jari Aaltob80f6442004-07-27 13:29:18 +0000227 { "pipefail", '\0', &pipefail_opt, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
Jari Aalto7117c2d2002-07-17 14:10:11 +0000228 { "posix", '\0', &posixly_correct, set_posix_mode, (setopt_get_func_t *)NULL },
229 { "privileged", 'p', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
230 { "verbose", 'v', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
231#if defined (READLINE)
232 { "vi", '\0', (int *)NULL, set_edit_mode, get_edit_mode },
233#endif
234 { "xtrace", 'x', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
235 {(char *)NULL, 0 , (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000236};
237
Jari Aalto7117c2d2002-07-17 14:10:11 +0000238#define N_O_OPTIONS (sizeof (o_options) / sizeof (o_options[0]))
239
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000240#define GET_BINARY_O_OPTION_VALUE(i, name) \
Jari Aalto7117c2d2002-07-17 14:10:11 +0000241 ((o_options[i].get_func) ? (*o_options[i].get_func) (name) \
242 : (*o_options[i].variable))
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000243
244#define SET_BINARY_O_OPTION_VALUE(i, onoff, name) \
Jari Aalto7117c2d2002-07-17 14:10:11 +0000245 ((o_options[i].set_func) ? (*o_options[i].set_func) (onoff, name) \
246 : (*o_options[i].variable = (onoff == FLAG_ON)))
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000247
248int
249minus_o_option_value (name)
250 char *name;
251{
252 register int i;
253 int *on_or_off;
254
255 for (i = 0; o_options[i].name; i++)
256 {
257 if (STREQ (name, o_options[i].name))
258 {
Jari Aalto7117c2d2002-07-17 14:10:11 +0000259 if (o_options[i].letter)
260 {
261 on_or_off = find_flag (o_options[i].letter);
262 return ((on_or_off == FLAG_UNKNOWN) ? -1 : *on_or_off);
263 }
264 else
265 return (GET_BINARY_O_OPTION_VALUE (i, name));
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000266 }
267 }
Jari Aalto28ef6c32001-04-06 19:14:31 +0000268
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000269 return (-1);
270}
271
Jari Aalto726f6381996-08-26 18:22:31 +0000272#define MINUS_O_FORMAT "%-15s\t%s\n"
273
Jari Aaltocce855b1998-04-17 19:52:44 +0000274static void
275print_minus_o_option (name, value, pflag)
276 char *name;
277 int value, pflag;
278{
279 if (pflag == 0)
280 printf (MINUS_O_FORMAT, name, value ? on : off);
281 else
282 printf ("set %co %s\n", value ? '-' : '+', name);
283}
284
Jari Aalto726f6381996-08-26 18:22:31 +0000285void
Jari Aaltocce855b1998-04-17 19:52:44 +0000286list_minus_o_opts (mode, reusable)
287 int mode, reusable;
Jari Aalto726f6381996-08-26 18:22:31 +0000288{
289 register int i;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000290 int *on_or_off, value;
Jari Aalto726f6381996-08-26 18:22:31 +0000291
Jari Aalto7117c2d2002-07-17 14:10:11 +0000292 for (i = 0; o_options[i].name; i++)
Jari Aalto726f6381996-08-26 18:22:31 +0000293 {
Jari Aalto7117c2d2002-07-17 14:10:11 +0000294 if (o_options[i].letter)
295 {
296 value = 0;
297 on_or_off = find_flag (o_options[i].letter);
298 if (on_or_off == FLAG_UNKNOWN)
299 on_or_off = &value;
300 if (mode == -1 || mode == *on_or_off)
301 print_minus_o_option (o_options[i].name, *on_or_off, reusable);
302 }
303 else
304 {
305 value = GET_BINARY_O_OPTION_VALUE (i, o_options[i].name);
306 if (mode == -1 || mode == value)
307 print_minus_o_option (o_options[i].name, value, reusable);
308 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000309 }
310}
311
Jari Aaltobb706242000-03-17 21:46:59 +0000312char **
313get_minus_o_opts ()
314{
315 char **ret;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000316 int i;
Jari Aaltobb706242000-03-17 21:46:59 +0000317
Jari Aalto7117c2d2002-07-17 14:10:11 +0000318 ret = strvec_create (N_O_OPTIONS + 1);
319 for (i = 0; o_options[i].name; i++)
320 ret[i] = o_options[i].name;
321 ret[i] = (char *)NULL;
Jari Aaltobb706242000-03-17 21:46:59 +0000322 return ret;
323}
324
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000325static int
326set_ignoreeof (on_or_off, option_name)
327 int on_or_off;
328 char *option_name;
329{
330 ignoreeof = on_or_off == FLAG_ON;
331 unbind_variable ("ignoreeof");
332 if (ignoreeof)
Jari Aalto95732b42005-12-07 14:08:12 +0000333 bind_variable ("IGNOREEOF", "10", 0);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000334 else
335 unbind_variable ("IGNOREEOF");
336 sv_ignoreeof ("IGNOREEOF");
337 return 0;
338}
339
Jari Aaltod166f041997-06-05 14:59:13 +0000340static int
341set_posix_mode (on_or_off, option_name)
342 int on_or_off;
343 char *option_name;
344{
345 posixly_correct = on_or_off == FLAG_ON;
346 if (posixly_correct == 0)
347 unbind_variable ("POSIXLY_CORRECT");
348 else
Jari Aalto95732b42005-12-07 14:08:12 +0000349 bind_variable ("POSIXLY_CORRECT", "y", 0);
Jari Aaltod166f041997-06-05 14:59:13 +0000350 sv_strict_posix ("POSIXLY_CORRECT");
351 return (0);
352}
353
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000354#if defined (READLINE)
355/* Magic. This code `knows' how readline handles rl_editing_mode. */
356static int
357set_edit_mode (on_or_off, option_name)
358 int on_or_off;
359 char *option_name;
360{
361 int isemacs;
362
363 if (on_or_off == FLAG_ON)
364 {
365 rl_variable_bind ("editing-mode", option_name);
366
367 if (interactive)
368 with_input_from_stdin ();
369 no_line_editing = 0;
370 }
371 else
372 {
373 isemacs = rl_editing_mode == 1;
374 if ((isemacs && *option_name == 'e') || (!isemacs && *option_name == 'v'))
375 {
376 if (interactive)
377 with_input_from_stream (stdin, "stdin");
378 no_line_editing = 1;
379 }
380 }
381 return 1-no_line_editing;
382}
383
384static int
385get_edit_mode (name)
386 char *name;
387{
388 return (*name == 'e' ? no_line_editing == 0 && rl_editing_mode == 1
389 : no_line_editing == 0 && rl_editing_mode == 0);
390}
391#endif /* READLINE */
392
393#if defined (HISTORY)
394static int
395bash_set_history (on_or_off, option_name)
396 int on_or_off;
397 char *option_name;
398{
399 if (on_or_off == FLAG_ON)
400 {
Jari Aaltof1be6662008-11-18 13:15:12 +0000401 enable_history_list = 1;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000402 bash_history_enable ();
403 if (history_lines_this_session == 0)
404 load_history ();
405 }
406 else
Jari Aaltof1be6662008-11-18 13:15:12 +0000407 {
408 enable_history_list = 0;
409 bash_history_disable ();
410 }
411 return (1 - enable_history_list);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000412}
413#endif
414
415int
Jari Aalto726f6381996-08-26 18:22:31 +0000416set_minus_o_option (on_or_off, option_name)
417 int on_or_off;
418 char *option_name;
419{
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000420 register int i;
Jari Aalto726f6381996-08-26 18:22:31 +0000421
Jari Aalto7117c2d2002-07-17 14:10:11 +0000422 for (i = 0; o_options[i].name; i++)
Jari Aalto726f6381996-08-26 18:22:31 +0000423 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000424 if (STREQ (option_name, o_options[i].name))
Jari Aalto28ef6c32001-04-06 19:14:31 +0000425 {
Jari Aalto7117c2d2002-07-17 14:10:11 +0000426 if (o_options[i].letter == 0)
427 {
428 SET_BINARY_O_OPTION_VALUE (i, on_or_off, option_name);
429 return (EXECUTION_SUCCESS);
430 }
431 else
432 {
433 if (change_flag (o_options[i].letter, on_or_off) == FLAG_ERROR)
434 {
435 sh_invalidoptname (option_name);
436 return (EXECUTION_FAILURE);
437 }
438 else
439 return (EXECUTION_SUCCESS);
440 }
441
Jari Aalto28ef6c32001-04-06 19:14:31 +0000442 }
Jari Aalto726f6381996-08-26 18:22:31 +0000443 }
Jari Aalto7117c2d2002-07-17 14:10:11 +0000444
445 sh_invalidoptname (option_name);
Jari Aalto31859422009-01-12 13:36:28 +0000446 return (EX_USAGE);
Jari Aalto726f6381996-08-26 18:22:31 +0000447}
448
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000449static void
450print_all_shell_variables ()
451{
452 SHELL_VAR **vars;
453
454 vars = all_shell_variables ();
455 if (vars)
456 {
457 print_var_list (vars);
458 free (vars);
459 }
460
Jari Aalto28ef6c32001-04-06 19:14:31 +0000461 /* POSIX.2 does not allow function names and definitions to be output when
462 `set' is invoked without options (PASC Interp #202). */
463 if (posixly_correct == 0)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000464 {
Jari Aalto28ef6c32001-04-06 19:14:31 +0000465 vars = all_shell_functions ();
466 if (vars)
467 {
468 print_func_list (vars);
469 free (vars);
470 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000471 }
472}
473
474void
475set_shellopts ()
476{
477 char *value;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000478 char tflag[N_O_OPTIONS];
Jari Aaltocce855b1998-04-17 19:52:44 +0000479 int vsize, i, vptr, *ip, exported;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000480 SHELL_VAR *v;
481
482 for (vsize = i = 0; o_options[i].name; i++)
483 {
Jari Aalto7117c2d2002-07-17 14:10:11 +0000484 tflag[i] = 0;
485 if (o_options[i].letter)
486 {
487 ip = find_flag (o_options[i].letter);
488 if (ip && *ip)
489 {
490 vsize += strlen (o_options[i].name) + 1;
491 tflag[i] = 1;
492 }
493 }
494 else if (GET_BINARY_O_OPTION_VALUE (i, o_options[i].name))
495 {
496 vsize += strlen (o_options[i].name) + 1;
497 tflag[i] = 1;
498 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000499 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000500
Jari Aaltof73dda02001-11-13 17:56:06 +0000501 value = (char *)xmalloc (vsize + 1);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000502
503 for (i = vptr = 0; o_options[i].name; i++)
504 {
Jari Aalto7117c2d2002-07-17 14:10:11 +0000505 if (tflag[i])
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000506 {
507 strcpy (value + vptr, o_options[i].name);
508 vptr += strlen (o_options[i].name);
509 value[vptr++] = ':';
510 }
511 }
Jari Aalto7117c2d2002-07-17 14:10:11 +0000512
Jari Aaltod166f041997-06-05 14:59:13 +0000513 if (vptr)
514 vptr--; /* cut off trailing colon */
515 value[vptr] = '\0';
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000516
517 v = find_variable ("SHELLOPTS");
Jari Aaltocce855b1998-04-17 19:52:44 +0000518
519 /* Turn off the read-only attribute so we can bind the new value, and
520 note whether or not the variable was exported. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000521 if (v)
Jari Aaltocce855b1998-04-17 19:52:44 +0000522 {
Jari Aaltobb706242000-03-17 21:46:59 +0000523 VUNSETATTR (v, att_readonly);
Jari Aaltocce855b1998-04-17 19:52:44 +0000524 exported = exported_p (v);
525 }
526 else
527 exported = 0;
528
Jari Aalto95732b42005-12-07 14:08:12 +0000529 v = bind_variable ("SHELLOPTS", value, 0);
Jari Aaltocce855b1998-04-17 19:52:44 +0000530
531 /* Turn the read-only attribute back on, and turn off the export attribute
532 if it was set implicitly by mark_modified_vars and SHELLOPTS was not
533 exported before we bound the new value. */
Jari Aaltobb706242000-03-17 21:46:59 +0000534 VSETATTR (v, att_readonly);
Jari Aaltocce855b1998-04-17 19:52:44 +0000535 if (mark_modified_vars && exported == 0 && exported_p (v))
Jari Aaltobb706242000-03-17 21:46:59 +0000536 VUNSETATTR (v, att_exported);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000537
538 free (value);
539}
540
541void
542parse_shellopts (value)
543 char *value;
544{
545 char *vname;
546 int vptr;
547
548 vptr = 0;
549 while (vname = extract_colon_unit (value, &vptr))
550 {
551 set_minus_o_option (FLAG_ON, vname);
552 free (vname);
553 }
554}
555
556void
Jari Aaltocce855b1998-04-17 19:52:44 +0000557initialize_shell_options (no_shellopts)
558 int no_shellopts;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000559{
560 char *temp;
Jari Aaltod166f041997-06-05 14:59:13 +0000561 SHELL_VAR *var;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000562
Jari Aaltocce855b1998-04-17 19:52:44 +0000563 if (no_shellopts == 0)
Jari Aaltod166f041997-06-05 14:59:13 +0000564 {
Jari Aaltocce855b1998-04-17 19:52:44 +0000565 var = find_variable ("SHELLOPTS");
566 /* set up any shell options we may have inherited. */
567 if (var && imported_p (var))
Jari Aaltod166f041997-06-05 14:59:13 +0000568 {
Jari Aalto31859422009-01-12 13:36:28 +0000569 temp = (array_p (var) || assoc_p (var)) ? (char *)NULL : savestring (value_cell (var));
Jari Aaltocce855b1998-04-17 19:52:44 +0000570 if (temp)
571 {
572 parse_shellopts (temp);
573 free (temp);
574 }
Jari Aaltod166f041997-06-05 14:59:13 +0000575 }
576 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000577
578 /* Set up the $SHELLOPTS variable. */
579 set_shellopts ();
580}
581
Jari Aalto28ef6c32001-04-06 19:14:31 +0000582/* Reset the values of the -o options that are not also shell flags. This is
583 called from execute_cmd.c:initialize_subshell() when setting up a subshell
584 to run an executable shell script without a leading `#!'. */
Jari Aaltod166f041997-06-05 14:59:13 +0000585void
586reset_shell_options ()
587{
588#if defined (HISTORY)
Jari Aaltof1be6662008-11-18 13:15:12 +0000589 remember_on_history = enable_history_list = 1;
Jari Aaltod166f041997-06-05 14:59:13 +0000590#endif
Jari Aalto28ef6c32001-04-06 19:14:31 +0000591 ignoreeof = 0;
Jari Aaltod166f041997-06-05 14:59:13 +0000592}
593
Jari Aalto726f6381996-08-26 18:22:31 +0000594/* Set some flags from the word values in the input list. If LIST is empty,
595 then print out the values of the variables instead. If LIST contains
596 non-flags, then set $1 - $9 to the successive words of LIST. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000597int
Jari Aalto726f6381996-08-26 18:22:31 +0000598set_builtin (list)
599 WORD_LIST *list;
600{
Jari Aalto31859422009-01-12 13:36:28 +0000601 int on_or_off, flag_name, force_assignment, opts_changed, rv, r;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000602 register char *arg;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000603 char s[3];
Jari Aalto726f6381996-08-26 18:22:31 +0000604
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000605 if (list == 0)
Jari Aalto726f6381996-08-26 18:22:31 +0000606 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000607 print_all_shell_variables ();
Jari Aalto31859422009-01-12 13:36:28 +0000608 return (sh_chkwrite (EXECUTION_SUCCESS));
Jari Aalto726f6381996-08-26 18:22:31 +0000609 }
610
611 /* Check validity of flag arguments. */
Jari Aalto31859422009-01-12 13:36:28 +0000612 rv = EXECUTION_SUCCESS;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000613 reset_internal_getopt ();
614 while ((flag_name = internal_getopt (list, optflags)) != -1)
Jari Aalto726f6381996-08-26 18:22:31 +0000615 {
Jari Aalto7117c2d2002-07-17 14:10:11 +0000616 switch (flag_name)
Jari Aalto726f6381996-08-26 18:22:31 +0000617 {
Jari Aalto7117c2d2002-07-17 14:10:11 +0000618 case '?':
619 builtin_usage ();
620 return (list_optopt == '?' ? EXECUTION_SUCCESS : EX_USAGE);
621 default:
Jari Aalto726f6381996-08-26 18:22:31 +0000622 break;
Jari Aalto726f6381996-08-26 18:22:31 +0000623 }
Jari Aalto726f6381996-08-26 18:22:31 +0000624 }
Jari Aalto7117c2d2002-07-17 14:10:11 +0000625
Jari Aalto726f6381996-08-26 18:22:31 +0000626 /* Do the set command. While the list consists of words starting with
627 '-' or '+' treat them as flags, otherwise, start assigning them to
628 $1 ... $n. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000629 for (force_assignment = opts_changed = 0; list; )
Jari Aalto726f6381996-08-26 18:22:31 +0000630 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000631 arg = list->word->word;
Jari Aalto726f6381996-08-26 18:22:31 +0000632
633 /* If the argument is `--' or `-' then signal the end of the list
634 and remember the remaining arguments. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000635 if (arg[0] == '-' && (!arg[1] || (arg[1] == '-' && !arg[2])))
Jari Aalto726f6381996-08-26 18:22:31 +0000636 {
637 list = list->next;
638
639 /* `set --' unsets the positional parameters. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000640 if (arg[1] == '-')
Jari Aalto726f6381996-08-26 18:22:31 +0000641 force_assignment = 1;
642
643 /* Until told differently, the old shell behaviour of
644 `set - [arg ...]' being equivalent to `set +xv [arg ...]'
645 stands. Posix.2 says the behaviour is marked as obsolescent. */
646 else
647 {
648 change_flag ('x', '+');
649 change_flag ('v', '+');
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000650 opts_changed = 1;
Jari Aalto726f6381996-08-26 18:22:31 +0000651 }
652
653 break;
654 }
655
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000656 if ((on_or_off = *arg) && (on_or_off == '-' || on_or_off == '+'))
Jari Aalto726f6381996-08-26 18:22:31 +0000657 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000658 while (flag_name = *++arg)
Jari Aalto726f6381996-08-26 18:22:31 +0000659 {
660 if (flag_name == '?')
661 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000662 builtin_usage ();
Jari Aalto726f6381996-08-26 18:22:31 +0000663 return (EXECUTION_SUCCESS);
664 }
665 else if (flag_name == 'o') /* -+o option-name */
666 {
667 char *option_name;
668 WORD_LIST *opt;
669
670 opt = list->next;
671
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000672 if (opt == 0)
Jari Aalto726f6381996-08-26 18:22:31 +0000673 {
Jari Aaltocce855b1998-04-17 19:52:44 +0000674 list_minus_o_opts (-1, (on_or_off == '+'));
Jari Aalto31859422009-01-12 13:36:28 +0000675 rv = sh_chkwrite (rv);
Jari Aalto726f6381996-08-26 18:22:31 +0000676 continue;
677 }
678
679 option_name = opt->word->word;
680
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000681 if (option_name == 0 || *option_name == '\0' ||
682 *option_name == '-' || *option_name == '+')
Jari Aalto726f6381996-08-26 18:22:31 +0000683 {
Jari Aaltocce855b1998-04-17 19:52:44 +0000684 list_minus_o_opts (-1, (on_or_off == '+'));
Jari Aalto726f6381996-08-26 18:22:31 +0000685 continue;
686 }
687 list = list->next; /* Skip over option name. */
688
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000689 opts_changed = 1;
Jari Aalto31859422009-01-12 13:36:28 +0000690 if ((r = set_minus_o_option (on_or_off, option_name)) != EXECUTION_SUCCESS)
Jari Aalto726f6381996-08-26 18:22:31 +0000691 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000692 set_shellopts ();
Jari Aalto31859422009-01-12 13:36:28 +0000693 return (r);
Jari Aalto726f6381996-08-26 18:22:31 +0000694 }
695 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000696 else if (change_flag (flag_name, on_or_off) == FLAG_ERROR)
697 {
Jari Aalto7117c2d2002-07-17 14:10:11 +0000698 s[0] = on_or_off;
699 s[1] = flag_name;
700 s[2] = '\0';
701 sh_invalidopt (s);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000702 builtin_usage ();
703 set_shellopts ();
704 return (EXECUTION_FAILURE);
705 }
706 opts_changed = 1;
Jari Aalto726f6381996-08-26 18:22:31 +0000707 }
708 }
709 else
710 {
711 break;
712 }
713 list = list->next;
714 }
715
716 /* Assigning $1 ... $n */
717 if (list || force_assignment)
718 remember_args (list, 1);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000719 /* Set up new value of $SHELLOPTS */
720 if (opts_changed)
721 set_shellopts ();
Jari Aalto31859422009-01-12 13:36:28 +0000722 return (rv);
Jari Aalto726f6381996-08-26 18:22:31 +0000723}
724
725$BUILTIN unset
726$FUNCTION unset_builtin
Chet Rameyac50fba2014-02-26 09:36:43 -0500727$SHORT_DOC unset [-f] [-v] [-n] [name ...]
Jari Aalto31859422009-01-12 13:36:28 +0000728Unset values and attributes of shell variables and functions.
729
730For each NAME, remove the corresponding variable or function.
731
732Options:
733 -f treat each NAME as a shell function
734 -v treat each NAME as a shell variable
Chet Rameyac50fba2014-02-26 09:36:43 -0500735 -n treat each NAME as a name reference and unset the variable itself
736 rather than the variable it references
Jari Aalto31859422009-01-12 13:36:28 +0000737
738Without options, unset first tries to unset a variable, and if that fails,
739tries to unset a function.
740
741Some variables cannot be unset; also see `readonly'.
742
743Exit Status:
744Returns success unless an invalid option is given or a NAME is read-only.
Jari Aalto726f6381996-08-26 18:22:31 +0000745$END
746
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000747#define NEXT_VARIABLE() any_failed++; list = list->next; continue;
748
749int
Jari Aalto726f6381996-08-26 18:22:31 +0000750unset_builtin (list)
751 WORD_LIST *list;
752{
Chet Rameyac50fba2014-02-26 09:36:43 -0500753 int unset_function, unset_variable, unset_array, opt, nameref, any_failed;
Chet Rameybb1e05a2015-05-19 14:55:02 -0400754 int global_unset_func, global_unset_var;
Jari Aalto726f6381996-08-26 18:22:31 +0000755 char *name;
756
Chet Rameyac50fba2014-02-26 09:36:43 -0500757 unset_function = unset_variable = unset_array = nameref = any_failed = 0;
Chet Rameybb1e05a2015-05-19 14:55:02 -0400758 global_unset_func = global_unset_var = 0;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000759
Jari Aalto726f6381996-08-26 18:22:31 +0000760 reset_internal_getopt ();
Chet Rameyac50fba2014-02-26 09:36:43 -0500761 while ((opt = internal_getopt (list, "fnv")) != -1)
Jari Aalto726f6381996-08-26 18:22:31 +0000762 {
763 switch (opt)
764 {
765 case 'f':
Chet Rameybb1e05a2015-05-19 14:55:02 -0400766 global_unset_func = 1;
Jari Aalto726f6381996-08-26 18:22:31 +0000767 break;
768 case 'v':
Chet Rameybb1e05a2015-05-19 14:55:02 -0400769 global_unset_var = 1;
Jari Aalto726f6381996-08-26 18:22:31 +0000770 break;
Chet Rameyac50fba2014-02-26 09:36:43 -0500771 case 'n':
772 nameref = 1;
773 break;
Jari Aalto726f6381996-08-26 18:22:31 +0000774 default:
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000775 builtin_usage ();
776 return (EX_USAGE);
Jari Aalto726f6381996-08-26 18:22:31 +0000777 }
778 }
779
780 list = loptend;
781
Chet Rameybb1e05a2015-05-19 14:55:02 -0400782 if (global_unset_func && global_unset_var)
Jari Aalto726f6381996-08-26 18:22:31 +0000783 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000784 builtin_error (_("cannot simultaneously unset a function and a variable"));
Jari Aalto726f6381996-08-26 18:22:31 +0000785 return (EXECUTION_FAILURE);
786 }
Chet Rameyac50fba2014-02-26 09:36:43 -0500787 else if (unset_function && nameref)
788 nameref = 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000789
790 while (list)
791 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000792 SHELL_VAR *var;
793 int tem;
794#if defined (ARRAY_VARS)
795 char *t;
796#endif
797
Jari Aalto726f6381996-08-26 18:22:31 +0000798 name = list->word->word;
799
Chet Rameybb1e05a2015-05-19 14:55:02 -0400800 unset_function = global_unset_func;
801 unset_variable = global_unset_var;
802
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000803#if defined (ARRAY_VARS)
Jari Aaltof73dda02001-11-13 17:56:06 +0000804 unset_array = 0;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000805 if (!unset_function && valid_array_reference (name))
806 {
807 t = strchr (name, '[');
808 *t++ = '\0';
809 unset_array++;
810 }
811#endif
Chet Rameyac50fba2014-02-26 09:36:43 -0500812 /* Get error checking out of the way first. The low-level functions
813 just perform the unset, relying on the caller to verify. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000814
Jari Aaltocce855b1998-04-17 19:52:44 +0000815 /* Bash allows functions with names which are not valid identifiers
816 to be created when not in posix mode, so check only when in posix
817 mode when unsetting a function. */
818 if (((unset_function && posixly_correct) || !unset_function) && legal_identifier (name) == 0)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000819 {
Jari Aalto7117c2d2002-07-17 14:10:11 +0000820 sh_invalidid (name);
Jari Aalto28ef6c32001-04-06 19:14:31 +0000821 NEXT_VARIABLE ();
822 }
Jari Aaltod166f041997-06-05 14:59:13 +0000823
Chet Rameyac50fba2014-02-26 09:36:43 -0500824 /* Only search for functions here if -f supplied. */
825 var = unset_function ? find_function (name)
826 : (nameref ? find_variable_last_nameref (name) : find_variable (name));
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000827
Chet Rameyac50fba2014-02-26 09:36:43 -0500828 /* Some variables (but not functions yet) cannot be unset, period. */
829 if (var && unset_function == 0 && non_unsettable_p (var))
Jari Aalto726f6381996-08-26 18:22:31 +0000830 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000831 builtin_error (_("%s: cannot unset"), name);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000832 NEXT_VARIABLE ();
833 }
834
Chet Rameyac50fba2014-02-26 09:36:43 -0500835 /* Posix.2 says try variables first, then functions. If we would
836 find a function after unsuccessfully searching for a variable,
837 note that we're acting on a function now as if -f were
838 supplied. The readonly check below takes care of it. */
839 if (var == 0 && unset_variable == 0 && unset_function == 0)
840 {
841 if (var = find_function (name))
842 unset_function = 1;
843 }
844
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000845 /* Posix.2 says that unsetting readonly variables is an error. */
846 if (var && readonly_p (var))
847 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000848 builtin_error (_("%s: cannot unset: readonly %s"),
Chet Rameyac50fba2014-02-26 09:36:43 -0500849 var->name, unset_function ? "function" : "variable");
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000850 NEXT_VARIABLE ();
851 }
852
853 /* Unless the -f option is supplied, the name refers to a variable. */
854#if defined (ARRAY_VARS)
855 if (var && unset_array)
856 {
Jari Aalto31859422009-01-12 13:36:28 +0000857 if (array_p (var) == 0 && assoc_p (var) == 0)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000858 {
Chet Rameyac50fba2014-02-26 09:36:43 -0500859 builtin_error (_("%s: not an array variable"), var->name);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000860 NEXT_VARIABLE ();
861 }
862 else
Jari Aalto7117c2d2002-07-17 14:10:11 +0000863 {
864 tem = unbind_array_element (var, t);
865 if (tem == -1)
866 any_failed++;
867 }
Jari Aalto726f6381996-08-26 18:22:31 +0000868 }
869 else
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000870#endif /* ARRAY_VARS */
Chet Rameyac50fba2014-02-26 09:36:43 -0500871 tem = unset_function ? unbind_func (name) : (nameref ? unbind_nameref (name) : unbind_variable (name));
Jari Aalto726f6381996-08-26 18:22:31 +0000872
Chet Rameyac50fba2014-02-26 09:36:43 -0500873 /* This is what Posix.2 says: ``If neither -f nor -v
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000874 is specified, the name refers to a variable; if a variable by
875 that name does not exist, a function by that name, if any,
876 shall be unset.'' */
Chet Rameyac50fba2014-02-26 09:36:43 -0500877 if (tem == -1 && unset_function == 0 && unset_variable == 0)
Jari Aalto7117c2d2002-07-17 14:10:11 +0000878 tem = unbind_func (name);
Jari Aalto726f6381996-08-26 18:22:31 +0000879
Jari Aalto7117c2d2002-07-17 14:10:11 +0000880 /* SUSv3, POSIX.1-2001 say: ``Unsetting a variable or function that
881 was not previously set shall not be considered an error.'' */
882
883 if (unset_function == 0)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000884 stupidly_hack_special_variables (name);
Jari Aalto726f6381996-08-26 18:22:31 +0000885
Jari Aalto726f6381996-08-26 18:22:31 +0000886 list = list->next;
887 }
888
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000889 return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
Jari Aalto726f6381996-08-26 18:22:31 +0000890}