diff options
Diffstat (limited to 'builtins/shopt.def')
-rw-r--r-- | builtins/shopt.def | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/builtins/shopt.def b/builtins/shopt.def index d30a869d..64355819 100644 --- a/builtins/shopt.def +++ b/builtins/shopt.def @@ -123,6 +123,7 @@ static int set_restricted_shell __P((int)); static int shopt_login_shell; static int shopt_compat31; static int shopt_compat32; +static int shopt_compat40; typedef int shopt_set_func_t __P((int)); @@ -197,6 +198,10 @@ static struct { { (char *)0, (int *)0, (shopt_set_func_t *)NULL } }; +#define N_SHOPT_OPTIONS (sizeof (shopt_vars) / sizeof (shopt_vars[0])) + +#define GET_SHOPT_OPTION_VALUE(i) (*shopt_vars[i].value) + static const char * const on = "on"; static const char * const off = "off"; @@ -343,6 +348,8 @@ toggle_shopts (mode, list, quiet) (*shopt_vars[ind].set_func) (mode); } } + + set_bashopts (); return (rval); } @@ -579,3 +586,104 @@ shopt_listopt (name, reusable) print_shopt (name, *shopt_vars[i].value, reusable ? PFLAG : 0); return (sh_chkwrite (EXECUTION_SUCCESS)); } + +void +set_bashopts () +{ + char *value; + char tflag[N_SHOPT_OPTIONS]; + int vsize, i, vptr, *ip, exported; + SHELL_VAR *v; + + for (vsize = i = 0; shopt_vars[i].name; i++) + { + tflag[i] = 0; + if (GET_SHOPT_OPTION_VALUE (i)) + { + vsize += strlen (shopt_vars[i].name) + 1; + tflag[i] = 1; + } + } + + value = (char *)xmalloc (vsize + 1); + + for (i = vptr = 0; shopt_vars[i].name; i++) + { + if (tflag[i]) + { + strcpy (value + vptr, shopt_vars[i].name); + vptr += strlen (shopt_vars[i].name); + value[vptr++] = ':'; + } + } + + if (vptr) + vptr--; /* cut off trailing colon */ + value[vptr] = '\0'; + + v = find_variable ("BASHOPTS"); + + /* Turn off the read-only attribute so we can bind the new value, and + note whether or not the variable was exported. */ + if (v) + { + VUNSETATTR (v, att_readonly); + exported = exported_p (v); + } + else + exported = 0; + + v = bind_variable ("BASHOPTS", value, 0); + + /* Turn the read-only attribute back on, and turn off the export attribute + if it was set implicitly by mark_modified_vars and SHELLOPTS was not + exported before we bound the new value. */ + VSETATTR (v, att_readonly); + if (mark_modified_vars && exported == 0 && exported_p (v)) + VUNSETATTR (v, att_exported); + + free (value); +} + +void +parse_bashopts (value) + char *value; +{ + char *vname; + int vptr, ind; + + vptr = 0; + while (vname = extract_colon_unit (value, &vptr)) + { + ind = find_shopt (vname); + if (ind >= 0) + *shopt_vars[ind].value = 1; + free (vname); + } +} + +void +initialize_bashopts (no_bashopts) + int no_bashopts; +{ + char *temp; + SHELL_VAR *var; + + if (no_bashopts == 0) + { + var = find_variable ("BASHOPTS"); + /* set up any shell options we may have inherited. */ + if (var && imported_p (var)) + { + temp = (array_p (var) || assoc_p (var)) ? (char *)NULL : savestring (value_cell (var)); + if (temp) + { + parse_bashopts (temp); + free (temp); + } + } + } + + /* Set up the $BASHOPTS variable. */ + set_bashopts (); +} |