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