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