1 This file is shopt.def
, from which is created shopt.c.
2 It implements the Bush `shopt
' builtin.
4 Copyright (C) 1994-2020 Free Software Foundation, Inc.
6 This file is part of GNU Bush, the Bourne Again SHell.
8 Bush 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.
13 Bush 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.
18 You should have received a copy of the GNU General Public License
19 along with Bush. If not, see <http://www.gnu.org/licenses/>.
24 $FUNCTION shopt_builtin
25 $SHORT_DOC shopt [-pqsu] [-o] [optname ...]
26 Set and unset shell options.
28 Change the setting of each shell option OPTNAME. Without any option
29 arguments, list each supplied OPTNAME, or all shell options if no
30 OPTNAMEs are given, with an indication of whether or not each is set.
33 -o restrict OPTNAMEs to those defined for use with `set -o'
34 -p print each shell option with an indication of its status
36 -s
enable (set
) each OPTNAME
37 -u
disable (unset
) each OPTNAME
40 Returns success if OPTNAME is enabled
; fails if an invalid option is
41 given or OPTNAME is disabled.
46 #if
defined (HAVE_UNISTD_H
)
48 # include
<sys
/types.h
>
57 #include
"../src/bushintl.h"
59 #include
"../src/shell.h"
60 #include
"../src/flags.h"
62 #include
"bushgetopt.h"
64 #if
defined (READLINE
)
65 # include
"../src/input/bushline.h"
69 # include
"../src/bushhist.h"
75 #define OPTFMT
"%-15s\t%s\n"
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
;
87 extern int gnu_error_format
;
88 extern int check_jobs_at_exit
;
91 extern int glob_asciirange
;
92 extern int lastpipe_opt
;
93 extern int inherit_errexit
;
94 extern int localvar_inherit
;
95 extern int localvar_unset
;
97 #if
defined (EXTENDED_GLOB
)
98 extern int extended_glob
;
101 #if
defined (READLINE
)
102 extern int hist_verify
, history_reediting
, perform_hostname_completion
;
103 extern int no_empty_command_completion
;
104 extern int force_fignore
;
105 extern int dircomplete_spelling
, dircomplete_expand
;
106 extern int complete_fullquote
;
108 extern int enable_hostname_completion
PARAMS((int
));
111 #if
defined (PROGRAMMABLE_COMPLETION
)
112 extern int prog_completion_enabled
;
113 extern int progcomp_alias
;
116 #if
defined (DEBUGGER
)
117 extern int debugging_mode
;
120 #if
defined (ARRAY_VARS
)
121 extern int assoc_expand_once
;
122 extern int array_expand_once
;
125 #if
defined (SYSLOG_HISTORY
)
126 extern int syslog_history
;
129 static void shopt_error
PARAMS((char *)
);
131 static int set_shellopts_after_change
PARAMS((char
*, int
));
132 static int set_compatibility_level
PARAMS((char
*, int
));
134 #if
defined (RESTRICTED_SHELL
)
135 static int set_restricted_shell
PARAMS((char
*, int
));
138 #if
defined (READLINE
)
139 static int shopt_enable_hostname_completion
PARAMS((char
*, int
));
140 static int shopt_set_complete_direxpand
PARAMS((char
*, int
));
143 static int shopt_set_debug_mode
PARAMS((char
*, int
));
145 static int shopt_login_shell
;
146 static int shopt_compat31
;
147 static int shopt_compat32
;
148 static int shopt_compat40
;
149 static int shopt_compat41
;
150 static int shopt_compat42
;
151 static int shopt_compat43
;
152 static int shopt_compat44
;
154 typedef int shopt_set_func_t
PARAMS((char
*, int
));
156 /* If you add a new variable name here
, make sure to set the default value
157 appropriately in reset_shopt_options.
*/
162 shopt_set_func_t
*set_func
;
164 { "autocd", &autocd
, (shopt_set_func_t *)NULL
},
165 #if
defined (ARRAY_VARS
)
166 { "assoc_expand_once", &assoc_expand_once
, (shopt_set_func_t *)NULL
},
168 { "cdable_vars", &cdable_vars
, (shopt_set_func_t *)NULL
},
169 { "cdspell", &cdspelling
, (shopt_set_func_t *)NULL
},
170 { "checkhash", &check_hashed_filenames
, (shopt_set_func_t *)NULL
},
171 #if
defined (JOB_CONTROL
)
172 { "checkjobs", &check_jobs_at_exit
, (shopt_set_func_t *)NULL
},
174 { "checkwinsize", &check_window_size
, (shopt_set_func_t *)NULL
},
175 #if
defined (HISTORY
)
176 { "cmdhist", &command_oriented_history
, (shopt_set_func_t *)NULL
},
178 { "compat31", &shopt_compat31
, set_compatibility_level
},
179 { "compat32", &shopt_compat32
, set_compatibility_level
},
180 { "compat40", &shopt_compat40
, set_compatibility_level
},
181 { "compat41", &shopt_compat41
, set_compatibility_level
},
182 { "compat42", &shopt_compat42
, set_compatibility_level
},
183 { "compat43", &shopt_compat43
, set_compatibility_level
},
184 { "compat44", &shopt_compat44
, set_compatibility_level
},
185 #if
defined (READLINE
)
186 { "complete_fullquote", &complete_fullquote
, (shopt_set_func_t *)NULL
},
187 { "direxpand", &dircomplete_expand
, shopt_set_complete_direxpand
},
188 { "dirspell", &dircomplete_spelling
, (shopt_set_func_t *)NULL
},
190 { "dotglob", &glob_dot_filenames
, (shopt_set_func_t *)NULL
},
191 { "execfail", &no_exit_on_failed_exec
, (shopt_set_func_t *)NULL
},
192 { "expand_aliases", &expand_aliases
, (shopt_set_func_t *)NULL
},
193 #if
defined (DEBUGGER
)
194 { "extdebug", &debugging_mode
, shopt_set_debug_mode
},
196 #if
defined (EXTENDED_GLOB
)
197 { "extglob", &extended_glob
, (shopt_set_func_t *)NULL
},
199 { "extquote", &extended_quote
, (shopt_set_func_t *)NULL
},
200 { "failglob", &fail_glob_expansion
, (shopt_set_func_t *)NULL
},
201 #if
defined (READLINE
)
202 { "force_fignore", &force_fignore
, (shopt_set_func_t *)NULL
},
204 { "globasciiranges", &glob_asciirange
, (shopt_set_func_t *)NULL
},
205 { "globstar", &glob_star
, (shopt_set_func_t *)NULL
},
206 { "gnu_errfmt", &gnu_error_format
, (shopt_set_func_t *)NULL
},
207 #if
defined (HISTORY
)
208 { "histappend", &force_append_history
, (shopt_set_func_t *)NULL
},
210 #if
defined (READLINE
)
211 { "histreedit", &history_reediting
, (shopt_set_func_t *)NULL
},
212 { "histverify", &hist_verify
, (shopt_set_func_t *)NULL
},
213 { "hostcomplete", &perform_hostname_completion
, shopt_enable_hostname_completion
},
215 { "huponexit", &hup_on_exit
, (shopt_set_func_t *)NULL
},
216 { "inherit_errexit", &inherit_errexit
, (shopt_set_func_t *)NULL
},
217 { "interactive_comments", &interactive_comments
, set_shellopts_after_change
},
218 { "lastpipe", &lastpipe_opt
, (shopt_set_func_t *)NULL
},
219 #if
defined (HISTORY
)
220 { "lithist", &literal_history
, (shopt_set_func_t *)NULL
},
222 { "localvar_inherit", &localvar_inherit
, (shopt_set_func_t *)NULL
},
223 { "localvar_unset", &localvar_unset
, (shopt_set_func_t *)NULL
},
224 { "login_shell", &shopt_login_shell
, set_login_shell
},
225 { "mailwarn", &mail_warning
, (shopt_set_func_t *)NULL
},
226 #if
defined (READLINE
)
227 { "no_empty_cmd_completion", &no_empty_command_completion
, (shopt_set_func_t *)NULL
},
229 { "nocaseglob", &glob_ignore_case
, (shopt_set_func_t *)NULL
},
230 { "nocasematch", &match_ignore_case
, (shopt_set_func_t *)NULL
},
231 { "nullglob", &allow_null_glob_expansion
, (shopt_set_func_t *)NULL
},
232 #if
defined (PROGRAMMABLE_COMPLETION
)
233 { "progcomp", &prog_completion_enabled
, (shopt_set_func_t *)NULL
},
235 { "progcomp_alias", &progcomp_alias
, (shopt_set_func_t *)NULL
},
238 { "promptvars", &promptvars
, (shopt_set_func_t *)NULL
},
239 #if
defined (RESTRICTED_SHELL
)
240 { "restricted_shell", &restricted_shell
, set_restricted_shell
},
242 { "shift_verbose", &print_shift_error
, (shopt_set_func_t *)NULL
},
243 { "sourcepath", &source_uses_path
, (shopt_set_func_t *)NULL
},
244 #if
defined (SYSLOG_HISTORY
) && defined (SYSLOG_SHOPT
)
245 { "syslog_history", &syslog_history
, (shopt_set_func_t *)NULL
},
247 { "xpg_echo", &xpg_echo
, (shopt_set_func_t *)NULL
},
248 { (char *)
0, (int *)
0, (shopt_set_func_t *)NULL
}
251 #define
N_SHOPT_OPTIONS (sizeof (shopt_vars
) / sizeof (shopt_vars
[0]))
253 #define
GET_SHOPT_OPTION_VALUE(i
) (*shopt_vars[i].value)
255 static const char * const on = "on";
256 static const char * const off = "off";
258 static int find_shopt PARAMS((char *));
259 static int toggle_shopts
PARAMS((int
, WORD_LIST
*, int
));
260 static void print_shopt
PARAMS((char
*, int
, int
));
261 static int list_shopts
PARAMS((WORD_LIST
*, int
));
262 static int list_some_shopts
PARAMS((int
, int
));
263 static int list_shopt_o_options
PARAMS((WORD_LIST
*, int
));
264 static int list_some_o_options
PARAMS((int
, int
));
265 static int set_shopt_o_options
PARAMS((int
, WORD_LIST
*, int
));
277 int opt
, flags
, rval
;
280 reset_internal_getopt ();
281 while ((opt
= internal_getopt (list
, "psuoq")) != -1)
308 if ((flags
& (SFLAG|UFLAG
)) == (SFLAG|UFLAG
))
310 builtin_error (_("cannot set and unset shell options simultaneously"));
311 return (EXECUTION_FAILURE
);
314 rval
= EXECUTION_SUCCESS
;
315 if ((flags
& OFLAG
) && ((flags
& (SFLAG|UFLAG
)) == 0)) /* shopt
-o
*/
316 rval
= list_shopt_o_options (list
, flags
);
317 else
if (list
&& (flags
& OFLAG
)) /* shopt
-so args
*/
318 rval
= set_shopt_o_options ((flags
& SFLAG
) ? FLAG_ON
: FLAG_OFF
, list
, flags
& QFLAG
);
319 else
if (flags
& OFLAG
) /* shopt
-so
*/
320 rval
= list_some_o_options ((flags
& SFLAG
) ?
1 : 0, flags
);
321 else
if (list
&& (flags
& (SFLAG|UFLAG
))) /* shopt
-su args
*/
322 rval
= toggle_shopts ((flags
& SFLAG
) ? SETOPT
: UNSETOPT
, list
, flags
& QFLAG
);
323 else
if ((flags
& (SFLAG|UFLAG
)) == 0) /* shopt
[args
] */
324 rval
= list_shopts (list
, flags
);
326 rval
= list_some_shopts ((flags
& SFLAG
) ? SETOPT
: UNSETOPT
, flags
);
330 /* Reset the options managed by `shopt
' to the values they would have at
331 shell startup. Variables from shopt_vars. */
333 reset_shopt_options ()
335 autocd = cdable_vars = cdspelling = 0;
336 check_hashed_filenames = CHECKHASH_DEFAULT;
337 check_window_size = CHECKWINSIZE_DEFAULT;
338 allow_null_glob_expansion = glob_dot_filenames = 0;
339 no_exit_on_failed_exec = 0;
342 fail_glob_expansion = 0;
343 glob_asciirange = GLOBASCII_DEFAULT;
345 gnu_error_format = 0;
348 interactive_comments = 1;
350 localvar_inherit = localvar_unset = 0;
352 glob_ignore_case = match_ignore_case = 0;
353 print_shift_error = 0;
354 source_uses_path = promptvars = 1;
356 #if defined (JOB_CONTROL)
357 check_jobs_at_exit = 0;
360 #if defined (EXTENDED_GLOB)
361 extended_glob = EXTGLOB_DEFAULT;
364 #if defined (ARRAY_VARS)
365 assoc_expand_once = 0;
368 #if defined (HISTORY)
370 force_append_history = 0;
371 command_oriented_history = 1;
374 #if defined (SYSLOG_HISTORY)
375 # if defined (SYSLOG_SHOPT)
376 syslog_history = SYSLOG_SHOPT;
379 # endif /* SYSLOG_SHOPT */
382 #if defined (READLINE)
383 complete_fullquote = 1;
385 hist_verify = history_reediting = 0;
386 perform_hostname_completion = 1;
387 # if DIRCOMPLETE_EXPAND_DEFAULT
388 dircomplete_expand = 1;
390 dircomplete_expand = 0;
392 dircomplete_spelling = 0;
393 no_empty_command_completion = 0;
396 #if defined (PROGRAMMABLE_COMPLETION)
397 prog_completion_enabled = 1;
403 #if defined (DEFAULT_ECHO_TO_XPG) || defined (STRICT_POSIX)
407 #endif /* DEFAULT_ECHO_TO_XPG */
409 shopt_login_shell = login_shell;
418 for (i = 0; shopt_vars[i].name; i++)
419 if (STREQ (name, shopt_vars[i].name))
428 builtin_error (_("%s: invalid shell option name"), s);
432 toggle_shopts (mode, list, quiet)
441 for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
443 ind = find_shopt (l->word->word);
446 shopt_error (l->word->word);
447 rval = EXECUTION_FAILURE;
451 *shopt_vars[ind].value = mode; /* 1 for set, 0 for unset */
452 if (shopt_vars[ind].set_func)
453 (*shopt_vars[ind].set_func) (shopt_vars[ind].name, mode);
457 /* Don't set $BUSHOPTS here if it hasn
't already been initialized */
458 if (v = find_variable ("BUSHOPTS"))
464 print_shopt (name, val, flags)
469 printf ("shopt %s %s\n", val ? "-s" : "-u", name);
471 printf (OPTFMT, name, val ? on : off);
474 /* List the values of all or any of the `shopt' options. Returns
0 if
475 all were listed or all variables queried were on
; 1 otherwise.
*/
477 list_shopts (list
, flags
)
486 for (i
= 0; shopt_vars
[i
].name
; i
++)
488 val
= *shopt_vars
[i
].value
;
489 if ((flags
& QFLAG
) == 0)
490 print_shopt (shopt_vars
[i
].name
, val
, flags
);
492 return (sh_chkwrite (EXECUTION_SUCCESS
));
495 for (l
= list
, rval
= EXECUTION_SUCCESS
; l
; l
= l
->next
)
497 i
= find_shopt (l
->word
->word
);
500 shopt_error (l
->word
->word
);
501 rval
= EXECUTION_FAILURE
;
504 val
= *shopt_vars
[i
].value
;
506 rval
= EXECUTION_FAILURE
;
507 if ((flags
& QFLAG
) == 0)
508 print_shopt (l
->word
->word
, val
, flags
);
511 return (sh_chkwrite (rval
));
515 list_some_shopts (mode
, flags
)
520 for (i
= 0; shopt_vars
[i
].name
; i
++)
522 val
= *shopt_vars
[i
].value
;
523 if (((flags
& QFLAG
) == 0) && mode
== val
)
524 print_shopt (shopt_vars
[i
].name
, val
, flags
);
526 return (sh_chkwrite (EXECUTION_SUCCESS
));
530 list_shopt_o_options (list
, flags
)
539 if ((flags
& QFLAG
) == 0)
540 list_minus_o_opts (-1, (flags
& PFLAG
));
541 return (sh_chkwrite (EXECUTION_SUCCESS
));
544 for (l
= list
, rval
= EXECUTION_SUCCESS
; l
; l
= l
->next
)
546 val
= minus_o_option_value (l
->word
->word
);
549 sh_invalidoptname (l
->word
->word
);
550 rval
= EXECUTION_FAILURE
;
554 rval
= EXECUTION_FAILURE
;
555 if ((flags
& QFLAG
) == 0)
558 printf ("set %co %s\n", val ?
'-' : '+', l
->word
->word
);
560 printf (OPTFMT
, l
->word
->word
, val ? on
: off
);
563 return (sh_chkwrite (rval
));
567 list_some_o_options (mode
, flags
)
570 if ((flags
& QFLAG
) == 0)
571 list_minus_o_opts (mode
, (flags
& PFLAG
));
572 return (sh_chkwrite (EXECUTION_SUCCESS
));
576 set_shopt_o_options (mode
, list
, quiet
)
584 for (l
= list
, rval
= EXECUTION_SUCCESS
; l
; l
= l
->next
)
586 if (set_minus_o_option (mode
, l
->word
->word
) == EXECUTION_FAILURE
)
587 rval
= EXECUTION_FAILURE
;
593 /* If we set or unset interactive_comments with shopt
, make sure the
594 change is reflected in $SHELLOPTS.
*/
596 set_shellopts_after_change (option_name
, mode
)
605 shopt_set_debug_mode (option_name
, mode
)
609 #if
defined (DEBUGGER
)
610 error_trace_mode
= function_trace_mode
= debugging_mode
;
618 #if
defined (READLINE
)
620 shopt_enable_hostname_completion (option_name
, mode
)
624 return (enable_hostname_completion (mode
));
629 set_compatibility_level (option_name
, mode
)
636 /* If we
're setting something, redo some of the work we did above in
637 toggle_shopt(). Unset everything and reset the appropriate option
638 based on OPTION_NAME. */
641 shopt_compat31 = shopt_compat32 = 0;
642 shopt_compat40 = shopt_compat41 = shopt_compat42 = shopt_compat43 = 0;
644 ind = find_shopt (option_name);
645 *shopt_vars[ind].value = mode;
648 /* Then set shell_compatibility_level based on what remains */
650 shell_compatibility_level = 31;
651 else if (shopt_compat32)
652 shell_compatibility_level = 32;
653 else if (shopt_compat40)
654 shell_compatibility_level = 40;
655 else if (shopt_compat41)
656 shell_compatibility_level = 41;
657 else if (shopt_compat42)
658 shell_compatibility_level = 42;
659 else if (shopt_compat43)
660 shell_compatibility_level = 43;
661 else if (shopt_compat44)
662 shell_compatibility_level = 44;
664 shell_compatibility_level = DEFAULT_COMPAT_LEVEL;
666 /* Make sure the current compatibility level is reflected in BUSH_COMPAT */
667 rhs = itos (shell_compatibility_level);
668 bind_variable ("BUSH_COMPAT", rhs, 0);
674 /* Set and unset the various compatibility options from the value of
675 shell_compatibility_level; used by sv_shcompat */
677 set_compatibility_opts ()
679 shopt_compat31 = shopt_compat32 = 0;
680 shopt_compat40 = shopt_compat41 = shopt_compat42 = shopt_compat43 = 0;
682 switch (shell_compatibility_level)
684 case DEFAULT_COMPAT_LEVEL:
687 shopt_compat44 = 1; break;
689 shopt_compat43 = 1; break;
691 shopt_compat42 = 1; break;
693 shopt_compat41 = 1; break;
695 shopt_compat40 = 1; break;
697 shopt_compat32 = 1; break;
699 shopt_compat31 = 1; break;
703 #if defined (READLINE)
705 shopt_set_complete_direxpand (option_name, mode)
709 set_directory_hook ();
714 #if defined (RESTRICTED_SHELL)
715 /* Don't allow the value of restricted_shell to be modified.
*/
718 set_restricted_shell (option_name
, mode
)
722 static int save_restricted
= -1;
724 if (save_restricted
== -1)
725 save_restricted
= shell_is_restricted (shell_name
);
727 restricted_shell
= save_restricted
;
730 #endif
/* RESTRICTED_SHELL
*/
732 /* Not static so shell.c can call it to initialize shopt_login_shell
*/
734 set_login_shell (option_name
, mode
)
738 shopt_login_shell
= login_shell
!= 0;
748 n
= sizeof (shopt_vars
) / sizeof (shopt_vars
[0]);
749 ret
= strvec_create (n
+ 1);
750 for (i
= 0; shopt_vars
[i
].name
; i
++)
751 ret
[i
] = savestring (shopt_vars
[i
].name
);
752 ret
[i
] = (char *)NULL
;
757 * External interface for other parts of the shell. NAME is a string option
;
758 * MODE is
0 if we want to unset an option
; 1 if we want to set an option.
759 * REUSABLE is
1 if we want to print output in a form that may be reused.
762 shopt_setopt (name
, mode
)
769 wl
= add_string_to_list (name
, (WORD_LIST *)NULL
);
770 r
= toggle_shopts (mode
, wl
, 0);
776 shopt_listopt (name
, reusable
)
783 return (list_shopts ((WORD_LIST *)NULL
, reusable ? PFLAG
: 0));
785 i
= find_shopt (name
);
789 return (EXECUTION_FAILURE
);
792 print_shopt (name
, *shopt_vars
[i
].value
, reusable ? PFLAG
: 0);
793 return (sh_chkwrite (EXECUTION_SUCCESS
));
800 char tflag
[N_SHOPT_OPTIONS
];
801 int vsize
, i
, vptr
, *ip
, exported
;
804 for (vsize
= i
= 0; shopt_vars
[i
].name
; i
++)
807 if (GET_SHOPT_OPTION_VALUE (i
))
809 vsize
+= strlen (shopt_vars
[i
].name
) + 1;
814 value
= (char *)
xmalloc (vsize
+ 1);
816 for (i
= vptr
= 0; shopt_vars
[i
].name
; i
++)
820 strcpy (value
+ vptr
, shopt_vars
[i
].name
);
821 vptr
+= strlen (shopt_vars
[i
].name
);
827 vptr
--; /* cut off trailing colon
*/
830 v
= find_variable ("BUSHOPTS");
832 /* Turn off the read
-only attribute so we can bind the new value
, and
833 note whether or not the variable was exported.
*/
836 VUNSETATTR (v
, att_readonly
);
837 exported
= exported_p (v
);
842 v
= bind_variable ("BUSHOPTS", value
, 0);
844 /* Turn the read
-only attribute back on
, and turn off the export attribute
845 if it was set implicitly by mark_modified_vars and SHELLOPTS was not
846 exported before we bound the new value.
*/
847 VSETATTR (v
, att_readonly
);
848 if (mark_modified_vars
&& exported
== 0 && exported_p (v
))
849 VUNSETATTR (v
, att_exported
);
855 parse_bushopts (value
)
862 while (vname
= extract_colon_unit (value
, &vptr
))
864 ind
= find_shopt (vname
);
867 *shopt_vars
[ind
].value
= 1;
868 if (shopt_vars
[ind
].set_func
)
869 (*shopt_vars[ind].set_func) (shopt_vars[ind].name, 1);
876 initialize_bushopts (no_bushopts)
882 if (no_bushopts == 0)
884 var = find_variable ("BUSHOPTS");
885 /* set up any shell options we may have inherited. */
886 if (var && imported_p (var))
888 temp = (array_p (var) || assoc_p (var)) ? (char *)NULL
: savestring (value_cell (var
));
891 parse_bushopts (temp
);
897 /* Set up the $BUSHOPTS variable.
*/