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