1/* variables.c -- Functions for hacking shell variables. */
2
3/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
4
5   This file is part of GNU Bash, the Bourne Again SHell.
6
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.
11
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.
16
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/>.
19*/
20
21#include "config.h"
22
23#include "bashtypes.h"
24#include "posixstat.h"
25#include "posixtime.h"
26
27#if defined (__QNX__)
28#  if defined (__QNXNTO__)
29#    include <sys/netmgr.h>
30#  else
31#    include <sys/vc.h>
32#  endif /* !__QNXNTO__ */
33#endif /* __QNX__ */
34
35#if defined (HAVE_UNISTD_H)
36#  include <unistd.h>
37#endif
38
39#include <stdio.h>
40#include "chartypes.h"
41#if defined (HAVE_PWD_H)
42#  include <pwd.h>
43#endif
44#include "bashansi.h"
45#include "bashintl.h"
46
47#include "shell.h"
48#include "flags.h"
49#include "execute_cmd.h"
50#include "findcmd.h"
51#include "mailcheck.h"
52#include "input.h"
53#include "hashcmd.h"
54#include "pathexp.h"
55#include "alias.h"
56
57#include "builtins/getopt.h"
58#include "builtins/common.h"
59
60#if defined (READLINE)
61#  include "bashline.h"
62#  include <readline/readline.h>
63#else
64#  include <tilde/tilde.h>
65#endif
66
67#if defined (HISTORY)
68#  include "bashhist.h"
69#  include <readline/history.h>
70#endif /* HISTORY */
71
72#if defined (PROGRAMMABLE_COMPLETION)
73#  include "pcomplete.h"
74#endif
75
76#define TEMPENV_HASH_BUCKETS	4	/* must be power of two */
77
78#define ifsname(s)	((s)[0] == 'I' && (s)[1] == 'F' && (s)[2] == 'S' && (s)[3] == '\0')
79
80extern char **environ;
81
82/* Variables used here and defined in other files. */
83extern int posixly_correct;
84extern int line_number;
85extern int subshell_environment, indirection_level, subshell_level;
86extern int build_version, patch_level;
87extern int expanding_redir;
88extern char *dist_version, *release_status;
89extern char *shell_name;
90extern char *primary_prompt, *secondary_prompt;
91extern char *current_host_name;
92extern sh_builtin_func_t *this_shell_builtin;
93extern SHELL_VAR *this_shell_function;
94extern char *the_printed_command_except_trap;
95extern char *this_command_name;
96extern char *command_execution_string;
97extern time_t shell_start_time;
98extern int assigning_in_environment;
99extern int executing_builtin;
100
101#if defined (READLINE)
102extern int no_line_editing;
103extern int perform_hostname_completion;
104#endif
105
106/* The list of shell variables that the user has created at the global
107   scope, or that came from the environment. */
108VAR_CONTEXT *global_variables = (VAR_CONTEXT *)NULL;
109
110/* The current list of shell variables, including function scopes */
111VAR_CONTEXT *shell_variables = (VAR_CONTEXT *)NULL;
112
113/* The list of shell functions that the user has created, or that came from
114   the environment. */
115HASH_TABLE *shell_functions = (HASH_TABLE *)NULL;
116
117#if defined (DEBUGGER)
118/* The table of shell function definitions that the user defined or that
119   came from the environment. */
120HASH_TABLE *shell_function_defs = (HASH_TABLE *)NULL;
121#endif
122
123/* The current variable context.  This is really a count of how deep into
124   executing functions we are. */
125int variable_context = 0;
126
127/* The set of shell assignments which are made only in the environment
128   for a single command. */
129HASH_TABLE *temporary_env = (HASH_TABLE *)NULL;
130
131/* Set to non-zero if an assignment error occurs while putting variables
132   into the temporary environment. */
133int tempenv_assign_error;
134
135/* Some funky variables which are known about specially.  Here is where
136   "$*", "$1", and all the cruft is kept. */
137char *dollar_vars[10];
138WORD_LIST *rest_of_args = (WORD_LIST *)NULL;
139
140/* The value of $$. */
141pid_t dollar_dollar_pid;
142
143/* Non-zero means that we have to remake EXPORT_ENV. */
144int array_needs_making = 1;
145
146/* The number of times BASH has been executed.  This is set
147   by initialize_variables (). */
148int shell_level = 0;
149
150/* An array which is passed to commands as their environment.  It is
151   manufactured from the union of the initial environment and the
152   shell variables that are marked for export. */
153char **export_env = (char **)NULL;
154static int export_env_index;
155static int export_env_size;
156
157#if defined (READLINE)
158static int winsize_assignment;		/* currently assigning to LINES or COLUMNS */
159static int winsize_assigned;		/* assigned to LINES or COLUMNS */
160#endif
161
162/* Some forward declarations. */
163static void create_variable_tables __P((void));
164
165static void set_machine_vars __P((void));
166static void set_home_var __P((void));
167static void set_shell_var __P((void));
168static char *get_bash_name __P((void));
169static void initialize_shell_level __P((void));
170static void uidset __P((void));
171#if defined (ARRAY_VARS)
172static void make_vers_array __P((void));
173#endif
174
175static SHELL_VAR *null_assign __P((SHELL_VAR *, char *, arrayind_t, char *));
176#if defined (ARRAY_VARS)
177static SHELL_VAR *null_array_assign __P((SHELL_VAR *, char *, arrayind_t, char *));
178#endif
179static SHELL_VAR *get_self __P((SHELL_VAR *));
180
181#if defined (ARRAY_VARS)
182static SHELL_VAR *init_dynamic_array_var __P((char *, sh_var_value_func_t *, sh_var_assign_func_t *, int));
183static SHELL_VAR *init_dynamic_assoc_var __P((char *, sh_var_value_func_t *, sh_var_assign_func_t *, int));
184#endif
185
186static SHELL_VAR *assign_seconds __P((SHELL_VAR *, char *, arrayind_t, char *));
187static SHELL_VAR *get_seconds __P((SHELL_VAR *));
188static SHELL_VAR *init_seconds_var __P((void));
189
190static int brand __P((void));
191static void sbrand __P((unsigned long));		/* set bash random number generator. */
192static void seedrand __P((void));			/* seed generator randomly */
193static SHELL_VAR *assign_random __P((SHELL_VAR *, char *, arrayind_t, char *));
194static SHELL_VAR *get_random __P((SHELL_VAR *));
195
196static SHELL_VAR *assign_lineno __P((SHELL_VAR *, char *, arrayind_t, char *));
197static SHELL_VAR *get_lineno __P((SHELL_VAR *));
198
199static SHELL_VAR *assign_subshell __P((SHELL_VAR *, char *, arrayind_t, char *));
200static SHELL_VAR *get_subshell __P((SHELL_VAR *));
201
202static SHELL_VAR *get_bashpid __P((SHELL_VAR *));
203
204#if defined (HISTORY)
205static SHELL_VAR *get_histcmd __P((SHELL_VAR *));
206#endif
207
208#if defined (READLINE)
209static SHELL_VAR *get_comp_wordbreaks __P((SHELL_VAR *));
210static SHELL_VAR *assign_comp_wordbreaks __P((SHELL_VAR *, char *, arrayind_t, char *));
211#endif
212
213#if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
214static SHELL_VAR *assign_dirstack __P((SHELL_VAR *, char *, arrayind_t, char *));
215static SHELL_VAR *get_dirstack __P((SHELL_VAR *));
216#endif
217
218#if defined (ARRAY_VARS)
219static SHELL_VAR *get_groupset __P((SHELL_VAR *));
220
221static SHELL_VAR *build_hashcmd __P((SHELL_VAR *));
222static SHELL_VAR *get_hashcmd __P((SHELL_VAR *));
223static SHELL_VAR *assign_hashcmd __P((SHELL_VAR *,  char *, arrayind_t, char *));
224static SHELL_VAR *build_aliasvar __P((SHELL_VAR *));
225static SHELL_VAR *get_aliasvar __P((SHELL_VAR *));
226static SHELL_VAR *assign_aliasvar __P((SHELL_VAR *,  char *, arrayind_t, char *));
227#endif
228
229static SHELL_VAR *get_funcname __P((SHELL_VAR *));
230static SHELL_VAR *init_funcname_var __P((void));
231
232static void initialize_dynamic_variables __P((void));
233
234static SHELL_VAR *hash_lookup __P((const char *, HASH_TABLE *));
235static SHELL_VAR *new_shell_variable __P((const char *));
236static SHELL_VAR *make_new_variable __P((const char *, HASH_TABLE *));
237static SHELL_VAR *bind_variable_internal __P((const char *, char *, HASH_TABLE *, int, int));
238
239static void dispose_variable_value __P((SHELL_VAR *));
240static void free_variable_hash_data __P((PTR_T));
241
242static VARLIST *vlist_alloc __P((int));
243static VARLIST *vlist_realloc __P((VARLIST *, int));
244static void vlist_add __P((VARLIST *, SHELL_VAR *, int));
245
246static void flatten __P((HASH_TABLE *, sh_var_map_func_t *, VARLIST *, int));
247
248static int qsort_var_comp __P((SHELL_VAR **, SHELL_VAR **));
249
250static SHELL_VAR **vapply __P((sh_var_map_func_t *));
251static SHELL_VAR **fapply __P((sh_var_map_func_t *));
252
253static int visible_var __P((SHELL_VAR *));
254static int visible_and_exported __P((SHELL_VAR *));
255static int export_environment_candidate __P((SHELL_VAR *));
256static int local_and_exported __P((SHELL_VAR *));
257static int variable_in_context __P((SHELL_VAR *));
258#if defined (ARRAY_VARS)
259static int visible_array_vars __P((SHELL_VAR *));
260#endif
261
262static SHELL_VAR *bind_tempenv_variable __P((const char *, char *));
263static void push_temp_var __P((PTR_T));
264static void propagate_temp_var __P((PTR_T));
265static void dispose_temporary_env __P((sh_free_func_t *));
266
267static inline char *mk_env_string __P((const char *, const char *));
268static char **make_env_array_from_var_list __P((SHELL_VAR **));
269static char **make_var_export_array __P((VAR_CONTEXT *));
270static char **make_func_export_array __P((void));
271static void add_temp_array_to_env __P((char **, int, int));
272
273static int n_shell_variables __P((void));
274static int set_context __P((SHELL_VAR *));
275
276static void push_func_var __P((PTR_T));
277static void push_exported_var __P((PTR_T));
278
279static inline int find_special_var __P((const char *));
280
281static void
282create_variable_tables ()
283{
284  if (shell_variables == 0)
285    {
286      shell_variables = global_variables = new_var_context ((char *)NULL, 0);
287      shell_variables->scope = 0;
288      shell_variables->table = hash_create (0);
289    }
290
291  if (shell_functions == 0)
292    shell_functions = hash_create (0);
293
294#if defined (DEBUGGER)
295  if (shell_function_defs == 0)
296    shell_function_defs = hash_create (0);
297#endif
298}
299
300/* Initialize the shell variables from the current environment.
301   If PRIVMODE is nonzero, don't import functions from ENV or
302   parse $SHELLOPTS. */
303void
304initialize_shell_variables (env, privmode)
305     char **env;
306     int privmode;
307{
308  char *name, *string, *temp_string;
309  int c, char_index, string_index, string_length;
310  SHELL_VAR *temp_var;
311
312  create_variable_tables ();
313
314  for (string_index = 0; string = env[string_index++]; )
315    {
316      char_index = 0;
317      name = string;
318      while ((c = *string++) && c != '=')
319	;
320      if (string[-1] == '=')
321	char_index = string - name - 1;
322
323      /* If there are weird things in the environment, like `=xxx' or a
324	 string without an `=', just skip them. */
325      if (char_index == 0)
326	continue;
327
328      /* ASSERT(name[char_index] == '=') */
329      name[char_index] = '\0';
330      /* Now, name = env variable name, string = env variable value, and
331	 char_index == strlen (name) */
332
333      temp_var = (SHELL_VAR *)NULL;
334
335      /* If exported function, define it now.  Don't import functions from
336	 the environment in privileged mode. */
337      if (privmode == 0 && read_but_dont_execute == 0 && STREQN ("() {", string, 4))
338	{
339	  string_length = strlen (string);
340	  temp_string = (char *)xmalloc (3 + string_length + char_index);
341
342	  strcpy (temp_string, name);
343	  temp_string[char_index] = ' ';
344	  strcpy (temp_string + char_index + 1, string);
345
346	  parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST);
347
348	  /* Ancient backwards compatibility.  Old versions of bash exported
349	     functions like name()=() {...} */
350	  if (name[char_index - 1] == ')' && name[char_index - 2] == '(')
351	    name[char_index - 2] = '\0';
352
353	  if (temp_var = find_function (name))
354	    {
355	      VSETATTR (temp_var, (att_exported|att_imported));
356	      array_needs_making = 1;
357	    }
358	  else
359	    report_error (_("error importing function definition for `%s'"), name);
360
361	  /* ( */
362	  if (name[char_index - 1] == ')' && name[char_index - 2] == '\0')
363	    name[char_index - 2] = '(';		/* ) */
364	}
365#if defined (ARRAY_VARS)
366#  if 0
367      /* Array variables may not yet be exported. */
368      else if (*string == '(' && string[1] == '[' && string[strlen (string) - 1] == ')')
369	{
370	  string_length = 1;
371	  temp_string = extract_array_assignment_list (string, &string_length);
372	  temp_var = assign_array_from_string (name, temp_string);
373	  FREE (temp_string);
374	  VSETATTR (temp_var, (att_exported | att_imported));
375	  array_needs_making = 1;
376	}
377#  endif
378#endif
379#if 0
380      else if (legal_identifier (name))
381#else
382      else
383#endif
384	{
385	  temp_var = bind_variable (name, string, 0);
386	  if (legal_identifier (name))
387	    VSETATTR (temp_var, (att_exported | att_imported));
388	  else
389	    VSETATTR (temp_var, (att_exported | att_imported | att_invisible));
390	  array_needs_making = 1;
391	}
392
393      name[char_index] = '=';
394      /* temp_var can be NULL if it was an exported function with a syntax
395	 error (a different bug, but it still shouldn't dump core). */
396      if (temp_var && function_p (temp_var) == 0)	/* XXX not yet */
397	{
398	  CACHE_IMPORTSTR (temp_var, name);
399	}
400    }
401
402  set_pwd ();
403
404  /* Set up initial value of $_ */
405  temp_var = set_if_not ("_", dollar_vars[0]);
406
407  /* Remember this pid. */
408  dollar_dollar_pid = getpid ();
409
410  /* Now make our own defaults in case the vars that we think are
411     important are missing. */
412  temp_var = set_if_not ("PATH", DEFAULT_PATH_VALUE);
413#if 0
414  set_auto_export (temp_var);	/* XXX */
415#endif
416
417  temp_var = set_if_not ("TERM", "dumb");
418#if 0
419  set_auto_export (temp_var);	/* XXX */
420#endif
421
422#if defined (__QNX__)
423  /* set node id -- don't import it from the environment */
424  {
425    char node_name[22];
426#  if defined (__QNXNTO__)
427    netmgr_ndtostr(ND2S_LOCAL_STR, ND_LOCAL_NODE, node_name, sizeof(node_name));
428#  else
429    qnx_nidtostr (getnid (), node_name, sizeof (node_name));
430#  endif
431    temp_var = bind_variable ("NODE", node_name, 0);
432    set_auto_export (temp_var);
433  }
434#endif
435
436  /* set up the prompts. */
437  if (interactive_shell)
438    {
439#if defined (PROMPT_STRING_DECODE)
440      set_if_not ("PS1", primary_prompt);
441#else
442      if (current_user.uid == -1)
443	get_current_user_info ();
444      set_if_not ("PS1", current_user.euid == 0 ? "# " : primary_prompt);
445#endif
446      set_if_not ("PS2", secondary_prompt);
447    }
448  set_if_not ("PS4", "+ ");
449
450  /* Don't allow IFS to be imported from the environment. */
451  temp_var = bind_variable ("IFS", " \t\n", 0);
452  setifs (temp_var);
453
454  /* Magic machine types.  Pretty convenient. */
455  set_machine_vars ();
456
457  /* Default MAILCHECK for interactive shells.  Defer the creation of a
458     default MAILPATH until the startup files are read, because MAIL
459     names a mail file if MAILPATH is not set, and we should provide a
460     default only if neither is set. */
461  if (interactive_shell)
462    {
463      temp_var = set_if_not ("MAILCHECK", posixly_correct ? "600" : "60");
464      VSETATTR (temp_var, att_integer);
465    }
466
467  /* Do some things with shell level. */
468  initialize_shell_level ();
469
470  set_ppid ();
471
472  /* Initialize the `getopts' stuff. */
473  temp_var = bind_variable ("OPTIND", "1", 0);
474  VSETATTR (temp_var, att_integer);
475  getopts_reset (0);
476  bind_variable ("OPTERR", "1", 0);
477  sh_opterr = 1;
478
479  if (login_shell == 1 && posixly_correct == 0)
480    set_home_var ();
481
482  /* Get the full pathname to THIS shell, and set the BASH variable
483     to it. */
484  name = get_bash_name ();
485  temp_var = bind_variable ("BASH", name, 0);
486  free (name);
487
488  /* Make the exported environment variable SHELL be the user's login
489     shell.  Note that the `tset' command looks at this variable
490     to determine what style of commands to output; if it ends in "csh",
491     then C-shell commands are output, else Bourne shell commands. */
492  set_shell_var ();
493
494  /* Make a variable called BASH_VERSION which contains the version info. */
495  bind_variable ("BASH_VERSION", shell_version_string (), 0);
496#if defined (ARRAY_VARS)
497  make_vers_array ();
498#endif
499
500  if (command_execution_string)
501    bind_variable ("BASH_EXECUTION_STRING", command_execution_string, 0);
502
503  /* Find out if we're supposed to be in Posix.2 mode via an
504     environment variable. */
505  temp_var = find_variable ("POSIXLY_CORRECT");
506  if (!temp_var)
507    temp_var = find_variable ("POSIX_PEDANTIC");
508  if (temp_var && imported_p (temp_var))
509    sv_strict_posix (temp_var->name);
510
511#if defined (HISTORY)
512  /* Set history variables to defaults, and then do whatever we would
513     do if the variable had just been set.  Do this only in the case
514     that we are remembering commands on the history list. */
515  if (remember_on_history)
516    {
517      name = bash_tilde_expand (posixly_correct ? "~/.sh_history" : "~/.bash_history", 0);
518
519      set_if_not ("HISTFILE", name);
520      free (name);
521
522#if 0
523      set_if_not ("HISTSIZE", "500");
524      sv_histsize ("HISTSIZE");
525#endif
526    }
527#endif /* HISTORY */
528
529  /* Seed the random number generator. */
530  seedrand ();
531
532  /* Handle some "special" variables that we may have inherited from a
533     parent shell. */
534  if (interactive_shell)
535    {
536      temp_var = find_variable ("IGNOREEOF");
537      if (!temp_var)
538	temp_var = find_variable ("ignoreeof");
539      if (temp_var && imported_p (temp_var))
540	sv_ignoreeof (temp_var->name);
541    }
542
543#if defined (HISTORY)
544  if (interactive_shell && remember_on_history)
545    {
546      sv_history_control ("HISTCONTROL");
547      sv_histignore ("HISTIGNORE");
548      sv_histtimefmt ("HISTTIMEFORMAT");
549    }
550#endif /* HISTORY */
551
552#if defined (READLINE) && defined (STRICT_POSIX)
553  /* POSIXLY_CORRECT will only be 1 here if the shell was compiled
554     -DSTRICT_POSIX */
555  if (interactive_shell && posixly_correct && no_line_editing == 0)
556    rl_prefer_env_winsize = 1;
557#endif /* READLINE && STRICT_POSIX */
558
559     /*
560      * 24 October 2001
561      *
562      * I'm tired of the arguing and bug reports.  Bash now leaves SSH_CLIENT
563      * and SSH2_CLIENT alone.  I'm going to rely on the shell_level check in
564      * isnetconn() to avoid running the startup files more often than wanted.
565      * That will, of course, only work if the user's login shell is bash, so
566      * I've made that behavior conditional on SSH_SOURCE_BASHRC being defined
567      * in config-top.h.
568      */
569#if 0
570  temp_var = find_variable ("SSH_CLIENT");
571  if (temp_var && imported_p (temp_var))
572    {
573      VUNSETATTR (temp_var, att_exported);
574      array_needs_making = 1;
575    }
576  temp_var = find_variable ("SSH2_CLIENT");
577  if (temp_var && imported_p (temp_var))
578    {
579      VUNSETATTR (temp_var, att_exported);
580      array_needs_making = 1;
581    }
582#endif
583
584  /* Get the user's real and effective user ids. */
585  uidset ();
586
587  /* Initialize the dynamic variables, and seed their values. */
588  initialize_dynamic_variables ();
589}
590
591/* **************************************************************** */
592/*								    */
593/*	     Setting values for special shell variables		    */
594/*								    */
595/* **************************************************************** */
596
597static void
598set_machine_vars ()
599{
600  SHELL_VAR *temp_var;
601
602  temp_var = set_if_not ("HOSTTYPE", HOSTTYPE);
603  temp_var = set_if_not ("OSTYPE", OSTYPE);
604  temp_var = set_if_not ("MACHTYPE", MACHTYPE);
605
606  temp_var = set_if_not ("HOSTNAME", current_host_name);
607}
608
609/* Set $HOME to the information in the password file if we didn't get
610   it from the environment. */
611
612/* This function is not static so the tilde and readline libraries can
613   use it. */
614char *
615sh_get_home_dir ()
616{
617  if (current_user.home_dir == 0)
618    get_current_user_info ();
619  return current_user.home_dir;
620}
621
622static void
623set_home_var ()
624{
625  SHELL_VAR *temp_var;
626
627  temp_var = find_variable ("HOME");
628  if (temp_var == 0)
629    temp_var = bind_variable ("HOME", sh_get_home_dir (), 0);
630#if 0
631  VSETATTR (temp_var, att_exported);
632#endif
633}
634
635/* Set $SHELL to the user's login shell if it is not already set.  Call
636   get_current_user_info if we haven't already fetched the shell. */
637static void
638set_shell_var ()
639{
640  SHELL_VAR *temp_var;
641
642  temp_var = find_variable ("SHELL");
643  if (temp_var == 0)
644    {
645      if (current_user.shell == 0)
646	get_current_user_info ();
647      temp_var = bind_variable ("SHELL", current_user.shell, 0);
648    }
649#if 0
650  VSETATTR (temp_var, att_exported);
651#endif
652}
653
654static char *
655get_bash_name ()
656{
657  char *name;
658
659  if ((login_shell == 1) && RELPATH(shell_name))
660    {
661      if (current_user.shell == 0)
662	get_current_user_info ();
663      name = savestring (current_user.shell);
664    }
665  else if (ABSPATH(shell_name))
666    name = savestring (shell_name);
667  else if (shell_name[0] == '.' && shell_name[1] == '/')
668    {
669      /* Fast path for common case. */
670      char *cdir;
671      int len;
672
673      cdir = get_string_value ("PWD");
674      if (cdir)
675	{
676	  len = strlen (cdir);
677	  name = (char *)xmalloc (len + strlen (shell_name) + 1);
678	  strcpy (name, cdir);
679	  strcpy (name + len, shell_name + 1);
680	}
681      else
682	name = savestring (shell_name);
683    }
684  else
685    {
686      char *tname;
687      int s;
688
689      tname = find_user_command (shell_name);
690
691      if (tname == 0)
692	{
693	  /* Try the current directory.  If there is not an executable
694	     there, just punt and use the login shell. */
695	  s = file_status (shell_name);
696	  if (s & FS_EXECABLE)
697	    {
698	      tname = make_absolute (shell_name, get_string_value ("PWD"));
699	      if (*shell_name == '.')
700		{
701		  name = sh_canonpath (tname, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
702		  if (name == 0)
703		    name = tname;
704		  else
705		    free (tname);
706		}
707	     else
708		name = tname;
709	    }
710	  else
711	    {
712	      if (current_user.shell == 0)
713		get_current_user_info ();
714	      name = savestring (current_user.shell);
715	    }
716	}
717      else
718	{
719	  name = full_pathname (tname);
720	  free (tname);
721	}
722    }
723
724  return (name);
725}
726
727void
728adjust_shell_level (change)
729     int change;
730{
731  char new_level[5], *old_SHLVL;
732  intmax_t old_level;
733  SHELL_VAR *temp_var;
734
735  old_SHLVL = get_string_value ("SHLVL");
736  if (old_SHLVL == 0 || *old_SHLVL == '\0' || legal_number (old_SHLVL, &old_level) == 0)
737    old_level = 0;
738
739  shell_level = old_level + change;
740  if (shell_level < 0)
741    shell_level = 0;
742  else if (shell_level > 1000)
743    {
744      internal_warning (_("shell level (%d) too high, resetting to 1"), shell_level);
745      shell_level = 1;
746    }
747
748  /* We don't need the full generality of itos here. */
749  if (shell_level < 10)
750    {
751      new_level[0] = shell_level + '0';
752      new_level[1] = '\0';
753    }
754  else if (shell_level < 100)
755    {
756      new_level[0] = (shell_level / 10) + '0';
757      new_level[1] = (shell_level % 10) + '0';
758      new_level[2] = '\0';
759    }
760  else if (shell_level < 1000)
761    {
762      new_level[0] = (shell_level / 100) + '0';
763      old_level = shell_level % 100;
764      new_level[1] = (old_level / 10) + '0';
765      new_level[2] = (old_level % 10) + '0';
766      new_level[3] = '\0';
767    }
768
769  temp_var = bind_variable ("SHLVL", new_level, 0);
770  set_auto_export (temp_var);
771}
772
773static void
774initialize_shell_level ()
775{
776  adjust_shell_level (1);
777}
778
779/* If we got PWD from the environment, update our idea of the current
780   working directory.  In any case, make sure that PWD exists before
781   checking it.  It is possible for getcwd () to fail on shell startup,
782   and in that case, PWD would be undefined.  If this is an interactive
783   login shell, see if $HOME is the current working directory, and if
784   that's not the same string as $PWD, set PWD=$HOME. */
785
786void
787set_pwd ()
788{
789  SHELL_VAR *temp_var, *home_var;
790  char *temp_string, *home_string;
791
792  home_var = find_variable ("HOME");
793  home_string = home_var ? value_cell (home_var) : (char *)NULL;
794
795  temp_var = find_variable ("PWD");
796  if (temp_var && imported_p (temp_var) &&
797      (temp_string = value_cell (temp_var)) &&
798      same_file (temp_string, ".", (struct stat *)NULL, (struct stat *)NULL))
799    set_working_directory (temp_string);
800  else if (home_string && interactive_shell && login_shell &&
801	   same_file (home_string, ".", (struct stat *)NULL, (struct stat *)NULL))
802    {
803      set_working_directory (home_string);
804      temp_var = bind_variable ("PWD", home_string, 0);
805      set_auto_export (temp_var);
806    }
807  else
808    {
809      temp_string = get_working_directory ("shell-init");
810      if (temp_string)
811	{
812	  temp_var = bind_variable ("PWD", temp_string, 0);
813	  set_auto_export (temp_var);
814	  free (temp_string);
815	}
816    }
817
818  /* According to the Single Unix Specification, v2, $OLDPWD is an
819     `environment variable' and therefore should be auto-exported.
820     Make a dummy invisible variable for OLDPWD, and mark it as exported. */
821  temp_var = bind_variable ("OLDPWD", (char *)NULL, 0);
822  VSETATTR (temp_var, (att_exported | att_invisible));
823}
824
825/* Make a variable $PPID, which holds the pid of the shell's parent.  */
826void
827set_ppid ()
828{
829  char namebuf[INT_STRLEN_BOUND(pid_t) + 1], *name;
830  SHELL_VAR *temp_var;
831
832  name = inttostr (getppid (), namebuf, sizeof(namebuf));
833  temp_var = find_variable ("PPID");
834  if (temp_var)
835    VUNSETATTR (temp_var, (att_readonly | att_exported));
836  temp_var = bind_variable ("PPID", name, 0);
837  VSETATTR (temp_var, (att_readonly | att_integer));
838}
839
840static void
841uidset ()
842{
843  char buff[INT_STRLEN_BOUND(uid_t) + 1], *b;
844  register SHELL_VAR *v;
845
846  b = inttostr (current_user.uid, buff, sizeof (buff));
847  v = find_variable ("UID");
848  if (v == 0)
849    {
850      v = bind_variable ("UID", b, 0);
851      VSETATTR (v, (att_readonly | att_integer));
852    }
853
854  if (current_user.euid != current_user.uid)
855    b = inttostr (current_user.euid, buff, sizeof (buff));
856
857  v = find_variable ("EUID");
858  if (v == 0)
859    {
860      v = bind_variable ("EUID", b, 0);
861      VSETATTR (v, (att_readonly | att_integer));
862    }
863}
864
865#if defined (ARRAY_VARS)
866static void
867make_vers_array ()
868{
869  SHELL_VAR *vv;
870  ARRAY *av;
871  char *s, d[32], b[INT_STRLEN_BOUND(int) + 1];
872
873  unbind_variable ("BASH_VERSINFO");
874
875  vv = make_new_array_variable ("BASH_VERSINFO");
876  av = array_cell (vv);
877  strcpy (d, dist_version);
878  s = xstrchr (d, '.');
879  if (s)
880    *s++ = '\0';
881  array_insert (av, 0, d);
882  array_insert (av, 1, s);
883  s = inttostr (patch_level, b, sizeof (b));
884  array_insert (av, 2, s);
885  s = inttostr (build_version, b, sizeof (b));
886  array_insert (av, 3, s);
887  array_insert (av, 4, release_status);
888  array_insert (av, 5, MACHTYPE);
889
890  VSETATTR (vv, att_readonly);
891}
892#endif /* ARRAY_VARS */
893
894/* Set the environment variables $LINES and $COLUMNS in response to
895   a window size change. */
896void
897sh_set_lines_and_columns (lines, cols)
898     int lines, cols;
899{
900  char val[INT_STRLEN_BOUND(int) + 1], *v;
901
902#if defined (READLINE)
903  /* If we are currently assigning to LINES or COLUMNS, don't do anything. */
904  if (winsize_assignment)
905    return;
906#endif
907
908  v = inttostr (lines, val, sizeof (val));
909  bind_variable ("LINES", v, 0);
910
911  v = inttostr (cols, val, sizeof (val));
912  bind_variable ("COLUMNS", v, 0);
913}
914
915/* **************************************************************** */
916/*								    */
917/*		   Printing variables and values		    */
918/*								    */
919/* **************************************************************** */
920
921/* Print LIST (a list of shell variables) to stdout in such a way that
922   they can be read back in. */
923void
924print_var_list (list)
925     register SHELL_VAR **list;
926{
927  register int i;
928  register SHELL_VAR *var;
929
930  for (i = 0; list && (var = list[i]); i++)
931    if (invisible_p (var) == 0)
932      print_assignment (var);
933}
934
935/* Print LIST (a list of shell functions) to stdout in such a way that
936   they can be read back in. */
937void
938print_func_list (list)
939     register SHELL_VAR **list;
940{
941  register int i;
942  register SHELL_VAR *var;
943
944  for (i = 0; list && (var = list[i]); i++)
945    {
946      printf ("%s ", var->name);
947      print_var_function (var);
948      printf ("\n");
949    }
950}
951
952/* Print the value of a single SHELL_VAR.  No newline is
953   output, but the variable is printed in such a way that
954   it can be read back in. */
955void
956print_assignment (var)
957     SHELL_VAR *var;
958{
959  if (var_isset (var) == 0)
960    return;
961
962  if (function_p (var))
963    {
964      printf ("%s", var->name);
965      print_var_function (var);
966      printf ("\n");
967    }
968#if defined (ARRAY_VARS)
969  else if (array_p (var))
970    print_array_assignment (var, 0);
971  else if (assoc_p (var))
972    print_assoc_assignment (var, 0);
973#endif /* ARRAY_VARS */
974  else
975    {
976      printf ("%s=", var->name);
977      print_var_value (var, 1);
978      printf ("\n");
979    }
980}
981
982/* Print the value cell of VAR, a shell variable.  Do not print
983   the name, nor leading/trailing newline.  If QUOTE is non-zero,
984   and the value contains shell metacharacters, quote the value
985   in such a way that it can be read back in. */
986void
987print_var_value (var, quote)
988     SHELL_VAR *var;
989     int quote;
990{
991  char *t;
992
993  if (var_isset (var) == 0)
994    return;
995
996  if (quote && posixly_correct == 0 && ansic_shouldquote (value_cell (var)))
997    {
998      t = ansic_quote (value_cell (var), 0, (int *)0);
999      printf ("%s", t);
1000      free (t);
1001    }
1002  else if (quote && sh_contains_shell_metas (value_cell (var)))
1003    {
1004      t = sh_single_quote (value_cell (var));
1005      printf ("%s", t);
1006      free (t);
1007    }
1008  else
1009    printf ("%s", value_cell (var));
1010}
1011
1012/* Print the function cell of VAR, a shell variable.  Do not
1013   print the name, nor leading/trailing newline. */
1014void
1015print_var_function (var)
1016     SHELL_VAR *var;
1017{
1018  char *x;
1019
1020  if (function_p (var) && var_isset (var))
1021    {
1022      x = named_function_string ((char *)NULL, function_cell(var), FUNC_MULTILINE|FUNC_EXTERNAL);
1023      printf ("%s", x);
1024    }
1025}
1026
1027/* **************************************************************** */
1028/*								    */
1029/*		 	Dynamic Variables			    */
1030/*								    */
1031/* **************************************************************** */
1032
1033/* DYNAMIC VARIABLES
1034
1035   These are variables whose values are generated anew each time they are
1036   referenced.  These are implemented using a pair of function pointers
1037   in the struct variable: assign_func, which is called from bind_variable
1038   and, if arrays are compiled into the shell, some of the functions in
1039   arrayfunc.c, and dynamic_value, which is called from find_variable.
1040
1041   assign_func is called from bind_variable_internal, if
1042   bind_variable_internal discovers that the variable being assigned to
1043   has such a function.  The function is called as
1044	SHELL_VAR *temp = (*(entry->assign_func)) (entry, value, ind)
1045   and the (SHELL_VAR *)temp is returned as the value of bind_variable.  It
1046   is usually ENTRY (self).  IND is an index for an array variable, and
1047   unused otherwise.
1048
1049   dynamic_value is called from find_variable_internal to return a `new'
1050   value for the specified dynamic varible.  If this function is NULL,
1051   the variable is treated as a `normal' shell variable.  If it is not,
1052   however, then this function is called like this:
1053	tempvar = (*(var->dynamic_value)) (var);
1054
1055   Sometimes `tempvar' will replace the value of `var'.  Other times, the
1056   shell will simply use the string value.  Pretty object-oriented, huh?
1057
1058   Be warned, though: if you `unset' a special variable, it loses its
1059   special meaning, even if you subsequently set it.
1060
1061   The special assignment code would probably have been better put in
1062   subst.c: do_assignment_internal, in the same style as
1063   stupidly_hack_special_variables, but I wanted the changes as
1064   localized as possible.  */
1065
1066#define INIT_DYNAMIC_VAR(var, val, gfunc, afunc) \
1067  do \
1068    { \
1069      v = bind_variable (var, (val), 0); \
1070      v->dynamic_value = gfunc; \
1071      v->assign_func = afunc; \
1072    } \
1073  while (0)
1074
1075#define INIT_DYNAMIC_ARRAY_VAR(var, gfunc, afunc) \
1076  do \
1077    { \
1078      v = make_new_array_variable (var); \
1079      v->dynamic_value = gfunc; \
1080      v->assign_func = afunc; \
1081    } \
1082  while (0)
1083
1084#define INIT_DYNAMIC_ASSOC_VAR(var, gfunc, afunc) \
1085  do \
1086    { \
1087      v = make_new_assoc_variable (var); \
1088      v->dynamic_value = gfunc; \
1089      v->assign_func = afunc; \
1090    } \
1091  while (0)
1092
1093static SHELL_VAR *
1094null_assign (self, value, unused, key)
1095     SHELL_VAR *self;
1096     char *value;
1097     arrayind_t unused;
1098     char *key;
1099{
1100  return (self);
1101}
1102
1103#if defined (ARRAY_VARS)
1104static SHELL_VAR *
1105null_array_assign (self, value, ind, key)
1106     SHELL_VAR *self;
1107     char *value;
1108     arrayind_t ind;
1109     char *key;
1110{
1111  return (self);
1112}
1113#endif
1114
1115/* Degenerate `dynamic_value' function; just returns what's passed without
1116   manipulation. */
1117static SHELL_VAR *
1118get_self (self)
1119     SHELL_VAR *self;
1120{
1121  return (self);
1122}
1123
1124#if defined (ARRAY_VARS)
1125/* A generic dynamic array variable initializer.  Intialize array variable
1126   NAME with dynamic value function GETFUNC and assignment function SETFUNC. */
1127static SHELL_VAR *
1128init_dynamic_array_var (name, getfunc, setfunc, attrs)
1129     char *name;
1130     sh_var_value_func_t *getfunc;
1131     sh_var_assign_func_t *setfunc;
1132     int attrs;
1133{
1134  SHELL_VAR *v;
1135
1136  v = find_variable (name);
1137  if (v)
1138    return (v);
1139  INIT_DYNAMIC_ARRAY_VAR (name, getfunc, setfunc);
1140  if (attrs)
1141    VSETATTR (v, attrs);
1142  return v;
1143}
1144
1145static SHELL_VAR *
1146init_dynamic_assoc_var (name, getfunc, setfunc, attrs)
1147     char *name;
1148     sh_var_value_func_t *getfunc;
1149     sh_var_assign_func_t *setfunc;
1150     int attrs;
1151{
1152  SHELL_VAR *v;
1153
1154  v = find_variable (name);
1155  if (v)
1156    return (v);
1157  INIT_DYNAMIC_ASSOC_VAR (name, getfunc, setfunc);
1158  if (attrs)
1159    VSETATTR (v, attrs);
1160  return v;
1161}
1162#endif
1163
1164/* The value of $SECONDS.  This is the number of seconds since shell
1165   invocation, or, the number of seconds since the last assignment + the
1166   value of the last assignment. */
1167static intmax_t seconds_value_assigned;
1168
1169static SHELL_VAR *
1170assign_seconds (self, value, unused, key)
1171     SHELL_VAR *self;
1172     char *value;
1173     arrayind_t unused;
1174     char *key;
1175{
1176  if (legal_number (value, &seconds_value_assigned) == 0)
1177    seconds_value_assigned = 0;
1178  shell_start_time = NOW;
1179  return (self);
1180}
1181
1182static SHELL_VAR *
1183get_seconds (var)
1184     SHELL_VAR *var;
1185{
1186  time_t time_since_start;
1187  char *p;
1188
1189  time_since_start = NOW - shell_start_time;
1190  p = itos(seconds_value_assigned + time_since_start);
1191
1192  FREE (value_cell (var));
1193
1194  VSETATTR (var, att_integer);
1195  var_setvalue (var, p);
1196  return (var);
1197}
1198
1199static SHELL_VAR *
1200init_seconds_var ()
1201{
1202  SHELL_VAR *v;
1203
1204  v = find_variable ("SECONDS");
1205  if (v)
1206    {
1207      if (legal_number (value_cell(v), &seconds_value_assigned) == 0)
1208	seconds_value_assigned = 0;
1209    }
1210  INIT_DYNAMIC_VAR ("SECONDS", (v ? value_cell (v) : (char *)NULL), get_seconds, assign_seconds);
1211  return v;
1212}
1213
1214/* The random number seed.  You can change this by setting RANDOM. */
1215static unsigned long rseed = 1;
1216static int last_random_value;
1217static int seeded_subshell = 0;
1218
1219/* A linear congruential random number generator based on the example
1220   one in the ANSI C standard.  This one isn't very good, but a more
1221   complicated one is overkill. */
1222
1223/* Returns a pseudo-random number between 0 and 32767. */
1224static int
1225brand ()
1226{
1227#if 0
1228  rseed = rseed * 1103515245 + 12345;
1229  return ((unsigned int)((rseed >> 16) & 32767));	/* was % 32768 */
1230#else
1231  /* From "Random number generators: good ones are hard to find",
1232     Park and Miller, Communications of the ACM, vol. 31, no. 10,
1233     October 1988, p. 1195. filtered through FreeBSD */
1234  long h, l;
1235
1236  if (rseed == 0)
1237    seedrand ();
1238  h = rseed / 127773;
1239  l = rseed % 127773;
1240  rseed = 16807 * l - 2836 * h;
1241#if 0
1242  if (rseed < 0)
1243    rseed += 0x7fffffff;
1244#endif
1245  return ((unsigned int)(rseed & 32767));	/* was % 32768 */
1246#endif
1247}
1248
1249/* Set the random number generator seed to SEED. */
1250static void
1251sbrand (seed)
1252     unsigned long seed;
1253{
1254  rseed = seed;
1255  last_random_value = 0;
1256}
1257
1258static void
1259seedrand ()
1260{
1261  struct timeval tv;
1262
1263  gettimeofday (&tv, NULL);
1264  sbrand (tv.tv_sec ^ tv.tv_usec ^ getpid ());
1265}
1266
1267static SHELL_VAR *
1268assign_random (self, value, unused, key)
1269     SHELL_VAR *self;
1270     char *value;
1271     arrayind_t unused;
1272     char *key;
1273{
1274  sbrand (strtoul (value, (char **)NULL, 10));
1275  if (subshell_environment)
1276    seeded_subshell = getpid ();
1277  return (self);
1278}
1279
1280int
1281get_random_number ()
1282{
1283  int rv, pid;
1284
1285  /* Reset for command and process substitution. */
1286  pid = getpid ();
1287  if (subshell_environment && seeded_subshell != pid)
1288    {
1289      seedrand ();
1290      seeded_subshell = pid;
1291    }
1292
1293  do
1294    rv = brand ();
1295  while (rv == last_random_value);
1296  return rv;
1297}
1298
1299static SHELL_VAR *
1300get_random (var)
1301     SHELL_VAR *var;
1302{
1303  int rv;
1304  char *p;
1305
1306  rv = get_random_number ();
1307  last_random_value = rv;
1308  p = itos (rv);
1309
1310  FREE (value_cell (var));
1311
1312  VSETATTR (var, att_integer);
1313  var_setvalue (var, p);
1314  return (var);
1315}
1316
1317static SHELL_VAR *
1318assign_lineno (var, value, unused, key)
1319     SHELL_VAR *var;
1320     char *value;
1321     arrayind_t unused;
1322     char *key;
1323{
1324  intmax_t new_value;
1325
1326  if (value == 0 || *value == '\0' || legal_number (value, &new_value) == 0)
1327    new_value = 0;
1328  line_number = new_value;
1329  return var;
1330}
1331
1332/* Function which returns the current line number. */
1333static SHELL_VAR *
1334get_lineno (var)
1335     SHELL_VAR *var;
1336{
1337  char *p;
1338  int ln;
1339
1340  ln = executing_line_number ();
1341  p = itos (ln);
1342  FREE (value_cell (var));
1343  var_setvalue (var, p);
1344  return (var);
1345}
1346
1347static SHELL_VAR *
1348assign_subshell (var, value, unused, key)
1349     SHELL_VAR *var;
1350     char *value;
1351     arrayind_t unused;
1352     char *key;
1353{
1354  intmax_t new_value;
1355
1356  if (value == 0 || *value == '\0' || legal_number (value, &new_value) == 0)
1357    new_value = 0;
1358  subshell_level = new_value;
1359  return var;
1360}
1361
1362static SHELL_VAR *
1363get_subshell (var)
1364     SHELL_VAR *var;
1365{
1366  char *p;
1367
1368  p = itos (subshell_level);
1369  FREE (value_cell (var));
1370  var_setvalue (var, p);
1371  return (var);
1372}
1373
1374static SHELL_VAR *
1375get_bashpid (var)
1376     SHELL_VAR *var;
1377{
1378  int pid;
1379  char *p;
1380
1381  pid = getpid ();
1382  p = itos (pid);
1383
1384  FREE (value_cell (var));
1385  VSETATTR (var, att_integer|att_readonly);
1386  var_setvalue (var, p);
1387  return (var);
1388}
1389
1390static SHELL_VAR *
1391get_bash_command (var)
1392     SHELL_VAR *var;
1393{
1394  char *p;
1395
1396  if (the_printed_command_except_trap)
1397    p = savestring (the_printed_command_except_trap);
1398  else
1399    {
1400      p = (char *)xmalloc (1);
1401      p[0] = '\0';
1402    }
1403  FREE (value_cell (var));
1404  var_setvalue (var, p);
1405  return (var);
1406}
1407
1408#if defined (HISTORY)
1409static SHELL_VAR *
1410get_histcmd (var)
1411     SHELL_VAR *var;
1412{
1413  char *p;
1414
1415  p = itos (history_number ());
1416  FREE (value_cell (var));
1417  var_setvalue (var, p);
1418  return (var);
1419}
1420#endif
1421
1422#if defined (READLINE)
1423/* When this function returns, VAR->value points to malloced memory. */
1424static SHELL_VAR *
1425get_comp_wordbreaks (var)
1426     SHELL_VAR *var;
1427{
1428  /* If we don't have anything yet, assign a default value. */
1429  if (rl_completer_word_break_characters == 0 && bash_readline_initialized == 0)
1430    enable_hostname_completion (perform_hostname_completion);
1431
1432  FREE (value_cell (var));
1433  var_setvalue (var, savestring (rl_completer_word_break_characters));
1434
1435  return (var);
1436}
1437
1438/* When this function returns, rl_completer_word_break_characters points to
1439   malloced memory. */
1440static SHELL_VAR *
1441assign_comp_wordbreaks (self, value, unused, key)
1442     SHELL_VAR *self;
1443     char *value;
1444     arrayind_t unused;
1445     char *key;
1446{
1447  if (rl_completer_word_break_characters &&
1448      rl_completer_word_break_characters != rl_basic_word_break_characters)
1449    free (rl_completer_word_break_characters);
1450
1451  rl_completer_word_break_characters = savestring (value);
1452  return self;
1453}
1454#endif /* READLINE */
1455
1456#if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
1457static SHELL_VAR *
1458assign_dirstack (self, value, ind, key)
1459     SHELL_VAR *self;
1460     char *value;
1461     arrayind_t ind;
1462     char *key;
1463{
1464  set_dirstack_element (ind, 1, value);
1465  return self;
1466}
1467
1468static SHELL_VAR *
1469get_dirstack (self)
1470     SHELL_VAR *self;
1471{
1472  ARRAY *a;
1473  WORD_LIST *l;
1474
1475  l = get_directory_stack (0);
1476  a = array_from_word_list (l);
1477  array_dispose (array_cell (self));
1478  dispose_words (l);
1479  var_setarray (self, a);
1480  return self;
1481}
1482#endif /* PUSHD AND POPD && ARRAY_VARS */
1483
1484#if defined (ARRAY_VARS)
1485/* We don't want to initialize the group set with a call to getgroups()
1486   unless we're asked to, but we only want to do it once. */
1487static SHELL_VAR *
1488get_groupset (self)
1489     SHELL_VAR *self;
1490{
1491  register int i;
1492  int ng;
1493  ARRAY *a;
1494  static char **group_set = (char **)NULL;
1495
1496  if (group_set == 0)
1497    {
1498      group_set = get_group_list (&ng);
1499      a = array_cell (self);
1500      for (i = 0; i < ng; i++)
1501	array_insert (a, i, group_set[i]);
1502    }
1503  return (self);
1504}
1505
1506static SHELL_VAR *
1507build_hashcmd (self)
1508     SHELL_VAR *self;
1509{
1510  HASH_TABLE *h;
1511  int i;
1512  char *k, *v;
1513  BUCKET_CONTENTS *item;
1514
1515  h = assoc_cell (self);
1516  if (h)
1517    assoc_dispose (h);
1518
1519  if (hashed_filenames == 0 || HASH_ENTRIES (hashed_filenames) == 0)
1520    {
1521      var_setvalue (self, (char *)NULL);
1522      return self;
1523    }
1524
1525  h = assoc_create (hashed_filenames->nbuckets);
1526  for (i = 0; i < hashed_filenames->nbuckets; i++)
1527    {
1528      for (item = hash_items (i, hashed_filenames); item; item = item->next)
1529	{
1530	  k = savestring (item->key);
1531	  v = pathdata(item)->path;
1532	  assoc_insert (h, k, v);
1533	}
1534    }
1535
1536  var_setvalue (self, (char *)h);
1537  return self;
1538}
1539
1540static SHELL_VAR *
1541get_hashcmd (self)
1542     SHELL_VAR *self;
1543{
1544  build_hashcmd (self);
1545  return (self);
1546}
1547
1548static SHELL_VAR *
1549assign_hashcmd (self, value, ind, key)
1550     SHELL_VAR *self;
1551     char *value;
1552     arrayind_t ind;
1553     char *key;
1554{
1555  phash_insert (key, value, 0, 0);
1556  return (build_hashcmd (self));
1557}
1558
1559static SHELL_VAR *
1560build_aliasvar (self)
1561     SHELL_VAR *self;
1562{
1563  HASH_TABLE *h;
1564  int i;
1565  char *k, *v;
1566  BUCKET_CONTENTS *item;
1567
1568  h = assoc_cell (self);
1569  if (h)
1570    assoc_dispose (h);
1571
1572  if (aliases == 0 || HASH_ENTRIES (aliases) == 0)
1573    {
1574      var_setvalue (self, (char *)NULL);
1575      return self;
1576    }
1577
1578  h = assoc_create (aliases->nbuckets);
1579  for (i = 0; i < aliases->nbuckets; i++)
1580    {
1581      for (item = hash_items (i, aliases); item; item = item->next)
1582	{
1583	  k = savestring (item->key);
1584	  v = ((alias_t *)(item->data))->value;
1585	  assoc_insert (h, k, v);
1586	}
1587    }
1588
1589  var_setvalue (self, (char *)h);
1590  return self;
1591}
1592
1593static SHELL_VAR *
1594get_aliasvar (self)
1595     SHELL_VAR *self;
1596{
1597  build_aliasvar (self);
1598  return (self);
1599}
1600
1601static SHELL_VAR *
1602assign_aliasvar (self, value, ind, key)
1603     SHELL_VAR *self;
1604     char *value;
1605     arrayind_t ind;
1606     char *key;
1607{
1608  add_alias (key, value);
1609  return (build_aliasvar (self));
1610}
1611#endif /* ARRAY_VARS */
1612
1613/* If ARRAY_VARS is not defined, this just returns the name of any
1614   currently-executing function.  If we have arrays, it's a call stack. */
1615static SHELL_VAR *
1616get_funcname (self)
1617     SHELL_VAR *self;
1618{
1619#if ! defined (ARRAY_VARS)
1620  char *t;
1621  if (variable_context && this_shell_function)
1622    {
1623      FREE (value_cell (self));
1624      t = savestring (this_shell_function->name);
1625      var_setvalue (self, t);
1626    }
1627#endif
1628  return (self);
1629}
1630
1631void
1632make_funcname_visible (on_or_off)
1633     int on_or_off;
1634{
1635  SHELL_VAR *v;
1636
1637  v = find_variable ("FUNCNAME");
1638  if (v == 0 || v->dynamic_value == 0)
1639    return;
1640
1641  if (on_or_off)
1642    VUNSETATTR (v, att_invisible);
1643  else
1644    VSETATTR (v, att_invisible);
1645}
1646
1647static SHELL_VAR *
1648init_funcname_var ()
1649{
1650  SHELL_VAR *v;
1651
1652  v = find_variable ("FUNCNAME");
1653  if (v)
1654    return v;
1655#if defined (ARRAY_VARS)
1656  INIT_DYNAMIC_ARRAY_VAR ("FUNCNAME", get_funcname, null_array_assign);
1657#else
1658  INIT_DYNAMIC_VAR ("FUNCNAME", (char *)NULL, get_funcname, null_assign);
1659#endif
1660  VSETATTR (v, att_invisible|att_noassign);
1661  return v;
1662}
1663
1664static void
1665initialize_dynamic_variables ()
1666{
1667  SHELL_VAR *v;
1668
1669  v = init_seconds_var ();
1670
1671  INIT_DYNAMIC_VAR ("BASH_COMMAND", (char *)NULL, get_bash_command, (sh_var_assign_func_t *)NULL);
1672  INIT_DYNAMIC_VAR ("BASH_SUBSHELL", (char *)NULL, get_subshell, assign_subshell);
1673
1674  INIT_DYNAMIC_VAR ("RANDOM", (char *)NULL, get_random, assign_random);
1675  VSETATTR (v, att_integer);
1676  INIT_DYNAMIC_VAR ("LINENO", (char *)NULL, get_lineno, assign_lineno);
1677  VSETATTR (v, att_integer);
1678
1679  INIT_DYNAMIC_VAR ("BASHPID", (char *)NULL, get_bashpid, null_assign);
1680  VSETATTR (v, att_integer|att_readonly);
1681
1682#if defined (HISTORY)
1683  INIT_DYNAMIC_VAR ("HISTCMD", (char *)NULL, get_histcmd, (sh_var_assign_func_t *)NULL);
1684  VSETATTR (v, att_integer);
1685#endif
1686
1687#if defined (READLINE)
1688  INIT_DYNAMIC_VAR ("COMP_WORDBREAKS", (char *)NULL, get_comp_wordbreaks, assign_comp_wordbreaks);
1689#endif
1690
1691#if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
1692  v = init_dynamic_array_var ("DIRSTACK", get_dirstack, assign_dirstack, 0);
1693#endif /* PUSHD_AND_POPD && ARRAY_VARS */
1694
1695#if defined (ARRAY_VARS)
1696  v = init_dynamic_array_var ("GROUPS", get_groupset, null_array_assign, att_noassign);
1697
1698#  if defined (DEBUGGER)
1699  v = init_dynamic_array_var ("BASH_ARGC", get_self, null_array_assign, att_noassign|att_nounset);
1700  v = init_dynamic_array_var ("BASH_ARGV", get_self, null_array_assign, att_noassign|att_nounset);
1701#  endif /* DEBUGGER */
1702  v = init_dynamic_array_var ("BASH_SOURCE", get_self, null_array_assign, att_noassign|att_nounset);
1703  v = init_dynamic_array_var ("BASH_LINENO", get_self, null_array_assign, att_noassign|att_nounset);
1704
1705  v = init_dynamic_assoc_var ("BASH_CMDS", get_hashcmd, assign_hashcmd, att_nofree);
1706  v = init_dynamic_assoc_var ("BASH_ALIASES", get_aliasvar, assign_aliasvar, att_nofree);
1707#endif
1708
1709  v = init_funcname_var ();
1710}
1711
1712/* **************************************************************** */
1713/*								    */
1714/*		Retrieving variables and values			    */
1715/*								    */
1716/* **************************************************************** */
1717
1718/* How to get a pointer to the shell variable or function named NAME.
1719   HASHED_VARS is a pointer to the hash table containing the list
1720   of interest (either variables or functions). */
1721
1722static SHELL_VAR *
1723hash_lookup (name, hashed_vars)
1724     const char *name;
1725     HASH_TABLE *hashed_vars;
1726{
1727  BUCKET_CONTENTS *bucket;
1728
1729  bucket = hash_search (name, hashed_vars, 0);
1730  return (bucket ? (SHELL_VAR *)bucket->data : (SHELL_VAR *)NULL);
1731}
1732
1733SHELL_VAR *
1734var_lookup (name, vcontext)
1735     const char *name;
1736     VAR_CONTEXT *vcontext;
1737{
1738  VAR_CONTEXT *vc;
1739  SHELL_VAR *v;
1740
1741  v = (SHELL_VAR *)NULL;
1742  for (vc = vcontext; vc; vc = vc->down)
1743    if (v = hash_lookup (name, vc->table))
1744      break;
1745
1746  return v;
1747}
1748
1749/* Look up the variable entry named NAME.  If SEARCH_TEMPENV is non-zero,
1750   then also search the temporarily built list of exported variables.
1751   The lookup order is:
1752	temporary_env
1753	shell_variables list
1754*/
1755
1756SHELL_VAR *
1757find_variable_internal (name, force_tempenv)
1758     const char *name;
1759     int force_tempenv;
1760{
1761  SHELL_VAR *var;
1762  int search_tempenv;
1763
1764  var = (SHELL_VAR *)NULL;
1765
1766  /* If explicitly requested, first look in the temporary environment for
1767     the variable.  This allows constructs such as "foo=x eval 'echo $foo'"
1768     to get the `exported' value of $foo.  This happens if we are executing
1769     a function or builtin, or if we are looking up a variable in a
1770     "subshell environment". */
1771  search_tempenv = force_tempenv || (expanding_redir == 0 && subshell_environment);
1772
1773  if (search_tempenv && temporary_env)
1774    var = hash_lookup (name, temporary_env);
1775
1776  if (var == 0)
1777    var = var_lookup (name, shell_variables);
1778
1779  if (var == 0)
1780    return ((SHELL_VAR *)NULL);
1781
1782  return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var);
1783}
1784
1785/* Look up the variable entry named NAME.  Returns the entry or NULL. */
1786SHELL_VAR *
1787find_variable (name)
1788     const char *name;
1789{
1790  return (find_variable_internal (name, (expanding_redir == 0 && (assigning_in_environment || executing_builtin))));
1791}
1792
1793/* Look up the function entry whose name matches STRING.
1794   Returns the entry or NULL. */
1795SHELL_VAR *
1796find_function (name)
1797     const char *name;
1798{
1799  return (hash_lookup (name, shell_functions));
1800}
1801
1802/* Find the function definition for the shell function named NAME.  Returns
1803   the entry or NULL. */
1804FUNCTION_DEF *
1805find_function_def (name)
1806     const char *name;
1807{
1808#if defined (DEBUGGER)
1809  return ((FUNCTION_DEF *)hash_lookup (name, shell_function_defs));
1810#else
1811  return ((FUNCTION_DEF *)0);
1812#endif
1813}
1814
1815/* Return the value of VAR.  VAR is assumed to have been the result of a
1816   lookup without any subscript, if arrays are compiled into the shell. */
1817char *
1818get_variable_value (var)
1819     SHELL_VAR *var;
1820{
1821  if (var == 0)
1822    return ((char *)NULL);
1823#if defined (ARRAY_VARS)
1824  else if (array_p (var))
1825    return (array_reference (array_cell (var), 0));
1826  else if (assoc_p (var))
1827    return (assoc_reference (assoc_cell (var), "0"));
1828#endif
1829  else
1830    return (value_cell (var));
1831}
1832
1833/* Return the string value of a variable.  Return NULL if the variable
1834   doesn't exist.  Don't cons a new string.  This is a potential memory
1835   leak if the variable is found in the temporary environment.  Since
1836   functions and variables have separate name spaces, returns NULL if
1837   var_name is a shell function only. */
1838char *
1839get_string_value (var_name)
1840     const char *var_name;
1841{
1842  SHELL_VAR *var;
1843
1844  var = find_variable (var_name);
1845  return ((var) ? get_variable_value (var) : (char *)NULL);
1846}
1847
1848/* This is present for use by the tilde and readline libraries. */
1849char *
1850sh_get_env_value (v)
1851     const char *v;
1852{
1853  return get_string_value (v);
1854}
1855
1856/* **************************************************************** */
1857/*								    */
1858/*		  Creating and setting variables		    */
1859/*								    */
1860/* **************************************************************** */
1861
1862/* Set NAME to VALUE if NAME has no value. */
1863SHELL_VAR *
1864set_if_not (name, value)
1865     char *name, *value;
1866{
1867  SHELL_VAR *v;
1868
1869  if (shell_variables == 0)
1870    create_variable_tables ();
1871
1872  v = find_variable (name);
1873  if (v == 0)
1874    v = bind_variable_internal (name, value, global_variables->table, HASH_NOSRCH, 0);
1875  return (v);
1876}
1877
1878/* Create a local variable referenced by NAME. */
1879SHELL_VAR *
1880make_local_variable (name)
1881     const char *name;
1882{
1883  SHELL_VAR *new_var, *old_var;
1884  VAR_CONTEXT *vc;
1885  int was_tmpvar;
1886  char *tmp_value;
1887
1888  /* local foo; local foo;  is a no-op. */
1889  old_var = find_variable (name);
1890  if (old_var && local_p (old_var) && old_var->context == variable_context)
1891    {
1892      VUNSETATTR (old_var, att_invisible);
1893      return (old_var);
1894    }
1895
1896  was_tmpvar = old_var && tempvar_p (old_var);
1897  if (was_tmpvar)
1898    tmp_value = value_cell (old_var);
1899
1900  for (vc = shell_variables; vc; vc = vc->down)
1901    if (vc_isfuncenv (vc) && vc->scope == variable_context)
1902      break;
1903
1904  if (vc == 0)
1905    {
1906      internal_error (_("make_local_variable: no function context at current scope"));
1907      return ((SHELL_VAR *)NULL);
1908    }
1909  else if (vc->table == 0)
1910    vc->table = hash_create (TEMPENV_HASH_BUCKETS);
1911
1912  /* Since this is called only from the local/declare/typeset code, we can
1913     call builtin_error here without worry (of course, it will also work
1914     for anything that sets this_command_name).  Variables with the `noassign'
1915     attribute may not be made local.  The test against old_var's context
1916     level is to disallow local copies of readonly global variables (since I
1917     believe that this could be a security hole).  Readonly copies of calling
1918     function local variables are OK. */
1919  if (old_var && (noassign_p (old_var) ||
1920		 (readonly_p (old_var) && old_var->context == 0)))
1921    {
1922      if (readonly_p (old_var))
1923	sh_readonly (name);
1924      return ((SHELL_VAR *)NULL);
1925    }
1926
1927  if (old_var == 0)
1928    new_var = make_new_variable (name, vc->table);
1929  else
1930    {
1931      new_var = make_new_variable (name, vc->table);
1932
1933      /* If we found this variable in one of the temporary environments,
1934	 inherit its value.  Watch to see if this causes problems with
1935	 things like `x=4 local x'. */
1936      if (was_tmpvar)
1937	var_setvalue (new_var, savestring (tmp_value));
1938
1939      new_var->attributes = exported_p (old_var) ? att_exported : 0;
1940    }
1941
1942  vc->flags |= VC_HASLOCAL;
1943
1944  new_var->context = variable_context;
1945  VSETATTR (new_var, att_local);
1946
1947  if (ifsname (name))
1948    setifs (new_var);
1949
1950  return (new_var);
1951}
1952
1953/* Create a new shell variable with name NAME. */
1954static SHELL_VAR *
1955new_shell_variable (name)
1956     const char *name;
1957{
1958  SHELL_VAR *entry;
1959
1960  entry = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
1961
1962  entry->name = savestring (name);
1963  var_setvalue (entry, (char *)NULL);
1964  CLEAR_EXPORTSTR (entry);
1965
1966  entry->dynamic_value = (sh_var_value_func_t *)NULL;
1967  entry->assign_func = (sh_var_assign_func_t *)NULL;
1968
1969  entry->attributes = 0;
1970
1971  /* Always assume variables are to be made at toplevel!
1972     make_local_variable has the responsibilty of changing the
1973     variable context. */
1974  entry->context = 0;
1975
1976  return (entry);
1977}
1978
1979/* Create a new shell variable with name NAME and add it to the hash table
1980   TABLE. */
1981static SHELL_VAR *
1982make_new_variable (name, table)
1983     const char *name;
1984     HASH_TABLE *table;
1985{
1986  SHELL_VAR *entry;
1987  BUCKET_CONTENTS *elt;
1988
1989  entry = new_shell_variable (name);
1990
1991  /* Make sure we have a shell_variables hash table to add to. */
1992  if (shell_variables == 0)
1993    create_variable_tables ();
1994
1995  elt = hash_insert (savestring (name), table, HASH_NOSRCH);
1996  elt->data = (PTR_T)entry;
1997
1998  return entry;
1999}
2000
2001#if defined (ARRAY_VARS)
2002SHELL_VAR *
2003make_new_array_variable (name)
2004     char *name;
2005{
2006  SHELL_VAR *entry;
2007  ARRAY *array;
2008
2009  entry = make_new_variable (name, global_variables->table);
2010  array = array_create ();
2011
2012  var_setarray (entry, array);
2013  VSETATTR (entry, att_array);
2014  return entry;
2015}
2016
2017SHELL_VAR *
2018make_local_array_variable (name)
2019     char *name;
2020{
2021  SHELL_VAR *var;
2022  ARRAY *array;
2023
2024  var = make_local_variable (name);
2025  if (var == 0 || array_p (var))
2026    return var;
2027
2028  array = array_create ();
2029
2030  dispose_variable_value (var);
2031  var_setarray (var, array);
2032  VSETATTR (var, att_array);
2033  return var;
2034}
2035
2036SHELL_VAR *
2037make_new_assoc_variable (name)
2038     char *name;
2039{
2040  SHELL_VAR *entry;
2041  HASH_TABLE *hash;
2042
2043  entry = make_new_variable (name, global_variables->table);
2044  hash = assoc_create (0);
2045
2046  var_setassoc (entry, hash);
2047  VSETATTR (entry, att_assoc);
2048  return entry;
2049}
2050
2051SHELL_VAR *
2052make_local_assoc_variable (name)
2053     char *name;
2054{
2055  SHELL_VAR *var;
2056  HASH_TABLE *hash;
2057
2058  var = make_local_variable (name);
2059  if (var == 0 || assoc_p (var))
2060    return var;
2061
2062  dispose_variable_value (var);
2063  hash = assoc_create (0);
2064
2065  var_setassoc (var, hash);
2066  VSETATTR (var, att_assoc);
2067  return var;
2068}
2069#endif
2070
2071char *
2072make_variable_value (var, value, flags)
2073     SHELL_VAR *var;
2074     char *value;
2075     int flags;
2076{
2077  char *retval, *oval;
2078  intmax_t lval, rval;
2079  int expok, olen, op;
2080
2081  /* If this variable has had its type set to integer (via `declare -i'),
2082     then do expression evaluation on it and store the result.  The
2083     functions in expr.c (evalexp()) and bind_int_variable() are responsible
2084     for turning off the integer flag if they don't want further
2085     evaluation done. */
2086  if (integer_p (var))
2087    {
2088      if (flags & ASS_APPEND)
2089	{
2090	  oval = value_cell (var);
2091	  lval = evalexp (oval, &expok);	/* ksh93 seems to do this */
2092	  if (expok == 0)
2093	    {
2094	      top_level_cleanup ();
2095	      jump_to_top_level (DISCARD);
2096	    }
2097	}
2098      rval = evalexp (value, &expok);
2099      if (expok == 0)
2100	{
2101	  top_level_cleanup ();
2102	  jump_to_top_level (DISCARD);
2103	}
2104      if (flags & ASS_APPEND)
2105	rval += lval;
2106      retval = itos (rval);
2107    }
2108#if defined (CASEMOD_ATTRS)
2109  else if (capcase_p (var) || uppercase_p (var) || lowercase_p (var))
2110    {
2111      if (flags & ASS_APPEND)
2112	{
2113	  oval = get_variable_value (var);
2114	  if (oval == 0)	/* paranoia */
2115	    oval = "";
2116	  olen = STRLEN (oval);
2117	  retval = (char *)xmalloc (olen + (value ? STRLEN (value) : 0) + 1);
2118	  strcpy (retval, oval);
2119	  if (value)
2120	    strcpy (retval+olen, value);
2121	}
2122      else if (*value)
2123	retval = savestring (value);
2124      else
2125	{
2126	  retval = (char *)xmalloc (1);
2127	  retval[0] = '\0';
2128	}
2129      op = capcase_p (var) ? CASE_CAPITALIZE
2130			 : (uppercase_p (var) ? CASE_UPPER : CASE_LOWER);
2131      oval = sh_modcase (retval, (char *)0, op);
2132      free (retval);
2133      retval = oval;
2134    }
2135#endif /* CASEMOD_ATTRS */
2136  else if (value)
2137    {
2138      if (flags & ASS_APPEND)
2139	{
2140	  oval = get_variable_value (var);
2141	  if (oval == 0)	/* paranoia */
2142	    oval = "";
2143	  olen = STRLEN (oval);
2144	  retval = (char *)xmalloc (olen + (value ? STRLEN (value) : 0) + 1);
2145	  strcpy (retval, oval);
2146	  if (value)
2147	    strcpy (retval+olen, value);
2148	}
2149      else if (*value)
2150	retval = savestring (value);
2151      else
2152	{
2153	  retval = (char *)xmalloc (1);
2154	  retval[0] = '\0';
2155	}
2156    }
2157  else
2158    retval = (char *)NULL;
2159
2160  return retval;
2161}
2162
2163/* Bind a variable NAME to VALUE in the HASH_TABLE TABLE, which may be the
2164   temporary environment (but usually is not). */
2165static SHELL_VAR *
2166bind_variable_internal (name, value, table, hflags, aflags)
2167     const char *name;
2168     char *value;
2169     HASH_TABLE *table;
2170     int hflags, aflags;
2171{
2172  char *newval;
2173  SHELL_VAR *entry;
2174
2175  entry = (hflags & HASH_NOSRCH) ? (SHELL_VAR *)NULL : hash_lookup (name, table);
2176
2177  if (entry == 0)
2178    {
2179      entry = make_new_variable (name, table);
2180      var_setvalue (entry, make_variable_value (entry, value, 0)); /* XXX */
2181    }
2182  else if (entry->assign_func)	/* array vars have assign functions now */
2183    {
2184      INVALIDATE_EXPORTSTR (entry);
2185      newval = (aflags & ASS_APPEND) ? make_variable_value (entry, value, aflags) : value;
2186      entry = (*(entry->assign_func)) (entry, newval, -1, 0);
2187      if (newval != value)
2188	free (newval);
2189      return (entry);
2190    }
2191  else
2192    {
2193      if (readonly_p (entry) || noassign_p (entry))
2194	{
2195	  if (readonly_p (entry))
2196	    err_readonly (name);
2197	  return (entry);
2198	}
2199
2200      /* Variables which are bound are visible. */
2201      VUNSETATTR (entry, att_invisible);
2202
2203      newval = make_variable_value (entry, value, aflags);	/* XXX */
2204
2205      /* Invalidate any cached export string */
2206      INVALIDATE_EXPORTSTR (entry);
2207
2208#if defined (ARRAY_VARS)
2209      /* XXX -- this bears looking at again -- XXX */
2210      /* If an existing array variable x is being assigned to with x=b or
2211	 `read x' or something of that nature, silently convert it to
2212	 x[0]=b or `read x[0]'. */
2213      if (array_p (entry))
2214	{
2215	  array_insert (array_cell (entry), 0, newval);
2216	  free (newval);
2217	}
2218      else if (assoc_p (entry))
2219	{
2220	  assoc_insert (assoc_cell (entry), savestring ("0"), newval);
2221	  free (newval);
2222	}
2223      else
2224#endif
2225	{
2226	  FREE (value_cell (entry));
2227	  var_setvalue (entry, newval);
2228	}
2229    }
2230
2231  if (mark_modified_vars)
2232    VSETATTR (entry, att_exported);
2233
2234  if (exported_p (entry))
2235    array_needs_making = 1;
2236
2237  return (entry);
2238}
2239
2240/* Bind a variable NAME to VALUE.  This conses up the name
2241   and value strings.  If we have a temporary environment, we bind there
2242   first, then we bind into shell_variables. */
2243
2244SHELL_VAR *
2245bind_variable (name, value, flags)
2246     const char *name;
2247     char *value;
2248     int flags;
2249{
2250  SHELL_VAR *v;
2251  VAR_CONTEXT *vc;
2252
2253  if (shell_variables == 0)
2254    create_variable_tables ();
2255
2256  /* If we have a temporary environment, look there first for the variable,
2257     and, if found, modify the value there before modifying it in the
2258     shell_variables table.  This allows sourced scripts to modify values
2259     given to them in a temporary environment while modifying the variable
2260     value that the caller sees. */
2261  if (temporary_env)
2262    bind_tempenv_variable (name, value);
2263
2264  /* XXX -- handle local variables here. */
2265  for (vc = shell_variables; vc; vc = vc->down)
2266    {
2267      if (vc_isfuncenv (vc) || vc_isbltnenv (vc))
2268	{
2269	  v = hash_lookup (name, vc->table);
2270	  if (v)
2271	    return (bind_variable_internal (name, value, vc->table, 0, flags));
2272	}
2273    }
2274  return (bind_variable_internal (name, value, global_variables->table, 0, flags));
2275}
2276
2277/* Make VAR, a simple shell variable, have value VALUE.  Once assigned a
2278   value, variables are no longer invisible.  This is a duplicate of part
2279   of the internals of bind_variable.  If the variable is exported, or
2280   all modified variables should be exported, mark the variable for export
2281   and note that the export environment needs to be recreated. */
2282SHELL_VAR *
2283bind_variable_value (var, value, aflags)
2284     SHELL_VAR *var;
2285     char *value;
2286     int aflags;
2287{
2288  char *t;
2289
2290  VUNSETATTR (var, att_invisible);
2291
2292  if (var->assign_func)
2293    {
2294      /* If we're appending, we need the old value, so use
2295	 make_variable_value */
2296      t = (aflags & ASS_APPEND) ? make_variable_value (var, value, aflags) : value;
2297      (*(var->assign_func)) (var, t, -1, 0);
2298      if (t != value && t)
2299	free (t);
2300    }
2301  else
2302    {
2303      t = make_variable_value (var, value, aflags);
2304      FREE (value_cell (var));
2305      var_setvalue (var, t);
2306    }
2307
2308  INVALIDATE_EXPORTSTR (var);
2309
2310  if (mark_modified_vars)
2311    VSETATTR (var, att_exported);
2312
2313  if (exported_p (var))
2314    array_needs_making = 1;
2315
2316  return (var);
2317}
2318
2319/* Bind/create a shell variable with the name LHS to the RHS.
2320   This creates or modifies a variable such that it is an integer.
2321
2322   This used to be in expr.c, but it is here so that all of the
2323   variable binding stuff is localized.  Since we don't want any
2324   recursive evaluation from bind_variable() (possible without this code,
2325   since bind_variable() calls the evaluator for variables with the integer
2326   attribute set), we temporarily turn off the integer attribute for each
2327   variable we set here, then turn it back on after binding as necessary. */
2328
2329SHELL_VAR *
2330bind_int_variable (lhs, rhs)
2331     char *lhs, *rhs;
2332{
2333  register SHELL_VAR *v;
2334  int isint, isarr;
2335
2336  isint = isarr = 0;
2337#if defined (ARRAY_VARS)
2338  if (valid_array_reference (lhs))
2339    {
2340      isarr = 1;
2341      v = array_variable_part (lhs, (char **)0, (int *)0);
2342    }
2343  else
2344#endif
2345    v = find_variable (lhs);
2346
2347  if (v)
2348    {
2349      isint = integer_p (v);
2350      VUNSETATTR (v, att_integer);
2351    }
2352
2353#if defined (ARRAY_VARS)
2354  if (isarr)
2355    v = assign_array_element (lhs, rhs, 0);
2356  else
2357#endif
2358    v = bind_variable (lhs, rhs, 0);
2359
2360  if (isint)
2361    VSETATTR (v, att_integer);
2362
2363  return (v);
2364}
2365
2366SHELL_VAR *
2367bind_var_to_int (var, val)
2368     char *var;
2369     intmax_t val;
2370{
2371  char ibuf[INT_STRLEN_BOUND (intmax_t) + 1], *p;
2372
2373  p = fmtulong (val, 10, ibuf, sizeof (ibuf), 0);
2374  return (bind_int_variable (var, p));
2375}
2376
2377/* Do a function binding to a variable.  You pass the name and
2378   the command to bind to.  This conses the name and command. */
2379SHELL_VAR *
2380bind_function (name, value)
2381     const char *name;
2382     COMMAND *value;
2383{
2384  SHELL_VAR *entry;
2385
2386  entry = find_function (name);
2387  if (entry == 0)
2388    {
2389      BUCKET_CONTENTS *elt;
2390
2391      elt = hash_insert (savestring (name), shell_functions, HASH_NOSRCH);
2392      entry = new_shell_variable (name);
2393      elt->data = (PTR_T)entry;
2394    }
2395  else
2396    INVALIDATE_EXPORTSTR (entry);
2397
2398  if (var_isset (entry))
2399    dispose_command (function_cell (entry));
2400
2401  if (value)
2402    var_setfunc (entry, copy_command (value));
2403  else
2404    var_setfunc (entry, 0);
2405
2406  VSETATTR (entry, att_function);
2407
2408  if (mark_modified_vars)
2409    VSETATTR (entry, att_exported);
2410
2411  VUNSETATTR (entry, att_invisible);		/* Just to be sure */
2412
2413  if (exported_p (entry))
2414    array_needs_making = 1;
2415
2416#if defined (PROGRAMMABLE_COMPLETION)
2417  set_itemlist_dirty (&it_functions);
2418#endif
2419
2420  return (entry);
2421}
2422
2423#if defined (DEBUGGER)
2424/* Bind a function definition, which includes source file and line number
2425   information in addition to the command, into the FUNCTION_DEF hash table.*/
2426void
2427bind_function_def (name, value)
2428     const char *name;
2429     FUNCTION_DEF *value;
2430{
2431  FUNCTION_DEF *entry;
2432  BUCKET_CONTENTS *elt;
2433  COMMAND *cmd;
2434
2435  entry = find_function_def (name);
2436  if (entry)
2437    {
2438      dispose_function_def_contents (entry);
2439      entry = copy_function_def_contents (value, entry);
2440    }
2441  else
2442    {
2443      cmd = value->command;
2444      value->command = 0;
2445      entry = copy_function_def (value);
2446      value->command = cmd;
2447
2448      elt = hash_insert (savestring (name), shell_function_defs, HASH_NOSRCH);
2449      elt->data = (PTR_T *)entry;
2450    }
2451}
2452#endif /* DEBUGGER */
2453
2454/* Add STRING, which is of the form foo=bar, to the temporary environment
2455   HASH_TABLE (temporary_env).  The functions in execute_cmd.c are
2456   responsible for moving the main temporary env to one of the other
2457   temporary environments.  The expansion code in subst.c calls this. */
2458int
2459assign_in_env (word)
2460     WORD_DESC *word;
2461{
2462  int offset;
2463  char *name, *temp, *value;
2464  SHELL_VAR *var;
2465  const char *string;
2466
2467  string = word->word;
2468
2469  offset = assignment (string, 0);
2470  name = savestring (string);
2471  value = (char *)NULL;
2472
2473  if (name[offset] == '=')
2474    {
2475      name[offset] = 0;
2476
2477      /* ignore the `+' when assigning temporary environment */
2478      if (name[offset - 1] == '+')
2479	name[offset - 1] = '\0';
2480
2481      var = find_variable (name);
2482      if (var && (readonly_p (var) || noassign_p (var)))
2483	{
2484	  if (readonly_p (var))
2485	    err_readonly (name);
2486	  free (name);
2487  	  return (0);
2488	}
2489
2490      temp = name + offset + 1;
2491      value = expand_assignment_string_to_string (temp, 0);
2492    }
2493
2494  if (temporary_env == 0)
2495    temporary_env = hash_create (TEMPENV_HASH_BUCKETS);
2496
2497  var = hash_lookup (name, temporary_env);
2498  if (var == 0)
2499    var = make_new_variable (name, temporary_env);
2500  else
2501    FREE (value_cell (var));
2502
2503  if (value == 0)
2504    {
2505      value = (char *)xmalloc (1);	/* like do_assignment_internal */
2506      value[0] = '\0';
2507    }
2508
2509  var_setvalue (var, value);
2510  var->attributes |= (att_exported|att_tempvar);
2511  var->context = variable_context;	/* XXX */
2512
2513  INVALIDATE_EXPORTSTR (var);
2514  var->exportstr = mk_env_string (name, value);
2515
2516  array_needs_making = 1;
2517
2518  if (ifsname (name))
2519    setifs (var);
2520
2521  if (echo_command_at_execute)
2522    /* The Korn shell prints the `+ ' in front of assignment statements,
2523	so we do too. */
2524    xtrace_print_assignment (name, value, 0, 1);
2525
2526  free (name);
2527  return 1;
2528}
2529
2530/* **************************************************************** */
2531/*								    */
2532/*			Copying variables			    */
2533/*								    */
2534/* **************************************************************** */
2535
2536#ifdef INCLUDE_UNUSED
2537/* Copy VAR to a new data structure and return that structure. */
2538SHELL_VAR *
2539copy_variable (var)
2540     SHELL_VAR *var;
2541{
2542  SHELL_VAR *copy = (SHELL_VAR *)NULL;
2543
2544  if (var)
2545    {
2546      copy = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
2547
2548      copy->attributes = var->attributes;
2549      copy->name = savestring (var->name);
2550
2551      if (function_p (var))
2552	var_setfunc (copy, copy_command (function_cell (var)));
2553#if defined (ARRAY_VARS)
2554      else if (array_p (var))
2555	var_setarray (copy, array_copy (array_cell (var)));
2556      else if (assoc_p (var))
2557	var_setassoc (copy, assoc_copy (assoc_cell (var)));
2558#endif
2559      else if (value_cell (var))
2560	var_setvalue (copy, savestring (value_cell (var)));
2561      else
2562	var_setvalue (copy, (char *)NULL);
2563
2564      copy->dynamic_value = var->dynamic_value;
2565      copy->assign_func = var->assign_func;
2566
2567      copy->exportstr = COPY_EXPORTSTR (var);
2568
2569      copy->context = var->context;
2570    }
2571  return (copy);
2572}
2573#endif
2574
2575/* **************************************************************** */
2576/*								    */
2577/*		  Deleting and unsetting variables		    */
2578/*								    */
2579/* **************************************************************** */
2580
2581/* Dispose of the information attached to VAR. */
2582static void
2583dispose_variable_value (var)
2584     SHELL_VAR *var;
2585{
2586  if (function_p (var))
2587    dispose_command (function_cell (var));
2588#if defined (ARRAY_VARS)
2589  else if (array_p (var))
2590    array_dispose (array_cell (var));
2591  else if (assoc_p (var))
2592    assoc_dispose (assoc_cell (var));
2593#endif
2594  else
2595    FREE (value_cell (var));
2596}
2597
2598void
2599dispose_variable (var)
2600     SHELL_VAR *var;
2601{
2602  if (var == 0)
2603    return;
2604
2605  if (nofree_p (var) == 0)
2606    dispose_variable_value (var);
2607
2608  FREE_EXPORTSTR (var);
2609
2610  free (var->name);
2611
2612  if (exported_p (var))
2613    array_needs_making = 1;
2614
2615  free (var);
2616}
2617
2618/* Unset the shell variable referenced by NAME. */
2619int
2620unbind_variable (name)
2621     const char *name;
2622{
2623  return makunbound (name, shell_variables);
2624}
2625
2626/* Unset the shell function named NAME. */
2627int
2628unbind_func (name)
2629     const char *name;
2630{
2631  BUCKET_CONTENTS *elt;
2632  SHELL_VAR *func;
2633
2634  elt = hash_remove (name, shell_functions, 0);
2635
2636  if (elt == 0)
2637    return -1;
2638
2639#if defined (PROGRAMMABLE_COMPLETION)
2640  set_itemlist_dirty (&it_functions);
2641#endif
2642
2643  func = (SHELL_VAR *)elt->data;
2644  if (func)
2645    {
2646      if (exported_p (func))
2647	array_needs_making++;
2648      dispose_variable (func);
2649    }
2650
2651  free (elt->key);
2652  free (elt);
2653
2654  return 0;
2655}
2656
2657#if defined (DEBUGGER)
2658int
2659unbind_function_def (name)
2660     const char *name;
2661{
2662  BUCKET_CONTENTS *elt;
2663  FUNCTION_DEF *funcdef;
2664
2665  elt = hash_remove (name, shell_function_defs, 0);
2666
2667  if (elt == 0)
2668    return -1;
2669
2670  funcdef = (FUNCTION_DEF *)elt->data;
2671  if (funcdef)
2672    dispose_function_def (funcdef);
2673
2674  free (elt->key);
2675  free (elt);
2676
2677  return 0;
2678}
2679#endif /* DEBUGGER */
2680
2681/* Make the variable associated with NAME go away.  HASH_LIST is the
2682   hash table from which this variable should be deleted (either
2683   shell_variables or shell_functions).
2684   Returns non-zero if the variable couldn't be found. */
2685int
2686makunbound (name, vc)
2687     const char *name;
2688     VAR_CONTEXT *vc;
2689{
2690  BUCKET_CONTENTS *elt, *new_elt;
2691  SHELL_VAR *old_var;
2692  VAR_CONTEXT *v;
2693  char *t;
2694
2695  for (elt = (BUCKET_CONTENTS *)NULL, v = vc; v; v = v->down)
2696    if (elt = hash_remove (name, v->table, 0))
2697      break;
2698
2699  if (elt == 0)
2700    return (-1);
2701
2702  old_var = (SHELL_VAR *)elt->data;
2703
2704  if (old_var && exported_p (old_var))
2705    array_needs_making++;
2706
2707  /* If we're unsetting a local variable and we're still executing inside
2708     the function, just mark the variable as invisible.  The function
2709     eventually called by pop_var_context() will clean it up later.  This
2710     must be done so that if the variable is subsequently assigned a new
2711     value inside the function, the `local' attribute is still present.
2712     We also need to add it back into the correct hash table. */
2713  if (old_var && local_p (old_var) && variable_context == old_var->context)
2714    {
2715      if (nofree_p (old_var))
2716	var_setvalue (old_var, (char *)NULL);
2717#if defined (ARRAY_VARS)
2718      else if (array_p (old_var))
2719	array_dispose (array_cell (old_var));
2720      else if (assoc_p (old_var))
2721	assoc_dispose (assoc_cell (old_var));
2722#endif
2723      else
2724	FREE (value_cell (old_var));
2725      /* Reset the attributes.  Preserve the export attribute if the variable
2726	 came from a temporary environment.  Make sure it stays local, and
2727	 make it invisible. */
2728      old_var->attributes = (exported_p (old_var) && tempvar_p (old_var)) ? att_exported : 0;
2729      VSETATTR (old_var, att_local);
2730      VSETATTR (old_var, att_invisible);
2731      var_setvalue (old_var, (char *)NULL);
2732      INVALIDATE_EXPORTSTR (old_var);
2733
2734      new_elt = hash_insert (savestring (old_var->name), v->table, 0);
2735      new_elt->data = (PTR_T)old_var;
2736      stupidly_hack_special_variables (old_var->name);
2737
2738      free (elt->key);
2739      free (elt);
2740      return (0);
2741    }
2742
2743  /* Have to save a copy of name here, because it might refer to
2744     old_var->name.  If so, stupidly_hack_special_variables will
2745     reference freed memory. */
2746  t = savestring (name);
2747
2748  free (elt->key);
2749  free (elt);
2750
2751  dispose_variable (old_var);
2752  stupidly_hack_special_variables (t);
2753  free (t);
2754
2755  return (0);
2756}
2757
2758/* Get rid of all of the variables in the current context. */
2759void
2760kill_all_local_variables ()
2761{
2762  VAR_CONTEXT *vc;
2763
2764  for (vc = shell_variables; vc; vc = vc->down)
2765    if (vc_isfuncenv (vc) && vc->scope == variable_context)
2766      break;
2767  if (vc == 0)
2768    return;		/* XXX */
2769
2770  if (vc->table && vc_haslocals (vc))
2771    {
2772      delete_all_variables (vc->table);
2773      hash_dispose (vc->table);
2774    }
2775  vc->table = (HASH_TABLE *)NULL;
2776}
2777
2778static void
2779free_variable_hash_data (data)
2780     PTR_T data;
2781{
2782  SHELL_VAR *var;
2783
2784  var = (SHELL_VAR *)data;
2785  dispose_variable (var);
2786}
2787
2788/* Delete the entire contents of the hash table. */
2789void
2790delete_all_variables (hashed_vars)
2791     HASH_TABLE *hashed_vars;
2792{
2793  hash_flush (hashed_vars, free_variable_hash_data);
2794}
2795
2796/* **************************************************************** */
2797/*								    */
2798/*		     Setting variable attributes		    */
2799/*								    */
2800/* **************************************************************** */
2801
2802#define FIND_OR_MAKE_VARIABLE(name, entry) \
2803  do \
2804    { \
2805      entry = find_variable (name); \
2806      if (!entry) \
2807	{ \
2808	  entry = bind_variable (name, "", 0); \
2809	  if (!no_invisible_vars) entry->attributes |= att_invisible; \
2810	} \
2811    } \
2812  while (0)
2813
2814/* Make the variable associated with NAME be readonly.
2815   If NAME does not exist yet, create it. */
2816void
2817set_var_read_only (name)
2818     char *name;
2819{
2820  SHELL_VAR *entry;
2821
2822  FIND_OR_MAKE_VARIABLE (name, entry);
2823  VSETATTR (entry, att_readonly);
2824}
2825
2826#ifdef INCLUDE_UNUSED
2827/* Make the function associated with NAME be readonly.
2828   If NAME does not exist, we just punt, like auto_export code below. */
2829void
2830set_func_read_only (name)
2831     const char *name;
2832{
2833  SHELL_VAR *entry;
2834
2835  entry = find_function (name);
2836  if (entry)
2837    VSETATTR (entry, att_readonly);
2838}
2839
2840/* Make the variable associated with NAME be auto-exported.
2841   If NAME does not exist yet, create it. */
2842void
2843set_var_auto_export (name)
2844     char *name;
2845{
2846  SHELL_VAR *entry;
2847
2848  FIND_OR_MAKE_VARIABLE (name, entry);
2849  set_auto_export (entry);
2850}
2851
2852/* Make the function associated with NAME be auto-exported. */
2853void
2854set_func_auto_export (name)
2855     const char *name;
2856{
2857  SHELL_VAR *entry;
2858
2859  entry = find_function (name);
2860  if (entry)
2861    set_auto_export (entry);
2862}
2863#endif
2864
2865/* **************************************************************** */
2866/*								    */
2867/*		     Creating lists of variables		    */
2868/*								    */
2869/* **************************************************************** */
2870
2871static VARLIST *
2872vlist_alloc (nentries)
2873     int nentries;
2874{
2875  VARLIST  *vlist;
2876
2877  vlist = (VARLIST *)xmalloc (sizeof (VARLIST));
2878  vlist->list = (SHELL_VAR **)xmalloc ((nentries + 1) * sizeof (SHELL_VAR *));
2879  vlist->list_size = nentries;
2880  vlist->list_len = 0;
2881  vlist->list[0] = (SHELL_VAR *)NULL;
2882
2883  return vlist;
2884}
2885
2886static VARLIST *
2887vlist_realloc (vlist, n)
2888     VARLIST *vlist;
2889     int n;
2890{
2891  if (vlist == 0)
2892    return (vlist = vlist_alloc (n));
2893  if (n > vlist->list_size)
2894    {
2895      vlist->list_size = n;
2896      vlist->list = (SHELL_VAR **)xrealloc (vlist->list, (vlist->list_size + 1) * sizeof (SHELL_VAR *));
2897    }
2898  return vlist;
2899}
2900
2901static void
2902vlist_add (vlist, var, flags)
2903     VARLIST *vlist;
2904     SHELL_VAR *var;
2905     int flags;
2906{
2907  register int i;
2908
2909  for (i = 0; i < vlist->list_len; i++)
2910    if (STREQ (var->name, vlist->list[i]->name))
2911      break;
2912  if (i < vlist->list_len)
2913    return;
2914
2915  if (i >= vlist->list_size)
2916    vlist = vlist_realloc (vlist, vlist->list_size + 16);
2917
2918  vlist->list[vlist->list_len++] = var;
2919  vlist->list[vlist->list_len] = (SHELL_VAR *)NULL;
2920}
2921
2922/* Map FUNCTION over the variables in VAR_HASH_TABLE.  Return an array of the
2923   variables for which FUNCTION returns a non-zero value.  A NULL value
2924   for FUNCTION means to use all variables. */
2925SHELL_VAR **
2926map_over (function, vc)
2927     sh_var_map_func_t *function;
2928     VAR_CONTEXT *vc;
2929{
2930  VAR_CONTEXT *v;
2931  VARLIST *vlist;
2932  SHELL_VAR **ret;
2933  int nentries;
2934
2935  for (nentries = 0, v = vc; v; v = v->down)
2936    nentries += HASH_ENTRIES (v->table);
2937
2938  if (nentries == 0)
2939    return (SHELL_VAR **)NULL;
2940
2941  vlist = vlist_alloc (nentries);
2942
2943  for (v = vc; v; v = v->down)
2944    flatten (v->table, function, vlist, 0);
2945
2946  ret = vlist->list;
2947  free (vlist);
2948  return ret;
2949}
2950
2951SHELL_VAR **
2952map_over_funcs (function)
2953     sh_var_map_func_t *function;
2954{
2955  VARLIST *vlist;
2956  SHELL_VAR **ret;
2957
2958  if (shell_functions == 0 || HASH_ENTRIES (shell_functions) == 0)
2959    return ((SHELL_VAR **)NULL);
2960
2961  vlist = vlist_alloc (HASH_ENTRIES (shell_functions));
2962
2963  flatten (shell_functions, function, vlist, 0);
2964
2965  ret = vlist->list;
2966  free (vlist);
2967  return ret;
2968}
2969
2970/* Flatten VAR_HASH_TABLE, applying FUNC to each member and adding those
2971   elements for which FUNC succeeds to VLIST->list.  FLAGS is reserved
2972   for future use.  Only unique names are added to VLIST.  If FUNC is
2973   NULL, each variable in VAR_HASH_TABLE is added to VLIST.  If VLIST is
2974   NULL, FUNC is applied to each SHELL_VAR in VAR_HASH_TABLE.  If VLIST
2975   and FUNC are both NULL, nothing happens. */
2976static void
2977flatten (var_hash_table, func, vlist, flags)
2978     HASH_TABLE *var_hash_table;
2979     sh_var_map_func_t *func;
2980     VARLIST *vlist;
2981     int flags;
2982{
2983  register int i;
2984  register BUCKET_CONTENTS *tlist;
2985  int r;
2986  SHELL_VAR *var;
2987
2988  if (var_hash_table == 0 || (HASH_ENTRIES (var_hash_table) == 0) || (vlist == 0 && func == 0))
2989    return;
2990
2991  for (i = 0; i < var_hash_table->nbuckets; i++)
2992    {
2993      for (tlist = hash_items (i, var_hash_table); tlist; tlist = tlist->next)
2994	{
2995	  var = (SHELL_VAR *)tlist->data;
2996
2997	  r = func ? (*func) (var) : 1;
2998	  if (r && vlist)
2999	    vlist_add (vlist, var, flags);
3000	}
3001    }
3002}
3003
3004void
3005sort_variables (array)
3006     SHELL_VAR **array;
3007{
3008  qsort (array, strvec_len ((char **)array), sizeof (SHELL_VAR *), (QSFUNC *)qsort_var_comp);
3009}
3010
3011static int
3012qsort_var_comp (var1, var2)
3013     SHELL_VAR **var1, **var2;
3014{
3015  int result;
3016
3017  if ((result = (*var1)->name[0] - (*var2)->name[0]) == 0)
3018    result = strcmp ((*var1)->name, (*var2)->name);
3019
3020  return (result);
3021}
3022
3023/* Apply FUNC to each variable in SHELL_VARIABLES, adding each one for
3024   which FUNC succeeds to an array of SHELL_VAR *s.  Returns the array. */
3025static SHELL_VAR **
3026vapply (func)
3027     sh_var_map_func_t *func;
3028{
3029  SHELL_VAR **list;
3030
3031  list = map_over (func, shell_variables);
3032  if (list /* && posixly_correct */)
3033    sort_variables (list);
3034  return (list);
3035}
3036
3037/* Apply FUNC to each variable in SHELL_FUNCTIONS, adding each one for
3038   which FUNC succeeds to an array of SHELL_VAR *s.  Returns the array. */
3039static SHELL_VAR **
3040fapply (func)
3041     sh_var_map_func_t *func;
3042{
3043  SHELL_VAR **list;
3044
3045  list = map_over_funcs (func);
3046  if (list /* && posixly_correct */)
3047    sort_variables (list);
3048  return (list);
3049}
3050
3051/* Create a NULL terminated array of all the shell variables. */
3052SHELL_VAR **
3053all_shell_variables ()
3054{
3055  return (vapply ((sh_var_map_func_t *)NULL));
3056}
3057
3058/* Create a NULL terminated array of all the shell functions. */
3059SHELL_VAR **
3060all_shell_functions ()
3061{
3062  return (fapply ((sh_var_map_func_t *)NULL));
3063}
3064
3065static int
3066visible_var (var)
3067     SHELL_VAR *var;
3068{
3069  return (invisible_p (var) == 0);
3070}
3071
3072SHELL_VAR **
3073all_visible_functions ()
3074{
3075  return (fapply (visible_var));
3076}
3077
3078SHELL_VAR **
3079all_visible_variables ()
3080{
3081  return (vapply (visible_var));
3082}
3083
3084/* Return non-zero if the variable VAR is visible and exported.  Array
3085   variables cannot be exported. */
3086static int
3087visible_and_exported (var)
3088     SHELL_VAR *var;
3089{
3090  return (invisible_p (var) == 0 && exported_p (var));
3091}
3092
3093/* Candidate variables for the export environment are either valid variables
3094   with the export attribute or invalid variables inherited from the initial
3095   environment and simply passed through. */
3096static int
3097export_environment_candidate (var)
3098     SHELL_VAR *var;
3099{
3100  return (exported_p (var) && (invisible_p (var) == 0 || imported_p (var)));
3101}
3102
3103/* Return non-zero if VAR is a local variable in the current context and
3104   is exported. */
3105static int
3106local_and_exported (var)
3107     SHELL_VAR *var;
3108{
3109  return (invisible_p (var) == 0 && local_p (var) && var->context == variable_context && exported_p (var));
3110}
3111
3112SHELL_VAR **
3113all_exported_variables ()
3114{
3115  return (vapply (visible_and_exported));
3116}
3117
3118SHELL_VAR **
3119local_exported_variables ()
3120{
3121  return (vapply (local_and_exported));
3122}
3123
3124static int
3125variable_in_context (var)
3126     SHELL_VAR *var;
3127{
3128  return (invisible_p (var) == 0 && local_p (var) && var->context == variable_context);
3129}
3130
3131SHELL_VAR **
3132all_local_variables ()
3133{
3134  VARLIST *vlist;
3135  SHELL_VAR **ret;
3136  VAR_CONTEXT *vc;
3137
3138  vc = shell_variables;
3139  for (vc = shell_variables; vc; vc = vc->down)
3140    if (vc_isfuncenv (vc) && vc->scope == variable_context)
3141      break;
3142
3143  if (vc == 0)
3144    {
3145      internal_error (_("all_local_variables: no function context at current scope"));
3146      return (SHELL_VAR **)NULL;
3147    }
3148  if (vc->table == 0 || HASH_ENTRIES (vc->table) == 0 || vc_haslocals (vc) == 0)
3149    return (SHELL_VAR **)NULL;
3150
3151  vlist = vlist_alloc (HASH_ENTRIES (vc->table));
3152
3153  flatten (vc->table, variable_in_context, vlist, 0);
3154
3155  ret = vlist->list;
3156  free (vlist);
3157  if (ret)
3158    sort_variables (ret);
3159  return ret;
3160}
3161
3162#if defined (ARRAY_VARS)
3163/* Return non-zero if the variable VAR is visible and an array. */
3164static int
3165visible_array_vars (var)
3166     SHELL_VAR *var;
3167{
3168  return (invisible_p (var) == 0 && array_p (var));
3169}
3170
3171SHELL_VAR **
3172all_array_variables ()
3173{
3174  return (vapply (visible_array_vars));
3175}
3176#endif /* ARRAY_VARS */
3177
3178char **
3179all_variables_matching_prefix (prefix)
3180     const char *prefix;
3181{
3182  SHELL_VAR **varlist;
3183  char **rlist;
3184  int vind, rind, plen;
3185
3186  plen = STRLEN (prefix);
3187  varlist = all_visible_variables ();
3188  for (vind = 0; varlist && varlist[vind]; vind++)
3189    ;
3190  if (varlist == 0 || vind == 0)
3191    return ((char **)NULL);
3192  rlist = strvec_create (vind + 1);
3193  for (vind = rind = 0; varlist[vind]; vind++)
3194    {
3195      if (plen == 0 || STREQN (prefix, varlist[vind]->name, plen))
3196	rlist[rind++] = savestring (varlist[vind]->name);
3197    }
3198  rlist[rind] = (char *)0;
3199  free (varlist);
3200
3201  return rlist;
3202}
3203
3204/* **************************************************************** */
3205/*								    */
3206/*		 Managing temporary variable scopes		    */
3207/*								    */
3208/* **************************************************************** */
3209
3210/* Make variable NAME have VALUE in the temporary environment. */
3211static SHELL_VAR *
3212bind_tempenv_variable (name, value)
3213     const char *name;
3214     char *value;
3215{
3216  SHELL_VAR *var;
3217
3218  var = temporary_env ? hash_lookup (name, temporary_env) : (SHELL_VAR *)NULL;
3219
3220  if (var)
3221    {
3222      FREE (value_cell (var));
3223      var_setvalue (var, savestring (value));
3224      INVALIDATE_EXPORTSTR (var);
3225    }
3226
3227  return (var);
3228}
3229
3230/* Find a variable in the temporary environment that is named NAME.
3231   Return the SHELL_VAR *, or NULL if not found. */
3232SHELL_VAR *
3233find_tempenv_variable (name)
3234     const char *name;
3235{
3236  return (temporary_env ? hash_lookup (name, temporary_env) : (SHELL_VAR *)NULL);
3237}
3238
3239/* Push the variable described by (SHELL_VAR *)DATA down to the next
3240   variable context from the temporary environment. */
3241static void
3242push_temp_var (data)
3243     PTR_T data;
3244{
3245  SHELL_VAR *var, *v;
3246  HASH_TABLE *binding_table;
3247
3248  var = (SHELL_VAR *)data;
3249
3250  binding_table = shell_variables->table;
3251  if (binding_table == 0)
3252    {
3253      if (shell_variables == global_variables)
3254	/* shouldn't happen */
3255	binding_table = shell_variables->table = global_variables->table = hash_create (0);
3256      else
3257	binding_table = shell_variables->table = hash_create (TEMPENV_HASH_BUCKETS);
3258    }
3259
3260  v = bind_variable_internal (var->name, value_cell (var), binding_table, 0, 0);
3261
3262  /* XXX - should we set the context here?  It shouldn't matter because of how
3263     assign_in_env works, but might want to check. */
3264  if (binding_table == global_variables->table)		/* XXX */
3265    var->attributes &= ~(att_tempvar|att_propagate);
3266  else
3267    {
3268      var->attributes |= att_propagate;
3269      if  (binding_table == shell_variables->table)
3270	shell_variables->flags |= VC_HASTMPVAR;
3271    }
3272  v->attributes |= var->attributes;
3273
3274  dispose_variable (var);
3275}
3276
3277static void
3278propagate_temp_var (data)
3279     PTR_T data;
3280{
3281  SHELL_VAR *var;
3282
3283  var = (SHELL_VAR *)data;
3284  if (tempvar_p (var) && (var->attributes & att_propagate))
3285    push_temp_var (data);
3286  else
3287    dispose_variable (var);
3288}
3289
3290/* Free the storage used in the hash table for temporary
3291   environment variables.  PUSHF is a function to be called
3292   to free each hash table entry.  It takes care of pushing variables
3293   to previous scopes if appropriate. */
3294static void
3295dispose_temporary_env (pushf)
3296     sh_free_func_t *pushf;
3297{
3298  hash_flush (temporary_env, pushf);
3299  hash_dispose (temporary_env);
3300  temporary_env = (HASH_TABLE *)NULL;
3301
3302  array_needs_making = 1;
3303
3304  sv_ifs ("IFS");		/* XXX here for now */
3305}
3306
3307void
3308dispose_used_env_vars ()
3309{
3310  if (temporary_env)
3311    {
3312      dispose_temporary_env (propagate_temp_var);
3313      maybe_make_export_env ();
3314    }
3315}
3316
3317/* Take all of the shell variables in the temporary environment HASH_TABLE
3318   and make shell variables from them at the current variable context. */
3319void
3320merge_temporary_env ()
3321{
3322  if (temporary_env)
3323    dispose_temporary_env (push_temp_var);
3324}
3325
3326/* **************************************************************** */
3327/*								    */
3328/*	     Creating and manipulating the environment		    */
3329/*								    */
3330/* **************************************************************** */
3331
3332static inline char *
3333mk_env_string (name, value)
3334     const char *name, *value;
3335{
3336  int name_len, value_len;
3337  char	*p;
3338
3339  name_len = strlen (name);
3340  value_len = STRLEN (value);
3341  p = (char *)xmalloc (2 + name_len + value_len);
3342  strcpy (p, name);
3343  p[name_len] = '=';
3344  if (value && *value)
3345    strcpy (p + name_len + 1, value);
3346  else
3347    p[name_len + 1] = '\0';
3348  return (p);
3349}
3350
3351#ifdef DEBUG
3352/* Debugging */
3353static int
3354valid_exportstr (v)
3355     SHELL_VAR *v;
3356{
3357  char *s;
3358
3359  s = v->exportstr;
3360  if (legal_variable_starter ((unsigned char)*s) == 0)
3361    {
3362      internal_error (_("invalid character %d in exportstr for %s"), *s, v->name);
3363      return (0);
3364    }
3365  for (s = v->exportstr + 1; s && *s; s++)
3366    {
3367      if (*s == '=')
3368	break;
3369      if (legal_variable_char ((unsigned char)*s) == 0)
3370	{
3371	  internal_error (_("invalid character %d in exportstr for %s"), *s, v->name);
3372	  return (0);
3373	}
3374    }
3375  if (*s != '=')
3376    {
3377      internal_error (_("no `=' in exportstr for %s"), v->name);
3378      return (0);
3379    }
3380  return (1);
3381}
3382#endif
3383
3384static char **
3385make_env_array_from_var_list (vars)
3386     SHELL_VAR **vars;
3387{
3388  register int i, list_index;
3389  register SHELL_VAR *var;
3390  char **list, *value;
3391
3392  list = strvec_create ((1 + strvec_len ((char **)vars)));
3393
3394#define USE_EXPORTSTR (value == var->exportstr)
3395
3396  for (i = 0, list_index = 0; var = vars[i]; i++)
3397    {
3398#if defined (__CYGWIN__)
3399      /* We don't use the exportstr stuff on Cygwin at all. */
3400      INVALIDATE_EXPORTSTR (var);
3401#endif
3402      if (var->exportstr)
3403	value = var->exportstr;
3404      else if (function_p (var))
3405	value = named_function_string ((char *)NULL, function_cell (var), 0);
3406#if defined (ARRAY_VARS)
3407      else if (array_p (var))
3408#  if 0
3409	value = array_to_assignment_string (array_cell (var));
3410#  else
3411	continue;	/* XXX array vars cannot yet be exported */
3412#  endif
3413      else if (assoc_p (var))
3414#  if 0
3415	value = assoc_to_assignment_string (assoc_cell (var));
3416#  else
3417	continue;	/* XXX associative array vars cannot yet be exported */
3418#  endif
3419#endif
3420      else
3421	value = value_cell (var);
3422
3423      if (value)
3424	{
3425	  /* Gee, I'd like to get away with not using savestring() if we're
3426	     using the cached exportstr... */
3427	  list[list_index] = USE_EXPORTSTR ? savestring (value)
3428					   : mk_env_string (var->name, value);
3429
3430	  if (USE_EXPORTSTR == 0)
3431	    SAVE_EXPORTSTR (var, list[list_index]);
3432
3433	  list_index++;
3434#undef USE_EXPORTSTR
3435
3436#if 0	/* not yet */
3437#if defined (ARRAY_VARS)
3438	  if (array_p (var) || assoc_p (var))
3439	    free (value);
3440#endif
3441#endif
3442	}
3443    }
3444
3445  list[list_index] = (char *)NULL;
3446  return (list);
3447}
3448
3449/* Make an array of assignment statements from the hash table
3450   HASHED_VARS which contains SHELL_VARs.  Only visible, exported
3451   variables are eligible. */
3452static char **
3453make_var_export_array (vcxt)
3454     VAR_CONTEXT *vcxt;
3455{
3456  char **list;
3457  SHELL_VAR **vars;
3458
3459#if 0
3460  vars = map_over (visible_and_exported, vcxt);
3461#else
3462  vars = map_over (export_environment_candidate, vcxt);
3463#endif
3464
3465  if (vars == 0)
3466    return (char **)NULL;
3467
3468  list = make_env_array_from_var_list (vars);
3469
3470  free (vars);
3471  return (list);
3472}
3473
3474static char **
3475make_func_export_array ()
3476{
3477  char **list;
3478  SHELL_VAR **vars;
3479
3480  vars = map_over_funcs (visible_and_exported);
3481  if (vars == 0)
3482    return (char **)NULL;
3483
3484  list = make_env_array_from_var_list (vars);
3485
3486  free (vars);
3487  return (list);
3488}
3489
3490/* Add ENVSTR to the end of the exported environment, EXPORT_ENV. */
3491#define add_to_export_env(envstr,do_alloc) \
3492do \
3493  { \
3494    if (export_env_index >= (export_env_size - 1)) \
3495      { \
3496	export_env_size += 16; \
3497	export_env = strvec_resize (export_env, export_env_size); \
3498	environ = export_env; \
3499      } \
3500    export_env[export_env_index++] = (do_alloc) ? savestring (envstr) : envstr; \
3501    export_env[export_env_index] = (char *)NULL; \
3502  } while (0)
3503
3504/* Add ASSIGN to EXPORT_ENV, or supercede a previous assignment in the
3505   array with the same left-hand side.  Return the new EXPORT_ENV. */
3506char **
3507add_or_supercede_exported_var (assign, do_alloc)
3508     char *assign;
3509     int do_alloc;
3510{
3511  register int i;
3512  int equal_offset;
3513
3514  equal_offset = assignment (assign, 0);
3515  if (equal_offset == 0)
3516    return (export_env);
3517
3518  /* If this is a function, then only supersede the function definition.
3519     We do this by including the `=() {' in the comparison, like
3520     initialize_shell_variables does. */
3521  if (assign[equal_offset + 1] == '(' &&
3522     strncmp (assign + equal_offset + 2, ") {", 3) == 0)		/* } */
3523    equal_offset += 4;
3524
3525  for (i = 0; i < export_env_index; i++)
3526    {
3527      if (STREQN (assign, export_env[i], equal_offset + 1))
3528	{
3529	  free (export_env[i]);
3530	  export_env[i] = do_alloc ? savestring (assign) : assign;
3531	  return (export_env);
3532	}
3533    }
3534  add_to_export_env (assign, do_alloc);
3535  return (export_env);
3536}
3537
3538static void
3539add_temp_array_to_env (temp_array, do_alloc, do_supercede)
3540     char **temp_array;
3541     int do_alloc, do_supercede;
3542{
3543  register int i;
3544
3545  if (temp_array == 0)
3546    return;
3547
3548  for (i = 0; temp_array[i]; i++)
3549    {
3550      if (do_supercede)
3551	export_env = add_or_supercede_exported_var (temp_array[i], do_alloc);
3552      else
3553	add_to_export_env (temp_array[i], do_alloc);
3554    }
3555
3556  free (temp_array);
3557}
3558
3559/* Make the environment array for the command about to be executed, if the
3560   array needs making.  Otherwise, do nothing.  If a shell action could
3561   change the array that commands receive for their environment, then the
3562   code should `array_needs_making++'.
3563
3564   The order to add to the array is:
3565   	temporary_env
3566   	list of var contexts whose head is shell_variables
3567  	shell_functions
3568
3569  This is the shell variable lookup order.  We add only new variable
3570  names at each step, which allows local variables and variables in
3571  the temporary environments to shadow variables in the global (or
3572  any previous) scope.
3573*/
3574
3575static int
3576n_shell_variables ()
3577{
3578  VAR_CONTEXT *vc;
3579  int n;
3580
3581  for (n = 0, vc = shell_variables; vc; vc = vc->down)
3582    n += HASH_ENTRIES (vc->table);
3583  return n;
3584}
3585
3586void
3587maybe_make_export_env ()
3588{
3589  register char **temp_array;
3590  int new_size;
3591  VAR_CONTEXT *tcxt;
3592
3593  if (array_needs_making)
3594    {
3595      if (export_env)
3596	strvec_flush (export_env);
3597
3598      /* Make a guess based on how many shell variables and functions we
3599	 have.  Since there will always be array variables, and array
3600	 variables are not (yet) exported, this will always be big enough
3601	 for the exported variables and functions. */
3602      new_size = n_shell_variables () + HASH_ENTRIES (shell_functions) + 1 +
3603		 HASH_ENTRIES (temporary_env);
3604      if (new_size > export_env_size)
3605	{
3606	  export_env_size = new_size;
3607	  export_env = strvec_resize (export_env, export_env_size);
3608	  environ = export_env;
3609	}
3610      export_env[export_env_index = 0] = (char *)NULL;
3611
3612      /* Make a dummy variable context from the  temporary_env, stick it on
3613	 the front of shell_variables, call make_var_export_array on the
3614	 whole thing to flatten it, and convert the list of SHELL_VAR *s
3615	 to the form needed by the environment. */
3616      if (temporary_env)
3617	{
3618	  tcxt = new_var_context ((char *)NULL, 0);
3619	  tcxt->table = temporary_env;
3620	  tcxt->down = shell_variables;
3621	}
3622      else
3623	tcxt = shell_variables;
3624
3625      temp_array = make_var_export_array (tcxt);
3626      if (temp_array)
3627	add_temp_array_to_env (temp_array, 0, 0);
3628
3629      if (tcxt != shell_variables)
3630	free (tcxt);
3631
3632#if defined (RESTRICTED_SHELL)
3633      /* Restricted shells may not export shell functions. */
3634      temp_array = restricted ? (char **)0 : make_func_export_array ();
3635#else
3636      temp_array = make_func_export_array ();
3637#endif
3638      if (temp_array)
3639	add_temp_array_to_env (temp_array, 0, 0);
3640
3641      array_needs_making = 0;
3642    }
3643}
3644
3645/* This is an efficiency hack.  PWD and OLDPWD are auto-exported, so
3646   we will need to remake the exported environment every time we
3647   change directories.  `_' is always put into the environment for
3648   every external command, so without special treatment it will always
3649   cause the environment to be remade.
3650
3651   If there is no other reason to make the exported environment, we can
3652   just update the variables in place and mark the exported environment
3653   as no longer needing a remake. */
3654void
3655update_export_env_inplace (env_prefix, preflen, value)
3656     char *env_prefix;
3657     int preflen;
3658     char *value;
3659{
3660  char *evar;
3661
3662  evar = (char *)xmalloc (STRLEN (value) + preflen + 1);
3663  strcpy (evar, env_prefix);
3664  if (value)
3665    strcpy (evar + preflen, value);
3666  export_env = add_or_supercede_exported_var (evar, 0);
3667}
3668
3669/* We always put _ in the environment as the name of this command. */
3670void
3671put_command_name_into_env (command_name)
3672     char *command_name;
3673{
3674  update_export_env_inplace ("_=", 2, command_name);
3675}
3676
3677#if 0	/* UNUSED -- it caused too many problems */
3678void
3679put_gnu_argv_flags_into_env (pid, flags_string)
3680     intmax_t pid;
3681     char *flags_string;
3682{
3683  char *dummy, *pbuf;
3684  int l, fl;
3685
3686  pbuf = itos (pid);
3687  l = strlen (pbuf);
3688
3689  fl = strlen (flags_string);
3690
3691  dummy = (char *)xmalloc (l + fl + 30);
3692  dummy[0] = '_';
3693  strcpy (dummy + 1, pbuf);
3694  strcpy (dummy + 1 + l, "_GNU_nonoption_argv_flags_");
3695  dummy[l + 27] = '=';
3696  strcpy (dummy + l + 28, flags_string);
3697
3698  free (pbuf);
3699
3700  export_env = add_or_supercede_exported_var (dummy, 0);
3701}
3702#endif
3703
3704/* **************************************************************** */
3705/*								    */
3706/*		      Managing variable contexts		    */
3707/*								    */
3708/* **************************************************************** */
3709
3710/* Allocate and return a new variable context with NAME and FLAGS.
3711   NAME can be NULL. */
3712
3713VAR_CONTEXT *
3714new_var_context (name, flags)
3715     char *name;
3716     int flags;
3717{
3718  VAR_CONTEXT *vc;
3719
3720  vc = (VAR_CONTEXT *)xmalloc (sizeof (VAR_CONTEXT));
3721  vc->name = name ? savestring (name) : (char *)NULL;
3722  vc->scope = variable_context;
3723  vc->flags = flags;
3724
3725  vc->up = vc->down = (VAR_CONTEXT *)NULL;
3726  vc->table = (HASH_TABLE *)NULL;
3727
3728  return vc;
3729}
3730
3731/* Free a variable context and its data, including the hash table.  Dispose
3732   all of the variables. */
3733void
3734dispose_var_context (vc)
3735     VAR_CONTEXT *vc;
3736{
3737  FREE (vc->name);
3738
3739  if (vc->table)
3740    {
3741      delete_all_variables (vc->table);
3742      hash_dispose (vc->table);
3743    }
3744
3745  free (vc);
3746}
3747
3748/* Set VAR's scope level to the current variable context. */
3749static int
3750set_context (var)
3751     SHELL_VAR *var;
3752{
3753  return (var->context = variable_context);
3754}
3755
3756/* Make a new variable context with NAME and FLAGS and a HASH_TABLE of
3757   temporary variables, and push it onto shell_variables.  This is
3758   for shell functions. */
3759VAR_CONTEXT *
3760push_var_context (name, flags, tempvars)
3761     char *name;
3762     int flags;
3763     HASH_TABLE *tempvars;
3764{
3765  VAR_CONTEXT *vc;
3766
3767  vc = new_var_context (name, flags);
3768  vc->table = tempvars;
3769  if (tempvars)
3770    {
3771      /* Have to do this because the temp environment was created before
3772	 variable_context was incremented. */
3773      flatten (tempvars, set_context, (VARLIST *)NULL, 0);
3774      vc->flags |= VC_HASTMPVAR;
3775    }
3776  vc->down = shell_variables;
3777  shell_variables->up = vc;
3778
3779  return (shell_variables = vc);
3780}
3781
3782static void
3783push_func_var (data)
3784     PTR_T data;
3785{
3786  SHELL_VAR *var, *v;
3787
3788  var = (SHELL_VAR *)data;
3789
3790  if (tempvar_p (var) && (posixly_correct || (var->attributes & att_propagate)))
3791    {
3792      /* XXX - should we set v->context here? */
3793      v = bind_variable_internal (var->name, value_cell (var), shell_variables->table, 0, 0);
3794      if (shell_variables == global_variables)
3795	var->attributes &= ~(att_tempvar|att_propagate);
3796      else
3797	shell_variables->flags |= VC_HASTMPVAR;
3798      v->attributes |= var->attributes;
3799    }
3800  else
3801    stupidly_hack_special_variables (var->name);	/* XXX */
3802
3803  dispose_variable (var);
3804}
3805
3806/* Pop the top context off of VCXT and dispose of it, returning the rest of
3807   the stack. */
3808void
3809pop_var_context ()
3810{
3811  VAR_CONTEXT *ret, *vcxt;
3812
3813  vcxt = shell_variables;
3814  if (vc_isfuncenv (vcxt) == 0)
3815    {
3816      internal_error (_("pop_var_context: head of shell_variables not a function context"));
3817      return;
3818    }
3819
3820  if (ret = vcxt->down)
3821    {
3822      ret->up = (VAR_CONTEXT *)NULL;
3823      shell_variables = ret;
3824      if (vcxt->table)
3825	hash_flush (vcxt->table, push_func_var);
3826      dispose_var_context (vcxt);
3827    }
3828  else
3829    internal_error (_("pop_var_context: no global_variables context"));
3830}
3831
3832/* Delete the HASH_TABLEs for all variable contexts beginning at VCXT, and
3833   all of the VAR_CONTEXTs except GLOBAL_VARIABLES. */
3834void
3835delete_all_contexts (vcxt)
3836     VAR_CONTEXT *vcxt;
3837{
3838  VAR_CONTEXT *v, *t;
3839
3840  for (v = vcxt; v != global_variables; v = t)
3841    {
3842      t = v->down;
3843      dispose_var_context (v);
3844    }
3845
3846  delete_all_variables (global_variables->table);
3847  shell_variables = global_variables;
3848}
3849
3850/* **************************************************************** */
3851/*								    */
3852/*	   Pushing and Popping temporary variable scopes	    */
3853/*								    */
3854/* **************************************************************** */
3855
3856VAR_CONTEXT *
3857push_scope (flags, tmpvars)
3858     int flags;
3859     HASH_TABLE *tmpvars;
3860{
3861  return (push_var_context ((char *)NULL, flags, tmpvars));
3862}
3863
3864static void
3865push_exported_var (data)
3866     PTR_T data;
3867{
3868  SHELL_VAR *var, *v;
3869
3870  var = (SHELL_VAR *)data;
3871
3872  /* If a temp var had its export attribute set, or it's marked to be
3873     propagated, bind it in the previous scope before disposing it. */
3874  /* XXX - This isn't exactly right, because all tempenv variables have the
3875    export attribute set. */
3876#if 0
3877  if (exported_p (var) || (var->attributes & att_propagate))
3878#else
3879  if (tempvar_p (var) && exported_p (var) && (var->attributes & att_propagate))
3880#endif
3881    {
3882      var->attributes &= ~att_tempvar;		/* XXX */
3883      v = bind_variable_internal (var->name, value_cell (var), shell_variables->table, 0, 0);
3884      if (shell_variables == global_variables)
3885	var->attributes &= ~att_propagate;
3886      v->attributes |= var->attributes;
3887    }
3888  else
3889    stupidly_hack_special_variables (var->name);	/* XXX */
3890
3891  dispose_variable (var);
3892}
3893
3894void
3895pop_scope (is_special)
3896     int is_special;
3897{
3898  VAR_CONTEXT *vcxt, *ret;
3899
3900  vcxt = shell_variables;
3901  if (vc_istempscope (vcxt) == 0)
3902    {
3903      internal_error (_("pop_scope: head of shell_variables not a temporary environment scope"));
3904      return;
3905    }
3906
3907  ret = vcxt->down;
3908  if (ret)
3909    ret->up = (VAR_CONTEXT *)NULL;
3910
3911  shell_variables = ret;
3912
3913  /* Now we can take care of merging variables in VCXT into set of scopes
3914     whose head is RET (shell_variables). */
3915  FREE (vcxt->name);
3916  if (vcxt->table)
3917    {
3918      if (is_special)
3919	hash_flush (vcxt->table, push_func_var);
3920      else
3921	hash_flush (vcxt->table, push_exported_var);
3922      hash_dispose (vcxt->table);
3923    }
3924  free (vcxt);
3925
3926  sv_ifs ("IFS");	/* XXX here for now */
3927}
3928
3929/* **************************************************************** */
3930/*								    */
3931/*		 Pushing and Popping function contexts		    */
3932/*								    */
3933/* **************************************************************** */
3934
3935static WORD_LIST **dollar_arg_stack = (WORD_LIST **)NULL;
3936static int dollar_arg_stack_slots;
3937static int dollar_arg_stack_index;
3938
3939/* XXX - we might want to consider pushing and popping the `getopts' state
3940   when we modify the positional parameters. */
3941void
3942push_context (name, is_subshell, tempvars)
3943     char *name;	/* function name */
3944     int is_subshell;
3945     HASH_TABLE *tempvars;
3946{
3947  if (is_subshell == 0)
3948    push_dollar_vars ();
3949  variable_context++;
3950  push_var_context (name, VC_FUNCENV, tempvars);
3951}
3952
3953/* Only called when subshell == 0, so we don't need to check, and can
3954   unconditionally pop the dollar vars off the stack. */
3955void
3956pop_context ()
3957{
3958  pop_dollar_vars ();
3959  variable_context--;
3960  pop_var_context ();
3961
3962  sv_ifs ("IFS");		/* XXX here for now */
3963}
3964
3965/* Save the existing positional parameters on a stack. */
3966void
3967push_dollar_vars ()
3968{
3969  if (dollar_arg_stack_index + 2 > dollar_arg_stack_slots)
3970    {
3971      dollar_arg_stack = (WORD_LIST **)
3972	xrealloc (dollar_arg_stack, (dollar_arg_stack_slots += 10)
3973		  * sizeof (WORD_LIST **));
3974    }
3975  dollar_arg_stack[dollar_arg_stack_index++] = list_rest_of_args ();
3976  dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
3977}
3978
3979/* Restore the positional parameters from our stack. */
3980void
3981pop_dollar_vars ()
3982{
3983  if (!dollar_arg_stack || dollar_arg_stack_index == 0)
3984    return;
3985
3986  remember_args (dollar_arg_stack[--dollar_arg_stack_index], 1);
3987  dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
3988  dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
3989  set_dollar_vars_unchanged ();
3990}
3991
3992void
3993dispose_saved_dollar_vars ()
3994{
3995  if (!dollar_arg_stack || dollar_arg_stack_index == 0)
3996    return;
3997
3998  dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
3999  dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
4000}
4001
4002/* Manipulate the special BASH_ARGV and BASH_ARGC variables. */
4003
4004void
4005push_args (list)
4006     WORD_LIST *list;
4007{
4008#if defined (ARRAY_VARS) && defined (DEBUGGER)
4009  SHELL_VAR *bash_argv_v, *bash_argc_v;
4010  ARRAY *bash_argv_a, *bash_argc_a;
4011  WORD_LIST *l;
4012  arrayind_t i;
4013  char *t;
4014
4015  GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a);
4016  GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
4017
4018  for (l = list, i = 0; l; l = l->next, i++)
4019    array_push (bash_argv_a, l->word->word);
4020
4021  t = itos (i);
4022  array_push (bash_argc_a, t);
4023  free (t);
4024#endif /* ARRAY_VARS && DEBUGGER */
4025}
4026
4027/* Remove arguments from BASH_ARGV array.  Pop top element off BASH_ARGC
4028   array and use that value as the count of elements to remove from
4029   BASH_ARGV. */
4030void
4031pop_args ()
4032{
4033#if defined (ARRAY_VARS) && defined (DEBUGGER)
4034  SHELL_VAR *bash_argv_v, *bash_argc_v;
4035  ARRAY *bash_argv_a, *bash_argc_a;
4036  ARRAY_ELEMENT *ce;
4037  intmax_t i;
4038
4039  GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a);
4040  GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
4041
4042  ce = array_shift (bash_argc_a, 1, 0);
4043  if (ce == 0 || legal_number (element_value (ce), &i) == 0)
4044    i = 0;
4045
4046  for ( ; i > 0; i--)
4047    array_pop (bash_argv_a);
4048  array_dispose_element (ce);
4049#endif /* ARRAY_VARS && DEBUGGER */
4050}
4051
4052/*************************************************
4053 *						 *
4054 *	Functions to manage special variables	 *
4055 *						 *
4056 *************************************************/
4057
4058/* Extern declarations for variables this code has to manage. */
4059extern int eof_encountered, eof_encountered_limit, ignoreeof;
4060
4061#if defined (READLINE)
4062extern int hostname_list_initialized;
4063#endif
4064
4065/* An alist of name.function for each special variable.  Most of the
4066   functions don't do much, and in fact, this would be faster with a
4067   switch statement, but by the end of this file, I am sick of switch
4068   statements. */
4069
4070#define SET_INT_VAR(name, intvar)  intvar = find_variable (name) != 0
4071
4072/* This table will be sorted with qsort() the first time it's accessed. */
4073struct name_and_function {
4074  char *name;
4075  sh_sv_func_t *function;
4076};
4077
4078static struct name_and_function special_vars[] = {
4079#if defined (READLINE)
4080#  if defined (STRICT_POSIX)
4081  { "COLUMNS", sv_winsize },
4082#  endif
4083  { "COMP_WORDBREAKS", sv_comp_wordbreaks },
4084#endif
4085
4086  { "GLOBIGNORE", sv_globignore },
4087
4088#if defined (HISTORY)
4089  { "HISTCONTROL", sv_history_control },
4090  { "HISTFILESIZE", sv_histsize },
4091  { "HISTIGNORE", sv_histignore },
4092  { "HISTSIZE", sv_histsize },
4093  { "HISTTIMEFORMAT", sv_histtimefmt },
4094#endif
4095
4096#if defined (__CYGWIN__)
4097  { "HOME", sv_home },
4098#endif
4099
4100#if defined (READLINE)
4101  { "HOSTFILE", sv_hostfile },
4102#endif
4103
4104  { "IFS", sv_ifs },
4105  { "IGNOREEOF", sv_ignoreeof },
4106
4107  { "LANG", sv_locale },
4108  { "LC_ALL", sv_locale },
4109  { "LC_COLLATE", sv_locale },
4110  { "LC_CTYPE", sv_locale },
4111  { "LC_MESSAGES", sv_locale },
4112  { "LC_NUMERIC", sv_locale },
4113  { "LC_TIME", sv_locale },
4114
4115#if defined (READLINE) && defined (STRICT_POSIX)
4116  { "LINES", sv_winsize },
4117#endif
4118
4119  { "MAIL", sv_mail },
4120  { "MAILCHECK", sv_mail },
4121  { "MAILPATH", sv_mail },
4122
4123  { "OPTERR", sv_opterr },
4124  { "OPTIND", sv_optind },
4125
4126  { "PATH", sv_path },
4127  { "POSIXLY_CORRECT", sv_strict_posix },
4128
4129#if defined (READLINE)
4130  { "TERM", sv_terminal },
4131  { "TERMCAP", sv_terminal },
4132  { "TERMINFO", sv_terminal },
4133#endif /* READLINE */
4134
4135  { "TEXTDOMAIN", sv_locale },
4136  { "TEXTDOMAINDIR", sv_locale },
4137
4138#if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE)
4139  { "TZ", sv_tz },
4140#endif
4141
4142#if defined (HISTORY) && defined (BANG_HISTORY)
4143  { "histchars", sv_histchars },
4144#endif /* HISTORY && BANG_HISTORY */
4145
4146  { "ignoreeof", sv_ignoreeof },
4147
4148  { (char *)0, (sh_sv_func_t *)0 }
4149};
4150
4151#define N_SPECIAL_VARS	(sizeof (special_vars) / sizeof (special_vars[0]) - 1)
4152
4153static int
4154sv_compare (sv1, sv2)
4155     struct name_and_function *sv1, *sv2;
4156{
4157  int r;
4158
4159  if ((r = sv1->name[0] - sv2->name[0]) == 0)
4160    r = strcmp (sv1->name, sv2->name);
4161  return r;
4162}
4163
4164static inline int
4165find_special_var (name)
4166     const char *name;
4167{
4168  register int i, r;
4169
4170  for (i = 0; special_vars[i].name; i++)
4171    {
4172      r = special_vars[i].name[0] - name[0];
4173      if (r == 0)
4174	r = strcmp (special_vars[i].name, name);
4175      if (r == 0)
4176	return i;
4177      else if (r > 0)
4178	/* Can't match any of rest of elements in sorted list.  Take this out
4179	   if it causes problems in certain environments. */
4180	break;
4181    }
4182  return -1;
4183}
4184
4185/* The variable in NAME has just had its state changed.  Check to see if it
4186   is one of the special ones where something special happens. */
4187void
4188stupidly_hack_special_variables (name)
4189     char *name;
4190{
4191  static int sv_sorted = 0;
4192  int i;
4193
4194  if (sv_sorted == 0)	/* shouldn't need, but it's fairly cheap. */
4195    {
4196      qsort (special_vars, N_SPECIAL_VARS, sizeof (special_vars[0]),
4197		(QSFUNC *)sv_compare);
4198      sv_sorted = 1;
4199    }
4200
4201  i = find_special_var (name);
4202  if (i != -1)
4203    (*(special_vars[i].function)) (name);
4204}
4205
4206/* Special variables that need hooks to be run when they are unset as part
4207   of shell reinitialization should have their sv_ functions run here. */
4208void
4209reinit_special_variables ()
4210{
4211#if defined (READLINE)
4212  sv_comp_wordbreaks ("COMP_WORDBREAKS");
4213#endif
4214  sv_globignore ("GLOBIGNORE");
4215  sv_opterr ("OPTERR");
4216}
4217
4218void
4219sv_ifs (name)
4220     char *name;
4221{
4222  SHELL_VAR *v;
4223
4224  v = find_variable ("IFS");
4225  setifs (v);
4226}
4227
4228/* What to do just after the PATH variable has changed. */
4229void
4230sv_path (name)
4231     char *name;
4232{
4233  /* hash -r */
4234  phash_flush ();
4235}
4236
4237/* What to do just after one of the MAILxxxx variables has changed.  NAME
4238   is the name of the variable.  This is called with NAME set to one of
4239   MAIL, MAILCHECK, or MAILPATH.  */
4240void
4241sv_mail (name)
4242     char *name;
4243{
4244  /* If the time interval for checking the files has changed, then
4245     reset the mail timer.  Otherwise, one of the pathname vars
4246     to the users mailbox has changed, so rebuild the array of
4247     filenames. */
4248  if (name[4] == 'C')  /* if (strcmp (name, "MAILCHECK") == 0) */
4249    reset_mail_timer ();
4250  else
4251    {
4252      free_mail_files ();
4253      remember_mail_dates ();
4254    }
4255}
4256
4257/* What to do when GLOBIGNORE changes. */
4258void
4259sv_globignore (name)
4260     char *name;
4261{
4262  if (privileged_mode == 0)
4263    setup_glob_ignore (name);
4264}
4265
4266#if defined (READLINE)
4267void
4268sv_comp_wordbreaks (name)
4269     char *name;
4270{
4271  SHELL_VAR *sv;
4272
4273  sv = find_variable (name);
4274  if (sv == 0)
4275    reset_completer_word_break_chars ();
4276}
4277
4278/* What to do just after one of the TERMxxx variables has changed.
4279   If we are an interactive shell, then try to reset the terminal
4280   information in readline. */
4281void
4282sv_terminal (name)
4283     char *name;
4284{
4285  if (interactive_shell && no_line_editing == 0)
4286    rl_reset_terminal (get_string_value ("TERM"));
4287}
4288
4289void
4290sv_hostfile (name)
4291     char *name;
4292{
4293  SHELL_VAR *v;
4294
4295  v = find_variable (name);
4296  if (v == 0)
4297    clear_hostname_list ();
4298  else
4299    hostname_list_initialized = 0;
4300}
4301
4302#if defined (STRICT_POSIX)
4303/* In strict posix mode, we allow assignments to LINES and COLUMNS (and values
4304   found in the initial environment) to override the terminal size reported by
4305   the kernel. */
4306void
4307sv_winsize (name)
4308     char *name;
4309{
4310  SHELL_VAR *v;
4311  intmax_t xd;
4312  int d;
4313
4314  if (posixly_correct == 0 || interactive_shell == 0 || no_line_editing)
4315    return;
4316
4317  v = find_variable (name);
4318  if (v == 0 || var_isnull (v))
4319    rl_reset_screen_size ();
4320  else
4321    {
4322      if (legal_number (value_cell (v), &xd) == 0)
4323	return;
4324      winsize_assignment = winsize_assigned = 1;
4325      d = xd;			/* truncate */
4326      if (name[0] == 'L')	/* LINES */
4327	rl_set_screen_size (d, -1);
4328      else			/* COLUMNS */
4329	rl_set_screen_size (-1, d);
4330      winsize_assignment = 0;
4331    }
4332}
4333#endif /* STRICT_POSIX */
4334#endif /* READLINE */
4335
4336/* Update the value of HOME in the export environment so tilde expansion will
4337   work on cygwin. */
4338#if defined (__CYGWIN__)
4339sv_home (name)
4340     char *name;
4341{
4342  array_needs_making = 1;
4343  maybe_make_export_env ();
4344}
4345#endif
4346
4347#if defined (HISTORY)
4348/* What to do after the HISTSIZE or HISTFILESIZE variables change.
4349   If there is a value for this HISTSIZE (and it is numeric), then stifle
4350   the history.  Otherwise, if there is NO value for this variable,
4351   unstifle the history.  If name is HISTFILESIZE, and its value is
4352   numeric, truncate the history file to hold no more than that many
4353   lines. */
4354void
4355sv_histsize (name)
4356     char *name;
4357{
4358  char *temp;
4359  intmax_t num;
4360  int hmax;
4361
4362  temp = get_string_value (name);
4363
4364  if (temp && *temp)
4365    {
4366      if (legal_number (temp, &num))
4367	{
4368	  hmax = num;
4369	  if (name[4] == 'S')
4370	    {
4371	      stifle_history (hmax);
4372	      hmax = where_history ();
4373	      if (history_lines_this_session > hmax)
4374		history_lines_this_session = hmax;
4375	    }
4376	  else
4377	    {
4378	      history_truncate_file (get_string_value ("HISTFILE"), hmax);
4379	      if (hmax <= history_lines_in_file)
4380		history_lines_in_file = hmax;
4381	    }
4382	}
4383    }
4384  else if (name[4] == 'S')
4385    unstifle_history ();
4386}
4387
4388/* What to do after the HISTIGNORE variable changes. */
4389void
4390sv_histignore (name)
4391     char *name;
4392{
4393  setup_history_ignore (name);
4394}
4395
4396/* What to do after the HISTCONTROL variable changes. */
4397void
4398sv_history_control (name)
4399     char *name;
4400{
4401  char *temp;
4402  char *val;
4403  int tptr;
4404
4405  history_control = 0;
4406  temp = get_string_value (name);
4407
4408  if (temp == 0 || *temp == 0)
4409    return;
4410
4411  tptr = 0;
4412  while (val = extract_colon_unit (temp, &tptr))
4413    {
4414      if (STREQ (val, "ignorespace"))
4415	history_control |= HC_IGNSPACE;
4416      else if (STREQ (val, "ignoredups"))
4417	history_control |= HC_IGNDUPS;
4418      else if (STREQ (val, "ignoreboth"))
4419	history_control |= HC_IGNBOTH;
4420      else if (STREQ (val, "erasedups"))
4421	history_control |= HC_ERASEDUPS;
4422
4423      free (val);
4424    }
4425}
4426
4427#if defined (BANG_HISTORY)
4428/* Setting/unsetting of the history expansion character. */
4429void
4430sv_histchars (name)
4431     char *name;
4432{
4433  char *temp;
4434
4435  temp = get_string_value (name);
4436  if (temp)
4437    {
4438      history_expansion_char = *temp;
4439      if (temp[0] && temp[1])
4440	{
4441	  history_subst_char = temp[1];
4442	  if (temp[2])
4443	      history_comment_char = temp[2];
4444	}
4445    }
4446  else
4447    {
4448      history_expansion_char = '!';
4449      history_subst_char = '^';
4450      history_comment_char = '#';
4451    }
4452}
4453#endif /* BANG_HISTORY */
4454
4455void
4456sv_histtimefmt (name)
4457     char *name;
4458{
4459  SHELL_VAR *v;
4460
4461  v = find_variable (name);
4462  history_write_timestamps = (v != 0);
4463}
4464#endif /* HISTORY */
4465
4466#if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE)
4467void
4468sv_tz (name)
4469     char *name;
4470{
4471  tzset ();
4472}
4473#endif
4474
4475/* If the variable exists, then the value of it can be the number
4476   of times we actually ignore the EOF.  The default is small,
4477   (smaller than csh, anyway). */
4478void
4479sv_ignoreeof (name)
4480     char *name;
4481{
4482  SHELL_VAR *tmp_var;
4483  char *temp;
4484
4485  eof_encountered = 0;
4486
4487  tmp_var = find_variable (name);
4488  ignoreeof = tmp_var != 0;
4489  temp = tmp_var ? value_cell (tmp_var) : (char *)NULL;
4490  if (temp)
4491    eof_encountered_limit = (*temp && all_digits (temp)) ? atoi (temp) : 10;
4492  set_shellopts ();	/* make sure `ignoreeof' is/is not in $SHELLOPTS */
4493}
4494
4495void
4496sv_optind (name)
4497     char *name;
4498{
4499  char *tt;
4500  int s;
4501
4502  tt = get_string_value ("OPTIND");
4503  if (tt && *tt)
4504    {
4505      s = atoi (tt);
4506
4507      /* According to POSIX, setting OPTIND=1 resets the internal state
4508	 of getopt (). */
4509      if (s < 0 || s == 1)
4510	s = 0;
4511    }
4512  else
4513    s = 0;
4514  getopts_reset (s);
4515}
4516
4517void
4518sv_opterr (name)
4519     char *name;
4520{
4521  char *tt;
4522
4523  tt = get_string_value ("OPTERR");
4524  sh_opterr = (tt && *tt) ? atoi (tt) : 1;
4525}
4526
4527void
4528sv_strict_posix (name)
4529     char *name;
4530{
4531  SET_INT_VAR (name, posixly_correct);
4532  posix_initialize (posixly_correct);
4533#if defined (READLINE)
4534  if (interactive_shell)
4535    posix_readline_initialize (posixly_correct);
4536#endif /* READLINE */
4537  set_shellopts ();	/* make sure `posix' is/is not in $SHELLOPTS */
4538}
4539
4540void
4541sv_locale (name)
4542     char *name;
4543{
4544  char *v;
4545
4546  v = get_string_value (name);
4547  if (name[0] == 'L' && name[1] == 'A')	/* LANG */
4548    set_lang (name, v);
4549  else
4550    set_locale_var (name, v);		/* LC_*, TEXTDOMAIN* */
4551}
4552
4553#if defined (ARRAY_VARS)
4554void
4555set_pipestatus_array (ps, nproc)
4556     int *ps;
4557     int nproc;
4558{
4559  SHELL_VAR *v;
4560  ARRAY *a;
4561  ARRAY_ELEMENT *ae;
4562  register int i;
4563  char *t, tbuf[INT_STRLEN_BOUND(int) + 1];
4564
4565  v = find_variable ("PIPESTATUS");
4566  if (v == 0)
4567    v = make_new_array_variable ("PIPESTATUS");
4568  if (array_p (v) == 0)
4569    return;		/* Do nothing if not an array variable. */
4570  a = array_cell (v);
4571
4572  if (a == 0 || array_num_elements (a) == 0)
4573    {
4574      for (i = 0; i < nproc; i++)	/* was ps[i] != -1, not i < nproc */
4575	{
4576	  t = inttostr (ps[i], tbuf, sizeof (tbuf));
4577	  array_insert (a, i, t);
4578	}
4579      return;
4580    }
4581
4582  /* Fast case */
4583  if (array_num_elements (a) == nproc && nproc == 1)
4584    {
4585      ae = element_forw (a->head);
4586      free (element_value (ae));
4587      ae->value = itos (ps[0]);
4588    }
4589  else if (array_num_elements (a) <= nproc)
4590    {
4591      /* modify in array_num_elements members in place, then add */
4592      ae = a->head;
4593      for (i = 0; i < array_num_elements (a); i++)
4594	{
4595	  ae = element_forw (ae);
4596	  free (element_value (ae));
4597	  ae->value = itos (ps[i]);
4598	}
4599      /* add any more */
4600      for ( ; i < nproc; i++)
4601	{
4602	  t = inttostr (ps[i], tbuf, sizeof (tbuf));
4603	  array_insert (a, i, t);
4604	}
4605    }
4606  else
4607    {
4608      /* deleting elements.  it's faster to rebuild the array. */
4609      array_flush (a);
4610      for (i = 0; ps[i] != -1; i++)
4611	{
4612	  t = inttostr (ps[i], tbuf, sizeof (tbuf));
4613	  array_insert (a, i, t);
4614	}
4615    }
4616}
4617#endif
4618
4619void
4620set_pipestatus_from_exit (s)
4621     int s;
4622{
4623#if defined (ARRAY_VARS)
4624  static int v[2] = { 0, -1 };
4625
4626  v[0] = s;
4627  set_pipestatus_array (v, 1);
4628#endif
4629}
4630