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