]> git.ipfire.org Git - thirdparty/bash.git/blob - builtins/shopt.def
Bash-4.2 patch 29
[thirdparty/bash.git] / builtins / shopt.def
1 This file is shopt.def, from which is created shopt.c.
2 It implements the Bash `shopt' builtin.
3
4 Copyright (C) 1994-2010 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 lastpipe_opt;
92
93 #if defined (EXTENDED_GLOB)
94 extern int extended_glob;
95 #endif
96
97 #if defined (READLINE)
98 extern int hist_verify, history_reediting, perform_hostname_completion;
99 extern int no_empty_command_completion;
100 extern int force_fignore;
101 extern int dircomplete_spelling, dircomplete_expand;
102
103 extern int enable_hostname_completion __P((int));
104 #endif
105
106 #if defined (PROGRAMMABLE_COMPLETION)
107 extern int prog_completion_enabled;
108 #endif
109
110 #if defined (RESTRICTED_SHELL)
111 extern char *shell_name;
112 #endif
113
114 #if defined (DEBUGGER)
115 extern int debugging_mode;
116 #endif
117
118 static void shopt_error __P((char *));
119
120 static int set_shellopts_after_change __P((char *, int));
121 static int shopt_enable_hostname_completion __P((char *, int));
122 static int set_compatibility_level __P((char *, int));
123
124 #if defined (RESTRICTED_SHELL)
125 static int set_restricted_shell __P((char *, int));
126 #endif
127
128 #if defined (READLINE)
129 static int shopt_set_complete_direxpand __P((char *, int));
130 #endif
131
132 static int shopt_login_shell;
133 static int shopt_compat31;
134 static int shopt_compat32;
135 static int shopt_compat40;
136 static int shopt_compat41;
137
138 typedef int shopt_set_func_t __P((char *, int));
139
140 static struct {
141 char *name;
142 int *value;
143 shopt_set_func_t *set_func;
144 } shopt_vars[] = {
145 { "autocd", &autocd, (shopt_set_func_t *)NULL },
146 { "cdable_vars", &cdable_vars, (shopt_set_func_t *)NULL },
147 { "cdspell", &cdspelling, (shopt_set_func_t *)NULL },
148 { "checkhash", &check_hashed_filenames, (shopt_set_func_t *)NULL },
149 #if defined (JOB_CONTROL)
150 { "checkjobs", &check_jobs_at_exit, (shopt_set_func_t *)NULL },
151 #endif
152 { "checkwinsize", &check_window_size, (shopt_set_func_t *)NULL },
153 #if defined (HISTORY)
154 { "cmdhist", &command_oriented_history, (shopt_set_func_t *)NULL },
155 #endif
156 { "compat31", &shopt_compat31, set_compatibility_level },
157 { "compat32", &shopt_compat32, set_compatibility_level },
158 { "compat40", &shopt_compat40, set_compatibility_level },
159 { "compat41", &shopt_compat41, set_compatibility_level },
160 #if defined (READLINE)
161 { "direxpand", &dircomplete_expand, shopt_set_complete_direxpand },
162 { "dirspell", &dircomplete_spelling, (shopt_set_func_t *)NULL },
163 #endif
164 { "dotglob", &glob_dot_filenames, (shopt_set_func_t *)NULL },
165 { "execfail", &no_exit_on_failed_exec, (shopt_set_func_t *)NULL },
166 { "expand_aliases", &expand_aliases, (shopt_set_func_t *)NULL },
167 #if defined (DEBUGGER)
168 { "extdebug", &debugging_mode, (shopt_set_func_t *)NULL },
169 #endif
170 #if defined (EXTENDED_GLOB)
171 { "extglob", &extended_glob, (shopt_set_func_t *)NULL },
172 #endif
173 { "extquote", &extended_quote, (shopt_set_func_t *)NULL },
174 { "failglob", &fail_glob_expansion, (shopt_set_func_t *)NULL },
175 #if defined (READLINE)
176 { "force_fignore", &force_fignore, (shopt_set_func_t *)NULL },
177 #endif
178 { "globstar", &glob_star, (shopt_set_func_t *)NULL },
179 { "gnu_errfmt", &gnu_error_format, (shopt_set_func_t *)NULL },
180 #if defined (HISTORY)
181 { "histappend", &force_append_history, (shopt_set_func_t *)NULL },
182 #endif
183 #if defined (READLINE)
184 { "histreedit", &history_reediting, (shopt_set_func_t *)NULL },
185 { "histverify", &hist_verify, (shopt_set_func_t *)NULL },
186 { "hostcomplete", &perform_hostname_completion, shopt_enable_hostname_completion },
187 #endif
188 { "huponexit", &hup_on_exit, (shopt_set_func_t *)NULL },
189 { "interactive_comments", &interactive_comments, set_shellopts_after_change },
190 { "lastpipe", &lastpipe_opt, (shopt_set_func_t *)NULL },
191 #if defined (HISTORY)
192 { "lithist", &literal_history, (shopt_set_func_t *)NULL },
193 #endif
194 { "login_shell", &shopt_login_shell, set_login_shell },
195 { "mailwarn", &mail_warning, (shopt_set_func_t *)NULL },
196 #if defined (READLINE)
197 { "no_empty_cmd_completion", &no_empty_command_completion, (shopt_set_func_t *)NULL },
198 #endif
199 { "nocaseglob", &glob_ignore_case, (shopt_set_func_t *)NULL },
200 { "nocasematch", &match_ignore_case, (shopt_set_func_t *)NULL },
201 { "nullglob", &allow_null_glob_expansion, (shopt_set_func_t *)NULL },
202 #if defined (PROGRAMMABLE_COMPLETION)
203 { "progcomp", &prog_completion_enabled, (shopt_set_func_t *)NULL },
204 #endif
205 { "promptvars", &promptvars, (shopt_set_func_t *)NULL },
206 #if defined (RESTRICTED_SHELL)
207 { "restricted_shell", &restricted_shell, set_restricted_shell },
208 #endif
209 { "shift_verbose", &print_shift_error, (shopt_set_func_t *)NULL },
210 { "sourcepath", &source_uses_path, (shopt_set_func_t *)NULL },
211 { "xpg_echo", &xpg_echo, (shopt_set_func_t *)NULL },
212 { (char *)0, (int *)0, (shopt_set_func_t *)NULL }
213 };
214
215 #define N_SHOPT_OPTIONS (sizeof (shopt_vars) / sizeof (shopt_vars[0]))
216
217 #define GET_SHOPT_OPTION_VALUE(i) (*shopt_vars[i].value)
218
219 static const char * const on = "on";
220 static const char * const off = "off";
221
222 static int find_shopt __P((char *));
223 static int toggle_shopts __P((int, WORD_LIST *, int));
224 static void print_shopt __P((char *, int, int));
225 static int list_shopts __P((WORD_LIST *, int));
226 static int list_some_shopts __P((int, int));
227 static int list_shopt_o_options __P((WORD_LIST *, int));
228 static int list_some_o_options __P((int, int));
229 static int set_shopt_o_options __P((int, WORD_LIST *, int));
230
231 #define SFLAG 0x01
232 #define UFLAG 0x02
233 #define QFLAG 0x04
234 #define OFLAG 0x08
235 #define PFLAG 0x10
236
237 int
238 shopt_builtin (list)
239 WORD_LIST *list;
240 {
241 int opt, flags, rval;
242
243 flags = 0;
244 reset_internal_getopt ();
245 while ((opt = internal_getopt (list, "psuoq")) != -1)
246 {
247 switch (opt)
248 {
249 case 's':
250 flags |= SFLAG;
251 break;
252 case 'u':
253 flags |= UFLAG;
254 break;
255 case 'q':
256 flags |= QFLAG;
257 break;
258 case 'o':
259 flags |= OFLAG;
260 break;
261 case 'p':
262 flags |= PFLAG;
263 break;
264 default:
265 builtin_usage ();
266 return (EX_USAGE);
267 }
268 }
269 list = loptend;
270
271 if ((flags & (SFLAG|UFLAG)) == (SFLAG|UFLAG))
272 {
273 builtin_error (_("cannot set and unset shell options simultaneously"));
274 return (EXECUTION_FAILURE);
275 }
276
277 rval = EXECUTION_SUCCESS;
278 if ((flags & OFLAG) && ((flags & (SFLAG|UFLAG)) == 0)) /* shopt -o */
279 rval = list_shopt_o_options (list, flags);
280 else if (list && (flags & OFLAG)) /* shopt -so args */
281 rval = set_shopt_o_options ((flags & SFLAG) ? FLAG_ON : FLAG_OFF, list, flags & QFLAG);
282 else if (flags & OFLAG) /* shopt -so */
283 rval = list_some_o_options ((flags & SFLAG) ? 1 : 0, flags);
284 else if (list && (flags & (SFLAG|UFLAG))) /* shopt -su args */
285 rval = toggle_shopts ((flags & SFLAG) ? SETOPT : UNSETOPT, list, flags & QFLAG);
286 else if ((flags & (SFLAG|UFLAG)) == 0) /* shopt [args] */
287 rval = list_shopts (list, flags);
288 else /* shopt -su */
289 rval = list_some_shopts ((flags & SFLAG) ? SETOPT : UNSETOPT, flags);
290 return (rval);
291 }
292
293 /* Reset the options managed by `shopt' to the values they would have at
294 shell startup. */
295 void
296 reset_shopt_options ()
297 {
298 allow_null_glob_expansion = glob_dot_filenames = 0;
299 cdable_vars = mail_warning = 0;
300 no_exit_on_failed_exec = print_shift_error = 0;
301 check_hashed_filenames = cdspelling = expand_aliases = check_window_size = 0;
302
303 source_uses_path = promptvars = 1;
304
305 #if defined (EXTENDED_GLOB)
306 extended_glob = 0;
307 #endif
308
309 #if defined (HISTORY)
310 literal_history = force_append_history = 0;
311 command_oriented_history = 1;
312 #endif
313
314 #if defined (READLINE)
315 hist_verify = history_reediting = 0;
316 perform_hostname_completion = 1;
317 #endif
318
319 shopt_login_shell = login_shell;
320 }
321
322 static int
323 find_shopt (name)
324 char *name;
325 {
326 int i;
327
328 for (i = 0; shopt_vars[i].name; i++)
329 if (STREQ (name, shopt_vars[i].name))
330 return i;
331 return -1;
332 }
333
334 static void
335 shopt_error (s)
336 char *s;
337 {
338 builtin_error (_("%s: invalid shell option name"), s);
339 }
340
341 static int
342 toggle_shopts (mode, list, quiet)
343 int mode;
344 WORD_LIST *list;
345 int quiet;
346 {
347 WORD_LIST *l;
348 int ind, rval;
349
350 for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
351 {
352 ind = find_shopt (l->word->word);
353 if (ind < 0)
354 {
355 shopt_error (l->word->word);
356 rval = EXECUTION_FAILURE;
357 }
358 else
359 {
360 *shopt_vars[ind].value = mode; /* 1 for set, 0 for unset */
361 if (shopt_vars[ind].set_func)
362 (*shopt_vars[ind].set_func) (shopt_vars[ind].name, mode);
363 }
364 }
365
366 set_bashopts ();
367 return (rval);
368 }
369
370 static void
371 print_shopt (name, val, flags)
372 char *name;
373 int val, flags;
374 {
375 if (flags & PFLAG)
376 printf ("shopt %s %s\n", val ? "-s" : "-u", name);
377 else
378 printf (OPTFMT, name, val ? on : off);
379 }
380
381 /* List the values of all or any of the `shopt' options. Returns 0 if
382 all were listed or all variables queried were on; 1 otherwise. */
383 static int
384 list_shopts (list, flags)
385 WORD_LIST *list;
386 int flags;
387 {
388 WORD_LIST *l;
389 int i, val, rval;
390
391 if (list == 0)
392 {
393 for (i = 0; shopt_vars[i].name; i++)
394 {
395 val = *shopt_vars[i].value;
396 if ((flags & QFLAG) == 0)
397 print_shopt (shopt_vars[i].name, val, flags);
398 }
399 return (sh_chkwrite (EXECUTION_SUCCESS));
400 }
401
402 for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
403 {
404 i = find_shopt (l->word->word);
405 if (i < 0)
406 {
407 shopt_error (l->word->word);
408 rval = EXECUTION_FAILURE;
409 continue;
410 }
411 val = *shopt_vars[i].value;
412 if (val == 0)
413 rval = EXECUTION_FAILURE;
414 if ((flags & QFLAG) == 0)
415 print_shopt (l->word->word, val, flags);
416 }
417
418 return (sh_chkwrite (rval));
419 }
420
421 static int
422 list_some_shopts (mode, flags)
423 int mode, flags;
424 {
425 int val, i;
426
427 for (i = 0; shopt_vars[i].name; i++)
428 {
429 val = *shopt_vars[i].value;
430 if (((flags & QFLAG) == 0) && mode == val)
431 print_shopt (shopt_vars[i].name, val, flags);
432 }
433 return (sh_chkwrite (EXECUTION_SUCCESS));
434 }
435
436 static int
437 list_shopt_o_options (list, flags)
438 WORD_LIST *list;
439 int flags;
440 {
441 WORD_LIST *l;
442 int val, rval;
443
444 if (list == 0)
445 {
446 if ((flags & QFLAG) == 0)
447 list_minus_o_opts (-1, (flags & PFLAG));
448 return (sh_chkwrite (EXECUTION_SUCCESS));
449 }
450
451 for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
452 {
453 val = minus_o_option_value (l->word->word);
454 if (val == -1)
455 {
456 sh_invalidoptname (l->word->word);
457 rval = EXECUTION_FAILURE;
458 continue;
459 }
460 if (val == 0)
461 rval = EXECUTION_FAILURE;
462 if ((flags & QFLAG) == 0)
463 {
464 if (flags & PFLAG)
465 printf ("set %co %s\n", val ? '-' : '+', l->word->word);
466 else
467 printf (OPTFMT, l->word->word, val ? on : off);
468 }
469 }
470 return (sh_chkwrite (rval));
471 }
472
473 static int
474 list_some_o_options (mode, flags)
475 int mode, flags;
476 {
477 if ((flags & QFLAG) == 0)
478 list_minus_o_opts (mode, (flags & PFLAG));
479 return (sh_chkwrite (EXECUTION_SUCCESS));
480 }
481
482 static int
483 set_shopt_o_options (mode, list, quiet)
484 int mode;
485 WORD_LIST *list;
486 int quiet;
487 {
488 WORD_LIST *l;
489 int rval;
490
491 for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
492 {
493 if (set_minus_o_option (mode, l->word->word) == EXECUTION_FAILURE)
494 rval = EXECUTION_FAILURE;
495 }
496 set_shellopts ();
497 return rval;
498 }
499
500 /* If we set or unset interactive_comments with shopt, make sure the
501 change is reflected in $SHELLOPTS. */
502 static int
503 set_shellopts_after_change (option_name, mode)
504 char *option_name;
505 int mode;
506 {
507 set_shellopts ();
508 return (0);
509 }
510
511 static int
512 shopt_enable_hostname_completion (option_name, mode)
513 char *option_name;
514 int mode;
515 {
516 return (enable_hostname_completion (mode));
517 }
518
519 static int
520 set_compatibility_level (option_name, mode)
521 char *option_name;
522 int mode;
523 {
524 /* Need to change logic here as we add more compatibility levels */
525
526 /* First, check option_name so we can turn off other compat options when
527 one is set. */
528 if (mode && option_name[6] == '3' && option_name[7] == '1')
529 shopt_compat32 = shopt_compat40 = 0;
530 else if (mode && option_name[6] == '3' && option_name[7] == '2')
531 shopt_compat31 = shopt_compat40 = 0;
532 else if (mode && option_name[6] == '4' && option_name[7] == '0')
533 shopt_compat31 = shopt_compat32 = 0;
534
535 /* Then set shell_compatibility_level based on what remains */
536 if (shopt_compat31)
537 shell_compatibility_level = 31;
538 else if (shopt_compat32)
539 shell_compatibility_level = 32;
540 else if (shopt_compat40)
541 shell_compatibility_level = 40;
542 else
543 shell_compatibility_level = DEFAULT_COMPAT_LEVEL;
544 return 0;
545 }
546
547 #if defined (READLINE)
548 static int
549 shopt_set_complete_direxpand (option_name, mode)
550 char *option_name;
551 int mode;
552 {
553 set_directory_hook ();
554 return 0;
555 }
556 #endif
557
558 #if defined (RESTRICTED_SHELL)
559 /* Don't allow the value of restricted_shell to be modified. */
560
561 static int
562 set_restricted_shell (option_name, mode)
563 char *option_name;
564 int mode;
565 {
566 static int save_restricted = -1;
567
568 if (save_restricted == -1)
569 save_restricted = shell_is_restricted (shell_name);
570
571 restricted_shell = save_restricted;
572 return (0);
573 }
574 #endif /* RESTRICTED_SHELL */
575
576 /* Not static so shell.c can call it to initialize shopt_login_shell */
577 int
578 set_login_shell (option_name, mode)
579 char *option_name;
580 int mode;
581 {
582 shopt_login_shell = login_shell != 0;
583 return (0);
584 }
585
586 char **
587 get_shopt_options ()
588 {
589 char **ret;
590 int n, i;
591
592 n = sizeof (shopt_vars) / sizeof (shopt_vars[0]);
593 ret = strvec_create (n + 1);
594 for (i = 0; shopt_vars[i].name; i++)
595 ret[i] = savestring (shopt_vars[i].name);
596 ret[i] = (char *)NULL;
597 return ret;
598 }
599
600 /*
601 * External interface for other parts of the shell. NAME is a string option;
602 * MODE is 0 if we want to unset an option; 1 if we want to set an option.
603 * REUSABLE is 1 if we want to print output in a form that may be reused.
604 */
605 int
606 shopt_setopt (name, mode)
607 char *name;
608 int mode;
609 {
610 WORD_LIST *wl;
611 int r;
612
613 wl = add_string_to_list (name, (WORD_LIST *)NULL);
614 r = toggle_shopts (mode, wl, 0);
615 dispose_words (wl);
616 return r;
617 }
618
619 int
620 shopt_listopt (name, reusable)
621 char *name;
622 int reusable;
623 {
624 int i;
625
626 if (name == 0)
627 return (list_shopts ((WORD_LIST *)NULL, reusable ? PFLAG : 0));
628
629 i = find_shopt (name);
630 if (i < 0)
631 {
632 shopt_error (name);
633 return (EXECUTION_FAILURE);
634 }
635
636 print_shopt (name, *shopt_vars[i].value, reusable ? PFLAG : 0);
637 return (sh_chkwrite (EXECUTION_SUCCESS));
638 }
639
640 void
641 set_bashopts ()
642 {
643 char *value;
644 char tflag[N_SHOPT_OPTIONS];
645 int vsize, i, vptr, *ip, exported;
646 SHELL_VAR *v;
647
648 for (vsize = i = 0; shopt_vars[i].name; i++)
649 {
650 tflag[i] = 0;
651 if (GET_SHOPT_OPTION_VALUE (i))
652 {
653 vsize += strlen (shopt_vars[i].name) + 1;
654 tflag[i] = 1;
655 }
656 }
657
658 value = (char *)xmalloc (vsize + 1);
659
660 for (i = vptr = 0; shopt_vars[i].name; i++)
661 {
662 if (tflag[i])
663 {
664 strcpy (value + vptr, shopt_vars[i].name);
665 vptr += strlen (shopt_vars[i].name);
666 value[vptr++] = ':';
667 }
668 }
669
670 if (vptr)
671 vptr--; /* cut off trailing colon */
672 value[vptr] = '\0';
673
674 v = find_variable ("BASHOPTS");
675
676 /* Turn off the read-only attribute so we can bind the new value, and
677 note whether or not the variable was exported. */
678 if (v)
679 {
680 VUNSETATTR (v, att_readonly);
681 exported = exported_p (v);
682 }
683 else
684 exported = 0;
685
686 v = bind_variable ("BASHOPTS", value, 0);
687
688 /* Turn the read-only attribute back on, and turn off the export attribute
689 if it was set implicitly by mark_modified_vars and SHELLOPTS was not
690 exported before we bound the new value. */
691 VSETATTR (v, att_readonly);
692 if (mark_modified_vars && exported == 0 && exported_p (v))
693 VUNSETATTR (v, att_exported);
694
695 free (value);
696 }
697
698 void
699 parse_bashopts (value)
700 char *value;
701 {
702 char *vname;
703 int vptr, ind;
704
705 vptr = 0;
706 while (vname = extract_colon_unit (value, &vptr))
707 {
708 ind = find_shopt (vname);
709 if (ind >= 0)
710 *shopt_vars[ind].value = 1;
711 free (vname);
712 }
713 }
714
715 void
716 initialize_bashopts (no_bashopts)
717 int no_bashopts;
718 {
719 char *temp;
720 SHELL_VAR *var;
721
722 if (no_bashopts == 0)
723 {
724 var = find_variable ("BASHOPTS");
725 /* set up any shell options we may have inherited. */
726 if (var && imported_p (var))
727 {
728 temp = (array_p (var) || assoc_p (var)) ? (char *)NULL : savestring (value_cell (var));
729 if (temp)
730 {
731 parse_bashopts (temp);
732 free (temp);
733 }
734 }
735 }
736
737 /* Set up the $BASHOPTS variable. */
738 set_bashopts ();
739 }