]> git.ipfire.org Git - thirdparty/bash.git/blame - flags.c
Bash-5.0 patch 5: prevent optimizing forks away too aggressively
[thirdparty/bash.git] / flags.c
CommitLineData
726f6388
JA
1/* flags.c -- Everything about flags except the `set' command. That
2 is in builtins.c */
3
a0c0a00f 4/* Copyright (C) 1987-2015 Free Software Foundation, Inc.
726f6388 5
3185942a 6 This file is part of GNU Bash, the Bourne Again SHell.
726f6388 7
3185942a
JA
8 Bash is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
726f6388 12
3185942a
JA
13 Bash is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
726f6388 17
3185942a
JA
18 You should have received a copy of the GNU General Public License
19 along with Bash. If not, see <http://www.gnu.org/licenses/>.
20*/
726f6388 21
ccc6cda3
JA
22#include "config.h"
23#if defined (HAVE_UNISTD_H)
24# include <unistd.h>
25#endif
726f6388
JA
26
27#include "shell.h"
d233b485 28#include "execute_cmd.h"
726f6388
JA
29#include "flags.h"
30
f73dda09
JA
31#if defined (BANG_HISTORY)
32# include "bashhist.h"
33#endif
34
ccc6cda3 35#if defined (JOB_CONTROL)
f73dda09 36extern int set_job_control __P((int));
ccc6cda3
JA
37#endif
38
726f6388
JA
39/* **************************************************************** */
40/* */
3185942a 41/* The Standard sh Flags. */
726f6388
JA
42/* */
43/* **************************************************************** */
44
45/* Non-zero means automatically mark variables which are modified or created
46 as auto export variables. */
47int mark_modified_vars = 0;
48
49/* Non-zero causes asynchronous job notification. Otherwise, job state
50 notification only takes place just before a primary prompt is printed. */
51int asynchronous_notification = 0;
52
53/* Non-zero means exit immediately if a command exits with a non-zero
ac50fbac
CR
54 exit status. The first is what controls set -e; the second is what
55 bash uses internally. */
56int errexit_flag = 0;
726f6388
JA
57int exit_immediately_on_error = 0;
58
59/* Non-zero means disable filename globbing. */
60int disallow_filename_globbing = 0;
61
726f6388
JA
62/* Non-zero means that all keyword arguments are placed into the environment
63 for a command, not just those that appear on the line before the command
64 name. */
65int place_keywords_in_env = 0;
66
ccc6cda3 67/* Non-zero means read commands, but don't execute them. This is useful
726f6388 68 for debugging shell scripts that should do something hairy and possibly
f73dda09 69 destructive. */
726f6388
JA
70int read_but_dont_execute = 0;
71
72/* Non-zero means end of file is after one command. */
73int just_one_command = 0;
74
75/* Non-zero means don't overwrite existing files while doing redirections. */
76int noclobber = 0;
77
78/* Non-zero means trying to get the value of $i where $i is undefined
79 causes an error, instead of a null substitution. */
80int unbound_vars_is_error = 0;
81
82/* Non-zero means type out input lines after you read them. */
83int echo_input_at_read = 0;
a0c0a00f 84int verbose_flag = 0;
726f6388
JA
85
86/* Non-zero means type out the command definition after reading, but
87 before executing. */
88int echo_command_at_execute = 0;
89
90/* Non-zero means turn on the job control features. */
91int jobs_m_flag = 0;
92
93/* Non-zero means this shell is interactive, even if running under a
94 pipe. */
95int forced_interactive = 0;
96
97/* By default, follow the symbolic links as if they were real directories
98 while hacking the `cd' command. This means that `cd ..' moves up in
99 the string of symbolic links that make up the current directory, instead
100 of the absolute directory. The shell variable `nolinks' also controls
101 this flag. */
102int no_symbolic_links = 0;
103
104/* **************************************************************** */
105/* */
106/* Non-Standard Flags Follow Here. */
107/* */
108/* **************************************************************** */
109
ccc6cda3 110#if 0
726f6388
JA
111/* Non-zero means do lexical scoping in the body of a FOR command. */
112int lexical_scoping = 0;
ccc6cda3 113#endif
726f6388
JA
114
115/* Non-zero means no such thing as invisible variables. */
116int no_invisible_vars = 0;
117
ccc6cda3
JA
118/* Non-zero means look up and remember command names in a hash table, */
119int hashing_enabled = 1;
726f6388
JA
120
121#if defined (BANG_HISTORY)
122/* Non-zero means that we are doing history expansion. The default.
123 This means !22 gets the 22nd line of history. */
d233b485
CR
124int history_expansion = HISTEXPAND_DEFAULT;
125int histexp_flag = 0;
726f6388
JA
126#endif /* BANG_HISTORY */
127
128/* Non-zero means that we allow comments to appear in interactive commands. */
726f6388 129int interactive_comments = 1;
726f6388
JA
130
131#if defined (RESTRICTED_SHELL)
132/* Non-zero means that this shell is `restricted'. A restricted shell
133 disallows: changing directories, command or path names containing `/',
134 unsetting or resetting the values of $PATH and $SHELL, and any type of
135 output redirection. */
b72432fd
JA
136int restricted = 0; /* currently restricted */
137int restricted_shell = 0; /* shell was started in restricted mode. */
726f6388
JA
138#endif /* RESTRICTED_SHELL */
139
140/* Non-zero means that this shell is running in `privileged' mode. This
e8ce775d
JA
141 is required if the shell is to run setuid. If the `-p' option is
142 not supplied at startup, and the real and effective uids or gids
143 differ, disable_priv_mode is called to relinquish setuid status. */
726f6388
JA
144int privileged_mode = 0;
145
ccc6cda3
JA
146#if defined (BRACE_EXPANSION)
147/* Zero means to disable brace expansion: foo{a,b} -> fooa foob */
148int brace_expansion = 1;
149#endif
150
b80f6443
JA
151/* Non-zero means that shell functions inherit the DEBUG trap. */
152int function_trace_mode = 0;
153
154/* Non-zero means that shell functions inherit the ERR trap. */
155int error_trace_mode = 0;
156
157/* Non-zero means that the rightmost non-zero exit status in a pipeline
158 is the exit status of the entire pipeline. If each processes exits
159 with a 0 status, the status of the pipeline is 0. */
160int pipefail_opt = 0;
161
726f6388
JA
162/* **************************************************************** */
163/* */
164/* The Flags ALIST. */
165/* */
166/* **************************************************************** */
167
3185942a 168const struct flags_alist shell_flags[] = {
726f6388
JA
169 /* Standard sh flags. */
170 { 'a', &mark_modified_vars },
171#if defined (JOB_CONTROL)
172 { 'b', &asynchronous_notification },
173#endif /* JOB_CONTROL */
ac50fbac 174 { 'e', &errexit_flag },
726f6388 175 { 'f', &disallow_filename_globbing },
ccc6cda3 176 { 'h', &hashing_enabled },
726f6388
JA
177 { 'i', &forced_interactive },
178 { 'k', &place_keywords_in_env },
179#if defined (JOB_CONTROL)
180 { 'm', &jobs_m_flag },
181#endif /* JOB_CONTROL */
182 { 'n', &read_but_dont_execute },
183 { 'p', &privileged_mode },
184#if defined (RESTRICTED_SHELL)
185 { 'r', &restricted },
186#endif /* RESTRICTED_SHELL */
187 { 't', &just_one_command },
188 { 'u', &unbound_vars_is_error },
a0c0a00f 189 { 'v', &verbose_flag },
726f6388 190 { 'x', &echo_command_at_execute },
726f6388
JA
191
192 /* New flags that control non-standard things. */
ccc6cda3 193#if 0
726f6388 194 { 'l', &lexical_scoping },
ccc6cda3 195#endif
ccc6cda3
JA
196#if defined (BRACE_EXPANSION)
197 { 'B', &brace_expansion },
198#endif
b80f6443
JA
199 { 'C', &noclobber },
200 { 'E', &error_trace_mode },
726f6388 201#if defined (BANG_HISTORY)
d233b485 202 { 'H', &histexp_flag },
726f6388 203#endif /* BANG_HISTORY */
b80f6443
JA
204 { 'I', &no_invisible_vars },
205 { 'P', &no_symbolic_links },
206 { 'T', &function_trace_mode },
726f6388
JA
207 {0, (int *)NULL}
208};
209
210#define NUM_SHELL_FLAGS (sizeof (shell_flags) / sizeof (struct flags_alist))
211
7117c2d2
JA
212char optflags[NUM_SHELL_FLAGS+4] = { '+' };
213
726f6388
JA
214int *
215find_flag (name)
216 int name;
217{
ccc6cda3
JA
218 int i;
219 for (i = 0; shell_flags[i].name; i++)
726f6388
JA
220 {
221 if (shell_flags[i].name == name)
222 return (shell_flags[i].value);
726f6388
JA
223 }
224 return (FLAG_UNKNOWN);
225}
226
227/* Change the state of a flag, and return it's original value, or return
cce855bc
JA
228 FLAG_ERROR if there is no flag FLAG. ON_OR_OFF must be either
229 FLAG_ON or FLAG_OFF. */
726f6388
JA
230int
231change_flag (flag, on_or_off)
232 int flag;
233 int on_or_off;
234{
ccc6cda3
JA
235 int *value, old_value;
236
726f6388
JA
237#if defined (RESTRICTED_SHELL)
238 /* Don't allow "set +r" in a shell which is `restricted'. */
239 if (restricted && flag == 'r' && on_or_off == FLAG_OFF)
240 return (FLAG_ERROR);
241#endif /* RESTRICTED_SHELL */
242
bb70624e
JA
243 value = find_flag (flag);
244
cce855bc 245 if ((value == (int *)FLAG_UNKNOWN) || (on_or_off != FLAG_ON && on_or_off != FLAG_OFF))
726f6388 246 return (FLAG_ERROR);
ccc6cda3
JA
247
248 old_value = *value;
cce855bc 249 *value = (on_or_off == FLAG_ON) ? 1 : 0;
726f6388
JA
250
251 /* Special cases for a few flags. */
252 switch (flag)
253 {
f73dda09
JA
254#if defined (BANG_HISTORY)
255 case 'H':
d233b485 256 history_expansion = histexp_flag;
f73dda09
JA
257 if (on_or_off == FLAG_ON)
258 bash_initialize_history ();
259 break;
260#endif
261
726f6388
JA
262#if defined (JOB_CONTROL)
263 case 'm':
d166f048 264 set_job_control (on_or_off == FLAG_ON);
726f6388
JA
265 break;
266#endif /* JOB_CONTROL */
267
ac50fbac
CR
268 case 'e':
269 if (builtin_ignoring_errexit == 0)
270 exit_immediately_on_error = errexit_flag;
271 break;
272
f73dda09
JA
273 case 'n':
274 if (interactive_shell)
275 read_but_dont_execute = 0;
d166f048 276 break;
d166f048 277
726f6388 278 case 'p':
d166f048 279 if (on_or_off == FLAG_OFF)
ccc6cda3 280 disable_priv_mode ();
f73dda09 281 break;
ccc6cda3 282
f73dda09
JA
283#if defined (RESTRICTED_SHELL)
284 case 'r':
b80f6443 285 if (on_or_off == FLAG_ON && shell_initialized)
f73dda09 286 maybe_make_restricted (shell_name);
726f6388 287 break;
f73dda09
JA
288#endif
289
a0c0a00f
CR
290 case 'v':
291 echo_input_at_read = verbose_flag;
292 break;
726f6388 293 }
ccc6cda3 294
726f6388
JA
295 return (old_value);
296}
297
298/* Return a string which is the names of all the currently
299 set shell flags. */
300char *
301which_set_flags ()
302{
ccc6cda3
JA
303 char *temp;
304 int i, string_index;
726f6388 305
f73dda09 306 temp = (char *)xmalloc (1 + NUM_SHELL_FLAGS + read_from_stdin + want_pending_command);
ccc6cda3 307 for (i = string_index = 0; shell_flags[i].name; i++)
726f6388
JA
308 if (*(shell_flags[i].value))
309 temp[string_index++] = shell_flags[i].name;
310
bb70624e
JA
311 if (want_pending_command)
312 temp[string_index++] = 'c';
313 if (read_from_stdin)
314 temp[string_index++] = 's';
315
726f6388
JA
316 temp[string_index] = '\0';
317 return (temp);
318}
d166f048 319
a0c0a00f
CR
320char *
321get_current_flags ()
322{
323 char *temp;
324 int i;
325
326 temp = (char *)xmalloc (1 + NUM_SHELL_FLAGS);
327 for (i = 0; shell_flags[i].name; i++)
328 temp[i] = *(shell_flags[i].value);
329 temp[i] = '\0';
330 return (temp);
331}
332
333void
334set_current_flags (bitmap)
335 const char *bitmap;
336{
337 int i;
338
339 if (bitmap == 0)
340 return;
341 for (i = 0; shell_flags[i].name; i++)
342 *(shell_flags[i].value) = bitmap[i];
343}
344
d166f048
JA
345void
346reset_shell_flags ()
347{
a0c0a00f 348 mark_modified_vars = disallow_filename_globbing = 0;
d166f048 349 place_keywords_in_env = read_but_dont_execute = just_one_command = 0;
a0c0a00f 350 noclobber = unbound_vars_is_error = 0;
d166f048 351 echo_command_at_execute = jobs_m_flag = forced_interactive = 0;
a0c0a00f
CR
352 no_symbolic_links = no_invisible_vars = 0;
353 privileged_mode = pipefail_opt = 0;
354
355 error_trace_mode = function_trace_mode = 0;
356
357 exit_immediately_on_error = errexit_flag = 0;
358 echo_input_at_read = verbose_flag = 0;
d166f048
JA
359
360 hashing_enabled = interactive_comments = 1;
361
362#if defined (JOB_CONTROL)
363 asynchronous_notification = 0;
364#endif
365
366#if defined (BANG_HISTORY)
a0c0a00f
CR
367# if defined (STRICT_POSIX)
368 history_expansion = 0;
369# else
d166f048 370 history_expansion = 1;
a0c0a00f 371# endif /* STRICT_POSIX */
d166f048
JA
372#endif
373
374#if defined (BRACE_EXPANSION)
375 brace_expansion = 1;
376#endif
377
378#if defined (RESTRICTED_SHELL)
379 restricted = 0;
380#endif
381}
7117c2d2
JA
382
383void
384initialize_flags ()
385{
386 register int i;
387
388 for (i = 0; shell_flags[i].name; i++)
389 optflags[i+1] = shell_flags[i].name;
390 optflags[++i] = 'o';
391 optflags[++i] = ';';
392 optflags[i+1] = '\0';
393}