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