Line data Source code
1 : This file is shopt.def, from which is created shopt.c.
2 : It implements the Bash `shopt' builtin.
3 :
4 : Copyright (C) 1994-2016 Free Software Foundation, Inc.
5 :
6 : This file is part of GNU Bash, the Bourne Again SHell.
7 :
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.
12 :
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.
17 :
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 :
21 : $PRODUCES shopt.c
22 :
23 : $BUILTIN shopt
24 : $FUNCTION shopt_builtin
25 : $SHORT_DOC shopt [-pqsu] [-o] [optname ...]
26 : Set and unset shell options.
27 :
28 : Change the setting of each shell option OPTNAME. Without any option
29 : arguments, list all shell options with an indication of whether or not each
30 : is set.
31 :
32 : Options:
33 : -o restrict OPTNAMEs to those defined for use with `set -o'
34 : -p print each shell option with an indication of its status
35 : -q suppress output
36 : -s enable (set) each OPTNAME
37 : -u disable (unset) each OPTNAME
38 :
39 : Exit Status:
40 : Returns success if OPTNAME is enabled; fails if an invalid option is
41 : given or OPTNAME is disabled.
42 : $END
43 :
44 : #include <config.h>
45 :
46 : #if defined (HAVE_UNISTD_H)
47 : # ifdef _MINIX
48 : # include <sys/types.h>
49 : # endif
50 : # include <unistd.h>
51 : #endif
52 :
53 : #include <stdio.h>
54 :
55 : #include "version.h"
56 :
57 : #include "../bashintl.h"
58 :
59 : #include "../shell.h"
60 : #include "../flags.h"
61 : #include "common.h"
62 : #include "bashgetopt.h"
63 :
64 : #if defined (READLINE)
65 : # include "../bashline.h"
66 : #endif
67 :
68 : #if defined (HISTORY)
69 : # include "../bashhist.h"
70 : #endif
71 :
72 : #define UNSETOPT 0
73 : #define SETOPT 1
74 :
75 : #define OPTFMT "%-15s\t%s\n"
76 :
77 : extern int allow_null_glob_expansion, fail_glob_expansion, glob_dot_filenames;
78 : extern int cdable_vars, mail_warning, source_uses_path;
79 : extern int no_exit_on_failed_exec, print_shift_error;
80 : extern int check_hashed_filenames, promptvars;
81 : extern int cdspelling, expand_aliases;
82 : extern int extended_quote;
83 : extern int check_window_size;
84 : extern int glob_ignore_case, match_ignore_case;
85 : extern int hup_on_exit;
86 : extern int xpg_echo;
87 : extern int gnu_error_format;
88 : extern int check_jobs_at_exit;
89 : extern int autocd;
90 : extern int glob_star;
91 : extern int glob_asciirange;
92 : extern int lastpipe_opt;
93 : extern int inherit_errexit;
94 :
95 : #if defined (EXTENDED_GLOB)
96 : extern int extended_glob;
97 : #endif
98 :
99 : #if defined (READLINE)
100 : extern int hist_verify, history_reediting, perform_hostname_completion;
101 : extern int no_empty_command_completion;
102 : extern int force_fignore;
103 : extern int dircomplete_spelling, dircomplete_expand;
104 : extern int complete_fullquote;
105 :
106 : extern int enable_hostname_completion __P((int));
107 : static int shopt_enable_hostname_completion __P((char *, int));
108 : #endif
109 :
110 : #if defined (PROGRAMMABLE_COMPLETION)
111 : extern int prog_completion_enabled;
112 : #endif
113 :
114 : #if defined (RESTRICTED_SHELL)
115 : extern char *shell_name;
116 : #endif
117 :
118 : #if defined (DEBUGGER)
119 : extern int debugging_mode;
120 : #endif
121 :
122 : static void shopt_error __P((char *));
123 :
124 : static int set_shellopts_after_change __P((char *, int));
125 : static int set_compatibility_level __P((char *, int));
126 :
127 : #if defined (RESTRICTED_SHELL)
128 : static int set_restricted_shell __P((char *, int));
129 : #endif
130 :
131 : #if defined (READLINE)
132 : static int shopt_set_complete_direxpand __P((char *, int));
133 : #endif
134 :
135 : static int shopt_set_debug_mode __P((char *, int));
136 :
137 : static int shopt_login_shell;
138 : static int shopt_compat31;
139 : static int shopt_compat32;
140 : static int shopt_compat40;
141 : static int shopt_compat41;
142 : static int shopt_compat42;
143 : static int shopt_compat43;
144 :
145 : typedef int shopt_set_func_t __P((char *, int));
146 :
147 : /* If you add a new variable name here, make sure to set the default value
148 : appropriately in reset_shopt_options. */
149 :
150 : static struct {
151 : char *name;
152 : int *value;
153 : shopt_set_func_t *set_func;
154 : } shopt_vars[] = {
155 : { "autocd", &autocd, (shopt_set_func_t *)NULL },
156 : { "cdable_vars", &cdable_vars, (shopt_set_func_t *)NULL },
157 : { "cdspell", &cdspelling, (shopt_set_func_t *)NULL },
158 : { "checkhash", &check_hashed_filenames, (shopt_set_func_t *)NULL },
159 : #if defined (JOB_CONTROL)
160 : { "checkjobs", &check_jobs_at_exit, (shopt_set_func_t *)NULL },
161 : #endif
162 : { "checkwinsize", &check_window_size, (shopt_set_func_t *)NULL },
163 : #if defined (HISTORY)
164 : { "cmdhist", &command_oriented_history, (shopt_set_func_t *)NULL },
165 : #endif
166 : { "compat31", &shopt_compat31, set_compatibility_level },
167 : { "compat32", &shopt_compat32, set_compatibility_level },
168 : { "compat40", &shopt_compat40, set_compatibility_level },
169 : { "compat41", &shopt_compat41, set_compatibility_level },
170 : { "compat42", &shopt_compat42, set_compatibility_level },
171 : { "compat43", &shopt_compat43, set_compatibility_level },
172 : #if defined (READLINE)
173 : { "complete_fullquote", &complete_fullquote, (shopt_set_func_t *)NULL},
174 : { "direxpand", &dircomplete_expand, shopt_set_complete_direxpand },
175 : { "dirspell", &dircomplete_spelling, (shopt_set_func_t *)NULL },
176 : #endif
177 : { "dotglob", &glob_dot_filenames, (shopt_set_func_t *)NULL },
178 : { "execfail", &no_exit_on_failed_exec, (shopt_set_func_t *)NULL },
179 : { "expand_aliases", &expand_aliases, (shopt_set_func_t *)NULL },
180 : #if defined (DEBUGGER)
181 : { "extdebug", &debugging_mode, shopt_set_debug_mode },
182 : #endif
183 : #if defined (EXTENDED_GLOB)
184 : { "extglob", &extended_glob, (shopt_set_func_t *)NULL },
185 : #endif
186 : { "extquote", &extended_quote, (shopt_set_func_t *)NULL },
187 : { "failglob", &fail_glob_expansion, (shopt_set_func_t *)NULL },
188 : #if defined (READLINE)
189 : { "force_fignore", &force_fignore, (shopt_set_func_t *)NULL },
190 : #endif
191 : { "globasciiranges", &glob_asciirange, (shopt_set_func_t *)NULL },
192 : { "globstar", &glob_star, (shopt_set_func_t *)NULL },
193 : { "gnu_errfmt", &gnu_error_format, (shopt_set_func_t *)NULL },
194 : #if defined (HISTORY)
195 : { "histappend", &force_append_history, (shopt_set_func_t *)NULL },
196 : #endif
197 : #if defined (READLINE)
198 : { "histreedit", &history_reediting, (shopt_set_func_t *)NULL },
199 : { "histverify", &hist_verify, (shopt_set_func_t *)NULL },
200 : { "hostcomplete", &perform_hostname_completion, shopt_enable_hostname_completion },
201 : #endif
202 : { "huponexit", &hup_on_exit, (shopt_set_func_t *)NULL },
203 : { "inherit_errexit", &inherit_errexit, (shopt_set_func_t *)NULL },
204 : { "interactive_comments", &interactive_comments, set_shellopts_after_change },
205 : { "lastpipe", &lastpipe_opt, (shopt_set_func_t *)NULL },
206 : #if defined (HISTORY)
207 : { "lithist", &literal_history, (shopt_set_func_t *)NULL },
208 : #endif
209 : { "login_shell", &shopt_login_shell, set_login_shell },
210 : { "mailwarn", &mail_warning, (shopt_set_func_t *)NULL },
211 : #if defined (READLINE)
212 : { "no_empty_cmd_completion", &no_empty_command_completion, (shopt_set_func_t *)NULL },
213 : #endif
214 : { "nocaseglob", &glob_ignore_case, (shopt_set_func_t *)NULL },
215 : { "nocasematch", &match_ignore_case, (shopt_set_func_t *)NULL },
216 : { "nullglob", &allow_null_glob_expansion, (shopt_set_func_t *)NULL },
217 : #if defined (PROGRAMMABLE_COMPLETION)
218 : { "progcomp", &prog_completion_enabled, (shopt_set_func_t *)NULL },
219 : #endif
220 : { "promptvars", &promptvars, (shopt_set_func_t *)NULL },
221 : #if defined (RESTRICTED_SHELL)
222 : { "restricted_shell", &restricted_shell, set_restricted_shell },
223 : #endif
224 : { "shift_verbose", &print_shift_error, (shopt_set_func_t *)NULL },
225 : { "sourcepath", &source_uses_path, (shopt_set_func_t *)NULL },
226 : { "xpg_echo", &xpg_echo, (shopt_set_func_t *)NULL },
227 : { (char *)0, (int *)0, (shopt_set_func_t *)NULL }
228 : };
229 :
230 : #define N_SHOPT_OPTIONS (sizeof (shopt_vars) / sizeof (shopt_vars[0]))
231 :
232 : #define GET_SHOPT_OPTION_VALUE(i) (*shopt_vars[i].value)
233 :
234 : static const char * const on = "on";
235 : static const char * const off = "off";
236 :
237 : static int find_shopt __P((char *));
238 : static int toggle_shopts __P((int, WORD_LIST *, int));
239 : static void print_shopt __P((char *, int, int));
240 : static int list_shopts __P((WORD_LIST *, int));
241 : static int list_some_shopts __P((int, int));
242 : static int list_shopt_o_options __P((WORD_LIST *, int));
243 : static int list_some_o_options __P((int, int));
244 : static int set_shopt_o_options __P((int, WORD_LIST *, int));
245 :
246 : #define SFLAG 0x01
247 : #define UFLAG 0x02
248 : #define QFLAG 0x04
249 : #define OFLAG 0x08
250 : #define PFLAG 0x10
251 :
252 : int
253 0 : shopt_builtin (list)
254 : WORD_LIST *list;
255 : {
256 0 : int opt, flags, rval;
257 :
258 0 : flags = 0;
259 0 : reset_internal_getopt ();
260 0 : while ((opt = internal_getopt (list, "psuoq")) != -1)
261 : {
262 0 : switch (opt)
263 : {
264 0 : case 's':
265 0 : flags |= SFLAG;
266 0 : break;
267 0 : case 'u':
268 0 : flags |= UFLAG;
269 0 : break;
270 0 : case 'q':
271 0 : flags |= QFLAG;
272 0 : break;
273 0 : case 'o':
274 0 : flags |= OFLAG;
275 0 : break;
276 0 : case 'p':
277 0 : flags |= PFLAG;
278 0 : break;
279 0 : CASE_HELPOPT;
280 0 : default:
281 0 : builtin_usage ();
282 0 : return (EX_USAGE);
283 : }
284 : }
285 0 : list = loptend;
286 :
287 0 : if ((flags & (SFLAG|UFLAG)) == (SFLAG|UFLAG))
288 : {
289 0 : builtin_error (_("cannot set and unset shell options simultaneously"));
290 0 : return (EXECUTION_FAILURE);
291 : }
292 :
293 0 : rval = EXECUTION_SUCCESS;
294 0 : if ((flags & OFLAG) && ((flags & (SFLAG|UFLAG)) == 0)) /* shopt -o */
295 0 : rval = list_shopt_o_options (list, flags);
296 0 : else if (list && (flags & OFLAG)) /* shopt -so args */
297 0 : rval = set_shopt_o_options ((flags & SFLAG) ? FLAG_ON : FLAG_OFF, list, flags & QFLAG);
298 0 : else if (flags & OFLAG) /* shopt -so */
299 0 : rval = list_some_o_options ((flags & SFLAG) ? 1 : 0, flags);
300 0 : else if (list && (flags & (SFLAG|UFLAG))) /* shopt -su args */
301 0 : rval = toggle_shopts ((flags & SFLAG) ? SETOPT : UNSETOPT, list, flags & QFLAG);
302 0 : else if ((flags & (SFLAG|UFLAG)) == 0) /* shopt [args] */
303 0 : rval = list_shopts (list, flags);
304 : else /* shopt -su */
305 0 : rval = list_some_shopts ((flags & SFLAG) ? SETOPT : UNSETOPT, flags);
306 : return (rval);
307 : }
308 :
309 : /* Reset the options managed by `shopt' to the values they would have at
310 : shell startup. Variables from shopt_vars. */
311 : void
312 9 : reset_shopt_options ()
313 : {
314 9 : autocd = cdable_vars = cdspelling = 0;
315 9 : check_hashed_filenames = CHECKHASH_DEFAULT;
316 9 : check_window_size = CHECKWINSIZE_DEFAULT;
317 9 : allow_null_glob_expansion = glob_dot_filenames = 0;
318 9 : no_exit_on_failed_exec = 0;
319 9 : expand_aliases = 0;
320 9 : extended_quote = 1;
321 9 : fail_glob_expansion = 0;
322 9 : glob_asciirange = GLOBASCII_DEFAULT;
323 9 : glob_star = 0;
324 9 : gnu_error_format = 0;
325 9 : hup_on_exit = 0;
326 9 : inherit_errexit = 0;
327 9 : interactive_comments = 1;
328 9 : lastpipe_opt = 0;
329 9 : mail_warning = 0;
330 9 : glob_ignore_case = match_ignore_case = 0;
331 9 : print_shift_error = 0;
332 9 : source_uses_path = promptvars = 1;
333 :
334 : #if defined (JOB_CONTROL)
335 9 : check_jobs_at_exit = 0;
336 : #endif
337 :
338 : #if defined (EXTENDED_GLOB)
339 9 : extended_glob = EXTGLOB_DEFAULT;
340 : #endif
341 :
342 : #if defined (HISTORY)
343 9 : literal_history = 0;
344 9 : force_append_history = 0;
345 9 : command_oriented_history = 1;
346 : #endif
347 :
348 : #if defined (READLINE)
349 9 : complete_fullquote = 1;
350 9 : force_fignore = 1;
351 9 : hist_verify = history_reediting = 0;
352 9 : perform_hostname_completion = 1;
353 : # if DIRCOMPLETE_EXPAND_DEFAULT
354 : dircomplete_expand = 1;
355 : # else
356 9 : dircomplete_expand = 0;
357 : #endif
358 9 : dircomplete_spelling = 0;
359 9 : no_empty_command_completion = 0;
360 : #endif
361 :
362 : #if defined (PROGRAMMABLE_COMPLETION)
363 9 : prog_completion_enabled = 1;
364 : #endif
365 :
366 : #if defined (DEFAULT_ECHO_TO_XPG) || defined (STRICT_POSIX)
367 : xpg_echo = 1;
368 : #else
369 9 : xpg_echo = 0;
370 : #endif /* DEFAULT_ECHO_TO_XPG */
371 :
372 9 : shopt_login_shell = login_shell;
373 9 : }
374 :
375 : static int
376 0 : find_shopt (name)
377 : char *name;
378 : {
379 0 : int i;
380 :
381 0 : for (i = 0; shopt_vars[i].name; i++)
382 0 : if (STREQ (name, shopt_vars[i].name))
383 0 : return i;
384 : return -1;
385 : }
386 :
387 : static void
388 0 : shopt_error (s)
389 : char *s;
390 : {
391 0 : builtin_error (_("%s: invalid shell option name"), s);
392 0 : }
393 :
394 : static int
395 0 : toggle_shopts (mode, list, quiet)
396 : int mode;
397 : WORD_LIST *list;
398 : int quiet;
399 : {
400 0 : WORD_LIST *l;
401 0 : int ind, rval;
402 0 : SHELL_VAR *v;
403 :
404 0 : for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
405 : {
406 0 : ind = find_shopt (l->word->word);
407 0 : if (ind < 0)
408 : {
409 0 : shopt_error (l->word->word);
410 0 : rval = EXECUTION_FAILURE;
411 : }
412 : else
413 : {
414 0 : *shopt_vars[ind].value = mode; /* 1 for set, 0 for unset */
415 0 : if (shopt_vars[ind].set_func)
416 0 : (*shopt_vars[ind].set_func) (shopt_vars[ind].name, mode);
417 : }
418 : }
419 :
420 : /* Don't set $BASHOPTS here if it hasn't already been initialized */
421 0 : if (v = find_variable ("BASHOPTS"))
422 0 : set_bashopts ();
423 0 : return (rval);
424 : }
425 :
426 : static void
427 0 : print_shopt (name, val, flags)
428 : char *name;
429 : int val, flags;
430 : {
431 0 : if (flags & PFLAG)
432 0 : printf ("shopt %s %s\n", val ? "-s" : "-u", name);
433 : else
434 0 : printf (OPTFMT, name, val ? on : off);
435 0 : }
436 :
437 : /* List the values of all or any of the `shopt' options. Returns 0 if
438 : all were listed or all variables queried were on; 1 otherwise. */
439 : static int
440 0 : list_shopts (list, flags)
441 : WORD_LIST *list;
442 : int flags;
443 : {
444 0 : WORD_LIST *l;
445 0 : int i, val, rval;
446 :
447 0 : if (list == 0)
448 : {
449 0 : for (i = 0; shopt_vars[i].name; i++)
450 : {
451 0 : val = *shopt_vars[i].value;
452 0 : if ((flags & QFLAG) == 0)
453 0 : print_shopt (shopt_vars[i].name, val, flags);
454 : }
455 0 : return (sh_chkwrite (EXECUTION_SUCCESS));
456 : }
457 :
458 0 : for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
459 : {
460 0 : i = find_shopt (l->word->word);
461 0 : if (i < 0)
462 : {
463 0 : shopt_error (l->word->word);
464 0 : rval = EXECUTION_FAILURE;
465 0 : continue;
466 : }
467 0 : val = *shopt_vars[i].value;
468 0 : if (val == 0)
469 0 : rval = EXECUTION_FAILURE;
470 0 : if ((flags & QFLAG) == 0)
471 0 : print_shopt (l->word->word, val, flags);
472 : }
473 :
474 0 : return (sh_chkwrite (rval));
475 : }
476 :
477 : static int
478 0 : list_some_shopts (mode, flags)
479 : int mode, flags;
480 : {
481 0 : int val, i;
482 :
483 0 : for (i = 0; shopt_vars[i].name; i++)
484 : {
485 0 : val = *shopt_vars[i].value;
486 0 : if (((flags & QFLAG) == 0) && mode == val)
487 0 : print_shopt (shopt_vars[i].name, val, flags);
488 : }
489 0 : return (sh_chkwrite (EXECUTION_SUCCESS));
490 : }
491 :
492 : static int
493 0 : list_shopt_o_options (list, flags)
494 : WORD_LIST *list;
495 : int flags;
496 : {
497 0 : WORD_LIST *l;
498 0 : int val, rval;
499 :
500 0 : if (list == 0)
501 : {
502 0 : if ((flags & QFLAG) == 0)
503 0 : list_minus_o_opts (-1, (flags & PFLAG));
504 0 : return (sh_chkwrite (EXECUTION_SUCCESS));
505 : }
506 :
507 0 : for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
508 : {
509 0 : val = minus_o_option_value (l->word->word);
510 0 : if (val == -1)
511 : {
512 0 : sh_invalidoptname (l->word->word);
513 0 : rval = EXECUTION_FAILURE;
514 0 : continue;
515 : }
516 0 : if (val == 0)
517 0 : rval = EXECUTION_FAILURE;
518 0 : if ((flags & QFLAG) == 0)
519 : {
520 0 : if (flags & PFLAG)
521 0 : printf ("set %co %s\n", val ? '-' : '+', l->word->word);
522 : else
523 0 : printf (OPTFMT, l->word->word, val ? on : off);
524 : }
525 : }
526 0 : return (sh_chkwrite (rval));
527 : }
528 :
529 : static int
530 0 : list_some_o_options (mode, flags)
531 : int mode, flags;
532 : {
533 0 : if ((flags & QFLAG) == 0)
534 0 : list_minus_o_opts (mode, (flags & PFLAG));
535 0 : return (sh_chkwrite (EXECUTION_SUCCESS));
536 : }
537 :
538 : static int
539 0 : set_shopt_o_options (mode, list, quiet)
540 : int mode;
541 : WORD_LIST *list;
542 : int quiet;
543 : {
544 0 : WORD_LIST *l;
545 0 : int rval;
546 :
547 0 : for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
548 : {
549 0 : if (set_minus_o_option (mode, l->word->word) == EXECUTION_FAILURE)
550 0 : rval = EXECUTION_FAILURE;
551 : }
552 0 : set_shellopts ();
553 0 : return rval;
554 : }
555 :
556 : /* If we set or unset interactive_comments with shopt, make sure the
557 : change is reflected in $SHELLOPTS. */
558 : static int
559 0 : set_shellopts_after_change (option_name, mode)
560 : char *option_name;
561 : int mode;
562 : {
563 0 : set_shellopts ();
564 0 : return (0);
565 : }
566 :
567 : static int
568 0 : shopt_set_debug_mode (option_name, mode)
569 : char *option_name;
570 : int mode;
571 : {
572 : #if defined (DEBUGGER)
573 0 : error_trace_mode = function_trace_mode = debugging_mode;
574 0 : set_shellopts ();
575 : #endif
576 0 : return (0);
577 : }
578 :
579 : #if defined (READLINE)
580 : static int
581 0 : shopt_enable_hostname_completion (option_name, mode)
582 : char *option_name;
583 : int mode;
584 : {
585 0 : return (enable_hostname_completion (mode));
586 : }
587 : #endif
588 :
589 : static int
590 0 : set_compatibility_level (option_name, mode)
591 : char *option_name;
592 : int mode;
593 : {
594 0 : int ind;
595 :
596 : /* If we're setting something, redo some of the work we did above in
597 : toggle_shopt(). Unset everything and reset the appropriate option
598 : based on OPTION_NAME. */
599 0 : if (mode)
600 : {
601 0 : shopt_compat31 = shopt_compat32 = 0;
602 0 : shopt_compat40 = shopt_compat41 = shopt_compat42 = shopt_compat43 = 0;
603 0 : ind = find_shopt (option_name);
604 0 : *shopt_vars[ind].value = mode;
605 : }
606 :
607 : /* Then set shell_compatibility_level based on what remains */
608 0 : if (shopt_compat31)
609 0 : shell_compatibility_level = 31;
610 0 : else if (shopt_compat32)
611 0 : shell_compatibility_level = 32;
612 0 : else if (shopt_compat40)
613 0 : shell_compatibility_level = 40;
614 0 : else if (shopt_compat41)
615 0 : shell_compatibility_level = 41;
616 0 : else if (shopt_compat42)
617 0 : shell_compatibility_level = 42;
618 0 : else if (shopt_compat43)
619 0 : shell_compatibility_level = 43;
620 : else
621 0 : shell_compatibility_level = DEFAULT_COMPAT_LEVEL;
622 :
623 0 : return 0;
624 : }
625 :
626 : /* Set and unset the various compatibility options from the value of
627 : shell_compatibility_level; used by sv_shcompat */
628 : void
629 9143297 : set_compatibility_opts ()
630 : {
631 9143297 : shopt_compat31 = shopt_compat32 = 0;
632 9143297 : shopt_compat40 = shopt_compat41 = shopt_compat42 = shopt_compat43 = 0;
633 9143297 : switch (shell_compatibility_level)
634 : {
635 : case DEFAULT_COMPAT_LEVEL:
636 : break;
637 0 : case 43:
638 0 : shopt_compat43 = 1; break;
639 0 : case 42:
640 0 : shopt_compat42 = 1; break;
641 0 : case 41:
642 0 : shopt_compat41 = 1; break;
643 0 : case 40:
644 0 : shopt_compat40 = 1; break;
645 0 : case 32:
646 0 : shopt_compat32 = 1; break;
647 0 : case 31:
648 0 : shopt_compat31 = 1; break;
649 : }
650 9143297 : }
651 :
652 : #if defined (READLINE)
653 : static int
654 0 : shopt_set_complete_direxpand (option_name, mode)
655 : char *option_name;
656 : int mode;
657 : {
658 0 : set_directory_hook ();
659 0 : return 0;
660 : }
661 : #endif
662 :
663 : #if defined (RESTRICTED_SHELL)
664 : /* Don't allow the value of restricted_shell to be modified. */
665 :
666 : static int
667 0 : set_restricted_shell (option_name, mode)
668 : char *option_name;
669 : int mode;
670 : {
671 0 : static int save_restricted = -1;
672 :
673 0 : if (save_restricted == -1)
674 0 : save_restricted = shell_is_restricted (shell_name);
675 :
676 0 : restricted_shell = save_restricted;
677 0 : return (0);
678 : }
679 : #endif /* RESTRICTED_SHELL */
680 :
681 : /* Not static so shell.c can call it to initialize shopt_login_shell */
682 : int
683 9143297 : set_login_shell (option_name, mode)
684 : char *option_name;
685 : int mode;
686 : {
687 9143297 : shopt_login_shell = login_shell != 0;
688 9143297 : return (0);
689 : }
690 :
691 : char **
692 0 : get_shopt_options ()
693 : {
694 0 : char **ret;
695 0 : int n, i;
696 :
697 0 : n = sizeof (shopt_vars) / sizeof (shopt_vars[0]);
698 0 : ret = strvec_create (n + 1);
699 0 : for (i = 0; shopt_vars[i].name; i++)
700 0 : ret[i] = savestring (shopt_vars[i].name);
701 0 : ret[i] = (char *)NULL;
702 0 : return ret;
703 : }
704 :
705 : /*
706 : * External interface for other parts of the shell. NAME is a string option;
707 : * MODE is 0 if we want to unset an option; 1 if we want to set an option.
708 : * REUSABLE is 1 if we want to print output in a form that may be reused.
709 : */
710 : int
711 0 : shopt_setopt (name, mode)
712 : char *name;
713 : int mode;
714 : {
715 0 : WORD_LIST *wl;
716 0 : int r;
717 :
718 0 : wl = add_string_to_list (name, (WORD_LIST *)NULL);
719 0 : r = toggle_shopts (mode, wl, 0);
720 0 : dispose_words (wl);
721 0 : return r;
722 : }
723 :
724 : int
725 0 : shopt_listopt (name, reusable)
726 : char *name;
727 : int reusable;
728 : {
729 0 : int i;
730 :
731 0 : if (name == 0)
732 0 : return (list_shopts ((WORD_LIST *)NULL, reusable ? PFLAG : 0));
733 :
734 0 : i = find_shopt (name);
735 0 : if (i < 0)
736 : {
737 0 : shopt_error (name);
738 0 : return (EXECUTION_FAILURE);
739 : }
740 :
741 0 : print_shopt (name, *shopt_vars[i].value, reusable ? PFLAG : 0);
742 0 : return (sh_chkwrite (EXECUTION_SUCCESS));
743 : }
744 :
745 : void
746 9143297 : set_bashopts ()
747 : {
748 9143297 : char *value;
749 9143297 : char tflag[N_SHOPT_OPTIONS];
750 9143297 : int vsize, i, vptr, exported;
751 9143297 : SHELL_VAR *v;
752 :
753 448021553 : for (vsize = i = 0; shopt_vars[i].name; i++)
754 : {
755 438878256 : tflag[i] = 0;
756 438878256 : if (GET_SHOPT_OPTION_VALUE (i))
757 : {
758 100576267 : vsize += strlen (shopt_vars[i].name) + 1;
759 100576267 : tflag[i] = 1;
760 : }
761 : }
762 :
763 9143297 : value = (char *)xmalloc (vsize + 1);
764 :
765 448021553 : for (i = vptr = 0; shopt_vars[i].name; i++)
766 : {
767 438878256 : if (tflag[i])
768 : {
769 100576267 : strcpy (value + vptr, shopt_vars[i].name);
770 100576267 : vptr += strlen (shopt_vars[i].name);
771 100576267 : value[vptr++] = ':';
772 : }
773 : }
774 :
775 9143297 : if (vptr)
776 9143297 : vptr--; /* cut off trailing colon */
777 9143297 : value[vptr] = '\0';
778 :
779 9143297 : v = find_variable ("BASHOPTS");
780 :
781 : /* Turn off the read-only attribute so we can bind the new value, and
782 : note whether or not the variable was exported. */
783 9143297 : if (v)
784 : {
785 0 : VUNSETATTR (v, att_readonly);
786 0 : exported = exported_p (v);
787 : }
788 : else
789 : exported = 0;
790 :
791 9143297 : v = bind_variable ("BASHOPTS", value, 0);
792 :
793 : /* Turn the read-only attribute back on, and turn off the export attribute
794 : if it was set implicitly by mark_modified_vars and SHELLOPTS was not
795 : exported before we bound the new value. */
796 9143297 : VSETATTR (v, att_readonly);
797 9143297 : if (mark_modified_vars && exported == 0 && exported_p (v))
798 0 : VUNSETATTR (v, att_exported);
799 :
800 9143297 : free (value);
801 9143297 : }
802 :
803 : void
804 0 : parse_bashopts (value)
805 : char *value;
806 : {
807 0 : char *vname;
808 0 : int vptr, ind;
809 :
810 0 : vptr = 0;
811 0 : while (vname = extract_colon_unit (value, &vptr))
812 : {
813 0 : ind = find_shopt (vname);
814 0 : if (ind >= 0)
815 : {
816 0 : *shopt_vars[ind].value = 1;
817 0 : if (shopt_vars[ind].set_func)
818 0 : (*shopt_vars[ind].set_func) (shopt_vars[ind].name, 1);
819 : }
820 0 : free (vname);
821 : }
822 0 : }
823 :
824 : void
825 9143297 : initialize_bashopts (no_bashopts)
826 : int no_bashopts;
827 : {
828 9143297 : char *temp;
829 9143297 : SHELL_VAR *var;
830 :
831 9143297 : if (no_bashopts == 0)
832 : {
833 9143297 : var = find_variable ("BASHOPTS");
834 : /* set up any shell options we may have inherited. */
835 9143297 : if (var && imported_p (var))
836 : {
837 0 : temp = (array_p (var) || assoc_p (var)) ? (char *)NULL : savestring (value_cell (var));
838 0 : if (temp)
839 : {
840 0 : parse_bashopts (temp);
841 0 : free (temp);
842 : }
843 : }
844 : }
845 :
846 : /* Set up the $BASHOPTS variable. */
847 9143297 : set_bashopts ();
848 9143297 : }
|