1 /* variables.c -- Functions for hacking shell variables. */
3 /* Copyright (C) 1987-2013 Free Software Foundation, Inc.
5 This file is part of GNU Bash, the Bourne Again SHell.
7 Bash is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 Bash is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Bash. If not, see <http://www.gnu.org/licenses/>.
23 #include "bashtypes.h"
24 #include "posixstat.h"
25 #include "posixtime.h"
28 # if defined (__QNXNTO__)
29 # include <sys/netmgr.h>
32 # endif /* !__QNXNTO__ */
35 #if defined (HAVE_UNISTD_H)
40 #include "chartypes.h"
41 #if defined (HAVE_PWD_H)
47 #define NEED_XTRACE_SET_DECL
51 #include "execute_cmd.h"
53 #include "mailcheck.h"
62 #include "builtins/getopt.h"
63 #include "builtins/common.h"
64 #include "builtins/builtext.h"
66 #if defined (READLINE)
67 # include "bashline.h"
68 # include <readline/readline.h>
70 # include <tilde/tilde.h>
74 # include "bashhist.h"
75 # include <readline/history.h>
78 #if defined (PROGRAMMABLE_COMPLETION)
79 # include "pcomplete.h"
82 #define TEMPENV_HASH_BUCKETS 4 /* must be power of two */
84 #define ifsname(s) ((s)[0] == 'I' && (s)[1] == 'F' && (s)[2] == 'S' && (s)[3] == '\0')
86 extern char **environ;
88 /* Variables used here and defined in other files. */
89 extern int posixly_correct;
90 extern int line_number, line_number_base;
91 extern int subshell_environment, indirection_level, subshell_level;
92 extern int build_version, patch_level;
93 extern int expanding_redir;
94 extern int last_command_exit_value;
95 extern char *dist_version, *release_status;
96 extern char *shell_name;
97 extern char *primary_prompt, *secondary_prompt;
98 extern char *current_host_name;
99 extern sh_builtin_func_t *this_shell_builtin;
100 extern SHELL_VAR *this_shell_function;
101 extern char *the_printed_command_except_trap;
102 extern char *this_command_name;
103 extern char *command_execution_string;
104 extern time_t shell_start_time;
105 extern int assigning_in_environment;
106 extern int executing_builtin;
107 extern int funcnest_max;
109 #if defined (READLINE)
110 extern int no_line_editing;
111 extern int perform_hostname_completion;
114 /* The list of shell variables that the user has created at the global
115 scope, or that came from the environment. */
116 VAR_CONTEXT *global_variables = (VAR_CONTEXT *)NULL;
118 /* The current list of shell variables, including function scopes */
119 VAR_CONTEXT *shell_variables = (VAR_CONTEXT *)NULL;
121 /* The list of shell functions that the user has created, or that came from
123 HASH_TABLE *shell_functions = (HASH_TABLE *)NULL;
125 #if defined (DEBUGGER)
126 /* The table of shell function definitions that the user defined or that
127 came from the environment. */
128 HASH_TABLE *shell_function_defs = (HASH_TABLE *)NULL;
131 /* The current variable context. This is really a count of how deep into
132 executing functions we are. */
133 int variable_context = 0;
135 /* The set of shell assignments which are made only in the environment
136 for a single command. */
137 HASH_TABLE *temporary_env = (HASH_TABLE *)NULL;
139 /* Set to non-zero if an assignment error occurs while putting variables
140 into the temporary environment. */
141 int tempenv_assign_error;
143 /* Some funky variables which are known about specially. Here is where
144 "$*", "$1", and all the cruft is kept. */
145 char *dollar_vars[10];
146 WORD_LIST *rest_of_args = (WORD_LIST *)NULL;
148 /* The value of $$. */
149 pid_t dollar_dollar_pid;
151 /* Non-zero means that we have to remake EXPORT_ENV. */
152 int array_needs_making = 1;
154 /* The number of times BASH has been executed. This is set
155 by initialize_variables (). */
158 /* An array which is passed to commands as their environment. It is
159 manufactured from the union of the initial environment and the
160 shell variables that are marked for export. */
161 char **export_env = (char **)NULL;
162 static int export_env_index;
163 static int export_env_size;
165 #if defined (READLINE)
166 static int winsize_assignment; /* currently assigning to LINES or COLUMNS */
169 static HASH_TABLE *last_table_searched; /* hash_lookup sets this */
171 /* Some forward declarations. */
172 static void create_variable_tables __P((void));
174 static void set_machine_vars __P((void));
175 static void set_home_var __P((void));
176 static void set_shell_var __P((void));
177 static char *get_bash_name __P((void));
178 static void initialize_shell_level __P((void));
179 static void uidset __P((void));
180 #if defined (ARRAY_VARS)
181 static void make_vers_array __P((void));
184 static SHELL_VAR *null_assign __P((SHELL_VAR *, char *, arrayind_t, char *));
185 #if defined (ARRAY_VARS)
186 static SHELL_VAR *null_array_assign __P((SHELL_VAR *, char *, arrayind_t, char *));
188 static SHELL_VAR *get_self __P((SHELL_VAR *));
190 #if defined (ARRAY_VARS)
191 static SHELL_VAR *init_dynamic_array_var __P((char *, sh_var_value_func_t *, sh_var_assign_func_t *, int));
192 static SHELL_VAR *init_dynamic_assoc_var __P((char *, sh_var_value_func_t *, sh_var_assign_func_t *, int));
195 static SHELL_VAR *assign_seconds __P((SHELL_VAR *, char *, arrayind_t, char *));
196 static SHELL_VAR *get_seconds __P((SHELL_VAR *));
197 static SHELL_VAR *init_seconds_var __P((void));
199 static int brand __P((void));
200 static void sbrand __P((unsigned long)); /* set bash random number generator. */
201 static void seedrand __P((void)); /* seed generator randomly */
202 static SHELL_VAR *assign_random __P((SHELL_VAR *, char *, arrayind_t, char *));
203 static SHELL_VAR *get_random __P((SHELL_VAR *));
205 static SHELL_VAR *assign_lineno __P((SHELL_VAR *, char *, arrayind_t, char *));
206 static SHELL_VAR *get_lineno __P((SHELL_VAR *));
208 static SHELL_VAR *assign_subshell __P((SHELL_VAR *, char *, arrayind_t, char *));
209 static SHELL_VAR *get_subshell __P((SHELL_VAR *));
211 static SHELL_VAR *get_bashpid __P((SHELL_VAR *));
213 #if defined (HISTORY)
214 static SHELL_VAR *get_histcmd __P((SHELL_VAR *));
217 #if defined (READLINE)
218 static SHELL_VAR *get_comp_wordbreaks __P((SHELL_VAR *));
219 static SHELL_VAR *assign_comp_wordbreaks __P((SHELL_VAR *, char *, arrayind_t, char *));
222 #if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
223 static SHELL_VAR *assign_dirstack __P((SHELL_VAR *, char *, arrayind_t, char *));
224 static SHELL_VAR *get_dirstack __P((SHELL_VAR *));
227 #if defined (ARRAY_VARS)
228 static SHELL_VAR *get_groupset __P((SHELL_VAR *));
230 static SHELL_VAR *build_hashcmd __P((SHELL_VAR *));
231 static SHELL_VAR *get_hashcmd __P((SHELL_VAR *));
232 static SHELL_VAR *assign_hashcmd __P((SHELL_VAR *, char *, arrayind_t, char *));
234 static SHELL_VAR *build_aliasvar __P((SHELL_VAR *));
235 static SHELL_VAR *get_aliasvar __P((SHELL_VAR *));
236 static SHELL_VAR *assign_aliasvar __P((SHELL_VAR *, char *, arrayind_t, char *));
240 static SHELL_VAR *get_funcname __P((SHELL_VAR *));
241 static SHELL_VAR *init_funcname_var __P((void));
243 static void initialize_dynamic_variables __P((void));
245 static SHELL_VAR *hash_lookup __P((const char *, HASH_TABLE *));
246 static SHELL_VAR *new_shell_variable __P((const char *));
247 static SHELL_VAR *make_new_variable __P((const char *, HASH_TABLE *));
248 static SHELL_VAR *bind_variable_internal __P((const char *, char *, HASH_TABLE *, int, int));
250 static void dispose_variable_value __P((SHELL_VAR *));
251 static void free_variable_hash_data __P((PTR_T));
253 static VARLIST *vlist_alloc __P((int));
254 static VARLIST *vlist_realloc __P((VARLIST *, int));
255 static void vlist_add __P((VARLIST *, SHELL_VAR *, int));
257 static void flatten __P((HASH_TABLE *, sh_var_map_func_t *, VARLIST *, int));
259 static int qsort_var_comp __P((SHELL_VAR **, SHELL_VAR **));
261 static SHELL_VAR **vapply __P((sh_var_map_func_t *));
262 static SHELL_VAR **fapply __P((sh_var_map_func_t *));
264 static int visible_var __P((SHELL_VAR *));
265 static int visible_and_exported __P((SHELL_VAR *));
266 static int export_environment_candidate __P((SHELL_VAR *));
267 static int local_and_exported __P((SHELL_VAR *));
268 static int variable_in_context __P((SHELL_VAR *));
269 #if defined (ARRAY_VARS)
270 static int visible_array_vars __P((SHELL_VAR *));
273 static SHELL_VAR *find_nameref_at_context __P((SHELL_VAR *, VAR_CONTEXT *));
274 static SHELL_VAR *find_variable_nameref_context __P((SHELL_VAR *, VAR_CONTEXT *, VAR_CONTEXT **));
275 static SHELL_VAR *find_variable_last_nameref_context __P((SHELL_VAR *, VAR_CONTEXT *, VAR_CONTEXT **));
277 static SHELL_VAR *bind_tempenv_variable __P((const char *, char *));
278 static void push_temp_var __P((PTR_T));
279 static void propagate_temp_var __P((PTR_T));
280 static void dispose_temporary_env __P((sh_free_func_t *));
282 static inline char *mk_env_string __P((const char *, const char *));
283 static char **make_env_array_from_var_list __P((SHELL_VAR **));
284 static char **make_var_export_array __P((VAR_CONTEXT *));
285 static char **make_func_export_array __P((void));
286 static void add_temp_array_to_env __P((char **, int, int));
288 static int n_shell_variables __P((void));
289 static int set_context __P((SHELL_VAR *));
291 static void push_func_var __P((PTR_T));
292 static void push_exported_var __P((PTR_T));
294 static inline int find_special_var __P((const char *));
297 create_variable_tables ()
299 if (shell_variables == 0)
301 shell_variables = global_variables = new_var_context ((char *)NULL, 0);
302 shell_variables->scope = 0;
303 shell_variables->table = hash_create (0);
306 if (shell_functions == 0)
307 shell_functions = hash_create (0);
309 #if defined (DEBUGGER)
310 if (shell_function_defs == 0)
311 shell_function_defs = hash_create (0);
315 /* Initialize the shell variables from the current environment.
316 If PRIVMODE is nonzero, don't import functions from ENV or
319 initialize_shell_variables (env, privmode)
323 char *name, *string, *temp_string;
324 int c, char_index, string_index, string_length, ro;
327 create_variable_tables ();
329 for (string_index = 0; string = env[string_index++]; )
333 while ((c = *string++) && c != '=')
335 if (string[-1] == '=')
336 char_index = string - name - 1;
338 /* If there are weird things in the environment, like `=xxx' or a
339 string without an `=', just skip them. */
343 /* ASSERT(name[char_index] == '=') */
344 name[char_index] = '\0';
345 /* Now, name = env variable name, string = env variable value, and
346 char_index == strlen (name) */
348 temp_var = (SHELL_VAR *)NULL;
350 #if 0 /* Disable exporting shell functions because they are mad. */
351 /* If exported function, define it now. Don't import functions from
352 the environment in privileged mode. */
353 if (privmode == 0 && read_but_dont_execute == 0 && STREQN ("() {", string, 4))
355 string_length = strlen (string);
356 temp_string = (char *)xmalloc (3 + string_length + char_index);
358 strcpy (temp_string, name);
359 temp_string[char_index] = ' ';
360 strcpy (temp_string + char_index + 1, string);
362 /* Don't import function names that are invalid identifiers from the
363 environment, though we still allow them to be defined as shell
365 if (legal_identifier (name))
366 parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD);
368 if (temp_var = find_function (name))
370 VSETATTR (temp_var, (att_exported|att_imported));
371 array_needs_making = 1;
375 if (temp_var = bind_variable (name, string, 0))
377 VSETATTR (temp_var, (att_exported | att_imported | att_invisible));
378 array_needs_making = 1;
380 last_command_exit_value = 1;
381 report_error (_("error importing function definition for `%s'"), name);
385 if (0) ; /* needed for syntax */
387 #if defined (ARRAY_VARS)
389 /* Array variables may not yet be exported. */
390 else if (*string == '(' && string[1] == '[' && string[strlen (string) - 1] == ')')
393 temp_string = extract_array_assignment_list (string, &string_length);
394 temp_var = assign_array_from_string (name, temp_string);
396 VSETATTR (temp_var, (att_exported | att_imported));
397 array_needs_making = 1;
399 # endif /* ARRAY_EXPORT */
402 else if (legal_identifier (name))
408 if (posixly_correct && STREQ (name, "SHELLOPTS"))
410 temp_var = find_variable ("SHELLOPTS");
411 ro = temp_var && readonly_p (temp_var);
413 VUNSETATTR (temp_var, att_readonly);
415 temp_var = bind_variable (name, string, 0);
418 if (legal_identifier (name))
419 VSETATTR (temp_var, (att_exported | att_imported));
421 VSETATTR (temp_var, (att_exported | att_imported | att_invisible));
423 VSETATTR (temp_var, att_readonly);
424 array_needs_making = 1;
428 name[char_index] = '=';
429 /* temp_var can be NULL if it was an exported function with a syntax
430 error (a different bug, but it still shouldn't dump core). */
431 if (temp_var && function_p (temp_var) == 0) /* XXX not yet */
433 CACHE_IMPORTSTR (temp_var, name);
439 /* Set up initial value of $_ */
440 temp_var = set_if_not ("_", dollar_vars[0]);
442 /* Remember this pid. */
443 dollar_dollar_pid = getpid ();
445 /* Now make our own defaults in case the vars that we think are
446 important are missing. */
447 temp_var = set_if_not ("PATH", DEFAULT_PATH_VALUE);
449 set_auto_export (temp_var); /* XXX */
452 temp_var = set_if_not ("TERM", "dumb");
454 set_auto_export (temp_var); /* XXX */
457 #if defined (__QNX__)
458 /* set node id -- don't import it from the environment */
461 # if defined (__QNXNTO__)
462 netmgr_ndtostr(ND2S_LOCAL_STR, ND_LOCAL_NODE, node_name, sizeof(node_name));
464 qnx_nidtostr (getnid (), node_name, sizeof (node_name));
466 temp_var = bind_variable ("NODE", node_name, 0);
467 set_auto_export (temp_var);
471 /* set up the prompts. */
472 if (interactive_shell)
474 #if defined (PROMPT_STRING_DECODE)
475 set_if_not ("PS1", primary_prompt);
477 if (current_user.uid == -1)
478 get_current_user_info ();
479 set_if_not ("PS1", current_user.euid == 0 ? "# " : primary_prompt);
481 set_if_not ("PS2", secondary_prompt);
483 set_if_not ("PS4", "+ ");
485 /* Don't allow IFS to be imported from the environment. */
486 temp_var = bind_variable ("IFS", " \t\n", 0);
489 /* Magic machine types. Pretty convenient. */
492 /* Default MAILCHECK for interactive shells. Defer the creation of a
493 default MAILPATH until the startup files are read, because MAIL
494 names a mail file if MAILPATH is not set, and we should provide a
495 default only if neither is set. */
496 if (interactive_shell)
498 temp_var = set_if_not ("MAILCHECK", posixly_correct ? "600" : "60");
499 VSETATTR (temp_var, att_integer);
502 /* Do some things with shell level. */
503 initialize_shell_level ();
507 /* Initialize the `getopts' stuff. */
508 temp_var = bind_variable ("OPTIND", "1", 0);
509 VSETATTR (temp_var, att_integer);
511 bind_variable ("OPTERR", "1", 0);
514 if (login_shell == 1 && posixly_correct == 0)
517 /* Get the full pathname to THIS shell, and set the BASH variable
519 name = get_bash_name ();
520 temp_var = bind_variable ("BASH", name, 0);
523 /* Make the exported environment variable SHELL be the user's login
524 shell. Note that the `tset' command looks at this variable
525 to determine what style of commands to output; if it ends in "csh",
526 then C-shell commands are output, else Bourne shell commands. */
529 /* Make a variable called BASH_VERSION which contains the version info. */
530 bind_variable ("BASH_VERSION", shell_version_string (), 0);
531 #if defined (ARRAY_VARS)
535 if (command_execution_string)
536 bind_variable ("BASH_EXECUTION_STRING", command_execution_string, 0);
538 /* Find out if we're supposed to be in Posix.2 mode via an
539 environment variable. */
540 temp_var = find_variable ("POSIXLY_CORRECT");
542 temp_var = find_variable ("POSIX_PEDANTIC");
543 if (temp_var && imported_p (temp_var))
544 sv_strict_posix (temp_var->name);
546 #if defined (HISTORY)
547 /* Set history variables to defaults, and then do whatever we would
548 do if the variable had just been set. Do this only in the case
549 that we are remembering commands on the history list. */
550 if (remember_on_history)
552 name = bash_tilde_expand (posixly_correct ? "~/.sh_history" : "~/.bash_history", 0);
554 set_if_not ("HISTFILE", name);
559 /* Seed the random number generator. */
562 /* Handle some "special" variables that we may have inherited from a
564 if (interactive_shell)
566 temp_var = find_variable ("IGNOREEOF");
568 temp_var = find_variable ("ignoreeof");
569 if (temp_var && imported_p (temp_var))
570 sv_ignoreeof (temp_var->name);
573 #if defined (HISTORY)
574 if (interactive_shell && remember_on_history)
576 sv_history_control ("HISTCONTROL");
577 sv_histignore ("HISTIGNORE");
578 sv_histtimefmt ("HISTTIMEFORMAT");
582 #if defined (READLINE) && defined (STRICT_POSIX)
583 /* POSIXLY_CORRECT will only be 1 here if the shell was compiled
585 if (interactive_shell && posixly_correct && no_line_editing == 0)
586 rl_prefer_env_winsize = 1;
587 #endif /* READLINE && STRICT_POSIX */
592 * I'm tired of the arguing and bug reports. Bash now leaves SSH_CLIENT
593 * and SSH2_CLIENT alone. I'm going to rely on the shell_level check in
594 * isnetconn() to avoid running the startup files more often than wanted.
595 * That will, of course, only work if the user's login shell is bash, so
596 * I've made that behavior conditional on SSH_SOURCE_BASHRC being defined
600 temp_var = find_variable ("SSH_CLIENT");
601 if (temp_var && imported_p (temp_var))
603 VUNSETATTR (temp_var, att_exported);
604 array_needs_making = 1;
606 temp_var = find_variable ("SSH2_CLIENT");
607 if (temp_var && imported_p (temp_var))
609 VUNSETATTR (temp_var, att_exported);
610 array_needs_making = 1;
614 /* Get the user's real and effective user ids. */
617 temp_var = find_variable ("BASH_XTRACEFD");
618 if (temp_var && imported_p (temp_var))
619 sv_xtracefd (temp_var->name);
621 /* Initialize the dynamic variables, and seed their values. */
622 initialize_dynamic_variables ();
625 /* **************************************************************** */
627 /* Setting values for special shell variables */
629 /* **************************************************************** */
636 temp_var = set_if_not ("HOSTTYPE", HOSTTYPE);
637 temp_var = set_if_not ("OSTYPE", OSTYPE);
638 temp_var = set_if_not ("MACHTYPE", MACHTYPE);
640 temp_var = set_if_not ("HOSTNAME", current_host_name);
643 /* Set $HOME to the information in the password file if we didn't get
644 it from the environment. */
646 /* This function is not static so the tilde and readline libraries can
651 if (current_user.home_dir == 0)
652 get_current_user_info ();
653 return current_user.home_dir;
661 temp_var = find_variable ("HOME");
663 temp_var = bind_variable ("HOME", sh_get_home_dir (), 0);
665 VSETATTR (temp_var, att_exported);
669 /* Set $SHELL to the user's login shell if it is not already set. Call
670 get_current_user_info if we haven't already fetched the shell. */
676 temp_var = find_variable ("SHELL");
679 if (current_user.shell == 0)
680 get_current_user_info ();
681 temp_var = bind_variable ("SHELL", current_user.shell, 0);
684 VSETATTR (temp_var, att_exported);
693 if ((login_shell == 1) && RELPATH(shell_name))
695 if (current_user.shell == 0)
696 get_current_user_info ();
697 name = savestring (current_user.shell);
699 else if (ABSPATH(shell_name))
700 name = savestring (shell_name);
701 else if (shell_name[0] == '.' && shell_name[1] == '/')
703 /* Fast path for common case. */
707 cdir = get_string_value ("PWD");
711 name = (char *)xmalloc (len + strlen (shell_name) + 1);
713 strcpy (name + len, shell_name + 1);
716 name = savestring (shell_name);
723 tname = find_user_command (shell_name);
727 /* Try the current directory. If there is not an executable
728 there, just punt and use the login shell. */
729 s = file_status (shell_name);
732 tname = make_absolute (shell_name, get_string_value ("PWD"));
733 if (*shell_name == '.')
735 name = sh_canonpath (tname, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
746 if (current_user.shell == 0)
747 get_current_user_info ();
748 name = savestring (current_user.shell);
753 name = full_pathname (tname);
762 adjust_shell_level (change)
765 char new_level[5], *old_SHLVL;
769 old_SHLVL = get_string_value ("SHLVL");
770 if (old_SHLVL == 0 || *old_SHLVL == '\0' || legal_number (old_SHLVL, &old_level) == 0)
773 shell_level = old_level + change;
776 else if (shell_level > 1000)
778 internal_warning (_("shell level (%d) too high, resetting to 1"), shell_level);
782 /* We don't need the full generality of itos here. */
783 if (shell_level < 10)
785 new_level[0] = shell_level + '0';
788 else if (shell_level < 100)
790 new_level[0] = (shell_level / 10) + '0';
791 new_level[1] = (shell_level % 10) + '0';
794 else if (shell_level < 1000)
796 new_level[0] = (shell_level / 100) + '0';
797 old_level = shell_level % 100;
798 new_level[1] = (old_level / 10) + '0';
799 new_level[2] = (old_level % 10) + '0';
803 temp_var = bind_variable ("SHLVL", new_level, 0);
804 set_auto_export (temp_var);
808 initialize_shell_level ()
810 adjust_shell_level (1);
813 /* If we got PWD from the environment, update our idea of the current
814 working directory. In any case, make sure that PWD exists before
815 checking it. It is possible for getcwd () to fail on shell startup,
816 and in that case, PWD would be undefined. If this is an interactive
817 login shell, see if $HOME is the current working directory, and if
818 that's not the same string as $PWD, set PWD=$HOME. */
823 SHELL_VAR *temp_var, *home_var;
824 char *temp_string, *home_string;
826 home_var = find_variable ("HOME");
827 home_string = home_var ? value_cell (home_var) : (char *)NULL;
829 temp_var = find_variable ("PWD");
830 if (temp_var && imported_p (temp_var) &&
831 (temp_string = value_cell (temp_var)) &&
832 same_file (temp_string, ".", (struct stat *)NULL, (struct stat *)NULL))
833 set_working_directory (temp_string);
834 else if (home_string && interactive_shell && login_shell &&
835 same_file (home_string, ".", (struct stat *)NULL, (struct stat *)NULL))
837 set_working_directory (home_string);
838 temp_var = bind_variable ("PWD", home_string, 0);
839 set_auto_export (temp_var);
843 temp_string = get_working_directory ("shell-init");
846 temp_var = bind_variable ("PWD", temp_string, 0);
847 set_auto_export (temp_var);
852 /* According to the Single Unix Specification, v2, $OLDPWD is an
853 `environment variable' and therefore should be auto-exported.
854 Make a dummy invisible variable for OLDPWD, and mark it as exported. */
855 temp_var = bind_variable ("OLDPWD", (char *)NULL, 0);
856 VSETATTR (temp_var, (att_exported | att_invisible));
859 /* Make a variable $PPID, which holds the pid of the shell's parent. */
863 char namebuf[INT_STRLEN_BOUND(pid_t) + 1], *name;
866 name = inttostr (getppid (), namebuf, sizeof(namebuf));
867 temp_var = find_variable ("PPID");
869 VUNSETATTR (temp_var, (att_readonly | att_exported));
870 temp_var = bind_variable ("PPID", name, 0);
871 VSETATTR (temp_var, (att_readonly | att_integer));
877 char buff[INT_STRLEN_BOUND(uid_t) + 1], *b;
878 register SHELL_VAR *v;
880 b = inttostr (current_user.uid, buff, sizeof (buff));
881 v = find_variable ("UID");
884 v = bind_variable ("UID", b, 0);
885 VSETATTR (v, (att_readonly | att_integer));
888 if (current_user.euid != current_user.uid)
889 b = inttostr (current_user.euid, buff, sizeof (buff));
891 v = find_variable ("EUID");
894 v = bind_variable ("EUID", b, 0);
895 VSETATTR (v, (att_readonly | att_integer));
899 #if defined (ARRAY_VARS)
905 char *s, d[32], b[INT_STRLEN_BOUND(int) + 1];
907 unbind_variable ("BASH_VERSINFO");
909 vv = make_new_array_variable ("BASH_VERSINFO");
910 av = array_cell (vv);
911 strcpy (d, dist_version);
915 array_insert (av, 0, d);
916 array_insert (av, 1, s);
917 s = inttostr (patch_level, b, sizeof (b));
918 array_insert (av, 2, s);
919 s = inttostr (build_version, b, sizeof (b));
920 array_insert (av, 3, s);
921 array_insert (av, 4, release_status);
922 array_insert (av, 5, MACHTYPE);
924 VSETATTR (vv, att_readonly);
926 #endif /* ARRAY_VARS */
928 /* Set the environment variables $LINES and $COLUMNS in response to
929 a window size change. */
931 sh_set_lines_and_columns (lines, cols)
934 char val[INT_STRLEN_BOUND(int) + 1], *v;
936 #if defined (READLINE)
937 /* If we are currently assigning to LINES or COLUMNS, don't do anything. */
938 if (winsize_assignment)
942 v = inttostr (lines, val, sizeof (val));
943 bind_variable ("LINES", v, 0);
945 v = inttostr (cols, val, sizeof (val));
946 bind_variable ("COLUMNS", v, 0);
949 /* **************************************************************** */
951 /* Printing variables and values */
953 /* **************************************************************** */
955 /* Print LIST (a list of shell variables) to stdout in such a way that
956 they can be read back in. */
958 print_var_list (list)
959 register SHELL_VAR **list;
962 register SHELL_VAR *var;
964 for (i = 0; list && (var = list[i]); i++)
965 if (invisible_p (var) == 0)
966 print_assignment (var);
969 /* Print LIST (a list of shell functions) to stdout in such a way that
970 they can be read back in. */
972 print_func_list (list)
973 register SHELL_VAR **list;
976 register SHELL_VAR *var;
978 for (i = 0; list && (var = list[i]); i++)
980 printf ("%s ", var->name);
981 print_var_function (var);
986 /* Print the value of a single SHELL_VAR. No newline is
987 output, but the variable is printed in such a way that
988 it can be read back in. */
990 print_assignment (var)
993 if (var_isset (var) == 0)
996 if (function_p (var))
998 printf ("%s", var->name);
999 print_var_function (var);
1002 #if defined (ARRAY_VARS)
1003 else if (array_p (var))
1004 print_array_assignment (var, 0);
1005 else if (assoc_p (var))
1006 print_assoc_assignment (var, 0);
1007 #endif /* ARRAY_VARS */
1010 printf ("%s=", var->name);
1011 print_var_value (var, 1);
1016 /* Print the value cell of VAR, a shell variable. Do not print
1017 the name, nor leading/trailing newline. If QUOTE is non-zero,
1018 and the value contains shell metacharacters, quote the value
1019 in such a way that it can be read back in. */
1021 print_var_value (var, quote)
1027 if (var_isset (var) == 0)
1030 if (quote && posixly_correct == 0 && ansic_shouldquote (value_cell (var)))
1032 t = ansic_quote (value_cell (var), 0, (int *)0);
1036 else if (quote && sh_contains_shell_metas (value_cell (var)))
1038 t = sh_single_quote (value_cell (var));
1043 printf ("%s", value_cell (var));
1046 /* Print the function cell of VAR, a shell variable. Do not
1047 print the name, nor leading/trailing newline. */
1049 print_var_function (var)
1054 if (function_p (var) && var_isset (var))
1056 x = named_function_string ((char *)NULL, function_cell(var), FUNC_MULTILINE|FUNC_EXTERNAL);
1061 /* **************************************************************** */
1063 /* Dynamic Variables */
1065 /* **************************************************************** */
1067 /* DYNAMIC VARIABLES
1069 These are variables whose values are generated anew each time they are
1070 referenced. These are implemented using a pair of function pointers
1071 in the struct variable: assign_func, which is called from bind_variable
1072 and, if arrays are compiled into the shell, some of the functions in
1073 arrayfunc.c, and dynamic_value, which is called from find_variable.
1075 assign_func is called from bind_variable_internal, if
1076 bind_variable_internal discovers that the variable being assigned to
1077 has such a function. The function is called as
1078 SHELL_VAR *temp = (*(entry->assign_func)) (entry, value, ind)
1079 and the (SHELL_VAR *)temp is returned as the value of bind_variable. It
1080 is usually ENTRY (self). IND is an index for an array variable, and
1083 dynamic_value is called from find_variable_internal to return a `new'
1084 value for the specified dynamic varible. If this function is NULL,
1085 the variable is treated as a `normal' shell variable. If it is not,
1086 however, then this function is called like this:
1087 tempvar = (*(var->dynamic_value)) (var);
1089 Sometimes `tempvar' will replace the value of `var'. Other times, the
1090 shell will simply use the string value. Pretty object-oriented, huh?
1092 Be warned, though: if you `unset' a special variable, it loses its
1093 special meaning, even if you subsequently set it.
1095 The special assignment code would probably have been better put in
1096 subst.c: do_assignment_internal, in the same style as
1097 stupidly_hack_special_variables, but I wanted the changes as
1098 localized as possible. */
1100 #define INIT_DYNAMIC_VAR(var, val, gfunc, afunc) \
1103 v = bind_variable (var, (val), 0); \
1104 v->dynamic_value = gfunc; \
1105 v->assign_func = afunc; \
1109 #define INIT_DYNAMIC_ARRAY_VAR(var, gfunc, afunc) \
1112 v = make_new_array_variable (var); \
1113 v->dynamic_value = gfunc; \
1114 v->assign_func = afunc; \
1118 #define INIT_DYNAMIC_ASSOC_VAR(var, gfunc, afunc) \
1121 v = make_new_assoc_variable (var); \
1122 v->dynamic_value = gfunc; \
1123 v->assign_func = afunc; \
1128 null_assign (self, value, unused, key)
1137 #if defined (ARRAY_VARS)
1139 null_array_assign (self, value, ind, key)
1149 /* Degenerate `dynamic_value' function; just returns what's passed without
1158 #if defined (ARRAY_VARS)
1159 /* A generic dynamic array variable initializer. Initialize array variable
1160 NAME with dynamic value function GETFUNC and assignment function SETFUNC. */
1162 init_dynamic_array_var (name, getfunc, setfunc, attrs)
1164 sh_var_value_func_t *getfunc;
1165 sh_var_assign_func_t *setfunc;
1170 v = find_variable (name);
1173 INIT_DYNAMIC_ARRAY_VAR (name, getfunc, setfunc);
1175 VSETATTR (v, attrs);
1180 init_dynamic_assoc_var (name, getfunc, setfunc, attrs)
1182 sh_var_value_func_t *getfunc;
1183 sh_var_assign_func_t *setfunc;
1188 v = find_variable (name);
1191 INIT_DYNAMIC_ASSOC_VAR (name, getfunc, setfunc);
1193 VSETATTR (v, attrs);
1198 /* The value of $SECONDS. This is the number of seconds since shell
1199 invocation, or, the number of seconds since the last assignment + the
1200 value of the last assignment. */
1201 static intmax_t seconds_value_assigned;
1204 assign_seconds (self, value, unused, key)
1210 if (legal_number (value, &seconds_value_assigned) == 0)
1211 seconds_value_assigned = 0;
1212 shell_start_time = NOW;
1220 time_t time_since_start;
1223 time_since_start = NOW - shell_start_time;
1224 p = itos(seconds_value_assigned + time_since_start);
1226 FREE (value_cell (var));
1228 VSETATTR (var, att_integer);
1229 var_setvalue (var, p);
1238 v = find_variable ("SECONDS");
1241 if (legal_number (value_cell(v), &seconds_value_assigned) == 0)
1242 seconds_value_assigned = 0;
1244 INIT_DYNAMIC_VAR ("SECONDS", (v ? value_cell (v) : (char *)NULL), get_seconds, assign_seconds);
1248 /* The random number seed. You can change this by setting RANDOM. */
1249 static unsigned long rseed = 1;
1250 static int last_random_value;
1251 static int seeded_subshell = 0;
1253 /* A linear congruential random number generator based on the example
1254 one in the ANSI C standard. This one isn't very good, but a more
1255 complicated one is overkill. */
1257 /* Returns a pseudo-random number between 0 and 32767. */
1261 /* From "Random number generators: good ones are hard to find",
1262 Park and Miller, Communications of the ACM, vol. 31, no. 10,
1263 October 1988, p. 1195. filtered through FreeBSD */
1266 /* Can't seed with 0. */
1271 rseed = 16807 * l - 2836 * h;
1274 rseed += 0x7fffffff;
1276 return ((unsigned int)(rseed & 32767)); /* was % 32768 */
1279 /* Set the random number generator seed to SEED. */
1285 last_random_value = 0;
1293 gettimeofday (&tv, NULL);
1294 sbrand (tv.tv_sec ^ tv.tv_usec ^ getpid ());
1298 assign_random (self, value, unused, key)
1304 sbrand (strtoul (value, (char **)NULL, 10));
1305 if (subshell_environment)
1306 seeded_subshell = getpid ();
1311 get_random_number ()
1315 /* Reset for command and process substitution. */
1317 if (subshell_environment && seeded_subshell != pid)
1320 seeded_subshell = pid;
1325 while (rv == last_random_value);
1336 rv = get_random_number ();
1337 last_random_value = rv;
1340 FREE (value_cell (var));
1342 VSETATTR (var, att_integer);
1343 var_setvalue (var, p);
1348 assign_lineno (var, value, unused, key)
1356 if (value == 0 || *value == '\0' || legal_number (value, &new_value) == 0)
1358 line_number = line_number_base = new_value;
1362 /* Function which returns the current line number. */
1370 ln = executing_line_number ();
1372 FREE (value_cell (var));
1373 var_setvalue (var, p);
1378 assign_subshell (var, value, unused, key)
1386 if (value == 0 || *value == '\0' || legal_number (value, &new_value) == 0)
1388 subshell_level = new_value;
1398 p = itos (subshell_level);
1399 FREE (value_cell (var));
1400 var_setvalue (var, p);
1414 FREE (value_cell (var));
1415 VSETATTR (var, att_integer|att_readonly);
1416 var_setvalue (var, p);
1421 get_bash_command (var)
1426 if (the_printed_command_except_trap)
1427 p = savestring (the_printed_command_except_trap);
1430 p = (char *)xmalloc (1);
1433 FREE (value_cell (var));
1434 var_setvalue (var, p);
1438 #if defined (HISTORY)
1445 p = itos (history_number ());
1446 FREE (value_cell (var));
1447 var_setvalue (var, p);
1452 #if defined (READLINE)
1453 /* When this function returns, VAR->value points to malloced memory. */
1455 get_comp_wordbreaks (var)
1458 /* If we don't have anything yet, assign a default value. */
1459 if (rl_completer_word_break_characters == 0 && bash_readline_initialized == 0)
1460 enable_hostname_completion (perform_hostname_completion);
1462 FREE (value_cell (var));
1463 var_setvalue (var, savestring (rl_completer_word_break_characters));
1468 /* When this function returns, rl_completer_word_break_characters points to
1471 assign_comp_wordbreaks (self, value, unused, key)
1477 if (rl_completer_word_break_characters &&
1478 rl_completer_word_break_characters != rl_basic_word_break_characters)
1479 free (rl_completer_word_break_characters);
1481 rl_completer_word_break_characters = savestring (value);
1484 #endif /* READLINE */
1486 #if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
1488 assign_dirstack (self, value, ind, key)
1494 set_dirstack_element (ind, 1, value);
1505 l = get_directory_stack (0);
1506 a = array_from_word_list (l);
1507 array_dispose (array_cell (self));
1509 var_setarray (self, a);
1512 #endif /* PUSHD AND POPD && ARRAY_VARS */
1514 #if defined (ARRAY_VARS)
1515 /* We don't want to initialize the group set with a call to getgroups()
1516 unless we're asked to, but we only want to do it once. */
1524 static char **group_set = (char **)NULL;
1528 group_set = get_group_list (&ng);
1529 a = array_cell (self);
1530 for (i = 0; i < ng; i++)
1531 array_insert (a, i, group_set[i]);
1537 build_hashcmd (self)
1543 BUCKET_CONTENTS *item;
1545 h = assoc_cell (self);
1549 if (hashed_filenames == 0 || HASH_ENTRIES (hashed_filenames) == 0)
1551 var_setvalue (self, (char *)NULL);
1555 h = assoc_create (hashed_filenames->nbuckets);
1556 for (i = 0; i < hashed_filenames->nbuckets; i++)
1558 for (item = hash_items (i, hashed_filenames); item; item = item->next)
1560 k = savestring (item->key);
1561 v = pathdata(item)->path;
1562 assoc_insert (h, k, v);
1566 var_setvalue (self, (char *)h);
1574 build_hashcmd (self);
1579 assign_hashcmd (self, value, ind, key)
1585 phash_insert (key, value, 0, 0);
1586 return (build_hashcmd (self));
1591 build_aliasvar (self)
1597 BUCKET_CONTENTS *item;
1599 h = assoc_cell (self);
1603 if (aliases == 0 || HASH_ENTRIES (aliases) == 0)
1605 var_setvalue (self, (char *)NULL);
1609 h = assoc_create (aliases->nbuckets);
1610 for (i = 0; i < aliases->nbuckets; i++)
1612 for (item = hash_items (i, aliases); item; item = item->next)
1614 k = savestring (item->key);
1615 v = ((alias_t *)(item->data))->value;
1616 assoc_insert (h, k, v);
1620 var_setvalue (self, (char *)h);
1628 build_aliasvar (self);
1633 assign_aliasvar (self, value, ind, key)
1639 add_alias (key, value);
1640 return (build_aliasvar (self));
1644 #endif /* ARRAY_VARS */
1646 /* If ARRAY_VARS is not defined, this just returns the name of any
1647 currently-executing function. If we have arrays, it's a call stack. */
1652 #if ! defined (ARRAY_VARS)
1654 if (variable_context && this_shell_function)
1656 FREE (value_cell (self));
1657 t = savestring (this_shell_function->name);
1658 var_setvalue (self, t);
1665 make_funcname_visible (on_or_off)
1670 v = find_variable ("FUNCNAME");
1671 if (v == 0 || v->dynamic_value == 0)
1675 VUNSETATTR (v, att_invisible);
1677 VSETATTR (v, att_invisible);
1681 init_funcname_var ()
1685 v = find_variable ("FUNCNAME");
1688 #if defined (ARRAY_VARS)
1689 INIT_DYNAMIC_ARRAY_VAR ("FUNCNAME", get_funcname, null_array_assign);
1691 INIT_DYNAMIC_VAR ("FUNCNAME", (char *)NULL, get_funcname, null_assign);
1693 VSETATTR (v, att_invisible|att_noassign);
1698 initialize_dynamic_variables ()
1702 v = init_seconds_var ();
1704 INIT_DYNAMIC_VAR ("BASH_COMMAND", (char *)NULL, get_bash_command, (sh_var_assign_func_t *)NULL);
1705 INIT_DYNAMIC_VAR ("BASH_SUBSHELL", (char *)NULL, get_subshell, assign_subshell);
1707 INIT_DYNAMIC_VAR ("RANDOM", (char *)NULL, get_random, assign_random);
1708 VSETATTR (v, att_integer);
1709 INIT_DYNAMIC_VAR ("LINENO", (char *)NULL, get_lineno, assign_lineno);
1710 VSETATTR (v, att_integer);
1712 INIT_DYNAMIC_VAR ("BASHPID", (char *)NULL, get_bashpid, null_assign);
1713 VSETATTR (v, att_integer|att_readonly);
1715 #if defined (HISTORY)
1716 INIT_DYNAMIC_VAR ("HISTCMD", (char *)NULL, get_histcmd, (sh_var_assign_func_t *)NULL);
1717 VSETATTR (v, att_integer);
1720 #if defined (READLINE)
1721 INIT_DYNAMIC_VAR ("COMP_WORDBREAKS", (char *)NULL, get_comp_wordbreaks, assign_comp_wordbreaks);
1724 #if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
1725 v = init_dynamic_array_var ("DIRSTACK", get_dirstack, assign_dirstack, 0);
1726 #endif /* PUSHD_AND_POPD && ARRAY_VARS */
1728 #if defined (ARRAY_VARS)
1729 v = init_dynamic_array_var ("GROUPS", get_groupset, null_array_assign, att_noassign);
1731 # if defined (DEBUGGER)
1732 v = init_dynamic_array_var ("BASH_ARGC", get_self, null_array_assign, att_noassign|att_nounset);
1733 v = init_dynamic_array_var ("BASH_ARGV", get_self, null_array_assign, att_noassign|att_nounset);
1734 # endif /* DEBUGGER */
1735 v = init_dynamic_array_var ("BASH_SOURCE", get_self, null_array_assign, att_noassign|att_nounset);
1736 v = init_dynamic_array_var ("BASH_LINENO", get_self, null_array_assign, att_noassign|att_nounset);
1738 v = init_dynamic_assoc_var ("BASH_CMDS", get_hashcmd, assign_hashcmd, att_nofree);
1739 # if defined (ALIAS)
1740 v = init_dynamic_assoc_var ("BASH_ALIASES", get_aliasvar, assign_aliasvar, att_nofree);
1744 v = init_funcname_var ();
1747 /* **************************************************************** */
1749 /* Retrieving variables and values */
1751 /* **************************************************************** */
1753 /* How to get a pointer to the shell variable or function named NAME.
1754 HASHED_VARS is a pointer to the hash table containing the list
1755 of interest (either variables or functions). */
1758 hash_lookup (name, hashed_vars)
1760 HASH_TABLE *hashed_vars;
1762 BUCKET_CONTENTS *bucket;
1764 bucket = hash_search (name, hashed_vars, 0);
1765 /* If we find the name in HASHED_VARS, set LAST_TABLE_SEARCHED to that
1768 last_table_searched = hashed_vars;
1769 return (bucket ? (SHELL_VAR *)bucket->data : (SHELL_VAR *)NULL);
1773 var_lookup (name, vcontext)
1775 VAR_CONTEXT *vcontext;
1780 v = (SHELL_VAR *)NULL;
1781 for (vc = vcontext; vc; vc = vc->down)
1782 if (v = hash_lookup (name, vc->table))
1788 /* Look up the variable entry named NAME. If SEARCH_TEMPENV is non-zero,
1789 then also search the temporarily built list of exported variables.
1790 The lookup order is:
1792 shell_variables list
1796 find_variable_internal (name, force_tempenv)
1804 var = (SHELL_VAR *)NULL;
1806 /* If explicitly requested, first look in the temporary environment for
1807 the variable. This allows constructs such as "foo=x eval 'echo $foo'"
1808 to get the `exported' value of $foo. This happens if we are executing
1809 a function or builtin, or if we are looking up a variable in a
1810 "subshell environment". */
1811 search_tempenv = force_tempenv || (expanding_redir == 0 && subshell_environment);
1813 if (search_tempenv && temporary_env)
1814 var = hash_lookup (name, temporary_env);
1816 vc = shell_variables;
1818 if (search_tempenv == 0 && /* (subshell_environment & SUBSHELL_COMSUB) && */
1820 (this_shell_builtin == eval_builtin || this_shell_builtin == command_builtin))
1822 itrace("find_variable_internal: search_tempenv == 0: skipping VC_BLTNENV");
1823 while (vc && (vc->flags & VC_BLTNENV))
1826 vc = shell_variables;
1831 var = var_lookup (name, vc);
1834 return ((SHELL_VAR *)NULL);
1836 return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var);
1839 /* Look up and resolve the chain of nameref variables starting at V all the
1840 way to NULL or non-nameref. */
1842 find_variable_nameref (v)
1847 SHELL_VAR *orig, *oldv;
1851 while (v && nameref_p (v))
1854 if (level > NAMEREF_MAX)
1855 return ((SHELL_VAR *)0); /* error message here? */
1856 newname = nameref_cell (v);
1857 if (newname == 0 || *newname == '\0')
1858 return ((SHELL_VAR *)0);
1860 v = find_variable_internal (newname, (expanding_redir == 0 && (assigning_in_environment || executing_builtin)));
1861 if (v == orig || v == oldv)
1863 internal_warning (_("%s: circular name reference"), orig->name);
1864 return ((SHELL_VAR *)0);
1870 /* Resolve the chain of nameref variables for NAME. XXX - could change later */
1872 find_variable_last_nameref (name)
1879 nv = v = find_variable_noref (name);
1881 while (v && nameref_p (v))
1884 if (level > NAMEREF_MAX)
1885 return ((SHELL_VAR *)0); /* error message here? */
1886 newname = nameref_cell (v);
1887 if (newname == 0 || *newname == '\0')
1888 return ((SHELL_VAR *)0);
1890 v = find_variable_internal (newname, (expanding_redir == 0 && (assigning_in_environment || executing_builtin)));
1895 /* Resolve the chain of nameref variables for NAME. XXX - could change later */
1897 find_global_variable_last_nameref (name)
1904 nv = v = find_global_variable_noref (name);
1906 while (v && nameref_p (v))
1909 if (level > NAMEREF_MAX)
1910 return ((SHELL_VAR *)0); /* error message here? */
1911 newname = nameref_cell (v);
1912 if (newname == 0 || *newname == '\0')
1913 return ((SHELL_VAR *)0);
1915 v = find_global_variable_noref (newname);
1921 find_nameref_at_context (v, vc)
1925 SHELL_VAR *nv, *nv2;
1932 while (nv && nameref_p (nv))
1935 if (level > NAMEREF_MAX)
1936 return ((SHELL_VAR *)NULL);
1937 newname = nameref_cell (nv);
1938 if (newname == 0 || *newname == '\0')
1939 return ((SHELL_VAR *)NULL);
1940 nv2 = hash_lookup (newname, vc->table);
1948 /* Do nameref resolution from the VC, which is the local context for some
1949 function or builtin, `up' the chain to the global variables context. If
1950 NVCP is not NULL, return the variable context where we finally ended the
1951 nameref resolution (so the bind_variable_internal can use the correct
1952 variable context and hash table). */
1954 find_variable_nameref_context (v, vc, nvcp)
1959 SHELL_VAR *nv, *nv2;
1962 /* Look starting at the current context all the way `up' */
1963 for (nv = v, nvc = vc; nvc; nvc = nvc->down)
1965 nv2 = find_nameref_at_context (nv, nvc);
1971 if (nameref_p (nv) == 0)
1974 return (nameref_p (nv) ? (SHELL_VAR *)NULL : nv);
1977 /* Do nameref resolution from the VC, which is the local context for some
1978 function or builtin, `up' the chain to the global variables context. If
1979 NVCP is not NULL, return the variable context where we finally ended the
1980 nameref resolution (so the bind_variable_internal can use the correct
1981 variable context and hash table). */
1983 find_variable_last_nameref_context (v, vc, nvcp)
1988 SHELL_VAR *nv, *nv2;
1991 /* Look starting at the current context all the way `up' */
1992 for (nv = v, nvc = vc; nvc; nvc = nvc->down)
1994 nv2 = find_nameref_at_context (nv, nvc);
2001 return (nameref_p (nv) ? nv : (SHELL_VAR *)NULL);
2004 /* Find a variable, forcing a search of the temporary environment first */
2006 find_variable_tempenv (name)
2011 var = find_variable_internal (name, 1);
2012 if (var && nameref_p (var))
2013 var = find_variable_nameref (var);
2017 /* Find a variable, not forcing a search of the temporary environment first */
2019 find_variable_notempenv (name)
2024 var = find_variable_internal (name, 0);
2025 if (var && nameref_p (var))
2026 var = find_variable_nameref (var);
2031 find_global_variable (name)
2036 var = var_lookup (name, global_variables);
2037 if (var && nameref_p (var))
2038 var = find_variable_nameref (var);
2041 return ((SHELL_VAR *)NULL);
2043 return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var);
2047 find_global_variable_noref (name)
2052 var = var_lookup (name, global_variables);
2055 return ((SHELL_VAR *)NULL);
2057 return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var);
2061 find_shell_variable (name)
2066 var = var_lookup (name, shell_variables);
2067 if (var && nameref_p (var))
2068 var = find_variable_nameref (var);
2071 return ((SHELL_VAR *)NULL);
2073 return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var);
2076 /* Look up the variable entry named NAME. Returns the entry or NULL. */
2078 find_variable (name)
2083 last_table_searched = 0;
2084 v = find_variable_internal (name, (expanding_redir == 0 && (assigning_in_environment || executing_builtin)));
2085 if (v && nameref_p (v))
2086 v = find_variable_nameref (v);
2091 find_variable_noref (name)
2096 v = find_variable_internal (name, (expanding_redir == 0 && (assigning_in_environment || executing_builtin)));
2100 /* Look up the function entry whose name matches STRING.
2101 Returns the entry or NULL. */
2103 find_function (name)
2106 return (hash_lookup (name, shell_functions));
2109 /* Find the function definition for the shell function named NAME. Returns
2110 the entry or NULL. */
2112 find_function_def (name)
2115 #if defined (DEBUGGER)
2116 return ((FUNCTION_DEF *)hash_lookup (name, shell_function_defs));
2118 return ((FUNCTION_DEF *)0);
2122 /* Return the value of VAR. VAR is assumed to have been the result of a
2123 lookup without any subscript, if arrays are compiled into the shell. */
2125 get_variable_value (var)
2129 return ((char *)NULL);
2130 #if defined (ARRAY_VARS)
2131 else if (array_p (var))
2132 return (array_reference (array_cell (var), 0));
2133 else if (assoc_p (var))
2134 return (assoc_reference (assoc_cell (var), "0"));
2137 return (value_cell (var));
2140 /* Return the string value of a variable. Return NULL if the variable
2141 doesn't exist. Don't cons a new string. This is a potential memory
2142 leak if the variable is found in the temporary environment. Since
2143 functions and variables have separate name spaces, returns NULL if
2144 var_name is a shell function only. */
2146 get_string_value (var_name)
2147 const char *var_name;
2151 var = find_variable (var_name);
2152 return ((var) ? get_variable_value (var) : (char *)NULL);
2155 /* This is present for use by the tilde and readline libraries. */
2157 sh_get_env_value (v)
2160 return get_string_value (v);
2163 /* **************************************************************** */
2165 /* Creating and setting variables */
2167 /* **************************************************************** */
2169 /* Set NAME to VALUE if NAME has no value. */
2171 set_if_not (name, value)
2176 if (shell_variables == 0)
2177 create_variable_tables ();
2179 v = find_variable (name);
2181 v = bind_variable_internal (name, value, global_variables->table, HASH_NOSRCH, 0);
2185 /* Create a local variable referenced by NAME. */
2187 make_local_variable (name)
2190 SHELL_VAR *new_var, *old_var;
2195 /* local foo; local foo; is a no-op. */
2196 old_var = find_variable (name);
2197 if (old_var && local_p (old_var) && old_var->context == variable_context)
2200 was_tmpvar = old_var && tempvar_p (old_var);
2201 /* If we're making a local variable in a shell function, the temporary env
2202 has already been merged into the function's variable context stack. We
2203 can assume that a temporary var in the same context appears in the same
2204 VAR_CONTEXT and can safely be returned without creating a new variable
2205 (which results in duplicate names in the same VAR_CONTEXT->table */
2206 /* We can't just test tmpvar_p because variables in the temporary env given
2207 to a shell function appear in the function's local variable VAR_CONTEXT
2208 but retain their tempvar attribute. We want temporary variables that are
2209 found in temporary_env, hence the test for last_table_searched, which is
2210 set in hash_lookup and only (so far) checked here. */
2211 if (was_tmpvar && old_var->context == variable_context && last_table_searched != temporary_env)
2213 VUNSETATTR (old_var, att_invisible);
2217 tmp_value = value_cell (old_var);
2219 for (vc = shell_variables; vc; vc = vc->down)
2220 if (vc_isfuncenv (vc) && vc->scope == variable_context)
2225 internal_error (_("make_local_variable: no function context at current scope"));
2226 return ((SHELL_VAR *)NULL);
2228 else if (vc->table == 0)
2229 vc->table = hash_create (TEMPENV_HASH_BUCKETS);
2231 /* Since this is called only from the local/declare/typeset code, we can
2232 call builtin_error here without worry (of course, it will also work
2233 for anything that sets this_command_name). Variables with the `noassign'
2234 attribute may not be made local. The test against old_var's context
2235 level is to disallow local copies of readonly global variables (since I
2236 believe that this could be a security hole). Readonly copies of calling
2237 function local variables are OK. */
2238 if (old_var && (noassign_p (old_var) ||
2239 (readonly_p (old_var) && old_var->context == 0)))
2241 if (readonly_p (old_var))
2243 else if (noassign_p (old_var))
2244 builtin_error (_("%s: variable may not be assigned value"), name);
2246 /* Let noassign variables through with a warning */
2247 if (readonly_p (old_var))
2249 return ((SHELL_VAR *)NULL);
2253 new_var = make_new_variable (name, vc->table);
2256 new_var = make_new_variable (name, vc->table);
2258 /* If we found this variable in one of the temporary environments,
2259 inherit its value. Watch to see if this causes problems with
2260 things like `x=4 local x'. XXX - see above for temporary env
2261 variables with the same context level as variable_context */
2262 /* XXX - we should only do this if the variable is not an array. */
2264 var_setvalue (new_var, savestring (tmp_value));
2266 new_var->attributes = exported_p (old_var) ? att_exported : 0;
2269 vc->flags |= VC_HASLOCAL;
2271 new_var->context = variable_context;
2272 VSETATTR (new_var, att_local);
2277 if (was_tmpvar == 0)
2278 VSETATTR (new_var, att_invisible); /* XXX */
2282 /* Create a new shell variable with name NAME. */
2284 new_shell_variable (name)
2289 entry = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
2291 entry->name = savestring (name);
2292 var_setvalue (entry, (char *)NULL);
2293 CLEAR_EXPORTSTR (entry);
2295 entry->dynamic_value = (sh_var_value_func_t *)NULL;
2296 entry->assign_func = (sh_var_assign_func_t *)NULL;
2298 entry->attributes = 0;
2300 /* Always assume variables are to be made at toplevel!
2301 make_local_variable has the responsibility of changing the
2302 variable context. */
2308 /* Create a new shell variable with name NAME and add it to the hash table
2311 make_new_variable (name, table)
2316 BUCKET_CONTENTS *elt;
2318 entry = new_shell_variable (name);
2320 /* Make sure we have a shell_variables hash table to add to. */
2321 if (shell_variables == 0)
2322 create_variable_tables ();
2324 elt = hash_insert (savestring (name), table, HASH_NOSRCH);
2325 elt->data = (PTR_T)entry;
2330 #if defined (ARRAY_VARS)
2332 make_new_array_variable (name)
2338 entry = make_new_variable (name, global_variables->table);
2339 array = array_create ();
2341 var_setarray (entry, array);
2342 VSETATTR (entry, att_array);
2347 make_local_array_variable (name, assoc_ok)
2354 var = make_local_variable (name);
2355 if (var == 0 || array_p (var) || (assoc_ok && assoc_p (var)))
2358 array = array_create ();
2360 dispose_variable_value (var);
2361 var_setarray (var, array);
2362 VSETATTR (var, att_array);
2367 make_new_assoc_variable (name)
2373 entry = make_new_variable (name, global_variables->table);
2374 hash = assoc_create (0);
2376 var_setassoc (entry, hash);
2377 VSETATTR (entry, att_assoc);
2382 make_local_assoc_variable (name)
2388 var = make_local_variable (name);
2389 if (var == 0 || assoc_p (var))
2392 dispose_variable_value (var);
2393 hash = assoc_create (0);
2395 var_setassoc (var, hash);
2396 VSETATTR (var, att_assoc);
2402 make_variable_value (var, value, flags)
2407 char *retval, *oval;
2408 intmax_t lval, rval;
2409 int expok, olen, op;
2411 /* If this variable has had its type set to integer (via `declare -i'),
2412 then do expression evaluation on it and store the result. The
2413 functions in expr.c (evalexp()) and bind_int_variable() are responsible
2414 for turning off the integer flag if they don't want further
2416 if (integer_p (var))
2418 if (flags & ASS_APPEND)
2420 oval = value_cell (var);
2421 lval = evalexp (oval, &expok); /* ksh93 seems to do this */
2424 top_level_cleanup ();
2425 jump_to_top_level (DISCARD);
2428 rval = evalexp (value, &expok);
2431 top_level_cleanup ();
2432 jump_to_top_level (DISCARD);
2434 /* This can be fooled if the variable's value changes while evaluating
2435 `rval'. We can change it if we move the evaluation of lval to here. */
2436 if (flags & ASS_APPEND)
2438 retval = itos (rval);
2440 #if defined (CASEMOD_ATTRS)
2441 else if (capcase_p (var) || uppercase_p (var) || lowercase_p (var))
2443 if (flags & ASS_APPEND)
2445 oval = get_variable_value (var);
2446 if (oval == 0) /* paranoia */
2448 olen = STRLEN (oval);
2449 retval = (char *)xmalloc (olen + (value ? STRLEN (value) : 0) + 1);
2450 strcpy (retval, oval);
2452 strcpy (retval+olen, value);
2455 retval = savestring (value);
2458 retval = (char *)xmalloc (1);
2461 op = capcase_p (var) ? CASE_CAPITALIZE
2462 : (uppercase_p (var) ? CASE_UPPER : CASE_LOWER);
2463 oval = sh_modcase (retval, (char *)0, op);
2467 #endif /* CASEMOD_ATTRS */
2470 if (flags & ASS_APPEND)
2472 oval = get_variable_value (var);
2473 if (oval == 0) /* paranoia */
2475 olen = STRLEN (oval);
2476 retval = (char *)xmalloc (olen + (value ? STRLEN (value) : 0) + 1);
2477 strcpy (retval, oval);
2479 strcpy (retval+olen, value);
2482 retval = savestring (value);
2485 retval = (char *)xmalloc (1);
2490 retval = (char *)NULL;
2495 /* Bind a variable NAME to VALUE in the HASH_TABLE TABLE, which may be the
2496 temporary environment (but usually is not). */
2498 bind_variable_internal (name, value, table, hflags, aflags)
2507 entry = (hflags & HASH_NOSRCH) ? (SHELL_VAR *)NULL : hash_lookup (name, table);
2508 /* Follow the nameref chain here if this is the global variables table */
2509 if (entry && nameref_p (entry) && (invisible_p (entry) == 0) && table == global_variables->table)
2511 entry = find_global_variable (entry->name);
2512 /* Let's see if we have a nameref referencing a variable that hasn't yet
2515 entry = find_variable_last_nameref (name); /* XXX */
2516 if (entry == 0) /* just in case */
2520 /* The first clause handles `declare -n ref; ref=x;' */
2521 if (entry && invisible_p (entry) && nameref_p (entry))
2523 else if (entry && nameref_p (entry))
2525 newval = nameref_cell (entry);
2526 #if defined (ARRAY_VARS)
2527 /* declare -n foo=x[2] */
2528 if (valid_array_reference (newval))
2529 /* XXX - should it be aflags? */
2530 entry = assign_array_element (newval, make_variable_value (entry, value, 0), aflags);
2534 entry = make_new_variable (newval, table);
2535 var_setvalue (entry, make_variable_value (entry, value, 0));
2538 else if (entry == 0)
2540 entry = make_new_variable (name, table);
2541 var_setvalue (entry, make_variable_value (entry, value, 0)); /* XXX */
2543 else if (entry->assign_func) /* array vars have assign functions now */
2545 INVALIDATE_EXPORTSTR (entry);
2546 newval = (aflags & ASS_APPEND) ? make_variable_value (entry, value, aflags) : value;
2547 if (assoc_p (entry))
2548 entry = (*(entry->assign_func)) (entry, newval, -1, savestring ("0"));
2549 else if (array_p (entry))
2550 entry = (*(entry->assign_func)) (entry, newval, 0, 0);
2552 entry = (*(entry->assign_func)) (entry, newval, -1, 0);
2553 if (newval != value)
2560 if (readonly_p (entry) || noassign_p (entry))
2562 if (readonly_p (entry))
2563 err_readonly (name);
2567 /* Variables which are bound are visible. */
2568 VUNSETATTR (entry, att_invisible);
2570 #if defined (ARRAY_VARS)
2571 if (assoc_p (entry) || array_p (entry))
2572 newval = make_array_variable_value (entry, 0, "0", value, aflags);
2576 newval = make_variable_value (entry, value, aflags); /* XXX */
2578 /* Invalidate any cached export string */
2579 INVALIDATE_EXPORTSTR (entry);
2581 #if defined (ARRAY_VARS)
2582 /* XXX -- this bears looking at again -- XXX */
2583 /* If an existing array variable x is being assigned to with x=b or
2584 `read x' or something of that nature, silently convert it to
2585 x[0]=b or `read x[0]'. */
2586 if (assoc_p (entry))
2588 assoc_insert (assoc_cell (entry), savestring ("0"), newval);
2591 else if (array_p (entry))
2593 array_insert (array_cell (entry), 0, newval);
2599 FREE (value_cell (entry));
2600 var_setvalue (entry, newval);
2604 if (mark_modified_vars)
2605 VSETATTR (entry, att_exported);
2607 if (exported_p (entry))
2608 array_needs_making = 1;
2613 /* Bind a variable NAME to VALUE. This conses up the name
2614 and value strings. If we have a temporary environment, we bind there
2615 first, then we bind into shell_variables. */
2618 bind_variable (name, value, flags)
2624 VAR_CONTEXT *vc, *nvc;
2627 if (shell_variables == 0)
2628 create_variable_tables ();
2630 /* If we have a temporary environment, look there first for the variable,
2631 and, if found, modify the value there before modifying it in the
2632 shell_variables table. This allows sourced scripts to modify values
2633 given to them in a temporary environment while modifying the variable
2634 value that the caller sees. */
2636 bind_tempenv_variable (name, value);
2638 /* XXX -- handle local variables here. */
2639 for (vc = shell_variables; vc; vc = vc->down)
2641 if (vc_isfuncenv (vc) || vc_isbltnenv (vc))
2643 v = hash_lookup (name, vc->table);
2645 if (v && nameref_p (v))
2647 nv = find_variable_nameref_context (v, vc, &nvc);
2650 nv = find_variable_last_nameref_context (v, vc, &nvc);
2651 if (nv && nameref_p (nv))
2653 /* If this nameref variable doesn't have a value yet,
2654 set the value. Otherwise, assign using the value as
2656 if (nameref_cell (nv) == 0)
2657 return (bind_variable_internal (nv->name, value, nvc->table, 0, flags));
2658 return (bind_variable_internal (nameref_cell (nv), value, nvc->table, 0, flags));
2667 return (bind_variable_internal (v->name, value, nvc->table, 0, flags));
2670 /* bind_variable_internal will handle nameref resolution in this case */
2671 return (bind_variable_internal (name, value, global_variables->table, 0, flags));
2675 bind_global_variable (name, value, flags)
2681 VAR_CONTEXT *vc, *nvc;
2684 if (shell_variables == 0)
2685 create_variable_tables ();
2687 /* bind_variable_internal will handle nameref resolution in this case */
2688 return (bind_variable_internal (name, value, global_variables->table, 0, flags));
2691 /* Make VAR, a simple shell variable, have value VALUE. Once assigned a
2692 value, variables are no longer invisible. This is a duplicate of part
2693 of the internals of bind_variable. If the variable is exported, or
2694 all modified variables should be exported, mark the variable for export
2695 and note that the export environment needs to be recreated. */
2697 bind_variable_value (var, value, aflags)
2705 invis = invisible_p (var);
2706 VUNSETATTR (var, att_invisible);
2708 if (var->assign_func)
2710 /* If we're appending, we need the old value, so use
2711 make_variable_value */
2712 t = (aflags & ASS_APPEND) ? make_variable_value (var, value, aflags) : value;
2713 (*(var->assign_func)) (var, t, -1, 0);
2714 if (t != value && t)
2719 t = make_variable_value (var, value, aflags);
2720 #if defined (ARRAY_VARS)
2721 if ((aflags & ASS_NAMEREF) && (t == 0 || *t == 0 || (legal_identifier (t) == 0 && valid_array_reference (t) == 0)))
2723 if ((aflags & ASS_NAMEREF) && (t == 0 || *t == 0 || legal_identifier (t) == 0))
2728 VSETATTR (var, att_invisible); /* XXX */
2729 return ((SHELL_VAR *)NULL);
2731 FREE (value_cell (var));
2732 var_setvalue (var, t);
2735 INVALIDATE_EXPORTSTR (var);
2737 if (mark_modified_vars)
2738 VSETATTR (var, att_exported);
2740 if (exported_p (var))
2741 array_needs_making = 1;
2746 /* Bind/create a shell variable with the name LHS to the RHS.
2747 This creates or modifies a variable such that it is an integer.
2749 This used to be in expr.c, but it is here so that all of the
2750 variable binding stuff is localized. Since we don't want any
2751 recursive evaluation from bind_variable() (possible without this code,
2752 since bind_variable() calls the evaluator for variables with the integer
2753 attribute set), we temporarily turn off the integer attribute for each
2754 variable we set here, then turn it back on after binding as necessary. */
2757 bind_int_variable (lhs, rhs)
2760 register SHELL_VAR *v;
2761 int isint, isarr, implicitarray;
2763 isint = isarr = implicitarray = 0;
2764 #if defined (ARRAY_VARS)
2765 if (valid_array_reference (lhs))
2768 v = array_variable_part (lhs, (char **)0, (int *)0);
2772 v = find_variable (lhs);
2776 isint = integer_p (v);
2777 VUNSETATTR (v, att_integer);
2778 #if defined (ARRAY_VARS)
2779 if (array_p (v) && isarr == 0)
2784 #if defined (ARRAY_VARS)
2786 v = assign_array_element (lhs, rhs, 0);
2787 else if (implicitarray)
2788 v = bind_array_variable (lhs, 0, rhs, 0);
2791 v = bind_variable (lhs, rhs, 0);
2794 VSETATTR (v, att_integer);
2796 VUNSETATTR (v, att_invisible);
2802 bind_var_to_int (var, val)
2806 char ibuf[INT_STRLEN_BOUND (intmax_t) + 1], *p;
2808 p = fmtulong (val, 10, ibuf, sizeof (ibuf), 0);
2809 return (bind_int_variable (var, p));
2812 /* Do a function binding to a variable. You pass the name and
2813 the command to bind to. This conses the name and command. */
2815 bind_function (name, value)
2821 entry = find_function (name);
2824 BUCKET_CONTENTS *elt;
2826 elt = hash_insert (savestring (name), shell_functions, HASH_NOSRCH);
2827 entry = new_shell_variable (name);
2828 elt->data = (PTR_T)entry;
2831 INVALIDATE_EXPORTSTR (entry);
2833 if (var_isset (entry))
2834 dispose_command (function_cell (entry));
2837 var_setfunc (entry, copy_command (value));
2839 var_setfunc (entry, 0);
2841 VSETATTR (entry, att_function);
2843 if (mark_modified_vars)
2844 VSETATTR (entry, att_exported);
2846 VUNSETATTR (entry, att_invisible); /* Just to be sure */
2848 if (exported_p (entry))
2849 array_needs_making = 1;
2851 #if defined (PROGRAMMABLE_COMPLETION)
2852 set_itemlist_dirty (&it_functions);
2858 #if defined (DEBUGGER)
2859 /* Bind a function definition, which includes source file and line number
2860 information in addition to the command, into the FUNCTION_DEF hash table.*/
2862 bind_function_def (name, value)
2864 FUNCTION_DEF *value;
2866 FUNCTION_DEF *entry;
2867 BUCKET_CONTENTS *elt;
2870 entry = find_function_def (name);
2873 dispose_function_def_contents (entry);
2874 entry = copy_function_def_contents (value, entry);
2878 cmd = value->command;
2880 entry = copy_function_def (value);
2881 value->command = cmd;
2883 elt = hash_insert (savestring (name), shell_function_defs, HASH_NOSRCH);
2884 elt->data = (PTR_T *)entry;
2887 #endif /* DEBUGGER */
2889 /* Add STRING, which is of the form foo=bar, to the temporary environment
2890 HASH_TABLE (temporary_env). The functions in execute_cmd.c are
2891 responsible for moving the main temporary env to one of the other
2892 temporary environments. The expansion code in subst.c calls this. */
2894 assign_in_env (word, flags)
2899 char *name, *temp, *value;
2903 string = word->word;
2906 offset = assignment (string, 0);
2907 name = savestring (string);
2908 value = (char *)NULL;
2910 if (name[offset] == '=')
2914 /* don't ignore the `+' when assigning temporary environment */
2915 if (name[offset - 1] == '+')
2917 name[offset - 1] = '\0';
2918 aflags |= ASS_APPEND;
2921 var = find_variable (name);
2922 if (var && (readonly_p (var) || noassign_p (var)))
2924 if (readonly_p (var))
2925 err_readonly (name);
2930 temp = name + offset + 1;
2931 value = expand_assignment_string_to_string (temp, 0);
2933 if (var && (aflags & ASS_APPEND))
2935 temp = make_variable_value (var, value, aflags);
2941 if (temporary_env == 0)
2942 temporary_env = hash_create (TEMPENV_HASH_BUCKETS);
2944 var = hash_lookup (name, temporary_env);
2946 var = make_new_variable (name, temporary_env);
2948 FREE (value_cell (var));
2952 value = (char *)xmalloc (1); /* like do_assignment_internal */
2956 var_setvalue (var, value);
2957 var->attributes |= (att_exported|att_tempvar);
2958 var->context = variable_context; /* XXX */
2960 INVALIDATE_EXPORTSTR (var);
2961 var->exportstr = mk_env_string (name, value);
2963 array_needs_making = 1;
2966 stupidly_hack_special_variables (name);
2968 if (echo_command_at_execute)
2969 /* The Korn shell prints the `+ ' in front of assignment statements,
2971 xtrace_print_assignment (name, value, 0, 1);
2977 /* **************************************************************** */
2979 /* Copying variables */
2981 /* **************************************************************** */
2983 #ifdef INCLUDE_UNUSED
2984 /* Copy VAR to a new data structure and return that structure. */
2989 SHELL_VAR *copy = (SHELL_VAR *)NULL;
2993 copy = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
2995 copy->attributes = var->attributes;
2996 copy->name = savestring (var->name);
2998 if (function_p (var))
2999 var_setfunc (copy, copy_command (function_cell (var)));
3000 #if defined (ARRAY_VARS)
3001 else if (array_p (var))
3002 var_setarray (copy, array_copy (array_cell (var)));
3003 else if (assoc_p (var))
3004 var_setassoc (copy, assoc_copy (assoc_cell (var)));
3006 else if (nameref_cell (var)) /* XXX - nameref */
3007 var_setref (copy, savestring (nameref_cell (var)));
3008 else if (value_cell (var)) /* XXX - nameref */
3009 var_setvalue (copy, savestring (value_cell (var)));
3011 var_setvalue (copy, (char *)NULL);
3013 copy->dynamic_value = var->dynamic_value;
3014 copy->assign_func = var->assign_func;
3016 copy->exportstr = COPY_EXPORTSTR (var);
3018 copy->context = var->context;
3024 /* **************************************************************** */
3026 /* Deleting and unsetting variables */
3028 /* **************************************************************** */
3030 /* Dispose of the information attached to VAR. */
3032 dispose_variable_value (var)
3035 if (function_p (var))
3036 dispose_command (function_cell (var));
3037 #if defined (ARRAY_VARS)
3038 else if (array_p (var))
3039 array_dispose (array_cell (var));
3040 else if (assoc_p (var))
3041 assoc_dispose (assoc_cell (var));
3043 else if (nameref_p (var))
3044 FREE (nameref_cell (var));
3046 FREE (value_cell (var));
3050 dispose_variable (var)
3056 if (nofree_p (var) == 0)
3057 dispose_variable_value (var);
3059 FREE_EXPORTSTR (var);
3063 if (exported_p (var))
3064 array_needs_making = 1;
3069 /* Unset the shell variable referenced by NAME. Unsetting a nameref variable
3070 unsets the variable it resolves to but leaves the nameref alone. */
3072 unbind_variable (name)
3078 v = var_lookup (name, shell_variables);
3079 nv = (v && nameref_p (v)) ? find_variable_nameref (v) : (SHELL_VAR *)NULL;
3081 r = nv ? makunbound (nv->name, shell_variables) : makunbound (name, shell_variables);
3085 /* Unbind NAME, where NAME is assumed to be a nameref variable */
3087 unbind_nameref (name)
3092 v = var_lookup (name, shell_variables);
3093 if (v && nameref_p (v))
3094 return makunbound (name, shell_variables);
3098 /* Unset the shell function named NAME. */
3103 BUCKET_CONTENTS *elt;
3106 elt = hash_remove (name, shell_functions, 0);
3111 #if defined (PROGRAMMABLE_COMPLETION)
3112 set_itemlist_dirty (&it_functions);
3115 func = (SHELL_VAR *)elt->data;
3118 if (exported_p (func))
3119 array_needs_making++;
3120 dispose_variable (func);
3129 #if defined (DEBUGGER)
3131 unbind_function_def (name)
3134 BUCKET_CONTENTS *elt;
3135 FUNCTION_DEF *funcdef;
3137 elt = hash_remove (name, shell_function_defs, 0);
3142 funcdef = (FUNCTION_DEF *)elt->data;
3144 dispose_function_def (funcdef);
3151 #endif /* DEBUGGER */
3154 delete_var (name, vc)
3158 BUCKET_CONTENTS *elt;
3162 for (elt = (BUCKET_CONTENTS *)NULL, v = vc; v; v = v->down)
3163 if (elt = hash_remove (name, v->table, 0))
3169 old_var = (SHELL_VAR *)elt->data;
3173 dispose_variable (old_var);
3177 /* Make the variable associated with NAME go away. HASH_LIST is the
3178 hash table from which this variable should be deleted (either
3179 shell_variables or shell_functions).
3180 Returns non-zero if the variable couldn't be found. */
3182 makunbound (name, vc)
3186 BUCKET_CONTENTS *elt, *new_elt;
3191 for (elt = (BUCKET_CONTENTS *)NULL, v = vc; v; v = v->down)
3192 if (elt = hash_remove (name, v->table, 0))
3198 old_var = (SHELL_VAR *)elt->data;
3200 if (old_var && exported_p (old_var))
3201 array_needs_making++;
3203 /* If we're unsetting a local variable and we're still executing inside
3204 the function, just mark the variable as invisible. The function
3205 eventually called by pop_var_context() will clean it up later. This
3206 must be done so that if the variable is subsequently assigned a new
3207 value inside the function, the `local' attribute is still present.
3208 We also need to add it back into the correct hash table. */
3209 if (old_var && local_p (old_var) && variable_context == old_var->context)
3211 if (nofree_p (old_var))
3212 var_setvalue (old_var, (char *)NULL);
3213 #if defined (ARRAY_VARS)
3214 else if (array_p (old_var))
3215 array_dispose (array_cell (old_var));
3216 else if (assoc_p (old_var))
3217 assoc_dispose (assoc_cell (old_var));
3219 else if (nameref_p (old_var))
3220 FREE (nameref_cell (old_var));
3222 FREE (value_cell (old_var));
3223 /* Reset the attributes. Preserve the export attribute if the variable
3224 came from a temporary environment. Make sure it stays local, and
3225 make it invisible. */
3226 old_var->attributes = (exported_p (old_var) && tempvar_p (old_var)) ? att_exported : 0;
3227 VSETATTR (old_var, att_local);
3228 VSETATTR (old_var, att_invisible);
3229 var_setvalue (old_var, (char *)NULL);
3230 INVALIDATE_EXPORTSTR (old_var);
3232 new_elt = hash_insert (savestring (old_var->name), v->table, 0);
3233 new_elt->data = (PTR_T)old_var;
3234 stupidly_hack_special_variables (old_var->name);
3241 /* Have to save a copy of name here, because it might refer to
3242 old_var->name. If so, stupidly_hack_special_variables will
3243 reference freed memory. */
3244 t = savestring (name);
3249 dispose_variable (old_var);
3250 stupidly_hack_special_variables (t);
3256 /* Get rid of all of the variables in the current context. */
3258 kill_all_local_variables ()
3262 for (vc = shell_variables; vc; vc = vc->down)
3263 if (vc_isfuncenv (vc) && vc->scope == variable_context)
3268 if (vc->table && vc_haslocals (vc))
3270 delete_all_variables (vc->table);
3271 hash_dispose (vc->table);
3273 vc->table = (HASH_TABLE *)NULL;
3277 free_variable_hash_data (data)
3282 var = (SHELL_VAR *)data;
3283 dispose_variable (var);
3286 /* Delete the entire contents of the hash table. */
3288 delete_all_variables (hashed_vars)
3289 HASH_TABLE *hashed_vars;
3291 hash_flush (hashed_vars, free_variable_hash_data);
3294 /* **************************************************************** */
3296 /* Setting variable attributes */
3298 /* **************************************************************** */
3300 #define FIND_OR_MAKE_VARIABLE(name, entry) \
3303 entry = find_variable (name); \
3306 entry = bind_variable (name, "", 0); \
3307 if (!no_invisible_vars && entry) entry->attributes |= att_invisible; \
3312 /* Make the variable associated with NAME be readonly.
3313 If NAME does not exist yet, create it. */
3315 set_var_read_only (name)
3320 FIND_OR_MAKE_VARIABLE (name, entry);
3321 VSETATTR (entry, att_readonly);
3324 #ifdef INCLUDE_UNUSED
3325 /* Make the function associated with NAME be readonly.
3326 If NAME does not exist, we just punt, like auto_export code below. */
3328 set_func_read_only (name)
3333 entry = find_function (name);
3335 VSETATTR (entry, att_readonly);
3338 /* Make the variable associated with NAME be auto-exported.
3339 If NAME does not exist yet, create it. */
3341 set_var_auto_export (name)
3346 FIND_OR_MAKE_VARIABLE (name, entry);
3347 set_auto_export (entry);
3350 /* Make the function associated with NAME be auto-exported. */
3352 set_func_auto_export (name)
3357 entry = find_function (name);
3359 set_auto_export (entry);
3363 /* **************************************************************** */
3365 /* Creating lists of variables */
3367 /* **************************************************************** */
3370 vlist_alloc (nentries)
3375 vlist = (VARLIST *)xmalloc (sizeof (VARLIST));
3376 vlist->list = (SHELL_VAR **)xmalloc ((nentries + 1) * sizeof (SHELL_VAR *));
3377 vlist->list_size = nentries;
3378 vlist->list_len = 0;
3379 vlist->list[0] = (SHELL_VAR *)NULL;
3385 vlist_realloc (vlist, n)
3390 return (vlist = vlist_alloc (n));
3391 if (n > vlist->list_size)
3393 vlist->list_size = n;
3394 vlist->list = (SHELL_VAR **)xrealloc (vlist->list, (vlist->list_size + 1) * sizeof (SHELL_VAR *));
3400 vlist_add (vlist, var, flags)
3407 for (i = 0; i < vlist->list_len; i++)
3408 if (STREQ (var->name, vlist->list[i]->name))
3410 if (i < vlist->list_len)
3413 if (i >= vlist->list_size)
3414 vlist = vlist_realloc (vlist, vlist->list_size + 16);
3416 vlist->list[vlist->list_len++] = var;
3417 vlist->list[vlist->list_len] = (SHELL_VAR *)NULL;
3420 /* Map FUNCTION over the variables in VAR_HASH_TABLE. Return an array of the
3421 variables for which FUNCTION returns a non-zero value. A NULL value
3422 for FUNCTION means to use all variables. */
3424 map_over (function, vc)
3425 sh_var_map_func_t *function;
3433 for (nentries = 0, v = vc; v; v = v->down)
3434 nentries += HASH_ENTRIES (v->table);
3437 return (SHELL_VAR **)NULL;
3439 vlist = vlist_alloc (nentries);
3441 for (v = vc; v; v = v->down)
3442 flatten (v->table, function, vlist, 0);
3450 map_over_funcs (function)
3451 sh_var_map_func_t *function;
3456 if (shell_functions == 0 || HASH_ENTRIES (shell_functions) == 0)
3457 return ((SHELL_VAR **)NULL);
3459 vlist = vlist_alloc (HASH_ENTRIES (shell_functions));
3461 flatten (shell_functions, function, vlist, 0);
3468 /* Flatten VAR_HASH_TABLE, applying FUNC to each member and adding those
3469 elements for which FUNC succeeds to VLIST->list. FLAGS is reserved
3470 for future use. Only unique names are added to VLIST. If FUNC is
3471 NULL, each variable in VAR_HASH_TABLE is added to VLIST. If VLIST is
3472 NULL, FUNC is applied to each SHELL_VAR in VAR_HASH_TABLE. If VLIST
3473 and FUNC are both NULL, nothing happens. */
3475 flatten (var_hash_table, func, vlist, flags)
3476 HASH_TABLE *var_hash_table;
3477 sh_var_map_func_t *func;
3482 register BUCKET_CONTENTS *tlist;
3486 if (var_hash_table == 0 || (HASH_ENTRIES (var_hash_table) == 0) || (vlist == 0 && func == 0))
3489 for (i = 0; i < var_hash_table->nbuckets; i++)
3491 for (tlist = hash_items (i, var_hash_table); tlist; tlist = tlist->next)
3493 var = (SHELL_VAR *)tlist->data;
3495 r = func ? (*func) (var) : 1;
3497 vlist_add (vlist, var, flags);
3503 sort_variables (array)
3506 qsort (array, strvec_len ((char **)array), sizeof (SHELL_VAR *), (QSFUNC *)qsort_var_comp);
3510 qsort_var_comp (var1, var2)
3511 SHELL_VAR **var1, **var2;
3515 if ((result = (*var1)->name[0] - (*var2)->name[0]) == 0)
3516 result = strcmp ((*var1)->name, (*var2)->name);
3521 /* Apply FUNC to each variable in SHELL_VARIABLES, adding each one for
3522 which FUNC succeeds to an array of SHELL_VAR *s. Returns the array. */
3525 sh_var_map_func_t *func;
3529 list = map_over (func, shell_variables);
3530 if (list /* && posixly_correct */)
3531 sort_variables (list);
3535 /* Apply FUNC to each variable in SHELL_FUNCTIONS, adding each one for
3536 which FUNC succeeds to an array of SHELL_VAR *s. Returns the array. */
3539 sh_var_map_func_t *func;
3543 list = map_over_funcs (func);
3544 if (list /* && posixly_correct */)
3545 sort_variables (list);
3549 /* Create a NULL terminated array of all the shell variables. */
3551 all_shell_variables ()
3553 return (vapply ((sh_var_map_func_t *)NULL));
3556 /* Create a NULL terminated array of all the shell functions. */
3558 all_shell_functions ()
3560 return (fapply ((sh_var_map_func_t *)NULL));
3567 return (invisible_p (var) == 0);
3571 all_visible_functions ()
3573 return (fapply (visible_var));
3577 all_visible_variables ()
3579 return (vapply (visible_var));
3582 /* Return non-zero if the variable VAR is visible and exported. Array
3583 variables cannot be exported. */
3585 visible_and_exported (var)
3588 return (invisible_p (var) == 0 && exported_p (var));
3591 /* Candidate variables for the export environment are either valid variables
3592 with the export attribute or invalid variables inherited from the initial
3593 environment and simply passed through. */
3595 export_environment_candidate (var)
3598 return (exported_p (var) && (invisible_p (var) == 0 || imported_p (var)));
3601 /* Return non-zero if VAR is a local variable in the current context and
3604 local_and_exported (var)
3607 return (invisible_p (var) == 0 && local_p (var) && var->context == variable_context && exported_p (var));
3611 all_exported_variables ()
3613 return (vapply (visible_and_exported));
3617 local_exported_variables ()
3619 return (vapply (local_and_exported));
3623 variable_in_context (var)
3626 return (invisible_p (var) == 0 && local_p (var) && var->context == variable_context);
3630 all_local_variables ()
3636 vc = shell_variables;
3637 for (vc = shell_variables; vc; vc = vc->down)
3638 if (vc_isfuncenv (vc) && vc->scope == variable_context)
3643 internal_error (_("all_local_variables: no function context at current scope"));
3644 return (SHELL_VAR **)NULL;
3646 if (vc->table == 0 || HASH_ENTRIES (vc->table) == 0 || vc_haslocals (vc) == 0)
3647 return (SHELL_VAR **)NULL;
3649 vlist = vlist_alloc (HASH_ENTRIES (vc->table));
3651 flatten (vc->table, variable_in_context, vlist, 0);
3656 sort_variables (ret);
3660 #if defined (ARRAY_VARS)
3661 /* Return non-zero if the variable VAR is visible and an array. */
3663 visible_array_vars (var)
3666 return (invisible_p (var) == 0 && array_p (var));
3670 all_array_variables ()
3672 return (vapply (visible_array_vars));
3674 #endif /* ARRAY_VARS */
3677 all_variables_matching_prefix (prefix)
3680 SHELL_VAR **varlist;
3682 int vind, rind, plen;
3684 plen = STRLEN (prefix);
3685 varlist = all_visible_variables ();
3686 for (vind = 0; varlist && varlist[vind]; vind++)
3688 if (varlist == 0 || vind == 0)
3689 return ((char **)NULL);
3690 rlist = strvec_create (vind + 1);
3691 for (vind = rind = 0; varlist[vind]; vind++)
3693 if (plen == 0 || STREQN (prefix, varlist[vind]->name, plen))
3694 rlist[rind++] = savestring (varlist[vind]->name);
3696 rlist[rind] = (char *)0;
3702 /* **************************************************************** */
3704 /* Managing temporary variable scopes */
3706 /* **************************************************************** */
3708 /* Make variable NAME have VALUE in the temporary environment. */
3710 bind_tempenv_variable (name, value)
3716 var = temporary_env ? hash_lookup (name, temporary_env) : (SHELL_VAR *)NULL;
3720 FREE (value_cell (var));
3721 var_setvalue (var, savestring (value));
3722 INVALIDATE_EXPORTSTR (var);
3728 /* Find a variable in the temporary environment that is named NAME.
3729 Return the SHELL_VAR *, or NULL if not found. */
3731 find_tempenv_variable (name)
3734 return (temporary_env ? hash_lookup (name, temporary_env) : (SHELL_VAR *)NULL);
3737 char **tempvar_list;
3740 /* Push the variable described by (SHELL_VAR *)DATA down to the next
3741 variable context from the temporary environment. */
3743 push_temp_var (data)
3747 HASH_TABLE *binding_table;
3749 var = (SHELL_VAR *)data;
3751 binding_table = shell_variables->table;
3752 if (binding_table == 0)
3754 if (shell_variables == global_variables)
3755 /* shouldn't happen */
3756 binding_table = shell_variables->table = global_variables->table = hash_create (0);
3758 binding_table = shell_variables->table = hash_create (TEMPENV_HASH_BUCKETS);
3761 v = bind_variable_internal (var->name, value_cell (var), binding_table, 0, 0);
3763 /* XXX - should we set the context here? It shouldn't matter because of how
3764 assign_in_env works, but might want to check. */
3765 if (binding_table == global_variables->table) /* XXX */
3766 var->attributes &= ~(att_tempvar|att_propagate);
3769 var->attributes |= att_propagate;
3770 if (binding_table == shell_variables->table)
3771 shell_variables->flags |= VC_HASTMPVAR;
3773 v->attributes |= var->attributes;
3775 if (find_special_var (var->name) >= 0)
3776 tempvar_list[tvlist_ind++] = savestring (var->name);
3778 dispose_variable (var);
3782 propagate_temp_var (data)
3787 var = (SHELL_VAR *)data;
3788 if (tempvar_p (var) && (var->attributes & att_propagate))
3789 push_temp_var (data);
3792 if (find_special_var (var->name) >= 0)
3793 tempvar_list[tvlist_ind++] = savestring (var->name);
3794 dispose_variable (var);
3798 /* Free the storage used in the hash table for temporary
3799 environment variables. PUSHF is a function to be called
3800 to free each hash table entry. It takes care of pushing variables
3801 to previous scopes if appropriate. PUSHF stores names of variables
3802 that require special handling (e.g., IFS) on tempvar_list, so this
3803 function can call stupidly_hack_special_variables on all the
3804 variables in the list when the temporary hash table is destroyed. */
3806 dispose_temporary_env (pushf)
3807 sh_free_func_t *pushf;
3811 tempvar_list = strvec_create (HASH_ENTRIES (temporary_env) + 1);
3812 tempvar_list[tvlist_ind = 0] = 0;
3814 hash_flush (temporary_env, pushf);
3815 hash_dispose (temporary_env);
3816 temporary_env = (HASH_TABLE *)NULL;
3818 tempvar_list[tvlist_ind] = 0;
3820 array_needs_making = 1;
3823 sv_ifs ("IFS"); /* XXX here for now -- check setifs in assign_in_env */
3825 for (i = 0; i < tvlist_ind; i++)
3826 stupidly_hack_special_variables (tempvar_list[i]);
3828 strvec_dispose (tempvar_list);
3834 dispose_used_env_vars ()
3838 dispose_temporary_env (propagate_temp_var);
3839 maybe_make_export_env ();
3843 /* Take all of the shell variables in the temporary environment HASH_TABLE
3844 and make shell variables from them at the current variable context. */
3846 merge_temporary_env ()
3849 dispose_temporary_env (push_temp_var);
3852 /* **************************************************************** */
3854 /* Creating and manipulating the environment */
3856 /* **************************************************************** */
3858 static inline char *
3859 mk_env_string (name, value)
3860 const char *name, *value;
3862 int name_len, value_len;
3865 name_len = strlen (name);
3866 value_len = STRLEN (value);
3867 p = (char *)xmalloc (2 + name_len + value_len);
3870 if (value && *value)
3871 strcpy (p + name_len + 1, value);
3873 p[name_len + 1] = '\0';
3888 internal_error (_("%s has null exportstr"), v->name);
3891 if (legal_variable_starter ((unsigned char)*s) == 0)
3893 internal_error (_("invalid character %d in exportstr for %s"), *s, v->name);
3896 for (s = v->exportstr + 1; s && *s; s++)
3900 if (legal_variable_char ((unsigned char)*s) == 0)
3902 internal_error (_("invalid character %d in exportstr for %s"), *s, v->name);
3908 internal_error (_("no `=' in exportstr for %s"), v->name);
3916 make_env_array_from_var_list (vars)
3919 register int i, list_index;
3920 register SHELL_VAR *var;
3921 char **list, *value;
3923 list = strvec_create ((1 + strvec_len ((char **)vars)));
3925 #define USE_EXPORTSTR (value == var->exportstr)
3927 for (i = 0, list_index = 0; var = vars[i]; i++)
3929 #if defined (__CYGWIN__)
3930 /* We don't use the exportstr stuff on Cygwin at all. */
3931 INVALIDATE_EXPORTSTR (var);
3934 value = var->exportstr;
3935 else if (function_p (var))
3936 value = named_function_string ((char *)NULL, function_cell (var), 0);
3937 #if defined (ARRAY_VARS)
3938 else if (array_p (var))
3940 value = array_to_assignment_string (array_cell (var));
3942 continue; /* XXX array vars cannot yet be exported */
3943 # endif /* ARRAY_EXPORT */
3944 else if (assoc_p (var))
3946 value = assoc_to_assignment_string (assoc_cell (var));
3948 continue; /* XXX associative array vars cannot yet be exported */
3952 value = value_cell (var);
3956 /* Gee, I'd like to get away with not using savestring() if we're
3957 using the cached exportstr... */
3958 list[list_index] = USE_EXPORTSTR ? savestring (value)
3959 : mk_env_string (var->name, value);
3961 if (USE_EXPORTSTR == 0)
3962 SAVE_EXPORTSTR (var, list[list_index]);
3965 #undef USE_EXPORTSTR
3968 #if defined (ARRAY_VARS)
3969 if (array_p (var) || assoc_p (var))
3976 list[list_index] = (char *)NULL;
3980 /* Make an array of assignment statements from the hash table
3981 HASHED_VARS which contains SHELL_VARs. Only visible, exported
3982 variables are eligible. */
3984 make_var_export_array (vcxt)
3991 vars = map_over (visible_and_exported, vcxt);
3993 vars = map_over (export_environment_candidate, vcxt);
3997 return (char **)NULL;
3999 list = make_env_array_from_var_list (vars);
4006 make_func_export_array ()
4011 vars = map_over_funcs (visible_and_exported);
4013 return (char **)NULL;
4015 list = make_env_array_from_var_list (vars);
4021 /* Add ENVSTR to the end of the exported environment, EXPORT_ENV. */
4022 #define add_to_export_env(envstr,do_alloc) \
4025 if (export_env_index >= (export_env_size - 1)) \
4027 export_env_size += 16; \
4028 export_env = strvec_resize (export_env, export_env_size); \
4029 environ = export_env; \
4031 export_env[export_env_index++] = (do_alloc) ? savestring (envstr) : envstr; \
4032 export_env[export_env_index] = (char *)NULL; \
4035 /* Add ASSIGN to EXPORT_ENV, or supercede a previous assignment in the
4036 array with the same left-hand side. Return the new EXPORT_ENV. */
4038 add_or_supercede_exported_var (assign, do_alloc)
4045 equal_offset = assignment (assign, 0);
4046 if (equal_offset == 0)
4047 return (export_env);
4049 /* If this is a function, then only supersede the function definition.
4050 We do this by including the `=() {' in the comparison, like
4051 initialize_shell_variables does. */
4052 if (assign[equal_offset + 1] == '(' &&
4053 strncmp (assign + equal_offset + 2, ") {", 3) == 0) /* } */
4056 for (i = 0; i < export_env_index; i++)
4058 if (STREQN (assign, export_env[i], equal_offset + 1))
4060 free (export_env[i]);
4061 export_env[i] = do_alloc ? savestring (assign) : assign;
4062 return (export_env);
4065 add_to_export_env (assign, do_alloc);
4066 return (export_env);
4070 add_temp_array_to_env (temp_array, do_alloc, do_supercede)
4072 int do_alloc, do_supercede;
4076 if (temp_array == 0)
4079 for (i = 0; temp_array[i]; i++)
4082 export_env = add_or_supercede_exported_var (temp_array[i], do_alloc);
4084 add_to_export_env (temp_array[i], do_alloc);
4090 /* Make the environment array for the command about to be executed, if the
4091 array needs making. Otherwise, do nothing. If a shell action could
4092 change the array that commands receive for their environment, then the
4093 code should `array_needs_making++'.
4095 The order to add to the array is:
4097 list of var contexts whose head is shell_variables
4100 This is the shell variable lookup order. We add only new variable
4101 names at each step, which allows local variables and variables in
4102 the temporary environments to shadow variables in the global (or
4103 any previous) scope.
4107 n_shell_variables ()
4112 for (n = 0, vc = shell_variables; vc; vc = vc->down)
4113 n += HASH_ENTRIES (vc->table);
4123 v = find_variable (name);
4124 if (v && exported_p (v))
4126 array_needs_making = 1;
4127 maybe_make_export_env ();
4134 maybe_make_export_env ()
4136 register char **temp_array;
4140 if (array_needs_making)
4143 strvec_flush (export_env);
4145 /* Make a guess based on how many shell variables and functions we
4146 have. Since there will always be array variables, and array
4147 variables are not (yet) exported, this will always be big enough
4148 for the exported variables and functions. */
4149 new_size = n_shell_variables () + HASH_ENTRIES (shell_functions) + 1 +
4150 HASH_ENTRIES (temporary_env);
4151 if (new_size > export_env_size)
4153 export_env_size = new_size;
4154 export_env = strvec_resize (export_env, export_env_size);
4155 environ = export_env;
4157 export_env[export_env_index = 0] = (char *)NULL;
4159 /* Make a dummy variable context from the temporary_env, stick it on
4160 the front of shell_variables, call make_var_export_array on the
4161 whole thing to flatten it, and convert the list of SHELL_VAR *s
4162 to the form needed by the environment. */
4165 tcxt = new_var_context ((char *)NULL, 0);
4166 tcxt->table = temporary_env;
4167 tcxt->down = shell_variables;
4170 tcxt = shell_variables;
4172 temp_array = make_var_export_array (tcxt);
4174 add_temp_array_to_env (temp_array, 0, 0);
4176 if (tcxt != shell_variables)
4179 #if defined (RESTRICTED_SHELL)
4180 /* Restricted shells may not export shell functions. */
4181 temp_array = restricted ? (char **)0 : make_func_export_array ();
4183 temp_array = make_func_export_array ();
4186 add_temp_array_to_env (temp_array, 0, 0);
4188 array_needs_making = 0;
4192 /* This is an efficiency hack. PWD and OLDPWD are auto-exported, so
4193 we will need to remake the exported environment every time we
4194 change directories. `_' is always put into the environment for
4195 every external command, so without special treatment it will always
4196 cause the environment to be remade.
4198 If there is no other reason to make the exported environment, we can
4199 just update the variables in place and mark the exported environment
4200 as no longer needing a remake. */
4202 update_export_env_inplace (env_prefix, preflen, value)
4209 evar = (char *)xmalloc (STRLEN (value) + preflen + 1);
4210 strcpy (evar, env_prefix);
4212 strcpy (evar + preflen, value);
4213 export_env = add_or_supercede_exported_var (evar, 0);
4216 /* We always put _ in the environment as the name of this command. */
4218 put_command_name_into_env (command_name)
4221 update_export_env_inplace ("_=", 2, command_name);
4224 /* **************************************************************** */
4226 /* Managing variable contexts */
4228 /* **************************************************************** */
4230 /* Allocate and return a new variable context with NAME and FLAGS.
4231 NAME can be NULL. */
4234 new_var_context (name, flags)
4240 vc = (VAR_CONTEXT *)xmalloc (sizeof (VAR_CONTEXT));
4241 vc->name = name ? savestring (name) : (char *)NULL;
4242 vc->scope = variable_context;
4245 vc->up = vc->down = (VAR_CONTEXT *)NULL;
4246 vc->table = (HASH_TABLE *)NULL;
4251 /* Free a variable context and its data, including the hash table. Dispose
4252 all of the variables. */
4254 dispose_var_context (vc)
4261 delete_all_variables (vc->table);
4262 hash_dispose (vc->table);
4268 /* Set VAR's scope level to the current variable context. */
4273 return (var->context = variable_context);
4276 /* Make a new variable context with NAME and FLAGS and a HASH_TABLE of
4277 temporary variables, and push it onto shell_variables. This is
4278 for shell functions. */
4280 push_var_context (name, flags, tempvars)
4283 HASH_TABLE *tempvars;
4287 vc = new_var_context (name, flags);
4288 vc->table = tempvars;
4291 /* Have to do this because the temp environment was created before
4292 variable_context was incremented. */
4293 flatten (tempvars, set_context, (VARLIST *)NULL, 0);
4294 vc->flags |= VC_HASTMPVAR;
4296 vc->down = shell_variables;
4297 shell_variables->up = vc;
4299 return (shell_variables = vc);
4303 push_func_var (data)
4308 var = (SHELL_VAR *)data;
4310 if (tempvar_p (var) && (posixly_correct || (var->attributes & att_propagate)))
4312 /* Make sure we have a hash table to store the variable in while it is
4313 being propagated down to the global variables table. Create one if
4315 if ((vc_isfuncenv (shell_variables) || vc_istempenv (shell_variables)) && shell_variables->table == 0)
4316 shell_variables->table = hash_create (0);
4317 /* XXX - should we set v->context here? */
4318 v = bind_variable_internal (var->name, value_cell (var), shell_variables->table, 0, 0);
4319 if (shell_variables == global_variables)
4320 var->attributes &= ~(att_tempvar|att_propagate);
4322 shell_variables->flags |= VC_HASTMPVAR;
4323 v->attributes |= var->attributes;
4326 stupidly_hack_special_variables (var->name); /* XXX */
4328 dispose_variable (var);
4331 /* Pop the top context off of VCXT and dispose of it, returning the rest of
4336 VAR_CONTEXT *ret, *vcxt;
4338 vcxt = shell_variables;
4339 if (vc_isfuncenv (vcxt) == 0)
4341 internal_error (_("pop_var_context: head of shell_variables not a function context"));
4345 if (ret = vcxt->down)
4347 ret->up = (VAR_CONTEXT *)NULL;
4348 shell_variables = ret;
4350 hash_flush (vcxt->table, push_func_var);
4351 dispose_var_context (vcxt);
4354 internal_error (_("pop_var_context: no global_variables context"));
4357 /* Delete the HASH_TABLEs for all variable contexts beginning at VCXT, and
4358 all of the VAR_CONTEXTs except GLOBAL_VARIABLES. */
4360 delete_all_contexts (vcxt)
4365 for (v = vcxt; v != global_variables; v = t)
4368 dispose_var_context (v);
4371 delete_all_variables (global_variables->table);
4372 shell_variables = global_variables;
4375 /* **************************************************************** */
4377 /* Pushing and Popping temporary variable scopes */
4379 /* **************************************************************** */
4382 push_scope (flags, tmpvars)
4384 HASH_TABLE *tmpvars;
4386 return (push_var_context ((char *)NULL, flags, tmpvars));
4390 push_exported_var (data)
4395 var = (SHELL_VAR *)data;
4397 /* If a temp var had its export attribute set, or it's marked to be
4398 propagated, bind it in the previous scope before disposing it. */
4399 /* XXX - This isn't exactly right, because all tempenv variables have the
4400 export attribute set. */
4402 if (exported_p (var) || (var->attributes & att_propagate))
4404 if (tempvar_p (var) && exported_p (var) && (var->attributes & att_propagate))
4407 var->attributes &= ~att_tempvar; /* XXX */
4408 v = bind_variable_internal (var->name, value_cell (var), shell_variables->table, 0, 0);
4409 if (shell_variables == global_variables)
4410 var->attributes &= ~att_propagate;
4411 v->attributes |= var->attributes;
4414 stupidly_hack_special_variables (var->name); /* XXX */
4416 dispose_variable (var);
4420 pop_scope (is_special)
4423 VAR_CONTEXT *vcxt, *ret;
4425 vcxt = shell_variables;
4426 if (vc_istempscope (vcxt) == 0)
4428 internal_error (_("pop_scope: head of shell_variables not a temporary environment scope"));
4434 ret->up = (VAR_CONTEXT *)NULL;
4436 shell_variables = ret;
4438 /* Now we can take care of merging variables in VCXT into set of scopes
4439 whose head is RET (shell_variables). */
4444 hash_flush (vcxt->table, push_func_var);
4446 hash_flush (vcxt->table, push_exported_var);
4447 hash_dispose (vcxt->table);
4451 sv_ifs ("IFS"); /* XXX here for now */
4454 /* **************************************************************** */
4456 /* Pushing and Popping function contexts */
4458 /* **************************************************************** */
4460 static WORD_LIST **dollar_arg_stack = (WORD_LIST **)NULL;
4461 static int dollar_arg_stack_slots;
4462 static int dollar_arg_stack_index;
4464 /* XXX - we might want to consider pushing and popping the `getopts' state
4465 when we modify the positional parameters. */
4467 push_context (name, is_subshell, tempvars)
4468 char *name; /* function name */
4470 HASH_TABLE *tempvars;
4472 if (is_subshell == 0)
4473 push_dollar_vars ();
4475 push_var_context (name, VC_FUNCENV, tempvars);
4478 /* Only called when subshell == 0, so we don't need to check, and can
4479 unconditionally pop the dollar vars off the stack. */
4487 sv_ifs ("IFS"); /* XXX here for now */
4490 /* Save the existing positional parameters on a stack. */
4494 if (dollar_arg_stack_index + 2 > dollar_arg_stack_slots)
4496 dollar_arg_stack = (WORD_LIST **)
4497 xrealloc (dollar_arg_stack, (dollar_arg_stack_slots += 10)
4498 * sizeof (WORD_LIST *));
4500 dollar_arg_stack[dollar_arg_stack_index++] = list_rest_of_args ();
4501 dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
4504 /* Restore the positional parameters from our stack. */
4508 if (!dollar_arg_stack || dollar_arg_stack_index == 0)
4511 remember_args (dollar_arg_stack[--dollar_arg_stack_index], 1);
4512 dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
4513 dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
4514 set_dollar_vars_unchanged ();
4518 dispose_saved_dollar_vars ()
4520 if (!dollar_arg_stack || dollar_arg_stack_index == 0)
4523 dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
4524 dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
4527 /* Manipulate the special BASH_ARGV and BASH_ARGC variables. */
4533 #if defined (ARRAY_VARS) && defined (DEBUGGER)
4534 SHELL_VAR *bash_argv_v, *bash_argc_v;
4535 ARRAY *bash_argv_a, *bash_argc_a;
4540 GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a);
4541 GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
4543 for (l = list, i = 0; l; l = l->next, i++)
4544 array_push (bash_argv_a, l->word->word);
4547 array_push (bash_argc_a, t);
4549 #endif /* ARRAY_VARS && DEBUGGER */
4552 /* Remove arguments from BASH_ARGV array. Pop top element off BASH_ARGC
4553 array and use that value as the count of elements to remove from
4558 #if defined (ARRAY_VARS) && defined (DEBUGGER)
4559 SHELL_VAR *bash_argv_v, *bash_argc_v;
4560 ARRAY *bash_argv_a, *bash_argc_a;
4564 GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a);
4565 GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
4567 ce = array_shift (bash_argc_a, 1, 0);
4568 if (ce == 0 || legal_number (element_value (ce), &i) == 0)
4572 array_pop (bash_argv_a);
4573 array_dispose_element (ce);
4574 #endif /* ARRAY_VARS && DEBUGGER */
4577 /*************************************************
4579 * Functions to manage special variables *
4581 *************************************************/
4583 /* Extern declarations for variables this code has to manage. */
4584 extern int eof_encountered, eof_encountered_limit, ignoreeof;
4586 #if defined (READLINE)
4587 extern int hostname_list_initialized;
4590 /* An alist of name.function for each special variable. Most of the
4591 functions don't do much, and in fact, this would be faster with a
4592 switch statement, but by the end of this file, I am sick of switch
4595 #define SET_INT_VAR(name, intvar) intvar = find_variable (name) != 0
4597 /* This table will be sorted with qsort() the first time it's accessed. */
4598 struct name_and_function {
4600 sh_sv_func_t *function;
4603 static struct name_and_function special_vars[] = {
4604 { "BASH_COMPAT", sv_shcompat },
4605 { "BASH_XTRACEFD", sv_xtracefd },
4607 #if defined (JOB_CONTROL)
4608 { "CHILD_MAX", sv_childmax },
4611 #if defined (READLINE)
4612 # if defined (STRICT_POSIX)
4613 { "COLUMNS", sv_winsize },
4615 { "COMP_WORDBREAKS", sv_comp_wordbreaks },
4618 { "FUNCNEST", sv_funcnest },
4620 { "GLOBIGNORE", sv_globignore },
4622 #if defined (HISTORY)
4623 { "HISTCONTROL", sv_history_control },
4624 { "HISTFILESIZE", sv_histsize },
4625 { "HISTIGNORE", sv_histignore },
4626 { "HISTSIZE", sv_histsize },
4627 { "HISTTIMEFORMAT", sv_histtimefmt },
4630 #if defined (__CYGWIN__)
4631 { "HOME", sv_home },
4634 #if defined (READLINE)
4635 { "HOSTFILE", sv_hostfile },
4639 { "IGNOREEOF", sv_ignoreeof },
4641 { "LANG", sv_locale },
4642 { "LC_ALL", sv_locale },
4643 { "LC_COLLATE", sv_locale },
4644 { "LC_CTYPE", sv_locale },
4645 { "LC_MESSAGES", sv_locale },
4646 { "LC_NUMERIC", sv_locale },
4647 { "LC_TIME", sv_locale },
4649 #if defined (READLINE) && defined (STRICT_POSIX)
4650 { "LINES", sv_winsize },
4653 { "MAIL", sv_mail },
4654 { "MAILCHECK", sv_mail },
4655 { "MAILPATH", sv_mail },
4657 { "OPTERR", sv_opterr },
4658 { "OPTIND", sv_optind },
4660 { "PATH", sv_path },
4661 { "POSIXLY_CORRECT", sv_strict_posix },
4663 #if defined (READLINE)
4664 { "TERM", sv_terminal },
4665 { "TERMCAP", sv_terminal },
4666 { "TERMINFO", sv_terminal },
4667 #endif /* READLINE */
4669 { "TEXTDOMAIN", sv_locale },
4670 { "TEXTDOMAINDIR", sv_locale },
4672 #if defined (HAVE_TZSET)
4676 #if defined (HISTORY) && defined (BANG_HISTORY)
4677 { "histchars", sv_histchars },
4678 #endif /* HISTORY && BANG_HISTORY */
4680 { "ignoreeof", sv_ignoreeof },
4682 { (char *)0, (sh_sv_func_t *)0 }
4685 #define N_SPECIAL_VARS (sizeof (special_vars) / sizeof (special_vars[0]) - 1)
4688 sv_compare (sv1, sv2)
4689 struct name_and_function *sv1, *sv2;
4693 if ((r = sv1->name[0] - sv2->name[0]) == 0)
4694 r = strcmp (sv1->name, sv2->name);
4699 find_special_var (name)
4704 for (i = 0; special_vars[i].name; i++)
4706 r = special_vars[i].name[0] - name[0];
4708 r = strcmp (special_vars[i].name, name);
4712 /* Can't match any of rest of elements in sorted list. Take this out
4713 if it causes problems in certain environments. */
4719 /* The variable in NAME has just had its state changed. Check to see if it
4720 is one of the special ones where something special happens. */
4722 stupidly_hack_special_variables (name)
4725 static int sv_sorted = 0;
4728 if (sv_sorted == 0) /* shouldn't need, but it's fairly cheap. */
4730 qsort (special_vars, N_SPECIAL_VARS, sizeof (special_vars[0]),
4731 (QSFUNC *)sv_compare);
4735 i = find_special_var (name);
4737 (*(special_vars[i].function)) (name);
4740 /* Special variables that need hooks to be run when they are unset as part
4741 of shell reinitialization should have their sv_ functions run here. */
4743 reinit_special_variables ()
4745 #if defined (READLINE)
4746 sv_comp_wordbreaks ("COMP_WORDBREAKS");
4748 sv_globignore ("GLOBIGNORE");
4749 sv_opterr ("OPTERR");
4758 v = find_variable ("IFS");
4762 /* What to do just after the PATH variable has changed. */
4771 /* What to do just after one of the MAILxxxx variables has changed. NAME
4772 is the name of the variable. This is called with NAME set to one of
4773 MAIL, MAILCHECK, or MAILPATH. */
4778 /* If the time interval for checking the files has changed, then
4779 reset the mail timer. Otherwise, one of the pathname vars
4780 to the users mailbox has changed, so rebuild the array of
4782 if (name[4] == 'C') /* if (strcmp (name, "MAILCHECK") == 0) */
4783 reset_mail_timer ();
4787 remember_mail_dates ();
4798 v = find_variable (name);
4801 else if (legal_number (value_cell (v), &num) == 0)
4807 /* What to do when GLOBIGNORE changes. */
4809 sv_globignore (name)
4812 if (privileged_mode == 0)
4813 setup_glob_ignore (name);
4816 #if defined (READLINE)
4818 sv_comp_wordbreaks (name)
4823 sv = find_variable (name);
4825 reset_completer_word_break_chars ();
4828 /* What to do just after one of the TERMxxx variables has changed.
4829 If we are an interactive shell, then try to reset the terminal
4830 information in readline. */
4835 if (interactive_shell && no_line_editing == 0)
4836 rl_reset_terminal (get_string_value ("TERM"));
4845 v = find_variable (name);
4847 clear_hostname_list ();
4849 hostname_list_initialized = 0;
4852 #if defined (STRICT_POSIX)
4853 /* In strict posix mode, we allow assignments to LINES and COLUMNS (and values
4854 found in the initial environment) to override the terminal size reported by
4864 if (posixly_correct == 0 || interactive_shell == 0 || no_line_editing)
4867 v = find_variable (name);
4868 if (v == 0 || var_isnull (v))
4869 rl_reset_screen_size ();
4872 if (legal_number (value_cell (v), &xd) == 0)
4874 winsize_assignment = 1;
4875 d = xd; /* truncate */
4876 if (name[0] == 'L') /* LINES */
4877 rl_set_screen_size (d, -1);
4879 rl_set_screen_size (-1, d);
4880 winsize_assignment = 0;
4883 #endif /* STRICT_POSIX */
4884 #endif /* READLINE */
4886 /* Update the value of HOME in the export environment so tilde expansion will
4888 #if defined (__CYGWIN__)
4892 array_needs_making = 1;
4893 maybe_make_export_env ();
4897 #if defined (HISTORY)
4898 /* What to do after the HISTSIZE or HISTFILESIZE variables change.
4899 If there is a value for this HISTSIZE (and it is numeric), then stifle
4900 the history. Otherwise, if there is NO value for this variable,
4901 unstifle the history. If name is HISTFILESIZE, and its value is
4902 numeric, truncate the history file to hold no more than that many
4912 temp = get_string_value (name);
4916 if (legal_number (temp, &num))
4919 if (hmax < 0 && name[4] == 'S')
4920 unstifle_history (); /* unstifle history if HISTSIZE < 0 */
4921 else if (name[4] == 'S')
4923 stifle_history (hmax);
4924 hmax = where_history ();
4925 if (history_lines_this_session > hmax)
4926 history_lines_this_session = hmax;
4928 else if (hmax >= 0) /* truncate HISTFILE if HISTFILESIZE >= 0 */
4930 history_truncate_file (get_string_value ("HISTFILE"), hmax);
4931 if (hmax <= history_lines_in_file)
4932 history_lines_in_file = hmax;
4936 else if (name[4] == 'S')
4937 unstifle_history ();
4940 /* What to do after the HISTIGNORE variable changes. */
4942 sv_histignore (name)
4945 setup_history_ignore (name);
4948 /* What to do after the HISTCONTROL variable changes. */
4950 sv_history_control (name)
4957 history_control = 0;
4958 temp = get_string_value (name);
4960 if (temp == 0 || *temp == 0)
4964 while (val = extract_colon_unit (temp, &tptr))
4966 if (STREQ (val, "ignorespace"))
4967 history_control |= HC_IGNSPACE;
4968 else if (STREQ (val, "ignoredups"))
4969 history_control |= HC_IGNDUPS;
4970 else if (STREQ (val, "ignoreboth"))
4971 history_control |= HC_IGNBOTH;
4972 else if (STREQ (val, "erasedups"))
4973 history_control |= HC_ERASEDUPS;
4979 #if defined (BANG_HISTORY)
4980 /* Setting/unsetting of the history expansion character. */
4987 temp = get_string_value (name);
4990 history_expansion_char = *temp;
4991 if (temp[0] && temp[1])
4993 history_subst_char = temp[1];
4995 history_comment_char = temp[2];
5000 history_expansion_char = '!';
5001 history_subst_char = '^';
5002 history_comment_char = '#';
5005 #endif /* BANG_HISTORY */
5008 sv_histtimefmt (name)
5013 if (v = find_variable (name))
5015 if (history_comment_char == 0)
5016 history_comment_char = '#';
5018 history_write_timestamps = (v != 0);
5020 #endif /* HISTORY */
5022 #if defined (HAVE_TZSET)
5027 if (chkexport (name))
5032 /* If the variable exists, then the value of it can be the number
5033 of times we actually ignore the EOF. The default is small,
5034 (smaller than csh, anyway). */
5042 eof_encountered = 0;
5044 tmp_var = find_variable (name);
5045 ignoreeof = tmp_var != 0;
5046 temp = tmp_var ? value_cell (tmp_var) : (char *)NULL;
5048 eof_encountered_limit = (*temp && all_digits (temp)) ? atoi (temp) : 10;
5049 set_shellopts (); /* make sure `ignoreeof' is/is not in $SHELLOPTS */
5059 tt = get_string_value ("OPTIND");
5064 /* According to POSIX, setting OPTIND=1 resets the internal state
5066 if (s < 0 || s == 1)
5080 tt = get_string_value ("OPTERR");
5081 sh_opterr = (tt && *tt) ? atoi (tt) : 1;
5085 sv_strict_posix (name)
5088 SET_INT_VAR (name, posixly_correct);
5089 posix_initialize (posixly_correct);
5090 #if defined (READLINE)
5091 if (interactive_shell)
5092 posix_readline_initialize (posixly_correct);
5093 #endif /* READLINE */
5094 set_shellopts (); /* make sure `posix' is/is not in $SHELLOPTS */
5104 v = get_string_value (name);
5105 if (name[0] == 'L' && name[1] == 'A') /* LANG */
5106 r = set_lang (name, v);
5108 r = set_locale_var (name, v); /* LC_*, TEXTDOMAIN* */
5111 if (r == 0 && posixly_correct)
5112 last_command_exit_value = 1;
5116 #if defined (ARRAY_VARS)
5118 set_pipestatus_array (ps, nproc)
5126 char *t, tbuf[INT_STRLEN_BOUND(int) + 1];
5128 v = find_variable ("PIPESTATUS");
5130 v = make_new_array_variable ("PIPESTATUS");
5131 if (array_p (v) == 0)
5132 return; /* Do nothing if not an array variable. */
5135 if (a == 0 || array_num_elements (a) == 0)
5137 for (i = 0; i < nproc; i++) /* was ps[i] != -1, not i < nproc */
5139 t = inttostr (ps[i], tbuf, sizeof (tbuf));
5140 array_insert (a, i, t);
5146 if (array_num_elements (a) == nproc && nproc == 1)
5148 ae = element_forw (a->head);
5149 free (element_value (ae));
5150 ae->value = itos (ps[0]);
5152 else if (array_num_elements (a) <= nproc)
5154 /* modify in array_num_elements members in place, then add */
5156 for (i = 0; i < array_num_elements (a); i++)
5158 ae = element_forw (ae);
5159 free (element_value (ae));
5160 ae->value = itos (ps[i]);
5163 for ( ; i < nproc; i++)
5165 t = inttostr (ps[i], tbuf, sizeof (tbuf));
5166 array_insert (a, i, t);
5171 /* deleting elements. it's faster to rebuild the array. */
5173 for (i = 0; ps[i] != -1; i++)
5175 t = inttostr (ps[i], tbuf, sizeof (tbuf));
5176 array_insert (a, i, t);
5182 save_pipestatus_array ()
5187 v = find_variable ("PIPESTATUS");
5188 if (v == 0 || array_p (v) == 0 || array_cell (v) == 0)
5189 return ((ARRAY *)NULL);
5192 a2 = array_copy (array_cell (v));
5198 restore_pipestatus_array (a)
5204 v = find_variable ("PIPESTATUS");
5205 /* XXX - should we still assign even if existing value is NULL? */
5206 if (v == 0 || array_p (v) == 0 || array_cell (v) == 0)
5209 a2 = array_cell (v);
5210 var_setarray (v, a);
5217 set_pipestatus_from_exit (s)
5220 #if defined (ARRAY_VARS)
5221 static int v[2] = { 0, -1 };
5224 set_pipestatus_array (v, 1);
5237 v = find_variable (name);
5245 if (t == 0 || *t == 0)
5249 fd = (int)strtol (t, &e, 10);
5250 if (e != t && *e == '\0' && sh_validfd (fd))
5252 fp = fdopen (fd, "w");
5254 internal_error (_("%s: %s: cannot open as FILE"), name, value_cell (v));
5256 xtrace_set (fd, fp);
5259 internal_error (_("%s: %s: invalid value for trace file descriptor"), name, value_cell (v));
5263 #define MIN_COMPAT_LEVEL 31
5271 int tens, ones, compatval;
5273 v = find_variable (name);
5276 shell_compatibility_level = DEFAULT_COMPAT_LEVEL;
5277 set_compatibility_opts ();
5280 val = value_cell (v);
5281 if (val == 0 || *val == '\0')
5283 shell_compatibility_level = DEFAULT_COMPAT_LEVEL;
5284 set_compatibility_opts ();
5287 /* Handle decimal-like compatibility version specifications: 4.2 */
5288 if (isdigit (val[0]) && val[1] == '.' && isdigit (val[2]) && val[3] == 0)
5290 tens = val[0] - '0';
5291 ones = val[2] - '0';
5292 compatval = tens*10 + ones;
5294 /* Handle integer-like compatibility version specifications: 42 */
5295 else if (isdigit (val[0]) && isdigit (val[1]) && val[2] == 0)
5297 tens = val[0] - '0';
5298 ones = val[1] - '0';
5299 compatval = tens*10 + ones;
5304 internal_error (_("%s: %s: compatibility value out of range"), name, val);
5305 shell_compatibility_level = DEFAULT_COMPAT_LEVEL;
5306 set_compatibility_opts ();
5310 if (compatval < MIN_COMPAT_LEVEL || compatval > DEFAULT_COMPAT_LEVEL)
5313 shell_compatibility_level = compatval;
5314 set_compatibility_opts ();
5317 #if defined (JOB_CONTROL)
5325 tt = get_string_value (name);
5326 s = (tt && *tt) ? atoi (tt) : 0;