b72fc4f8428b409b74728abca74858cdc40abed8
[platform/upstream/bash.git] / variables.c
1 /* variables.c -- Functions for hacking shell variables. */
2
3 /* Copyright (C) 1987,1989 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 it
8    under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 1, or (at your option)
10    any later version.
11
12    Bash is distributed in the hope that it will be useful, but WITHOUT
13    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15    License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with Bash; see the file COPYING.  If not, write to the Free
19    Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21 #include "config.h"
22
23 #include "bashtypes.h"
24 #include "posixstat.h"
25
26 #if defined (qnx)
27 #  include <sys/vc.h>
28 #endif
29
30 #if defined (HAVE_UNISTD_H)
31 #  include <unistd.h>
32 #endif
33
34 #include <stdio.h>
35 #include <ctype.h>
36 #include <pwd.h>
37 #include "bashansi.h"
38
39 #include "shell.h"
40 #include "flags.h"
41 #include "execute_cmd.h"
42 #include "findcmd.h"
43 #include "mailcheck.h"
44 #include "input.h"
45
46 #include "builtins/getopt.h"
47 #include "builtins/common.h"
48
49 #if defined (READLINE)
50 #  include "bashline.h"
51 #  include <readline/readline.h>
52 #else
53 #  include <tilde/tilde.h>
54 #endif
55
56 #if defined (HISTORY)
57 #  include "bashhist.h"
58 #  include <readline/history.h>
59 #endif /* HISTORY */
60
61 /* Variables used here and defined in other files. */
62 extern int posixly_correct;
63 extern int variable_context, line_number;
64 extern int interactive, interactive_shell, login_shell;
65 extern int subshell_environment, indirection_level;
66 extern int build_version, patch_level;
67 extern char *dist_version, *release_status;
68 extern char *shell_name;
69 extern char *primary_prompt, *secondary_prompt;
70 extern char *current_host_name;
71 extern Function *this_shell_builtin;
72 extern char *this_command_name;
73 extern time_t shell_start_time;
74
75 /* The list of shell variables that the user has created, or that came from
76    the environment. */
77 HASH_TABLE *shell_variables = (HASH_TABLE *)NULL;
78
79 /* The list of shell functions that the user has created, or that came from
80    the environment. */
81 HASH_TABLE *shell_functions = (HASH_TABLE *)NULL;
82
83 /* The current variable context.  This is really a count of how deep into
84    executing functions we are. */
85 int variable_context = 0;
86
87 /* The array of shell assignments which are made only in the environment
88    for a single command. */
89 char **temporary_env = (char **)NULL;
90
91 /* The array of shell assignments which are in the environment for the
92    execution of a shell function. */
93 char **function_env = (char **)NULL;
94
95 /* The array of shell assignments which are made only in the environment
96    for the execution of a shell builtin command which may cause more than
97    one command to be executed (e.g., "source"). */
98 char **builtin_env = (char **)NULL;
99
100 /* Some funky variables which are known about specially.  Here is where
101    "$*", "$1", and all the cruft is kept. */
102 char *dollar_vars[10];
103 WORD_LIST *rest_of_args = (WORD_LIST *)NULL;
104
105 /* The value of $$. */
106 int dollar_dollar_pid;
107
108 /* An array which is passed to commands as their environment.  It is
109    manufactured from the union of the initial environment and the
110    shell variables that are marked for export. */
111 char **export_env = (char **)NULL;
112 static int export_env_index;
113 static int export_env_size;
114
115 /* Non-zero means that we have to remake EXPORT_ENV. */
116 int array_needs_making = 1;
117
118 /* The number of times BASH has been executed.  This is set
119    by initialize_variables (). */
120 int shell_level = 0;
121
122 static char *have_local_variables;
123 static int local_variable_stack_size;
124
125 /* Some forward declarations. */
126 static void set_home_var ();
127 static void set_shell_var ();
128 static char *get_bash_name ();
129 static void initialize_shell_level ();
130 static void uidset ();
131 static void initialize_dynamic_variables ();
132 static void make_vers_array ();
133 static void sbrand ();          /* set bash random number generator. */
134 static int qsort_var_comp ();
135
136 /* Make VAR be auto-exported.  VAR is a pointer to a SHELL_VAR. */
137 #define set_auto_export(var) \
138   do { var->attributes |= att_exported; array_needs_making = 1; } while (0)
139
140 /* Initialize the shell variables from the current environment.
141    If PRIVMODE is nonzero, don't import functions from ENV or
142    parse $SHELLOPTS. */
143 void
144 initialize_shell_variables (env, privmode)
145      char **env;
146      int privmode;
147 {
148   char *name, *string, *temp_string;
149   int c, char_index, string_index, string_length;
150   SHELL_VAR *temp_var;
151
152   if (shell_variables == 0)
153     shell_variables = make_hash_table (0);
154
155   if (shell_functions == 0)
156     shell_functions = make_hash_table (0);
157
158   for (string_index = 0; string = env[string_index++]; )
159     {
160       char_index = 0;
161       name = string;
162       while ((c = *string++) && c != '=')
163         ;
164       if (string[-1] == '=')
165         char_index = string - name - 1;
166
167       /* If there are weird things in the environment, like `=xxx' or a
168          string without an `=', just skip them. */
169       if (char_index == 0)
170         continue;
171
172       /* ASSERT(name[char_index] == '=') */
173       name[char_index] = '\0';
174       /* Now, name = env variable name, string = env variable value, and
175          char_index == strlen (name) */
176
177       /* If exported function, define it now. */
178       if (privmode == 0 && STREQN ("() {", string, 4))
179         {
180           string_length = strlen (string);
181           temp_string = xmalloc (3 + string_length + char_index);
182 #if 1
183           strcpy (temp_string, name);
184           temp_string[char_index] = ' ';
185           strcpy (temp_string + char_index + 1, string);
186 #else
187           sprintf (temp_string, "%s %s", name, string);
188 #endif
189
190           parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST);
191
192           /* Ancient backwards compatibility.  Old versions of bash exported
193              functions like name()=() {...} */
194           if (name[char_index - 1] == ')' && name[char_index - 2] == '(')
195             name[char_index - 2] = '\0';
196
197           if (temp_var = find_function (name))
198             {
199               temp_var->attributes |= (att_exported | att_imported);
200               array_needs_making = 1;
201             }
202           else
203             report_error ("error importing function definition for `%s'", name);
204
205           if (name[char_index - 1] == ')' && name[char_index - 2] == '\0')
206             name[char_index - 2] = '(';
207         }
208 #if defined (ARRAY_VARS)
209 #  if 0
210       /* Array variables may not yet be exported. */
211       else if (*string == '(' && string[1] == '[' && strchr (string, ')'))
212         {
213           string_length = 1;
214           temp_string = extract_array_assignment_list (string, &string_length);
215           temp_var = assign_array_from_string (name, temp_string);
216           FREE (temp_string);
217           temp_var->attributes |= (att_exported | att_imported);
218           array_needs_making = 1;
219         }
220 #  endif
221 #endif
222       else
223         {
224           temp_var = bind_variable (name, string);
225           temp_var->attributes |= (att_exported | att_imported);
226           array_needs_making = 1;
227         }
228
229       name[char_index] = '=';
230     }
231
232   /* If we got PWD from the environment, update our idea of the current
233      working directory.  In any case, make sure that PWD exists before
234      checking it.  It is possible for getcwd () to fail on shell startup,
235      and in that case, PWD would be undefined. */
236   temp_var = find_variable ("PWD");
237   if (temp_var && imported_p (temp_var) &&
238       (temp_string = value_cell (temp_var)) &&
239       same_file (temp_string, ".", (struct stat *)NULL, (struct stat *)NULL))
240     set_working_directory (temp_string);
241   else
242     {
243       temp_string = get_working_directory ("shell-init");
244       if (temp_string)
245         {
246           temp_var = bind_variable ("PWD", temp_string);
247           set_auto_export (temp_var);
248           free (temp_string);
249         }
250     }
251
252   /* Set up initial value of $_ */
253   temp_var = bind_variable ("_", dollar_vars[0]);
254
255   /* Remember this pid. */
256   dollar_dollar_pid = (int)getpid ();
257
258   /* Now make our own defaults in case the vars that we think are
259      important are missing. */
260   temp_var = set_if_not ("PATH", DEFAULT_PATH_VALUE);
261   set_auto_export (temp_var);
262
263   temp_var = set_if_not ("TERM", "dumb");
264   set_auto_export (temp_var);
265
266 #if defined (qnx)
267   /* set node id -- don't import it from the environment */
268   {
269     char node_name[22];
270     qnx_nidtostr (getnid (), node_name, sizeof (node_name));
271     temp_var = bind_variable ("NODE", node_name);
272     set_auto_export (temp_var);
273   }
274 #endif
275
276   /* set up the prompts. */
277   if (interactive_shell)
278     {
279       set_if_not ("PS1", primary_prompt);
280       set_if_not ("PS2", secondary_prompt);
281     }
282   set_if_not ("PS4", "+ ");
283
284   /* Don't allow IFS to be imported from the environment. */
285   temp_var = bind_variable ("IFS", " \t\n");
286
287   /* Magic machine types.  Pretty convenient. */
288   temp_var = bind_variable ("HOSTTYPE", HOSTTYPE);
289   set_auto_export (temp_var);
290   temp_var = bind_variable ("OSTYPE", OSTYPE);
291   set_auto_export (temp_var);
292   temp_var = bind_variable ("MACHTYPE", MACHTYPE);
293   set_auto_export (temp_var);
294   temp_var = bind_variable ("HOSTNAME", current_host_name);
295   set_auto_export (temp_var);
296
297   /* Default MAILCHECK for interactive shells.  Defer the creation of a
298      default MAILPATH until the startup files are read, because MAIL
299      names a mail file if MAILCHECK is not set, and we should provide a
300      default only if neither is set. */
301   if (interactive_shell)
302     set_if_not ("MAILCHECK", "60");
303
304   /* Do some things with shell level. */
305   initialize_shell_level ();
306
307   /* Make a variable $PPID, which holds the pid of the shell's parent.  */
308   name = itos ((int) getppid ());
309   temp_var = find_variable ("PPID");
310   if (temp_var)
311     temp_var->attributes &= ~(att_readonly | att_exported);
312   temp_var = bind_variable ("PPID", name);
313   temp_var->attributes |= (att_readonly | att_integer);
314   free (name);
315
316   /* Initialize the `getopts' stuff. */
317   bind_variable ("OPTIND", "1");
318   getopts_reset (0);
319   bind_variable ("OPTERR", "1");
320   sh_opterr = 1;
321
322   if (login_shell == 1)
323     set_home_var ();
324
325   /* Get the full pathname to THIS shell, and set the BASH variable
326      to it. */
327   name = get_bash_name ();
328   temp_var = bind_variable ("BASH", name);
329   free (name);
330
331   /* Make the exported environment variable SHELL be the user's login
332      shell.  Note that the `tset' command looks at this variable
333      to determine what style of commands to output; if it ends in "csh",
334      then C-shell commands are output, else Bourne shell commands. */
335   set_shell_var ();
336
337   /* Make a variable called BASH_VERSION which contains the version info. */
338   bind_variable ("BASH_VERSION", shell_version_string ());
339 #if defined (ARRAY_VARS)
340   make_vers_array ();
341 #endif
342
343   /* Find out if we're supposed to be in Posix.2 mode via an
344      environment variable. */
345   temp_var = find_variable ("POSIXLY_CORRECT");
346   if (!temp_var)
347     temp_var = find_variable ("POSIX_PEDANTIC");
348   if (temp_var && imported_p (temp_var))
349     sv_strict_posix (temp_var->name);
350
351 #if defined (HISTORY)
352   /* Set history variables to defaults, and then do whatever we would
353      do if the variable had just been set.  Do this only in the case
354      that we are remembering commands on the history list. */
355   if (remember_on_history)
356     {
357       name = bash_tilde_expand (posixly_correct ? "~/.sh_history" : "~/.bash_history");
358
359       set_if_not ("HISTFILE", name);
360       free (name);
361
362       set_if_not ("HISTSIZE", "500");
363       sv_histsize ("HISTSIZE");
364     }
365 #endif /* HISTORY */
366
367   /* Seed the random number generator. */
368   sbrand (dollar_dollar_pid + (long)shell_start_time);
369
370   /* Handle some "special" variables that we may have inherited from a
371      parent shell. */
372   if (interactive_shell)
373     {
374       temp_var = find_variable ("IGNOREEOF");
375       if (!temp_var)
376         temp_var = find_variable ("ignoreeof");
377       if (temp_var && imported_p (temp_var))
378         sv_ignoreeof (temp_var->name);
379     }
380
381 #if defined (HISTORY)
382   if (interactive_shell && remember_on_history)
383     {
384       sv_history_control ("HISTCONTROL");
385       sv_histignore ("HISTIGNORE");
386     }
387 #endif /* HISTORY */
388
389   /* Get the user's real and effective user ids. */
390   uidset ();
391
392   /* Initialize the dynamic variables, and seed their values. */
393   initialize_dynamic_variables ();
394 }
395
396 /* Set $HOME to the information in the password file if we didn't get
397    it from the environment. */
398 static void
399 set_home_var ()
400 {
401   SHELL_VAR *temp_var;
402
403   temp_var = find_variable ("HOME");
404   if (temp_var == 0)
405     {
406       if (current_user.home_dir == 0)
407         get_current_user_info ();
408       temp_var = bind_variable ("HOME", current_user.home_dir);
409     }
410   temp_var->attributes |= att_exported;
411 }
412
413 /* Set $SHELL to the user's login shell if it is not already set.  Call
414    get_current_user_info if we haven't already fetched the shell. */
415 static void
416 set_shell_var ()
417 {
418   SHELL_VAR *temp_var;
419
420   temp_var = find_variable ("SHELL");
421   if (temp_var == 0)
422     {
423       if (current_user.shell == 0)
424         get_current_user_info ();
425       temp_var = bind_variable ("SHELL", current_user.shell);
426     }
427   temp_var->attributes |= att_exported;
428 }
429
430 static char *
431 get_bash_name ()
432 {
433   char *name;
434
435   if ((login_shell == 1) && (*shell_name != '/'))
436     {
437       if (current_user.shell == 0)
438         get_current_user_info ();
439       name = savestring (current_user.shell);
440     }
441   else if (*shell_name == '/')
442     name = savestring (shell_name);
443   else if (shell_name[0] == '.' && shell_name[1] == '/')
444     {
445       /* Fast path for common case. */
446       char *cdir;
447       int len;
448
449       cdir = get_string_value ("PWD");
450       len = strlen (cdir);
451       name = xmalloc (len + strlen (shell_name) + 1);
452       strcpy (name, cdir);
453       strcpy (name + len, shell_name + 1);
454     }
455   else
456     {
457       char *tname;
458       int s;
459
460       tname = find_user_command (shell_name);
461
462       if (tname == 0)
463         {
464           /* Try the current directory.  If there is not an executable
465              there, just punt and use the login shell. */
466           s = file_status (shell_name);
467           if (s & FS_EXECABLE)
468             {
469               tname = make_absolute (shell_name, get_string_value ("PWD"));
470               if (*shell_name == '.')
471                 {
472                   name = canonicalize_pathname (tname);
473                   if (name == 0)
474                     name = tname;
475                   else
476                     free (tname);
477                 }
478              else
479                 name = tname;
480             }
481           else
482             {
483               if (current_user.shell == 0)
484                 get_current_user_info ();
485               name = savestring (current_user.shell);
486             }
487         }
488       else
489         {
490           name = full_pathname (tname);
491           free (tname);
492         }
493     }
494
495   return (name);
496 }
497
498 void
499 adjust_shell_level (change)
500      int change;
501 {
502   char new_level[5], *old_SHLVL;
503   int old_level;
504   SHELL_VAR *temp_var;
505
506   old_SHLVL = get_string_value ("SHLVL");
507   old_level = old_SHLVL ? atoi (old_SHLVL) : 0;
508
509   shell_level = old_level + change;
510   if (shell_level < 0)
511     shell_level = 0;
512   else if (shell_level > 1000)
513     {
514       internal_warning ("shell level (%d) too high, resetting to 1", shell_level);
515       shell_level = 1;
516     }
517
518   /* We don't need the full generality of itos here. */
519   if (shell_level < 10)
520     {
521       new_level[0] = shell_level + '0';
522       new_level[1] = '\0';
523     }
524   else if (shell_level < 100)
525     {
526       new_level[0] = (shell_level / 10) + '0';
527       new_level[1] = (shell_level % 10) + '0';
528       new_level[2] = '\0';
529     }
530   else if (shell_level < 1000)
531     {
532       new_level[0] = (shell_level / 100) + '0';
533       old_level = shell_level % 100;
534       new_level[1] = (old_level / 10) + '0';
535       new_level[2] = (old_level % 10) + '0';
536       new_level[3] = '\0';
537     }
538
539   temp_var = bind_variable ("SHLVL", new_level);
540   set_auto_export (temp_var);
541 }
542
543 static void
544 initialize_shell_level ()
545 {
546 #if 0
547   SHELL_VAR *temp_var;
548
549   temp_var = set_if_not ("SHLVL", "0");
550   set_auto_export (temp_var);
551 #endif
552   adjust_shell_level (1);
553 }
554
555 static void
556 uidset ()
557 {
558   char *buff;
559   register SHELL_VAR *v;
560
561   buff = itos (current_user.uid);
562   v = find_variable ("UID");
563   if (v)
564     v->attributes &= ~att_readonly;
565
566   v = bind_variable ("UID", buff);
567   v->attributes |= (att_readonly | att_integer);
568
569   if (current_user.euid != current_user.uid)
570     {
571       free (buff);
572       buff = itos (current_user.euid);
573     }
574
575   v = find_variable ("EUID");
576   if (v)
577     v->attributes &= ~att_readonly;
578
579   v = bind_variable ("EUID", buff);
580   v->attributes |= (att_readonly | att_integer);
581   free (buff);
582 }
583
584 #if defined (ARRAY_VARS)
585 static void
586 make_vers_array ()
587 {
588   SHELL_VAR *vv;
589   ARRAY *av;
590   char *s, d[16];
591
592   makunbound ("BASH_VERSINFO", shell_variables);
593
594   vv = make_new_array_variable ("BASH_VERSINFO");
595   av = array_cell (vv);
596   strcpy (d, dist_version);
597   s = strchr (d, '.');
598   if (s)
599     *s++ = '\0';
600   array_add_element (av, 0, d);
601   array_add_element (av, 1, s);
602   s = itos (patch_level);
603   array_add_element (av, 2, s);
604   free (s);
605   s = itos (build_version);
606   array_add_element (av, 3, s);
607   free (s);
608   array_add_element (av, 4, release_status);
609   array_add_element (av, 5, MACHTYPE);
610
611   vv->attributes |= att_readonly;
612 }
613 #endif /* ARRAY_VARS */
614
615 /* Set the environment variables $LINES and $COLUMNS in response to
616    a window size change. */
617 void
618 set_lines_and_columns (lines, cols)
619      int lines, cols;
620 {
621   char *val;
622
623   val = itos (lines);
624   bind_variable ("LINES", val);
625   free (val);
626
627   val = itos (cols);
628   bind_variable ("COLUMNS", val);
629   free (val);
630 }
631
632 /* Set NAME to VALUE if NAME has no value. */
633 SHELL_VAR *
634 set_if_not (name, value)
635      char *name, *value;
636 {
637   SHELL_VAR *v;
638
639   v = find_variable (name);
640   if (v == 0)
641     v = bind_variable (name, value);
642   return (v);
643 }
644
645 /* Map FUNCTION over the variables in VARIABLES.  Return an array of the
646    variables for which FUNCTION returns a non-zero value.  A NULL value
647    for FUNCTION means to use all variables. */
648 SHELL_VAR **
649 map_over (function, var_hash_table)
650      Function *function;
651      HASH_TABLE* var_hash_table;
652 {
653   register int i;
654   register BUCKET_CONTENTS *tlist;
655   SHELL_VAR *var, **list;
656   int list_index, list_size;
657
658   list = (SHELL_VAR **)NULL;
659   for (i = list_index = list_size = 0; i < var_hash_table->nbuckets; i++)
660     {
661       tlist = get_hash_bucket (i, var_hash_table);
662
663       while (tlist)
664         {
665           var = (SHELL_VAR *)tlist->data;
666
667           if (!function || (*function) (var))
668             {
669               if (list_index + 1 >= list_size)
670                 list = (SHELL_VAR **)
671                   xrealloc (list, (list_size += 20) * sizeof (SHELL_VAR *));
672
673               list[list_index++] = var;
674               list[list_index] = (SHELL_VAR *)NULL;
675             }
676           tlist = tlist->next;
677         }
678     }
679   return (list);
680 }
681
682 void
683 sort_variables (array)
684      SHELL_VAR **array;
685 {
686   qsort (array, array_len ((char **)array), sizeof (SHELL_VAR *), qsort_var_comp);
687 }
688
689 static int
690 qsort_var_comp (var1, var2)
691      SHELL_VAR **var1, **var2;
692 {
693   int result;
694
695   if ((result = (*var1)->name[0] - (*var2)->name[0]) == 0)
696     result = strcmp ((*var1)->name, (*var2)->name);
697
698   return (result);
699 }
700
701 /* Create a NULL terminated array of all the shell variables in TABLE. */
702 static SHELL_VAR **
703 all_vars (table)
704      HASH_TABLE *table;
705 {
706   SHELL_VAR **list;
707
708   list = map_over ((Function *)NULL, table);
709   if (list /* && posixly_correct */)
710     sort_variables (list);
711   return (list);
712 }
713
714 /* Create a NULL terminated array of all the shell variables. */
715 SHELL_VAR **
716 all_shell_variables ()
717 {
718   return (all_vars (shell_variables));
719 }
720
721 /* Create a NULL terminated array of all the shell functions. */
722 SHELL_VAR **
723 all_shell_functions ()
724 {
725   return (all_vars (shell_functions));
726 }
727
728 /* Print VARS to stdout in such a way that they can be read back in. */
729 void
730 print_var_list (list)
731      register SHELL_VAR **list;
732 {
733   register int i;
734   register SHELL_VAR *var;
735
736   for (i = 0; list && (var = list[i]); i++)
737     if (!invisible_p (var))
738       print_assignment (var);
739 }
740
741 #if defined (NOTDEF)
742 /* Print LIST (a linked list of shell variables) to stdout
743    by printing the names, without the values.  Used to support the
744    `set +' command. */
745 void
746 print_vars_no_values (list)
747      register SHELL_VAR **list;
748 {
749   register int i;
750   register SHELL_VAR *var;
751
752   for (i = 0; list && (var = list[i]); i++)
753     if (!invisible_p (var))
754       printf ("%s\n", var->name);
755 }
756 #endif
757
758 /* Print the value of a single SHELL_VAR.  No newline is
759    output, but the variable is printed in such a way that
760    it can be read back in. */
761 void
762 print_assignment (var)
763      SHELL_VAR *var;
764 {
765   if (function_p (var) && var->value)
766     {
767       printf ("%s=", var->name);
768       print_var_function (var);
769       printf ("\n");
770     }
771 #if defined (ARRAY_VARS)
772   else if (array_p (var) && var->value)
773     print_array_assignment (var, 0);
774 #endif /* ARRAY_VARS */
775   else if (var->value)
776     {
777       printf ("%s=", var->name);
778       print_var_value (var, 1);
779       printf ("\n");
780     }
781 }
782
783 /* Print the value cell of VAR, a shell variable.  Do not print
784    the name, nor leading/trailing newline.  If QUOTE is non-zero,
785    and the value contains shell metacharacters, quote the value
786    in such a way that it can be read back in. */
787 void
788 print_var_value (var, quote)
789      SHELL_VAR *var;
790      int quote;
791 {
792   char *t;
793
794   if (var->value)
795     {
796       if (quote && contains_shell_metas (var->value))
797         {
798           t = single_quote (var->value);
799           printf ("%s", t);
800           free (t);
801         }
802       else
803         printf ("%s", var->value);
804     }
805 }
806
807 /* Print the function cell of VAR, a shell variable.  Do not
808    print the name, nor leading/trailing newline. */
809 void
810 print_var_function (var)
811      SHELL_VAR *var;
812 {
813   if (function_p (var) && var->value)
814     printf ("%s", named_function_string ((char *)NULL, function_cell(var), 1));
815 }
816
817 #if defined (ARRAY_VARS)
818 void
819 print_array_assignment (var, quoted)
820      SHELL_VAR *var;
821      int quoted;
822 {
823   char *vstr;
824
825   if (quoted)
826     vstr = quoted_array_assignment_string (array_cell (var));
827   else
828     vstr = array_to_assignment_string (array_cell (var));
829
830   if (vstr == 0)
831     printf ("%s=%s\n", var->name, quoted ? "'()'" : "()");
832   else
833     {
834       printf ("%s=%s\n", var->name, vstr);
835       free (vstr);
836     }
837 }
838 #endif /* ARRAY_VARS */
839
840 /* **************************************************************** */
841 /*                                                                  */
842 /*               Dynamic Variable Extension                         */
843 /*                                                                  */
844 /* **************************************************************** */
845
846 /* DYNAMIC VARIABLES
847
848    These are variables whose values are generated anew each time they are
849    referenced.  These are implemented using a pair of function pointers
850    in the struct variable: assign_func, which is called from bind_variable,
851    and dynamic_value, which is called from find_variable.
852
853    assign_func is called from bind_variable, if bind_variable discovers
854    that the variable being assigned to has such a function.  The function
855    is called as
856         SHELL_VAR *temp = (*(entry->assign_func)) (entry, value)
857    and the (SHELL_VAR *)temp is returned as the value of bind_variable.  It
858    is usually ENTRY (self).
859
860    dynamic_value is called from find_variable to return a `new' value for
861    the specified dynamic varible.  If this function is NULL, the variable
862    is treated as a `normal' shell variable.  If it is not, however, then
863    this function is called like this:
864         tempvar = (*(var->dynamic_value)) (var);
865
866    Sometimes `tempvar' will replace the value of `var'.  Other times, the
867    shell will simply use the string value.  Pretty object-oriented, huh?
868
869    Be warned, though: if you `unset' a special variable, it loses its
870    special meaning, even if you subsequently set it.
871
872    The special assignment code would probably have been better put in
873    subst.c: do_assignment, in the same style as
874    stupidly_hack_special_variables, but I wanted the changes as
875    localized as possible.  */
876
877 /* The value of $SECONDS.  This is the number of seconds since shell
878    invocation, or, the number of seconds since the last assignment + the
879    value of the last assignment. */
880 static long seconds_value_assigned;
881
882 static SHELL_VAR *
883 assign_seconds (self, value)
884      SHELL_VAR *self;
885      char *value;
886 {
887   seconds_value_assigned = strtol (value, (char **)NULL, 10);
888   shell_start_time = NOW;
889   return (self);
890 }
891
892 static SHELL_VAR *
893 get_seconds (var)
894      SHELL_VAR *var;
895 {
896   time_t time_since_start;
897   char *p;
898
899   time_since_start = NOW - shell_start_time;
900   p = itos((int) seconds_value_assigned + time_since_start);
901
902   FREE (var->value);
903
904   var->attributes |= att_integer;
905   var->value = p;
906   return (var);
907 }
908
909 /* The random number seed.  You can change this by setting RANDOM. */
910 static unsigned long rseed = 1;
911 static unsigned long last_random_value;
912
913 /* A linear congruential random number generator based on the ANSI
914    C standard.  This one isn't very good (the values are alternately
915    odd and even, for example), but a more complicated one is overkill.  */
916
917 /* Returns a pseudo-random number between 0 and 32767. */
918 static int
919 brand ()
920 {
921   rseed = rseed * 1103515245 + 12345;
922   return ((unsigned int)(rseed & 32767));       /* was % 32768 */
923 }
924
925 /* Set the random number generator seed to SEED. */
926 static void
927 sbrand (seed)
928      int seed;
929 {
930   rseed = seed;
931   last_random_value = 0;
932 }
933
934 static SHELL_VAR *
935 assign_random (self, value)
936      SHELL_VAR *self;
937      char *value;
938 {
939   sbrand (atoi (value));
940   return (self);
941 }
942
943 static SHELL_VAR *
944 get_random (var)
945      SHELL_VAR *var;
946 {
947   int rv;
948   char *p;
949
950   /* Reset for command and process substitution. */
951   if (subshell_environment)
952     sbrand (rseed + (int)(getpid() + NOW));
953
954   do
955     rv = brand ();
956   while (rv == (int)last_random_value);
957
958   last_random_value = rv;
959   p = itos ((int)rv);
960
961   FREE (var->value);
962
963   var->attributes |= att_integer;
964   var->value = p;
965   return (var);
966 }
967
968 /* Function which returns the current line number. */
969 static SHELL_VAR *
970 get_lineno (var)
971      SHELL_VAR *var;
972 {
973   char *p;
974   int ln;
975
976   ln = executing_line_number ();
977   p = itos (ln);
978   FREE (var->value);
979   var->value = p;
980   return (var);
981 }
982
983 static SHELL_VAR *
984 assign_lineno (var, value)
985      SHELL_VAR *var;
986      char *value;
987 {
988   line_number = atoi (value);
989   return var;
990 }
991
992 #if defined (HISTORY)
993 static SHELL_VAR *
994 get_histcmd (var)
995      SHELL_VAR *var;
996 {
997   char *p;
998
999   p = itos (history_number ());
1000   FREE (var->value);
1001   var->value = p;
1002   return (var);
1003 }
1004 #endif
1005
1006 #if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
1007 static SHELL_VAR *
1008 get_dirstack (self)
1009      SHELL_VAR *self;
1010 {
1011   ARRAY *a;
1012   WORD_LIST *l;
1013
1014   l = get_directory_stack ();
1015   a = word_list_to_array (l);
1016   dispose_array (array_cell (self));
1017   dispose_words (l);
1018   self->value = (char *)a;
1019   return self;
1020 }
1021
1022 static  SHELL_VAR *
1023 assign_dirstack (self, ind, value)
1024      SHELL_VAR *self;
1025      int ind;
1026      char *value;
1027 {
1028   set_dirstack_element (ind, 1, value);
1029   return self;
1030 }
1031 #endif /* PUSHD AND POPD && ARRAY_VARS */
1032
1033 #if defined (ARRAY_VARS)
1034 /* We don't want to initialize the group set with a call to getgroups()
1035    unless we're asked to, but we only want to do it once. */
1036 static SHELL_VAR *
1037 get_groupset (self)
1038      SHELL_VAR *self;
1039 {
1040   register int i;
1041   int ng;
1042   ARRAY *a;
1043   static char **group_set = (char **)NULL;
1044
1045   if (group_set == 0)
1046     {
1047       group_set = get_group_list (&ng);
1048       a = array_cell (self);
1049       for (i = 0; i < ng; i++)
1050         array_add_element (a, i, group_set[i]);
1051     }
1052   return (self);
1053 }
1054 #endif /* ARRAY_VARS */
1055   
1056 static void
1057 initialize_dynamic_variables ()
1058 {
1059   SHELL_VAR *v;
1060
1061   v = bind_variable ("SECONDS", (char *)NULL);
1062   v->dynamic_value = get_seconds;
1063   v->assign_func = assign_seconds;
1064
1065   v = bind_variable ("RANDOM", (char *)NULL);
1066   v->dynamic_value = get_random;
1067   v->assign_func = assign_random;
1068
1069   v = bind_variable ("LINENO", (char *)NULL);
1070   v->dynamic_value = get_lineno;
1071   v->assign_func = assign_lineno;
1072
1073 #if defined (HISTORY)
1074   v = bind_variable ("HISTCMD", (char *)NULL);
1075   v->dynamic_value = get_histcmd;
1076   v->assign_func = (DYNAMIC_FUNC *)NULL;
1077 #endif
1078
1079 #if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
1080   v = make_new_array_variable ("DIRSTACK");
1081   v->dynamic_value = get_dirstack;
1082   v->assign_func = assign_dirstack;
1083 #endif /* PUSHD_AND_POPD && ARRAY_VARS */
1084
1085 #if defined (ARRAY_VARS)
1086   v = make_new_array_variable ("GROUPS");
1087   v->dynamic_value = get_groupset;
1088   v->assign_func = (DYNAMIC_FUNC *)NULL;
1089   v->attributes |= att_readonly;
1090 #endif
1091 }
1092
1093 /* How to get a pointer to the shell variable or function named NAME.
1094    HASHED_VARS is a pointer to the hash table containing the list
1095    of interest (either variables or functions). */
1096 SHELL_VAR *
1097 var_lookup (name, hashed_vars)
1098      char *name;
1099      HASH_TABLE *hashed_vars;
1100 {
1101   BUCKET_CONTENTS *bucket;
1102
1103   bucket = find_hash_item (name, hashed_vars);
1104   return (bucket ? (SHELL_VAR *)bucket->data : (SHELL_VAR *)NULL);
1105 }
1106
1107 /* Look up the variable entry named NAME.  If SEARCH_TEMPENV is non-zero,
1108    then also search the temporarily built list of exported variables. */
1109 SHELL_VAR *
1110 find_variable_internal (name, search_tempenv)
1111      char *name;
1112      int search_tempenv;
1113 {
1114   SHELL_VAR *var = (SHELL_VAR *)NULL;
1115
1116   /* If explicitly requested, first look in the temporary environment for
1117      the variable.  This allows constructs such as "foo=x eval 'echo $foo'"
1118      to get the `exported' value of $foo.  This happens if we are executing
1119      a function or builtin, or if we are looking up a variable in a
1120      "subshell environment". */
1121   if ((search_tempenv || subshell_environment) &&
1122       (temporary_env || builtin_env || function_env))
1123     var = find_tempenv_variable (name);
1124
1125   if (!var)
1126     var = var_lookup (name, shell_variables);
1127
1128   if (!var)
1129     return ((SHELL_VAR *)NULL);
1130
1131   return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var);
1132 }
1133
1134 /* Look up the variable entry named NAME.  Returns the entry or NULL. */
1135 SHELL_VAR *
1136 find_variable (name)
1137      char *name;
1138 {
1139   return (find_variable_internal
1140           (name, (variable_context || this_shell_builtin || builtin_env)));
1141 }
1142
1143 /* Look up the function entry whose name matches STRING.
1144    Returns the entry or NULL. */
1145 SHELL_VAR *
1146 find_function (name)
1147      char *name;
1148 {
1149   return (var_lookup (name, shell_functions));
1150 }
1151
1152 /* Return the string value of a variable.  Return NULL if the variable
1153    doesn't exist, or only has a function as a value.  Don't cons a new
1154    string.  This is a potential memory leak if the variable is found
1155    in the temporary environment. */
1156 char *
1157 get_string_value (var_name)
1158      char *var_name;
1159 {
1160   SHELL_VAR *var;
1161
1162   var = find_variable (var_name);
1163
1164   if (!var)
1165     return (char *)NULL;
1166 #if defined (ARRAY_VARS)
1167   else if (array_p (var))
1168     return (array_reference (array_cell (var), 0));
1169 #endif
1170   else
1171     return (var->value);
1172 }
1173
1174 /* Create a local variable referenced by NAME. */
1175 SHELL_VAR *
1176 make_local_variable (name)
1177      char *name;
1178 {
1179   SHELL_VAR *new_var, *old_var;
1180   BUCKET_CONTENTS *elt;
1181
1182   /* local foo; local foo;  is a no-op. */
1183   old_var = find_variable (name);
1184   if (old_var && old_var->context == variable_context)
1185     return (old_var);
1186
1187   elt = remove_hash_item (name, shell_variables);
1188   if (elt)
1189     {
1190       old_var = (SHELL_VAR *)elt->data;
1191       free (elt->key);
1192       free (elt);
1193     }
1194   else
1195     old_var = (SHELL_VAR *)NULL;
1196
1197   /* If a variable does not already exist with this name, then
1198      just make a new one. */
1199   if (old_var == 0)
1200     new_var = bind_variable (name, "");
1201   else
1202     {
1203       new_var = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
1204
1205       new_var->name = savestring (name);
1206       new_var->value = xmalloc (1);
1207       new_var->value[0] = '\0';
1208
1209       new_var->dynamic_value = (DYNAMIC_FUNC *)NULL;
1210       new_var->assign_func = (DYNAMIC_FUNC *)NULL;
1211
1212       new_var->attributes = exported_p (old_var) ? att_exported : 0;
1213
1214       new_var->prev_context = old_var;
1215       elt = add_hash_item (savestring (name), shell_variables);
1216       elt->data = (char *)new_var;
1217     }
1218
1219   new_var->context = variable_context;
1220   new_var->attributes |= att_local;
1221
1222   /* XXX */
1223   if (variable_context >= local_variable_stack_size)
1224     {
1225       int old_size = local_variable_stack_size;
1226       RESIZE_MALLOCED_BUFFER (have_local_variables, variable_context, 1,
1227                               local_variable_stack_size, 8);
1228       bzero ((char *)have_local_variables + old_size,
1229              local_variable_stack_size - old_size);
1230     }
1231   have_local_variables[variable_context] = 1;           /* XXX */
1232
1233   return (new_var);
1234 }
1235
1236 #if defined (ARRAY_VARS)
1237 SHELL_VAR *
1238 make_local_array_variable (name)
1239      char *name;
1240 {
1241   SHELL_VAR *var;
1242   ARRAY *array;
1243
1244   var = make_local_variable (name);
1245   array = new_array ();
1246
1247   FREE (value_cell(var));
1248   var->value = (char *)array;
1249   var->attributes |= att_array;
1250   return var;
1251 }
1252 #endif /* ARRAY_VARS */
1253
1254 /* Create a new shell variable with name NAME and add it to the hash table
1255    of shell variables. */
1256 static
1257 SHELL_VAR *
1258 make_new_variable (name)
1259      char *name;
1260 {
1261   SHELL_VAR *entry;
1262   BUCKET_CONTENTS *elt;
1263
1264   entry = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
1265
1266   entry->attributes = 0;
1267   entry->name = savestring (name);
1268   entry->value = (char *)NULL;
1269
1270   entry->dynamic_value = (DYNAMIC_FUNC *)NULL;
1271   entry->assign_func = (DYNAMIC_FUNC *)NULL;
1272
1273   /* Always assume variables are to be made at toplevel!
1274      make_local_variable has the responsibilty of changing the
1275      variable context. */
1276   entry->context = 0;
1277   entry->prev_context = (SHELL_VAR *)NULL;
1278
1279   elt = add_hash_item (savestring (name), shell_variables);
1280   elt->data = (char *)entry;
1281
1282   return entry;
1283 }
1284
1285 #if defined (ARRAY_VARS)
1286 SHELL_VAR *
1287 make_new_array_variable (name)
1288      char *name;
1289 {
1290   SHELL_VAR *entry;
1291   ARRAY *array;
1292
1293   entry = make_new_variable (name);
1294   array = new_array ();
1295   entry->value = (char *)array;
1296   entry->attributes |= att_array;
1297   return entry;
1298 }
1299 #endif
1300
1301 char *
1302 make_variable_value (var, value)
1303      SHELL_VAR *var;
1304      char *value;
1305 {
1306   char *retval;
1307   long lval;
1308   int expok;
1309
1310   /* If this variable has had its type set to integer (via `declare -i'),
1311      then do expression evaluation on it and store the result.  The
1312      functions in expr.c (evalexp and bind_int_variable) are responsible
1313      for turning off the integer flag if they don't want further
1314      evaluation done. */
1315   if (integer_p (var))
1316     {
1317       lval = evalexp (value, &expok);
1318       if (expok == 0)
1319         jump_to_top_level (DISCARD);
1320       retval = itos (lval);
1321     }
1322   else if (value)
1323     {
1324       if (*value)
1325         retval = savestring (value);
1326       else
1327         {
1328           retval = xmalloc (1);
1329           retval[0] = '\0';
1330         }
1331     }
1332   else
1333     retval = (char *)NULL;
1334
1335   return retval;
1336 }
1337
1338 /* Bind a variable NAME to VALUE.  This conses up the name
1339    and value strings. */
1340 SHELL_VAR *
1341 bind_variable (name, value)
1342      char *name, *value;
1343 {
1344   char *newval;
1345   SHELL_VAR *entry;
1346
1347   entry = var_lookup (name, shell_variables);
1348
1349   if (entry == 0)
1350     {
1351       entry = make_new_variable (name);
1352       entry->value = make_variable_value (entry, value);
1353     }
1354 #if defined (ARRAY_VARS)
1355   else if (entry->assign_func && array_p (entry) == 0)
1356 #else
1357   else if (entry->assign_func)
1358 #endif
1359     return ((*(entry->assign_func)) (entry, value));
1360   else
1361     {
1362       if (readonly_p (entry))
1363         {
1364           report_error ("%s: readonly variable", name);
1365           return (entry);
1366         }
1367
1368       /* Variables which are bound are visible. */
1369       entry->attributes &= ~att_invisible;
1370
1371       newval = make_variable_value (entry, value);
1372
1373 #if defined (ARRAY_VARS)
1374       /* XXX -- this bears looking at again -- XXX */
1375       /* If an existing array variable x is being assigned to with x=b or
1376          `read x' or something of that nature, silently convert it to
1377          x[0]=b or `read x[0]'. */
1378       if (array_p (entry))
1379         {
1380           array_add_element (array_cell (entry), 0, newval);
1381           free (newval);
1382         }
1383       else
1384         {
1385           FREE (entry->value);
1386           entry->value = newval;
1387         }
1388 #else
1389       FREE (entry->value);
1390       entry->value = newval;
1391 #endif
1392     }
1393
1394   if (mark_modified_vars)
1395     entry->attributes |= att_exported;
1396
1397   if (exported_p (entry))
1398     array_needs_making = 1;
1399
1400   return (entry);
1401 }
1402
1403 #if defined (ARRAY_VARS)
1404 /* Convert a shell variable to an array variable.  The original value is
1405    saved as array[0]. */
1406 SHELL_VAR *
1407 convert_var_to_array (var)
1408      SHELL_VAR *var;
1409 {
1410   char *oldval;
1411   ARRAY *array;
1412
1413   oldval = value_cell (var);
1414   array = new_array ();
1415   array_add_element (array, 0, oldval);
1416   FREE (value_cell (var));
1417   var->value = (char *)array;
1418   var->attributes |= att_array;
1419   var->attributes &= ~att_invisible;
1420
1421   return var;
1422 }
1423
1424 /* Perform an array assignment name[ind]=value.  If NAME already exists and
1425    is not an array, and IND is 0, perform name=value instead.  If NAME exists
1426    and is not an array, and IND is not 0, convert it into an array with the
1427    existing value as name[0].
1428
1429    If NAME does not exist, just create an array variable, no matter what
1430    IND's value may be. */
1431 SHELL_VAR *
1432 bind_array_variable (name, ind, value)
1433      char *name;
1434      int ind;
1435      char *value;
1436 {
1437   SHELL_VAR *entry;
1438   char *newval;
1439
1440   entry = var_lookup (name, shell_variables);
1441
1442   if (entry == (SHELL_VAR *) 0)
1443     entry = make_new_array_variable (name);
1444   else if (readonly_p (entry))
1445     {
1446       report_error ("%s: readonly variable", name);
1447       return (entry);
1448     }
1449   else if (array_p (entry) == 0)
1450     entry = convert_var_to_array (entry);
1451
1452   /* ENTRY is an array variable, and ARRAY points to the value. */
1453   newval = make_variable_value (entry, value);
1454   if (entry->assign_func)
1455     (*entry->assign_func) (entry, ind, newval);
1456   else
1457     array_add_element (array_cell (entry), ind, newval);
1458   FREE (newval);
1459
1460   return (entry);
1461 }
1462
1463 /* Perform a compound assignment statement for array NAME, where VALUE is
1464    the text between the parens:  NAME=( VALUE ) */
1465 SHELL_VAR *
1466 assign_array_from_string (name, value)
1467      char *name, *value;
1468 {
1469   SHELL_VAR *var;
1470
1471   var = find_variable (name);
1472   if (var == 0)
1473     var = make_new_array_variable (name);
1474   else if (readonly_p (var))
1475     {
1476       report_error ("%s: readonly variable", name);
1477       return ((SHELL_VAR *)NULL);
1478     }
1479   else if (array_p (var) == 0)
1480     var = convert_var_to_array (var);
1481
1482   return (assign_array_var_from_string (var, value));
1483 }
1484
1485 SHELL_VAR *
1486 assign_array_var_from_word_list (var, list)
1487      SHELL_VAR *var;
1488      WORD_LIST *list;
1489 {
1490   register int i;
1491   register WORD_LIST *l;
1492   ARRAY *a;
1493
1494   for (a = array_cell (var), l = list, i = 0; l; l = l->next, i++)
1495     if (var->assign_func)
1496       (*var->assign_func) (var, i, l->word->word);
1497     else
1498       array_add_element (a, i, l->word->word);
1499   return var;
1500 }
1501
1502 /* Perform a compound array assignment:  VAR->name=( VALUE ).  The
1503    VALUE has already had the parentheses stripped. */
1504 SHELL_VAR *
1505 assign_array_var_from_string (var, value)
1506      SHELL_VAR *var;
1507      char *value;
1508 {
1509   ARRAY *a;
1510   WORD_LIST *list, *nlist;
1511   char *w, *val, *nval;
1512   int ni, len, ind, last_ind;
1513
1514   if (value == 0)
1515     return var;
1516
1517   /* If this is called from declare_builtin, value[0] == '(' and
1518      strchr(value, ')') != 0.  In this case, we need to extract
1519      the value from between the parens before going on. */
1520   if (*value == '(')    /*)*/
1521     {
1522       ni = 1;
1523       val = extract_array_assignment_list (value, &ni);
1524       if (val == 0)
1525         return var;
1526     }
1527   else
1528     val = value;
1529
1530   /* Expand the value string into a list of words, performing all the
1531      shell expansions including word splitting. */
1532 #if 1
1533   /* First we split the string on whitespace, using the shell parser
1534      (ksh93 seems to do this). */
1535   list = parse_string_to_word_list (val, "array assign");
1536   /* Now that we've split it, perform the shell expansions on each
1537      word in the list. */
1538   nlist = list ? expand_words_shellexp (list) : (WORD_LIST *)NULL;
1539   dispose_words (list);
1540 #else
1541   nlist = expand_string (val, 0);
1542 #endif
1543
1544   if (val != value)
1545     free (val);
1546
1547   a = array_cell (var);
1548
1549   /* Now that we are ready to assign values to the array, kill the existing
1550      value. */
1551   if (a)
1552     empty_array (a);
1553
1554   for (last_ind = 0, list = nlist; list; list = list->next)
1555     {
1556       w = list->word->word;
1557
1558       /* We have a word of the form [ind]=value */
1559       if (w[0] == '[')
1560         {
1561           len = skipsubscript (w, 0);
1562
1563           if (w[len] != ']' || w[len+1] != '=')
1564             {
1565               nval = make_variable_value (var, w);
1566               if (var->assign_func)
1567                 (*var->assign_func) (var, last_ind, nval);
1568               else
1569                 array_add_element (a, last_ind, nval);
1570               FREE (nval);
1571               last_ind++;
1572               continue;
1573             }
1574
1575           if (len == 1)
1576             {
1577               report_error ("%s: bad array subscript", w);
1578               continue;
1579             }
1580
1581           if (ALL_ELEMENT_SUB (w[1]) && len == 2)
1582             {
1583               report_error ("%s: cannot assign to non-numeric index", w);
1584               continue;
1585             }
1586
1587           ind = array_expand_index (w + 1, len);
1588           if (ind < 0)
1589             {
1590               report_error ("%s: bad array subscript", w);
1591               continue;
1592             }
1593           last_ind = ind;
1594           val = w + len + 2;
1595         }
1596       else              /* No [ind]=value, just a stray `=' */
1597         {
1598           ind = last_ind;
1599           val = w;
1600         }
1601
1602       if (integer_p (var))
1603         this_command_name = (char *)NULL;       /* no command name for errors */
1604       nval = make_variable_value (var, val);
1605       if (var->assign_func)
1606         (*var->assign_func) (var, ind, nval);
1607       else
1608         array_add_element (a, ind, nval);
1609       FREE (nval);
1610       last_ind++;
1611     }
1612
1613   dispose_words (nlist);
1614   return (var);
1615 }
1616 #endif /* ARRAY_VARS */
1617
1618 /* Dispose of the information attached to VAR. */
1619 void
1620 dispose_variable (var)
1621      SHELL_VAR *var;
1622 {
1623   if (!var)
1624     return;
1625
1626   if (function_p (var))
1627     dispose_command (function_cell (var));
1628 #if defined (ARRAY_VARS)
1629   else if (array_p (var))
1630     dispose_array (array_cell (var));
1631 #endif
1632   else
1633     FREE (value_cell (var));
1634
1635   free (var->name);
1636
1637   if (exported_p (var))
1638     array_needs_making = 1;
1639
1640   free (var);
1641 }
1642
1643 #if defined (ARRAY_VARS)
1644 /* This function is called with SUB pointing to just after the beginning
1645    `[' of an array subscript. */
1646 int
1647 unbind_array_element (var, sub)
1648      SHELL_VAR *var;
1649      char *sub;
1650 {
1651   int len, ind;
1652   ARRAY_ELEMENT *ae;
1653
1654   len = skipsubscript (sub, 0);
1655   if (sub[len] != ']' || len == 0)
1656     {
1657       builtin_error ("%s[%s: bad array subscript", var->name, sub);
1658       return -1;
1659     }
1660   sub[len] = '\0';
1661
1662   if (ALL_ELEMENT_SUB (sub[0]) && sub[1] == 0)
1663     {
1664       makunbound (var->name, shell_variables);
1665       return (0);
1666     }
1667   ind = array_expand_index (sub, len+1);
1668   if (ind < 0)
1669     {
1670       builtin_error ("[%s]: bad array subscript", sub);
1671       return -1;
1672     }
1673   ae = array_delete_element (array_cell (var), ind);
1674   if (ae)
1675     destroy_array_element (ae);
1676   return 0;
1677 }
1678 #endif
1679
1680 /* Unset the variable referenced by NAME. */
1681 int
1682 unbind_variable (name)
1683      char *name;
1684 {
1685   SHELL_VAR *var;
1686
1687   var = find_variable (name);
1688   if (!var)
1689     return (-1);
1690
1691   /* This function should never be called with an array variable name. */
1692 #if defined (ARRAY_VARS)
1693   if (array_p (var) == 0 && var->value)
1694 #else
1695   if (var->value)
1696 #endif
1697     {
1698       free (var->value);
1699       var->value = (char *)NULL;
1700     }
1701
1702   makunbound (name, shell_variables);
1703
1704   return (0);
1705 }
1706
1707 /* Make the variable associated with NAME go away.  HASH_LIST is the
1708    hash table from which this variable should be deleted (either
1709    shell_variables or shell_functions).
1710    Returns non-zero if the variable couldn't be found. */
1711 int
1712 makunbound (name, hash_list)
1713      char *name;
1714      HASH_TABLE *hash_list;
1715 {
1716   BUCKET_CONTENTS *elt, *new_elt;
1717   SHELL_VAR *old_var, *new_var;
1718   char *t;
1719
1720   elt = remove_hash_item (name, hash_list);
1721
1722   if (elt == 0)
1723     return (-1);
1724
1725   old_var = (SHELL_VAR *)elt->data;
1726   new_var = old_var->prev_context;
1727
1728   if (old_var && exported_p (old_var))
1729     array_needs_making++;
1730
1731   /* If we're unsetting a local variable and we're still executing inside
1732      the function, just mark the variable as invisible.
1733      kill_all_local_variables will clean it up later.  This must be done
1734      so that if the variable is subsequently assigned a new value inside
1735      the function, the `local' attribute is still present.  We also need
1736      to add it back into the correct hash table. */
1737   if (old_var && local_p (old_var) && variable_context == old_var->context)
1738     {
1739       old_var->attributes |= att_invisible;
1740       new_elt = add_hash_item (savestring (old_var->name), hash_list);
1741       new_elt->data = (char *)old_var;
1742       stupidly_hack_special_variables (old_var->name);
1743       free (elt->key);
1744       free (elt);
1745       return (0);
1746     }
1747
1748   if (new_var)
1749     {
1750       /* Has to be a variable, functions don't have previous contexts. */
1751       new_elt = add_hash_item (savestring (new_var->name), hash_list);
1752       new_elt->data = (char *)new_var;
1753
1754       if (exported_p (new_var))
1755         set_auto_export (new_var);
1756     }
1757
1758   /* Have to save a copy of name here, because it might refer to
1759      old_var->name.  If so, stupidly_hack_special_variables will
1760      reference freed memory. */
1761   t = savestring (name);
1762
1763   free (elt->key);
1764   free (elt);
1765
1766   dispose_variable (old_var);
1767   stupidly_hack_special_variables (t);
1768   free (t);
1769   return (0);
1770 }
1771
1772 #ifdef INCLUDE_UNUSED
1773 /* Remove the variable with NAME if it is a local variable in the
1774    current context. */
1775 int
1776 kill_local_variable (name)
1777      char *name;
1778 {
1779   SHELL_VAR *temp;
1780
1781   temp = find_variable (name);
1782   if (temp && temp->context == variable_context)
1783     {
1784       makunbound (name, shell_variables);
1785       return (0);
1786     }
1787   return (-1);
1788 }
1789 #endif
1790
1791 /* Get rid of all of the variables in the current context. */
1792 int
1793 variable_in_context (var)
1794      SHELL_VAR *var;
1795 {
1796   return (var && var->context == variable_context);
1797 }
1798
1799 void
1800 kill_all_local_variables ()
1801 {
1802   register int i, pass;
1803   register SHELL_VAR *var, **list;
1804   HASH_TABLE *varlist;
1805
1806   /* If HAVE_LOCAL_VARIABLES == 0, it means that we don't have any local
1807      variables at all.  If VARIABLE_CONTEXT >= LOCAL_VARIABLE_STACK_SIZE,
1808      it means that we have some local variables, but not in this variable
1809      context (level of function nesting).  Also, if
1810      HAVE_LOCAL_VARIABLES[VARIABLE_CONTEXT] == 0, we have no local variables
1811      at this context. */
1812   if (have_local_variables == 0 ||
1813       variable_context >= local_variable_stack_size ||
1814       have_local_variables[variable_context] == 0)
1815     return;
1816
1817   for (pass = 0; pass < 2; pass++)
1818     {
1819       varlist = pass ? shell_functions : shell_variables;
1820
1821       list = map_over (variable_in_context, varlist);
1822
1823       if (list)
1824         {
1825           for (i = 0; var = list[i]; i++)
1826             {
1827               var->attributes &= ~att_local;
1828               makunbound (var->name, varlist);
1829             }
1830           free (list);
1831         }
1832     }
1833
1834   have_local_variables[variable_context] = 0;           /* XXX */
1835 }
1836
1837 static void
1838 free_variable_hash_data (data)
1839      char *data;
1840 {
1841   SHELL_VAR *var, *prev;
1842
1843   var = (SHELL_VAR *)data;
1844   while (var)
1845     {
1846       prev = var->prev_context;
1847       dispose_variable (var);
1848       var = prev;
1849     }
1850 }
1851
1852 /* Delete the entire contents of the hash table. */
1853 void
1854 delete_all_variables (hashed_vars)
1855      HASH_TABLE *hashed_vars;
1856 {
1857   flush_hash_table (hashed_vars, free_variable_hash_data);
1858 }
1859
1860 static SHELL_VAR *
1861 new_shell_variable (name)
1862      char *name;
1863 {
1864   SHELL_VAR *var;
1865
1866   var = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
1867
1868   bzero ((char *)var, sizeof (SHELL_VAR));
1869   var->name = savestring (name);
1870   return (var);
1871 }
1872
1873 /* Do a function binding to a variable.  You pass the name and
1874    the command to bind to.  This conses the name and command. */
1875 SHELL_VAR *
1876 bind_function (name, value)
1877      char *name;
1878      COMMAND *value;
1879 {
1880   SHELL_VAR *entry;
1881
1882   entry = find_function (name);
1883   if (!entry)
1884     {
1885       BUCKET_CONTENTS *elt;
1886
1887       elt = add_hash_item (savestring (name), shell_functions);
1888
1889       elt->data = (char *)new_shell_variable (name);
1890       entry = (SHELL_VAR *)elt->data;
1891       entry->dynamic_value = entry->assign_func = (DYNAMIC_FUNC *)NULL;
1892
1893       /* Functions are always made at the top level.  This allows a
1894          function to define another function (like autoload). */
1895       entry->context = 0;
1896     }
1897
1898   if (entry->value)
1899     dispose_command ((COMMAND *)entry->value);
1900
1901   entry->value = value ? (char *)copy_command (value) : (char *)NULL;
1902   entry->attributes |= att_function;
1903
1904   if (mark_modified_vars)
1905     entry->attributes |= att_exported;
1906
1907   entry->attributes &= ~att_invisible;  /* Just to be sure */
1908
1909   if (exported_p (entry))
1910     array_needs_making = 1;
1911
1912   return (entry);
1913 }
1914
1915 #ifdef INCLUDE_UNUSED
1916 /* Copy VAR to a new data structure and return that structure. */
1917 SHELL_VAR *
1918 copy_variable (var)
1919      SHELL_VAR *var;
1920 {
1921   SHELL_VAR *copy = (SHELL_VAR *)NULL;
1922
1923   if (var)
1924     {
1925       copy = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
1926
1927       copy->attributes = var->attributes;
1928       copy->name = savestring (var->name);
1929
1930       if (function_p (var))
1931         copy->value = (char *)copy_command (function_cell (var));
1932 #if defined (ARRAY_VARS)
1933       else if (array_p (var))
1934         copy->value = (char *)dup_array (array_cell (var));
1935 #endif
1936       else if (value_cell (var))
1937         copy->value = savestring (value_cell (var));
1938       else
1939         copy->value = (char *)NULL;
1940
1941       copy->dynamic_value = var->dynamic_value;
1942       copy->assign_func = var->assign_func;
1943
1944       copy->context = var->context;
1945
1946       /* Don't bother copying previous contexts along with this variable. */
1947       copy->prev_context = (SHELL_VAR *)NULL;
1948     }
1949   return (copy);
1950 }
1951 #endif
1952
1953 #define FIND_OR_MAKE_VARIABLE(name, entry) \
1954   do \
1955     { \
1956       entry = find_variable (name); \
1957       if (!entry) \
1958         { \
1959           entry = bind_variable (name, ""); \
1960           if (!no_invisible_vars) entry->attributes |= att_invisible; \
1961         } \
1962     } \
1963   while (0)
1964
1965 /* Make the variable associated with NAME be readonly.
1966    If NAME does not exist yet, create it. */
1967 void
1968 set_var_read_only (name)
1969      char *name;
1970 {
1971   SHELL_VAR *entry;
1972
1973   FIND_OR_MAKE_VARIABLE (name, entry);
1974   entry->attributes |= att_readonly;
1975 }
1976
1977 #ifdef INCLUDE_UNUSED
1978 /* Make the function associated with NAME be readonly.
1979    If NAME does not exist, we just punt, like auto_export code below. */
1980 void
1981 set_func_read_only (name)
1982      char *name;
1983 {
1984   SHELL_VAR *entry;
1985
1986   entry = find_function (name);
1987   if (entry)
1988     entry->attributes |= att_readonly;
1989 }
1990
1991 /* Make the variable associated with NAME be auto-exported.
1992    If NAME does not exist yet, create it. */
1993 void
1994 set_var_auto_export (name)
1995      char *name;
1996 {
1997   SHELL_VAR *entry;
1998
1999   FIND_OR_MAKE_VARIABLE (name, entry);
2000   set_auto_export (entry);
2001 }
2002
2003 /* Make the function associated with NAME be auto-exported. */
2004 void
2005 set_func_auto_export (name)
2006      char *name;
2007 {
2008   SHELL_VAR *entry;
2009
2010   entry = find_function (name);
2011   if (entry)
2012     set_auto_export (entry);
2013 }
2014 #endif
2015
2016 #if defined (ARRAY_VARS)
2017 /* This function assumes s[i] == '['; returns with s[ret] == ']' if
2018    an array subscript is correctly parsed. */
2019 int
2020 skipsubscript (s, i)
2021      char *s;
2022      int i;
2023 {
2024   int count, c;
2025
2026   for (count = 1; count && (c = s[++i]); )
2027     {
2028       if (c == '[')
2029         count++;
2030       else if (c == ']')
2031         count--;
2032     }
2033   return i;
2034 }
2035 #endif /* ARRAY_VARS */
2036
2037 /* Returns non-zero if STRING is an assignment statement.  The returned value
2038    is the index of the `=' sign. */
2039 int
2040 assignment (string)
2041      char *string;
2042 {
2043   register int c, newi, indx;
2044
2045   c = string[indx = 0];
2046
2047   if (legal_variable_starter (c) == 0)
2048     return (0);
2049
2050   while (c = string[indx])
2051     {
2052       /* The following is safe.  Note that '=' at the start of a word
2053          is not an assignment statement. */
2054       if (c == '=')
2055         return (indx);
2056
2057 #if defined (ARRAY_VARS)
2058       if (c == '[')
2059         {
2060           newi = skipsubscript (string, indx);
2061           if (string[newi++] != ']')
2062             return (0);
2063           return ((string[newi] == '=') ? newi : 0);
2064         }
2065 #endif /* ARRAY_VARS */
2066
2067       /* Variable names in assignment statements may contain only letters,
2068          digits, and `_'. */
2069       if (legal_variable_char (c) == 0)
2070         return (0);
2071
2072       indx++;
2073     }
2074   return (0);
2075 }
2076
2077 #ifdef READLINE
2078
2079 static int
2080 visible_var (var)
2081      SHELL_VAR *var;
2082 {
2083   return (invisible_p (var) == 0);
2084 }
2085
2086 static SHELL_VAR **
2087 _visible_names (table)
2088      HASH_TABLE *table;
2089 {
2090   SHELL_VAR **list;
2091
2092   list = map_over (visible_var, table);
2093
2094   if (list /* && posixly_correct */)
2095     sort_variables (list);
2096
2097   return (list);
2098 }
2099
2100 SHELL_VAR **
2101 all_visible_variables ()
2102 {
2103   return (_visible_names (shell_variables));
2104 }
2105
2106 SHELL_VAR **
2107 all_visible_functions ()
2108 {
2109   return (_visible_names (shell_functions));
2110 }
2111
2112 #endif /* READLINE */
2113
2114 /* Return non-zero if the variable VAR is visible and exported.  Array
2115    variables cannot be exported. */
2116 static int
2117 visible_and_exported (var)
2118      SHELL_VAR *var;
2119 {
2120   return (invisible_p (var) == 0 && exported_p (var));
2121 }
2122
2123 /* Make an array of assignment statements from the hash table
2124    HASHED_VARS which contains SHELL_VARs.  Only visible, exported
2125    variables are eligible. */
2126 char **
2127 make_var_array (hashed_vars)
2128      HASH_TABLE *hashed_vars;
2129 {
2130   register int i, list_index;
2131   register SHELL_VAR *var;
2132   char **list, *value;
2133   SHELL_VAR **vars;
2134
2135   vars = map_over (visible_and_exported, hashed_vars);
2136
2137   if (vars == 0)
2138     return (char **)NULL;
2139
2140   list = (char **)xmalloc ((1 + array_len ((char **)vars)) * sizeof (char *));
2141
2142   for (i = 0, list_index = 0; var = vars[i]; i++)
2143     {
2144       if (function_p (var))
2145         value = named_function_string ((char *)NULL, function_cell (var), 0);
2146 #if defined (ARRAY_VARS)
2147       else if (array_p (var))
2148 #  if 0
2149         value = array_to_assignment_string (array_cell (var));
2150 #  else
2151         continue;       /* XXX array vars cannot yet be exported */
2152 #  endif
2153 #endif
2154       else
2155         value = value_cell (var);
2156
2157       if (value)
2158         {
2159           int name_len, value_len;
2160           char  *p;
2161
2162           name_len = strlen (var->name);
2163           value_len = strlen (value);
2164           p = list[list_index] = xmalloc (2 + name_len + value_len);
2165           strcpy (p, var->name);
2166           p[name_len] = '=';
2167           strcpy (p + name_len + 1, value);
2168           list_index++;
2169 #if defined (ARRAY_VARS)
2170           if (array_p (var))
2171             free (value);
2172 #endif
2173         }
2174     }
2175
2176   free (vars);
2177   list[list_index] = (char *)NULL;
2178   return (list);
2179 }
2180
2181 /* Add STRING to the array of foo=bar strings that we already
2182    have to add to the environment.  */
2183 int
2184 assign_in_env (string)
2185      char *string;
2186 {
2187   int size, offset;
2188   char *name, *temp, *value;
2189   int nlen, vlen;
2190   WORD_LIST *list;
2191   SHELL_VAR *var;
2192
2193   offset = assignment (string);
2194   name = savestring (string);
2195   value = (char *)NULL;
2196
2197   if (name[offset] == '=')
2198     {
2199       name[offset] = 0;
2200
2201       var = find_variable (name);
2202       if (var && readonly_p (var))
2203         {
2204           report_error ("%s: readonly variable", name);
2205           free (name);
2206           return (0);
2207         }
2208       temp = name + offset + 1;
2209       temp = (strchr (temp, '~') != 0) ? bash_tilde_expand (temp) : savestring (temp);
2210
2211       list = expand_string_unsplit (temp, 0);
2212       value = string_list (list);
2213
2214       if (list)
2215         dispose_words (list);
2216
2217       free (temp);
2218     }
2219
2220   nlen = strlen (name);
2221   vlen = value ? strlen (value) : 0;
2222   temp = xmalloc (2 + nlen + vlen);
2223   strcpy (temp, name);
2224   temp[nlen] = '=';
2225   temp[nlen + 1] = '\0';
2226   if (value)
2227     {
2228       if (*value)
2229         strcpy (temp + nlen + 1, value);
2230       free (value);
2231     }
2232   free (name);
2233
2234   if (temporary_env == 0)
2235     {
2236       temporary_env = (char **)xmalloc (sizeof (char *));
2237       temporary_env [0] = (char *)NULL;
2238     }
2239
2240   size = array_len (temporary_env);
2241   temporary_env = (char **)
2242     xrealloc (temporary_env, (size + 2) * (sizeof (char *)));
2243
2244   temporary_env[size] = temp;
2245   temporary_env[size + 1] = (char *)NULL;
2246   array_needs_making = 1;
2247
2248   if (echo_command_at_execute)
2249     {
2250       /* The Korn shell prints the `+ ' in front of assignment statements,
2251          so we do too. */
2252       fprintf (stderr, "%s%s\n", indirection_level_string (), temp);
2253       fflush (stderr);
2254     }
2255
2256   return 1;
2257 }
2258
2259 /* Search for NAME in ARRAY, an array of strings in the same format as the
2260    environment array (i.e, name=value).  If NAME is present, make a new
2261    variable and return it.  Otherwise, return NULL. */
2262 static SHELL_VAR *
2263 find_name_in_env_array (name, array)
2264      char *name;
2265      char **array;
2266 {
2267   register int i, l;
2268
2269   if (array == 0)
2270     return ((SHELL_VAR *)NULL);
2271
2272   for (i = 0, l = strlen (name); array[i]; i++)
2273     {
2274       if (STREQN (array[i], name, l) && array[i][l] == '=')
2275         {
2276           SHELL_VAR *temp;
2277           char *w;
2278
2279           /* This is a potential memory leak.  The code should really save
2280              the created variables in some auxiliary data structure, which
2281              can be disposed of at the appropriate time. */
2282           temp = new_shell_variable (name);
2283           w = array[i] + l + 1;
2284
2285           temp->value = *w ? savestring (w) : (char *)NULL;
2286
2287           temp->attributes = att_exported|att_tempvar;
2288           temp->context = 0;
2289           temp->prev_context = (SHELL_VAR *)NULL;
2290
2291           temp->dynamic_value = temp->assign_func = (DYNAMIC_FUNC *)NULL;
2292
2293           return (temp);
2294         }
2295     }
2296   return ((SHELL_VAR *)NULL);
2297 }
2298
2299 /* Find a variable in the temporary environment that is named NAME.
2300    The temporary environment can be either the environment provided
2301    to a simple command, or the environment provided to a shell function.
2302    We only search the function environment if we are currently executing
2303    a shell function body (variable_context > 0).  Return a consed variable,
2304    or NULL if not found. */
2305 SHELL_VAR *
2306 find_tempenv_variable (name)
2307      char *name;
2308 {
2309   SHELL_VAR *var;
2310
2311   var = (SHELL_VAR *)NULL;
2312
2313   if (temporary_env)
2314     var = find_name_in_env_array (name, temporary_env);
2315
2316   /* We don't check this_shell_builtin because the command that needs the
2317      value from builtin_env may be a disk command run inside a script run
2318      with `.' and a temporary env. */
2319   if (!var && builtin_env)
2320     var = find_name_in_env_array (name, builtin_env);
2321
2322   if (!var && variable_context && function_env)
2323     var = find_name_in_env_array (name, function_env);
2324
2325   return (var);
2326 }
2327
2328 /* Free the storage allocated to the string array pointed to by ARRAYP, and
2329    make that variable have a null pointer as a value. */
2330 static void
2331 dispose_temporary_vars (arrayp)
2332      char ***arrayp;
2333 {
2334   if (!*arrayp)
2335     return;
2336
2337   free_array (*arrayp);
2338   *arrayp = (char **)NULL;
2339   array_needs_making = 1;
2340 }
2341
2342 /* Free the storage used in the variable array for temporary
2343    environment variables. */
2344 void
2345 dispose_used_env_vars ()
2346 {
2347   dispose_temporary_vars (&temporary_env);
2348 }
2349
2350 /* Free the storage used for temporary environment variables given to
2351    commands when executing inside of a function body. */
2352 void
2353 dispose_function_env ()
2354 {
2355   dispose_temporary_vars (&function_env);
2356 }
2357
2358 /* Free the storage used for temporary environment variables given to
2359    commands when executing a builtin command such as "source". */
2360 void
2361 dispose_builtin_env ()
2362 {
2363   dispose_temporary_vars (&builtin_env);
2364 }
2365
2366 /* Take all of the shell variables in ENV_ARRAY and make shell variables
2367    from them at the current variable context. */
2368 static void
2369 merge_env_array (env_array)
2370      char **env_array;
2371 {
2372   register int i, l;
2373   SHELL_VAR *temp;
2374   char *val, *name;
2375
2376   if (env_array == 0)
2377     return;
2378
2379   for (i = 0; env_array[i]; i++)
2380     {
2381       l = assignment (env_array[i]);
2382       name = env_array[i];
2383       val = env_array[i] + l + 1;
2384       name[l] = '\0';
2385       temp = bind_variable (name, val);
2386       name[l] = '=';
2387     }
2388 }
2389
2390 void
2391 merge_temporary_env ()
2392 {
2393   merge_env_array (temporary_env);
2394 }
2395
2396 void
2397 merge_builtin_env ()
2398 {
2399   merge_env_array (builtin_env);
2400 }
2401
2402 /* Add ENVSTR to the end of the exported environment, EXPORT_ENV. */
2403 #define add_to_export_env(envstr,do_alloc) \
2404 do \
2405   { \
2406     if (export_env_index >= (export_env_size - 1)) \
2407       { \
2408         export_env_size += 16; \
2409         export_env = (char **)xrealloc (export_env, export_env_size * sizeof (char *)); \
2410       } \
2411     export_env[export_env_index++] = (do_alloc) ? savestring (envstr) : envstr; \
2412     export_env[export_env_index] = (char *)NULL; \
2413   } while (0)
2414
2415 #define ISFUNCTION(s, o) ((s[o + 1] == '(')  && (s[o + 2] == ')'))
2416
2417 /* Add ASSIGN to EXPORT_ENV, or supercede a previous assignment in the
2418    array with the same left-hand side.  Return the new EXPORT_ENV. */
2419 char **
2420 add_or_supercede_exported_var (assign, do_alloc)
2421      char *assign;
2422      int do_alloc;
2423 {
2424   register int i;
2425   int equal_offset;
2426
2427   equal_offset = assignment (assign);
2428   if (equal_offset == 0)
2429     return (export_env);
2430
2431   /* If this is a function, then only supercede the function definition.
2432      We do this by including the `=(' in the comparison.  */
2433   if (assign[equal_offset + 1] == '(')
2434     equal_offset++;
2435
2436   for (i = 0; i < export_env_index; i++)
2437     {
2438       if (STREQN (assign, export_env[i], equal_offset + 1))
2439         {
2440           free (export_env[i]);
2441           export_env[i] = do_alloc ? savestring (assign) : assign;
2442           return (export_env);
2443         }
2444     }
2445   add_to_export_env (assign, do_alloc);
2446   return (export_env);
2447 }
2448
2449 /* Make the environment array for the command about to be executed, if the
2450    array needs making.  Otherwise, do nothing.  If a shell action could
2451    change the array that commands receive for their environment, then the
2452    code should `array_needs_making++'. */
2453 void
2454 maybe_make_export_env ()
2455 {
2456   register int i;
2457   register char **temp_array;
2458   int new_size;
2459
2460   if (array_needs_making)
2461     {
2462       if (export_env)
2463         free_array_members (export_env);
2464
2465       /* Make a guess based on how many shell variables and functions we
2466          have.  Since there will always be array variables, and array
2467          variables are not (yet) exported, this will always be big enough
2468          for the exported variables and functions, without any temporary
2469          or function environments. */
2470       new_size = shell_variables->nentries + shell_functions->nentries + 1;
2471       if (new_size > export_env_size)
2472         {
2473           export_env_size = new_size;
2474           export_env = (char **)xrealloc (export_env, export_env_size * sizeof (char *));
2475         }
2476       export_env[export_env_index = 0] = (char *)NULL;
2477
2478       temp_array = make_var_array (shell_variables);
2479       if (temp_array)
2480         {
2481           for (i = 0; temp_array[i]; i++)
2482             add_to_export_env (temp_array[i], 0);
2483           free (temp_array);
2484         }
2485
2486       temp_array = make_var_array (shell_functions);
2487       if (temp_array)
2488         {
2489           for (i = 0; temp_array[i]; i++)
2490             add_to_export_env (temp_array[i], 0);
2491           free (temp_array);
2492         }
2493
2494       if (function_env)
2495         for (i = 0; function_env[i]; i++)
2496           export_env = add_or_supercede_exported_var (function_env[i], 1);
2497
2498       if (temporary_env)
2499         for (i = 0; temporary_env[i]; i++)
2500           export_env = add_or_supercede_exported_var (temporary_env[i], 1);
2501
2502 #if 0
2503       /* If we changed the array, then sort it alphabetically. */
2504       if (posixly_correct == 0 && (temporary_env || function_env))
2505         sort_char_array (export_env);
2506 #endif
2507
2508       array_needs_making = 0;
2509     }
2510 }
2511
2512 /* We always put _ in the environment as the name of this command. */
2513 void
2514 put_command_name_into_env (command_name)
2515      char *command_name;
2516 {
2517   char *dummy;
2518
2519   dummy = xmalloc (4 + strlen (command_name));
2520
2521   /* These three statements replace a call to sprintf */
2522   dummy[0] = '_';
2523   dummy[1] = '=';
2524   strcpy (dummy + 2, command_name);
2525   export_env = add_or_supercede_exported_var (dummy, 0);
2526 }
2527
2528 #if 0   /* UNUSED -- it caused too many problems */
2529 void
2530 put_gnu_argv_flags_into_env (pid, flags_string)
2531      int pid;
2532      char *flags_string;
2533 {
2534   char *dummy, *pbuf;
2535   int l, fl;
2536
2537   pbuf = itos (pid);
2538   l = strlen (pbuf);
2539
2540   fl = strlen (flags_string);
2541
2542   dummy = xmalloc (l + fl + 30);
2543   dummy[0] = '_';
2544   strcpy (dummy + 1, pbuf);
2545   strcpy (dummy + 1 + l, "_GNU_nonoption_argv_flags_");
2546   dummy[l + 27] = '=';
2547   strcpy (dummy + l + 28, flags_string);
2548
2549   free (pbuf);
2550
2551   export_env = add_or_supercede_exported_var (dummy, 0);
2552 }
2553 #endif
2554
2555 /* Return a string denoting what our indirection level is. */
2556 static char indirection_string[100];
2557
2558 char *
2559 indirection_level_string ()
2560 {
2561   register int i, j;
2562   char *ps4;
2563
2564   indirection_string[0] = '\0';
2565   ps4 = get_string_value ("PS4");
2566
2567   if (ps4 == 0 || *ps4 == '\0')
2568     return (indirection_string);
2569
2570   ps4 = decode_prompt_string (ps4);
2571
2572   for (i = 0; *ps4 && i < indirection_level && i < 99; i++)
2573     indirection_string[i] = *ps4;
2574
2575   for (j = 1; *ps4 && ps4[j] && i < 99; i++, j++)
2576     indirection_string[i] = ps4[j];
2577
2578   indirection_string[i] = '\0';
2579   free (ps4);
2580   return (indirection_string);
2581 }
2582
2583 /*************************************************
2584  *                                               *
2585  *      Functions to manage special variables    *
2586  *                                               *
2587  *************************************************/
2588
2589 /* Extern declarations for variables this code has to manage. */
2590 extern int eof_encountered, eof_encountered_limit, ignoreeof;
2591
2592 #if defined (READLINE)
2593 extern int no_line_editing;
2594 extern int hostname_list_initialized;
2595 #endif
2596
2597 /* An alist of name.function for each special variable.  Most of the
2598    functions don't do much, and in fact, this would be faster with a
2599    switch statement, but by the end of this file, I am sick of switch
2600    statements. */
2601
2602 #define SET_INT_VAR(name, intvar)  intvar = find_variable (name) != 0
2603
2604 struct name_and_function {
2605   char *name;
2606   VFunction *function;
2607 } special_vars[] = {
2608   { "PATH", sv_path },
2609   { "MAIL", sv_mail },
2610   { "MAILPATH", sv_mail },
2611   { "MAILCHECK", sv_mail },
2612
2613   { "POSIXLY_CORRECT", sv_strict_posix },
2614   { "GLOBIGNORE", sv_globignore },
2615
2616   /* Variables which only do something special when READLINE is defined. */
2617 #if defined (READLINE)
2618   { "TERM", sv_terminal },
2619   { "TERMCAP", sv_terminal },
2620   { "TERMINFO", sv_terminal },
2621   { "HOSTFILE", sv_hostfile },
2622 #endif /* READLINE */
2623
2624   /* Variables which only do something special when HISTORY is defined. */
2625 #if defined (HISTORY)
2626   { "HISTIGNORE", sv_histignore },
2627   { "HISTSIZE", sv_histsize },
2628   { "HISTFILESIZE", sv_histsize },
2629   { "HISTCONTROL", sv_history_control },
2630 #  if defined (BANG_HISTORY)
2631   { "histchars", sv_histchars },
2632 #  endif /* BANG_HISTORY */
2633 #endif /* HISTORY */
2634
2635   { "IGNOREEOF", sv_ignoreeof },
2636   { "ignoreeof", sv_ignoreeof },
2637
2638   { "OPTIND", sv_optind },
2639   { "OPTERR", sv_opterr },
2640
2641   { "TEXTDOMAIN", sv_locale },
2642   { "TEXTDOMAINDIR", sv_locale },
2643   { "LC_ALL", sv_locale },
2644   { "LC_COLLATE", sv_locale },
2645   { "LC_CTYPE", sv_locale },
2646   { "LC_MESSAGES", sv_locale },
2647   { "LANG", sv_locale },
2648
2649 #if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE)
2650   { "TZ", sv_tz },
2651 #endif
2652
2653   { (char *)0, (VFunction *)0 }
2654 };
2655
2656 /* The variable in NAME has just had its state changed.  Check to see if it
2657    is one of the special ones where something special happens. */
2658 void
2659 stupidly_hack_special_variables (name)
2660      char *name;
2661 {
2662   int i;
2663
2664   for (i = 0; special_vars[i].name; i++)
2665     {
2666       if (STREQ (special_vars[i].name, name))
2667         {
2668           (*(special_vars[i].function)) (name);
2669           return;
2670         }
2671     }
2672 }
2673
2674 /* What to do just after the PATH variable has changed. */
2675 void
2676 sv_path (name)
2677      char *name;
2678 {
2679   /* hash -r */
2680   flush_hashed_filenames ();
2681 }
2682
2683 /* What to do just after one of the MAILxxxx variables has changed.  NAME
2684    is the name of the variable.  This is called with NAME set to one of
2685    MAIL, MAILCHECK, or MAILPATH.  */
2686 void
2687 sv_mail (name)
2688      char *name;
2689 {
2690   /* If the time interval for checking the files has changed, then
2691      reset the mail timer.  Otherwise, one of the pathname vars
2692      to the users mailbox has changed, so rebuild the array of
2693      filenames. */
2694   if (name[4] == 'C')  /* if (strcmp (name, "MAILCHECK") == 0) */
2695     reset_mail_timer ();
2696   else
2697     {
2698       free_mail_files ();
2699       remember_mail_dates ();
2700     }
2701 }
2702
2703 /* What to do when GLOBIGNORE changes. */
2704 void
2705 sv_globignore (name)
2706      char *name;
2707 {
2708   setup_glob_ignore (name);
2709 }
2710
2711 #if defined (READLINE)
2712 /* What to do just after one of the TERMxxx variables has changed.
2713    If we are an interactive shell, then try to reset the terminal
2714    information in readline. */
2715 void
2716 sv_terminal (name)
2717      char *name;
2718 {
2719   if (interactive_shell && no_line_editing == 0)
2720     rl_reset_terminal (get_string_value ("TERM"));
2721 }
2722
2723 void
2724 sv_hostfile (name)
2725      char *name;
2726 {
2727   hostname_list_initialized = 0;
2728 }
2729 #endif /* READLINE */
2730
2731 #if defined (HISTORY)
2732 /* What to do after the HISTSIZE or HISTFILESIZE variables change.
2733    If there is a value for this HISTSIZE (and it is numeric), then stifle
2734    the history.  Otherwise, if there is NO value for this variable,
2735    unstifle the history.  If name is HISTFILESIZE, and its value is
2736    numeric, truncate the history file to hold no more than that many
2737    lines. */
2738 void
2739 sv_histsize (name)
2740      char *name;
2741 {
2742   char *temp;
2743   long num;
2744
2745   temp = get_string_value (name);
2746
2747   if (temp && *temp)
2748     {
2749       if (legal_number (temp, &num))
2750         {
2751           if (name[4] == 'S')
2752             {
2753               stifle_history (num);
2754               num = where_history ();
2755               if (history_lines_this_session > num)
2756                 history_lines_this_session = num;
2757             }
2758           else
2759             {
2760               history_truncate_file (get_string_value ("HISTFILE"), (int)num);
2761               if (num <= history_lines_in_file)
2762                 history_lines_in_file = num;
2763             }
2764         }
2765     }
2766   else if (name[4] == 'S')
2767     unstifle_history ();
2768 }
2769
2770 /* What to do after the HISTIGNORE variable changes. */
2771 void
2772 sv_histignore (name)
2773      char *name;
2774 {
2775   setup_history_ignore (name);
2776 }
2777
2778 /* What to do after the HISTCONTROL variable changes. */
2779 void
2780 sv_history_control (name)
2781      char *name;
2782 {
2783   char *temp;
2784
2785   history_control = 0;
2786   temp = get_string_value (name);
2787
2788   if (temp && *temp && STREQN (temp, "ignore", 6))
2789     {
2790       if (temp[6] == 's')       /* ignorespace */
2791         history_control = 1;
2792       else if (temp[6] == 'd')  /* ignoredups */
2793         history_control = 2;
2794       else if (temp[6] == 'b')  /* ignoreboth */
2795         history_control = 3;
2796     }
2797 }
2798
2799 #if defined (BANG_HISTORY)
2800 /* Setting/unsetting of the history expansion character. */
2801 void
2802 sv_histchars (name)
2803      char *name;
2804 {
2805   char *temp;
2806
2807   temp = get_string_value (name);
2808   if (temp)
2809     {
2810       history_expansion_char = *temp;
2811       if (temp[0] && temp[1])
2812         {
2813           history_subst_char = temp[1];
2814           if (temp[2])
2815               history_comment_char = temp[2];
2816         }
2817     }
2818   else
2819     {
2820       history_expansion_char = '!';
2821       history_subst_char = '^';
2822       history_comment_char = '#';
2823     }
2824 }
2825 #endif /* BANG_HISTORY */
2826 #endif /* HISTORY */
2827
2828 #if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE)
2829 void
2830 sv_tz (name)
2831      char *name;
2832 {
2833   tzset ();
2834 }
2835 #endif
2836
2837 /* If the variable exists, then the value of it can be the number
2838    of times we actually ignore the EOF.  The default is small,
2839    (smaller than csh, anyway). */
2840 void
2841 sv_ignoreeof (name)
2842      char *name;
2843 {
2844   SHELL_VAR *tmp_var;
2845   char *temp;
2846
2847   eof_encountered = 0;
2848
2849   tmp_var = find_variable (name);
2850   ignoreeof = tmp_var != 0;
2851   temp = tmp_var ? value_cell (tmp_var) : (char *)NULL;
2852   if (temp)
2853     eof_encountered_limit = (*temp && all_digits (temp)) ? atoi (temp) : 10;
2854   set_shellopts ();     /* make sure `ignoreeof' is/is not in $SHELLOPTS */
2855 }
2856
2857 void
2858 sv_optind (name)
2859      char *name;
2860 {
2861   char *tt;
2862   int s;
2863
2864   tt = get_string_value ("OPTIND");
2865   if (tt && *tt)
2866     {
2867       s = atoi (tt);
2868
2869       /* According to POSIX, setting OPTIND=1 resets the internal state
2870          of getopt (). */
2871       if (s < 0 || s == 1)
2872         s = 0;
2873     }
2874   else
2875     s = 0;
2876   getopts_reset (s);
2877 }
2878
2879 void
2880 sv_opterr (name)
2881      char *name;
2882 {
2883   char *tt;
2884
2885   tt = get_string_value ("OPTERR");
2886   sh_opterr = (tt && *tt) ? atoi (tt) : 1;
2887 }
2888
2889 void
2890 sv_strict_posix (name)
2891      char *name;
2892 {
2893   SET_INT_VAR (name, posixly_correct);
2894   posix_initialize (posixly_correct);
2895 #if defined (READLINE)
2896   if (interactive_shell)
2897     posix_readline_initialize (posixly_correct);
2898 #endif /* READLINE */
2899   set_shellopts ();     /* make sure `posix' is/is not in $SHELLOPTS */
2900 }
2901
2902 void
2903 sv_locale (name)
2904      char *name;
2905 {
2906   char *v;
2907
2908   v = get_string_value (name);
2909   if (name[0] == 'L' && name[1] == 'A') /* LANG */
2910     set_lang (name, v);
2911   else
2912     set_locale_var (name, v);           /* LC_*, TEXTDOMAIN* */
2913 }
2914
2915 #if defined (ARRAY_VARS)
2916 void
2917 set_pipestatus_array (ps)
2918      int *ps;
2919 {
2920   SHELL_VAR *v;
2921   ARRAY *a;
2922   register int i;
2923   char *t;
2924
2925   v = find_variable ("PIPESTATUS");
2926   if (v == 0)
2927     v = make_new_array_variable ("PIPESTATUS");
2928   if (array_p (v) == 0)
2929     return;             /* Do nothing if not an array variable. */
2930   a = array_cell (v);
2931   if (a)
2932     empty_array (a);
2933   for (i = 0; ps[i] != -1; i++)
2934     {
2935       t = itos (ps[i]);
2936       array_add_element (a, i, t);
2937       free (t);
2938     }
2939 }
2940 #endif
2941
2942 void
2943 set_pipestatus_from_exit (s)
2944      int s;
2945 {
2946 #if defined (ARRAY_VARS)
2947   static int v[2] = { 0, -1 };
2948
2949   v[0] = s;
2950   set_pipestatus_array (v);
2951 #endif
2952 }