]> git.ipfire.org Git - thirdparty/bash.git/blame - flags.c
commit bash-20120606 snapshot
[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
012bac39 4/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
726f6388 5
2e4498b3 6 This file is part of GNU Bash, the Bourne Again SHell.
726f6388 7
2e4498b3
CR
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
2e4498b3
CR
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
2e4498b3
CR
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
a5e25162
CR
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/* */
6a8fd0ed 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. */
77638cbf
CR
129# if defined (STRICT_POSIX)
130int history_expansion = 0;
131# else
726f6388 132int history_expansion = 1;
77638cbf 133# endif
726f6388
JA
134#endif /* BANG_HISTORY */
135
136/* Non-zero means that we allow comments to appear in interactive commands. */
726f6388 137int interactive_comments = 1;
726f6388
JA
138
139#if defined (RESTRICTED_SHELL)
140/* Non-zero means that this shell is `restricted'. A restricted shell
141 disallows: changing directories, command or path names containing `/',
142 unsetting or resetting the values of $PATH and $SHELL, and any type of
143 output redirection. */
b72432fd
JA
144int restricted = 0; /* currently restricted */
145int restricted_shell = 0; /* shell was started in restricted mode. */
726f6388
JA
146#endif /* RESTRICTED_SHELL */
147
148/* Non-zero means that this shell is running in `privileged' mode. This
e8ce775d
JA
149 is required if the shell is to run setuid. If the `-p' option is
150 not supplied at startup, and the real and effective uids or gids
151 differ, disable_priv_mode is called to relinquish setuid status. */
726f6388
JA
152int privileged_mode = 0;
153
ccc6cda3
JA
154#if defined (BRACE_EXPANSION)
155/* Zero means to disable brace expansion: foo{a,b} -> fooa foob */
156int brace_expansion = 1;
157#endif
158
d3a24ed2
CR
159/* Non-zero means that shell functions inherit the DEBUG trap. */
160int function_trace_mode = 0;
161
162/* Non-zero means that shell functions inherit the ERR trap. */
163int error_trace_mode = 0;
164
165/* Non-zero means that the rightmost non-zero exit status in a pipeline
166 is the exit status of the entire pipeline. If each processes exits
167 with a 0 status, the status of the pipeline is 0. */
168int pipefail_opt = 0;
169
726f6388
JA
170/* **************************************************************** */
171/* */
172/* The Flags ALIST. */
173/* */
174/* **************************************************************** */
175
d3ad40de 176const struct flags_alist shell_flags[] = {
726f6388
JA
177 /* Standard sh flags. */
178 { 'a', &mark_modified_vars },
179#if defined (JOB_CONTROL)
180 { 'b', &asynchronous_notification },
181#endif /* JOB_CONTROL */
182 { 'e', &exit_immediately_on_error },
183 { 'f', &disallow_filename_globbing },
ccc6cda3 184 { 'h', &hashing_enabled },
726f6388
JA
185 { 'i', &forced_interactive },
186 { 'k', &place_keywords_in_env },
187#if defined (JOB_CONTROL)
188 { 'm', &jobs_m_flag },
189#endif /* JOB_CONTROL */
190 { 'n', &read_but_dont_execute },
191 { 'p', &privileged_mode },
192#if defined (RESTRICTED_SHELL)
193 { 'r', &restricted },
194#endif /* RESTRICTED_SHELL */
195 { 't', &just_one_command },
196 { 'u', &unbound_vars_is_error },
197 { 'v', &echo_input_at_read },
198 { 'x', &echo_command_at_execute },
726f6388
JA
199
200 /* New flags that control non-standard things. */
ccc6cda3 201#if 0
726f6388 202 { 'l', &lexical_scoping },
ccc6cda3 203#endif
ccc6cda3
JA
204#if defined (BRACE_EXPANSION)
205 { 'B', &brace_expansion },
206#endif
d3a24ed2
CR
207 { 'C', &noclobber },
208 { 'E', &error_trace_mode },
726f6388 209#if defined (BANG_HISTORY)
726f6388
JA
210 { 'H', &history_expansion },
211#endif /* BANG_HISTORY */
d3a24ed2
CR
212 { 'I', &no_invisible_vars },
213 { 'P', &no_symbolic_links },
214 { 'T', &function_trace_mode },
726f6388
JA
215 {0, (int *)NULL}
216};
217
218#define NUM_SHELL_FLAGS (sizeof (shell_flags) / sizeof (struct flags_alist))
219
7117c2d2
JA
220char optflags[NUM_SHELL_FLAGS+4] = { '+' };
221
726f6388
JA
222int *
223find_flag (name)
224 int name;
225{
ccc6cda3
JA
226 int i;
227 for (i = 0; shell_flags[i].name; i++)
726f6388
JA
228 {
229 if (shell_flags[i].name == name)
230 return (shell_flags[i].value);
726f6388
JA
231 }
232 return (FLAG_UNKNOWN);
233}
234
235/* Change the state of a flag, and return it's original value, or return
cce855bc
JA
236 FLAG_ERROR if there is no flag FLAG. ON_OR_OFF must be either
237 FLAG_ON or FLAG_OFF. */
726f6388
JA
238int
239change_flag (flag, on_or_off)
240 int flag;
241 int on_or_off;
242{
ccc6cda3
JA
243 int *value, old_value;
244
726f6388
JA
245#if defined (RESTRICTED_SHELL)
246 /* Don't allow "set +r" in a shell which is `restricted'. */
247 if (restricted && flag == 'r' && on_or_off == FLAG_OFF)
248 return (FLAG_ERROR);
249#endif /* RESTRICTED_SHELL */
250
bb70624e
JA
251 value = find_flag (flag);
252
cce855bc 253 if ((value == (int *)FLAG_UNKNOWN) || (on_or_off != FLAG_ON && on_or_off != FLAG_OFF))
726f6388 254 return (FLAG_ERROR);
ccc6cda3
JA
255
256 old_value = *value;
cce855bc 257 *value = (on_or_off == FLAG_ON) ? 1 : 0;
726f6388
JA
258
259 /* Special cases for a few flags. */
260 switch (flag)
261 {
f73dda09
JA
262#if defined (BANG_HISTORY)
263 case 'H':
264 if (on_or_off == FLAG_ON)
265 bash_initialize_history ();
266 break;
267#endif
268
726f6388
JA
269#if defined (JOB_CONTROL)
270 case 'm':
d166f048 271 set_job_control (on_or_off == FLAG_ON);
726f6388
JA
272 break;
273#endif /* JOB_CONTROL */
274
f73dda09
JA
275 case 'n':
276 if (interactive_shell)
277 read_but_dont_execute = 0;
d166f048 278 break;
d166f048 279
726f6388 280 case 'p':
d166f048 281 if (on_or_off == FLAG_OFF)
ccc6cda3 282 disable_priv_mode ();
f73dda09 283 break;
ccc6cda3 284
f73dda09
JA
285#if defined (RESTRICTED_SHELL)
286 case 'r':
a5e25162 287 if (on_or_off == FLAG_ON && shell_initialized)
f73dda09 288 maybe_make_restricted (shell_name);
726f6388 289 break;
f73dda09
JA
290#endif
291
726f6388 292 }
ccc6cda3 293
726f6388
JA
294 return (old_value);
295}
296
297/* Return a string which is the names of all the currently
298 set shell flags. */
299char *
300which_set_flags ()
301{
ccc6cda3
JA
302 char *temp;
303 int i, string_index;
726f6388 304
f73dda09 305 temp = (char *)xmalloc (1 + NUM_SHELL_FLAGS + read_from_stdin + want_pending_command);
ccc6cda3 306 for (i = string_index = 0; shell_flags[i].name; i++)
726f6388
JA
307 if (*(shell_flags[i].value))
308 temp[string_index++] = shell_flags[i].name;
309
bb70624e
JA
310 if (want_pending_command)
311 temp[string_index++] = 'c';
312 if (read_from_stdin)
313 temp[string_index++] = 's';
314
726f6388
JA
315 temp[string_index] = '\0';
316 return (temp);
317}
d166f048
JA
318
319void
320reset_shell_flags ()
321{
322 mark_modified_vars = exit_immediately_on_error = disallow_filename_globbing = 0;
323 place_keywords_in_env = read_but_dont_execute = just_one_command = 0;
324 noclobber = unbound_vars_is_error = echo_input_at_read = 0;
325 echo_command_at_execute = jobs_m_flag = forced_interactive = 0;
d3a24ed2 326 no_symbolic_links = no_invisible_vars = privileged_mode = pipefail_opt = 0;
d166f048
JA
327
328 hashing_enabled = interactive_comments = 1;
329
330#if defined (JOB_CONTROL)
331 asynchronous_notification = 0;
332#endif
333
334#if defined (BANG_HISTORY)
335 history_expansion = 1;
336#endif
337
338#if defined (BRACE_EXPANSION)
339 brace_expansion = 1;
340#endif
341
342#if defined (RESTRICTED_SHELL)
343 restricted = 0;
344#endif
345}
7117c2d2
JA
346
347void
348initialize_flags ()
349{
350 register int i;
351
352 for (i = 0; shell_flags[i].name; i++)
353 optflags[i+1] = shell_flags[i].name;
354 optflags[++i] = 'o';
355 optflags[++i] = ';';
356 optflags[i+1] = '\0';
357}