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