Imported from ../bash-1.14.7.tar.gz.
[platform/upstream/bash.git] / variables.c
1 /* variables.c -- Functions for hacking shell variables. */
2
3 /* Copyright (C) 1987,1989 Free Software Foundation, Inc.
4
5    This file is part of GNU Bash, the Bourne Again SHell.
6
7    Bash is free software; you can redistribute it and/or modify it
8    under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 1, or (at your option)
10    any later version.
11
12    Bash is distributed in the hope that it will be useful, but WITHOUT
13    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15    License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with Bash; see the file COPYING.  If not, write to the Free
19    Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21 #include <stdio.h>
22 #include "bashtypes.h"
23 #include "posixstat.h"
24 #include <ctype.h>
25 #include <pwd.h>
26
27 #include "bashansi.h"
28 #include "shell.h"
29 #include "hash.h"
30 #include "flags.h"
31 #include "execute_cmd.h"
32
33 #include "builtins/common.h"
34 #include <tilde/tilde.h>
35
36 /* Variables used here and defined in other files. */
37 extern int posixly_correct;
38 extern int variable_context, line_number;
39 extern int interactive, interactive_shell, login_shell, shell_level;
40 extern int subshell_environment;
41 extern int build_version;
42 extern char *dist_version;
43 extern char *shell_name;
44 extern char *primary_prompt, *secondary_prompt;
45 extern Function *this_shell_builtin;
46 extern time_t shell_start_time;
47
48 /* The list of shell variables that the user has created, or that came from
49    the environment. */
50 HASH_TABLE *shell_variables = (HASH_TABLE *)NULL;
51
52 /* The list of shell functions that the user has created, or that came from
53    the environment. */
54 HASH_TABLE *shell_functions = (HASH_TABLE *)NULL;
55
56 /* The current variable context.  This is really a count of how deep into
57    executing functions we are. */
58 int variable_context = 0;
59
60 /* The array of shell assignments which are made only in the environment
61    for a single command. */
62 char **temporary_env = (char **)NULL;
63
64 /* The array of shell assignments which are in the environment for the
65    execution of a shell function. */
66 char **function_env = (char **)NULL;
67
68 /* The array of shell assignments which are made only in the environment
69    for the execution of a shell builtin command which may cause more than
70    one command to be executed (e.g., "source"). */
71 char **builtin_env = (char **)NULL;
72
73 /* Some funky variables which are known about specially.  Here is where
74    "$*", "$1", and all the cruft is kept. */
75 char *dollar_vars[10];
76 WORD_LIST *rest_of_args = (WORD_LIST *)NULL;
77
78 /* The value of $$. */
79 int dollar_dollar_pid;
80
81 /* An array which is passed to commands as their environment.  It is
82    manufactured from the overlap of the initial environment and the
83    shell variables that are marked for export. */
84 char **export_env = (char **)NULL;
85
86 /* Non-zero means that we have to remake EXPORT_ENV. */
87 int array_needs_making = 1;
88
89 /* The list of variables that may not be unset in this shell. */
90 char **non_unsettable_vars = (char **)NULL;
91
92 static char *have_local_variables;              /* XXX */
93 static int local_variable_stack_size = 0;       /* XXX */
94
95 /* Some forward declarations. */
96 static void initialize_dynamic_variables ();
97 static void sbrand ();          /* set bash random number generator. */
98 static int qsort_var_comp ();
99
100 /* Make VAR be auto-exported.  VAR is a pointer to a SHELL_VAR. */
101 #define set_auto_export(var) \
102   do { var->attributes |= att_exported; array_needs_making = 1; } while (0)
103
104 #if defined (HISTORY)
105 #  include "bashhist.h"
106 #endif /* HISTORY */
107
108 /* Initialize the shell variables from the current environment. */
109 void
110 initialize_shell_variables (env)
111      char **env;
112 {
113   char *name, *string, *current_dir;
114   int c, char_index;
115   int string_index = 0;
116   SHELL_VAR *temp_var;
117
118   if (!shell_variables)
119     shell_variables = make_hash_table (0);
120
121   if (!shell_functions)
122     shell_functions = make_hash_table (0);
123
124   while (string = env[string_index++])
125     {
126       int string_length;
127
128       char_index = 0;
129
130       string_length = strlen (string);
131       name = xmalloc (1 + string_length);
132
133       while ((c = *string++) && c != '=')
134         name[char_index++] = c;
135
136       name[char_index] = '\0';
137
138       /* If exported function, define it now. */
139       if (!privileged_mode && STREQN ("() {", string, 4))
140         {
141           SHELL_VAR *f;
142           char *eval_string;
143
144           eval_string = xmalloc (3 + string_length + strlen (name));
145           sprintf (eval_string, "%s %s", name, string);
146
147           parse_and_execute (eval_string, name, 0);
148
149           if (name[char_index - 1] == ')')
150             name[char_index - 2] = '\0';
151
152           if (f = find_function (name))
153             {
154               f->attributes |= (att_exported | att_imported);
155               array_needs_making = 1;
156             }
157           else
158             report_error ("error importing function definition for `%s'", name);
159         }
160       else
161         {
162           SHELL_VAR *v;
163
164           v = bind_variable (name, string);
165           v->attributes |= (att_exported | att_imported);
166           array_needs_making = 1;
167         }
168       free (name);
169     }
170
171   /* If we got PWD from the environment, update our idea of the current
172      working directory.  In any case, make sure that PWD exists before
173      checking it.  It is possible for getwd () to fail on shell startup,
174      and in that case, PWD would be undefined. */
175   temp_var = find_variable ("PWD");
176   if (temp_var && imported_p (temp_var) &&
177       (current_dir = value_cell (temp_var)) &&
178       same_file (current_dir, ".", (struct stat *)NULL, (struct stat *)NULL))
179     set_working_directory (current_dir);
180   else
181     {
182       current_dir = get_working_directory ("shell-init");
183       if (current_dir)
184         {
185           bind_variable ("PWD", current_dir);
186           free (current_dir);
187         }
188     }
189
190   /* Remember this pid. */
191   dollar_dollar_pid = (int)getpid ();
192
193   /* Now make our own defaults in case the vars that we think are
194      important are missing. */
195   temp_var = set_if_not ("PATH", DEFAULT_PATH_VALUE);
196   set_auto_export (temp_var);
197
198   temp_var = set_if_not ("TERM", "dumb");
199   set_auto_export (temp_var);
200
201   if (interactive_shell)
202     {
203       set_if_not ("PS1", primary_prompt);
204       set_if_not ("PS2", secondary_prompt);
205     }
206   set_if_not ("PS4", "+ ");
207
208 #if defined (INSECURITY)
209   set_if_not ("IFS", " \t\n");
210 #else
211   bind_variable ("IFS", " \t\n");
212 #endif /* INSECURITY */
213
214   /* Magic machine types.  Pretty convenient. */
215   temp_var = set_if_not ("HOSTTYPE", HOSTTYPE);
216   set_auto_export (temp_var);
217   temp_var = set_if_not ("OSTYPE", OSTYPE);
218   set_auto_export (temp_var);
219
220   /* Default MAILCHECK for interactive shells. */
221   if (interactive_shell)
222     set_if_not ("MAILCHECK", "60");
223
224   /* Do some things with shell level. */
225   temp_var = set_if_not ("SHLVL", "0");
226   set_auto_export (temp_var);
227   adjust_shell_level (1);
228
229   /* Make a variable $PPID, which holds the pid of the shell's parent.  */
230   {
231     char *ppid;
232     SHELL_VAR *v;
233
234     ppid = itos ((int) getppid ());
235     v = find_variable ("PPID");
236
237     if (v)
238       v->attributes &= ~(att_readonly | att_exported);
239
240     v = bind_variable ("PPID", ppid);
241     v->attributes |= (att_readonly | att_integer);
242
243     non_unsettable ("PPID");
244     free (ppid);
245   }
246
247 #if defined (GETOPTS_BUILTIN)
248   /* Initialize the `getopts' stuff. */
249   bind_variable ("OPTIND", "1");
250   bind_variable ("OPTERR", "1");
251 #endif /* GETOPTS_BUILTIN */
252
253   /* Get the full pathname to THIS shell, and set the BASH variable
254      to it. */
255   {
256     char *tname;
257
258     if ((login_shell == 1) && (*shell_name != '/'))
259       {
260         /* If HOME doesn't exist, set it. */
261         temp_var = set_if_not ("HOME", current_user.home_dir);
262         temp_var->attributes |= att_exported;
263
264         name = savestring (current_user.shell);
265       }
266     else if (*shell_name == '/')
267       name = savestring (shell_name);
268     else
269       {
270         int s;
271
272         tname = find_user_command (shell_name);
273         if (tname == 0)
274           {
275             /* Try the current directory.  If there is not an executable
276                there, just punt and use the login shell. */
277             s = file_status (shell_name);
278             if (s & FS_EXECABLE)
279               {
280                 tname = make_absolute (shell_name, get_string_value ("PWD"));
281                 if (*shell_name == '.')
282                   {
283                     name = canonicalize_pathname (tname);
284                     free (tname);
285                   }
286                 else
287                   name = tname;
288               }
289             else
290               name = savestring (current_user.shell);
291           }
292         else
293           {
294             name = full_pathname (tname);
295             free (tname);
296           }
297       }
298
299     /* Make the exported environment variable SHELL be the user's login
300        shell.  Note that the `tset' command looks at this variable
301        to determine what style of commands to output; if it ends in "csh",
302        then C-shell commands are output, else Bourne shell commands. */
303     temp_var = set_if_not ("SHELL", current_user.shell);
304     set_auto_export (temp_var);
305
306     /* Make a variable called BASH, which is the name of THIS shell. */
307     temp_var = bind_variable ("BASH", name);
308
309     free (name);
310   }
311
312   /* Make a variable called BASH_VERSION which contains the version info. */
313   bind_variable ("BASH_VERSION", shell_version_string ());
314
315   /* Find out if we're supposed to be in Posix.2 mode via an
316      environment variable. */
317   temp_var = find_variable ("POSIXLY_CORRECT");
318   if (!temp_var)
319     temp_var = find_variable ("POSIX_PEDANTIC");
320   if (temp_var && imported_p (temp_var))
321     sv_strict_posix (temp_var->name);
322
323 #if defined (HISTORY)
324   /* Set history variables to defaults, and then do whatever we would
325      do if the variable had just been set.  Do this only in the case
326      that we are remembering commands on the history list. */
327   if (remember_on_history)
328     {
329       if (posixly_correct)
330         name = tilde_expand ("~/.sh_history");
331       else
332         name = tilde_expand ("~/.bash_history");
333
334       set_if_not ("HISTFILE", name);
335       free (name);
336
337       set_if_not ("HISTSIZE", "500");
338       sv_histsize ("HISTSIZE");
339     }
340 #endif /* HISTORY */
341
342   /* Seed the random number generator. */
343   sbrand (dollar_dollar_pid);
344
345   /* Handle some "special" variables that we may have inherited from a
346      parent shell. */
347
348   noclobber = find_variable ("noclobber") != (SHELL_VAR *)NULL;
349
350   temp_var = find_variable ("IGNOREEOF");
351   if (!temp_var)
352     temp_var = find_variable ("ignoreeof");
353   if (temp_var && imported_p (temp_var))
354     sv_ignoreeof (temp_var->name);
355
356 #if defined (HISTORY)
357   if (interactive_shell && remember_on_history)
358     {
359       sv_command_oriented_history ("command_oriented_history");
360       if (find_variable ("history_control"))
361         sv_history_control ("history_control"); /* gone in next release */
362       else
363         sv_history_control ("HISTCONTROL");
364     }
365 #endif /* HISTORY */
366
367   /* Initialize the dynamic variables, and seed their values. */
368   initialize_dynamic_variables ();
369
370   non_unsettable ("PATH");
371   non_unsettable ("IFS");
372
373   if (interactive_shell)
374     {
375       non_unsettable ("PS1");
376       non_unsettable ("PS2");
377     }
378
379   /* Get the users real user id, and save that in a readonly variable.
380      To make the variable *really* readonly, we have added it to a special
381      list of vars. */
382
383   sv_uids ();
384   set_var_read_only ("UID");
385   set_var_read_only ("EUID");
386
387   non_unsettable ("EUID");
388   non_unsettable ("UID");
389 }
390
391 void
392 adjust_shell_level (change)
393      int change;
394 {
395   char *new_level, *old_SHLVL;
396   int old_level;
397
398   old_SHLVL = get_string_value ("SHLVL");
399   if (old_SHLVL)
400     old_level = atoi (old_SHLVL);
401   else
402     old_level = 0;
403
404   shell_level = old_level + change;
405   if (shell_level < 0)
406     shell_level = 0;
407   new_level = itos (shell_level);
408   bind_variable ("SHLVL", new_level);
409   free (new_level);
410 }
411
412 /* Add NAME to the list of variables that cannot be unset
413    if it isn't already there. */
414 void
415 non_unsettable (name)
416      char *name;
417 {
418   register int i;
419
420   if (!non_unsettable_vars)
421     {
422       non_unsettable_vars = (char **)xmalloc (1 * sizeof (char *));
423       non_unsettable_vars[0] = (char *)NULL;
424     }
425
426   for (i = 0; non_unsettable_vars[i]; i++)
427     if (STREQ (non_unsettable_vars[i], name))
428       return;
429
430   non_unsettable_vars = (char **)
431     xrealloc (non_unsettable_vars, (2 + i) * sizeof (char *));
432   non_unsettable_vars[i] = savestring (name);
433   non_unsettable_vars[i + 1] = (char *)NULL;
434 }
435
436 /* Set NAME to VALUE if NAME has no value. */
437 SHELL_VAR *
438 set_if_not (name, value)
439      char *name, *value;
440 {
441   SHELL_VAR *v = find_variable (name);
442
443   if (!v)
444     v = bind_variable (name, value);
445   return (v);
446 }
447
448 /* Map FUNCTION over the variables in VARIABLES.  Return an array of the
449    variables that satisfy FUNCTION.  Satisfy means that FUNCTION returns
450    a non-zero value for.  A NULL value for FUNCTION means to use all
451    variables. */
452 SHELL_VAR **
453 map_over (function, var_hash_table)
454      Function *function;
455      HASH_TABLE* var_hash_table;
456 {
457   register int i;
458   register BUCKET_CONTENTS *tlist;
459   SHELL_VAR *var, **list = (SHELL_VAR **)NULL;
460   int list_index = 0, list_size = 0;
461
462   for (i = 0; i < var_hash_table->nbuckets; i++)
463     {
464       tlist = get_hash_bucket (i, var_hash_table);
465
466       while (tlist)
467         {
468           var = (SHELL_VAR *)tlist->data;
469
470           if (!function || (*function) (var))
471             {
472               if (list_index + 1 >= list_size)
473                 list = (SHELL_VAR **)
474                   xrealloc (list, (list_size += 20) * sizeof (SHELL_VAR *));
475
476               list[list_index++] = var;
477               list[list_index] = (SHELL_VAR *)NULL;
478             }
479           tlist = tlist->next;
480         }
481     }
482   return (list);
483 }
484
485 void
486 sort_variables (array)
487      SHELL_VAR **array;
488 {
489   qsort (array, array_len ((char **)array), sizeof (SHELL_VAR *), qsort_var_comp);
490 }
491
492 static int
493 qsort_var_comp (var1, var2)
494      SHELL_VAR **var1, **var2;
495 {
496   int result;
497
498   if ((result = (*var1)->name[0] - (*var2)->name[0]) == 0)
499     result = strcmp ((*var1)->name, (*var2)->name);
500
501   return (result);
502 }
503
504 /* Create a NULL terminated array of all the shell variables in TABLE. */
505 static SHELL_VAR **
506 all_vars (table)
507      HASH_TABLE *table;
508 {
509   SHELL_VAR **list;
510
511   list = map_over ((Function *)NULL, table);
512   if (list)
513     sort_variables (list);
514   return (list);
515 }
516
517 /* Create a NULL terminated array of all the shell variables. */
518 SHELL_VAR **
519 all_shell_variables ()
520 {
521   return (all_vars (shell_variables));
522 }
523
524 /* Create a NULL terminated array of all the shell functions. */
525 SHELL_VAR **
526 all_shell_functions ()
527 {
528   return (all_vars (shell_functions));
529 }
530
531 /* Print VARS to stdout in such a way that they can be read back in. */
532 void
533 print_var_list (list)
534      register SHELL_VAR **list;
535 {
536   register int i;
537   register SHELL_VAR *var;
538
539   for (i = 0; list && (var = list[i]); i++)
540     if (!invisible_p (var))
541       print_assignment (var);
542 }
543
544 #if defined (NOTDEF)
545 /* Print LIST (a linked list of shell variables) to stdout
546    by printing the names, without the values.  Used to support the
547    `set +' command. */
548 print_vars_no_values (list)
549      register SHELL_VAR **list;
550 {
551   register int i;
552   register SHELL_VAR *var;
553
554   for (i = 0; list && (var = list[i]); i++)
555     if (!invisible_p (var))
556       printf ("%s\n", var->name);
557 }
558 #endif
559
560 /* Print the value of a single SHELL_VAR.  No newline is
561    output, but the variable is printed in such a way that
562    it can be read back in. */
563 void
564 print_assignment (var)
565      SHELL_VAR *var;
566 {
567   if (function_p (var) && var->value)
568     {
569       printf ("%s=", var->name);
570       print_var_function (var);
571       printf ("\n");
572     }
573   else if (var->value)
574     {
575       printf ("%s=", var->name);
576       print_var_value (var);
577       printf ("\n");
578     }
579 }
580
581 /* Print the value cell of VAR, a shell variable.  Do not print
582    the name, nor leading/trailing newline. */
583 void
584 print_var_value (var)
585      SHELL_VAR *var;
586 {
587   if (var->value)
588     printf ("%s", var->value);
589 }
590
591 /* Print the function cell of VAR, a shell variable.  Do not
592    print the name, nor leading/trailing newline. */
593 void
594 print_var_function (var)
595      SHELL_VAR *var;
596 {
597   if (function_p (var) && var->value)
598     printf ("%s", named_function_string ((char *)NULL, function_cell(var), 1));
599 }
600
601 /* **************************************************************** */
602 /*                                                                  */
603 /*                 Dynamic Variable Extension                       */
604 /*                                                                  */
605 /* **************************************************************** */
606
607 /* DYNAMIC VARIABLES
608    
609    These are variables whose values are generated anew each time they are
610    referenced.  These are implemented using a pair of function pointers
611    in the struct variable: assign_func, which is called from bind_variable,
612    and dynamic_value, which is called from find_variable.
613    
614    assign_func is called from bind_variable, if bind_variable discovers
615    that the variable being assigned to has such a function.  The function
616    is called as
617         SHELL_VAR *temp = (*(entry->assign_func)) (entry, value)
618    and the (SHELL_VAR *)temp is returned as the value of bind_variable.  It
619    is usually ENTRY (self).
620    
621    dynamic_value is called from find_variable to return a `new' value for
622    the specified dynamic varible.  If this function is NULL, the variable
623    is treated as a `normal' shell variable.  If it is not, however, then
624    this function is called like this:
625         tempvar = (*(var->dynamic_value)) (var);
626    
627    Sometimes `tempvar' will replace the value of `var'.  Other times, the
628    shell will simply use the string value.  Pretty object-oriented, huh?
629    
630    Be warned, though: if you `unset' a special variable, it loses its
631    special meaning, even if you subsequently set it.
632    
633    The special assignment code would probably have been better put in
634    subst.c: do_assignment, in the same style as
635    stupidly_hack_special_variables, but I wanted the changes as
636    localized as possible.  */
637
638 /* The value of $SECONDS.  This is the number of seconds since shell
639    invocation, or, the number of seconds since the last assignment + the
640    value of the last assignment. */
641 static long seconds_value_assigned = (long)0;
642
643 static SHELL_VAR *
644 assign_seconds (self, value)
645      SHELL_VAR *self;
646      char *value;
647 {
648   seconds_value_assigned = atol (value);
649   shell_start_time = NOW;
650   return (self);
651 }
652
653 static SHELL_VAR *
654 get_seconds (var)
655      SHELL_VAR *var;
656 {
657   time_t time_since_start;
658   char *p;
659
660   time_since_start = NOW - shell_start_time;
661   p = itos((int) seconds_value_assigned + time_since_start);
662
663   FREE (var->value);
664
665   var->attributes |= att_integer;
666   var->value = p;
667   return (var);
668 }
669
670 /* The random number seed.  You can change this by setting RANDOM. */
671 static unsigned long rseed = 1;
672
673 /* A linear congruential random number generator based on the ANSI
674    C standard.  A more complicated one is overkill.  */
675
676 /* Returns a pseudo-random number between 0 and 32767. */
677 static int
678 brand ()
679 {
680   rseed = rseed * 1103515245 + 12345;
681   return ((unsigned int)(rseed / 65536) % 32768);
682 }
683
684 /* Set the random number generator seed to SEED. */
685 static void
686 sbrand (seed)
687      int seed;
688 {
689   rseed = seed;
690 }
691
692 static SHELL_VAR *
693 assign_random (self, value)
694      SHELL_VAR *self;
695      char *value;
696 {
697   int s = atoi (value);
698
699   sbrand (s);
700   return (self);
701 }
702
703 static SHELL_VAR *
704 get_random (var)
705      SHELL_VAR *var;
706 {
707   int rv;
708   char *p;
709
710   rv = brand ();
711   p = itos ((int)rv);
712
713   FREE (var->value);
714
715   var->attributes |= att_integer;
716   var->value = p;
717   return (var);
718 }
719
720 /* Function which returns the current line number. */
721 static SHELL_VAR *
722 get_lineno (var)
723      SHELL_VAR *var;
724 {
725   char *p;
726
727   p = itos (line_number);
728   FREE (var->value);
729   var->value = p;
730   return (var);
731 }
732
733 #if defined (HISTORY)
734 static SHELL_VAR *
735 get_histcmd (var)
736      SHELL_VAR *var;
737 {
738   char *p;
739
740   p = itos (history_number ());
741   FREE (var->value);
742   var->value = p;
743   return (var);
744 }
745 #endif
746
747 static void
748 initialize_dynamic_variables ()
749 {
750   SHELL_VAR *v;
751
752   v = bind_variable ("SECONDS", (char *)NULL);
753   v->dynamic_value = get_seconds;
754   v->assign_func = assign_seconds;
755
756   v = bind_variable ("RANDOM", (char *)NULL);
757   v->dynamic_value = get_random;
758   v->assign_func = assign_random;
759
760   v = bind_variable ("LINENO", (char *)NULL);
761   v->dynamic_value = get_lineno;
762   v->assign_func = (DYNAMIC_FUNC *)NULL;
763
764 #if defined (HISTORY)
765   v = bind_variable ("HISTCMD", (char *)NULL);
766   v->dynamic_value = get_histcmd;
767   v->assign_func = (DYNAMIC_FUNC *)NULL;
768 #endif
769 }
770
771 /* How to get a pointer to the shell variable or function named NAME.
772    HASHED_VARS is a pointer to the hash table containing the list
773    of interest (either variables or functions). */
774 SHELL_VAR *
775 var_lookup (name, hashed_vars)
776      char *name;
777      HASH_TABLE *hashed_vars;
778 {
779   BUCKET_CONTENTS *bucket;
780
781   bucket = find_hash_item (name, hashed_vars);
782
783   if (bucket)
784     return ((SHELL_VAR *)bucket->data);
785   else
786     return ((SHELL_VAR *)NULL);
787 }
788
789 /* Look up the variable entry named NAME.  If SEARCH_TEMPENV is non-zero,
790    then also search the temporarily built list of exported variables. */
791 SHELL_VAR *
792 find_variable_internal (name, search_tempenv)
793      char *name;
794      int search_tempenv;
795 {
796   SHELL_VAR *var = (SHELL_VAR *)NULL;
797
798   /* If explicitly requested, first look in the temporary environment for
799      the variable.  This allows constructs such as "foo=x eval 'echo $foo'"
800      to get the `exported' value of $foo.  This happens if we are executing
801      a function or builtin, or if we are looking up a variable in a
802      "subshell environment". */
803   if ((search_tempenv || subshell_environment) &&
804       (temporary_env || builtin_env || function_env))
805     var = find_tempenv_variable (name);
806
807   if (!var)
808     var = var_lookup (name, shell_variables);
809
810   if (!var)
811     return ((SHELL_VAR *)NULL);
812
813   if (var->dynamic_value)
814     return ((*(var->dynamic_value)) (var));
815   else
816     return (var);
817 }
818
819 /* Look up the variable entry named NAME.  Returns the entry or NULL. */
820 SHELL_VAR *
821 find_variable (name)
822      char *name;
823 {
824   return (find_variable_internal
825           (name, (variable_context || this_shell_builtin || builtin_env)));
826 }
827
828 /* Look up the function entry whose name matches STRING.
829    Returns the entry or NULL. */
830 SHELL_VAR *
831 find_function (name)
832      char *name;
833 {
834   return (var_lookup (name, shell_functions));
835 }
836
837 /* Return the string value of a variable.  Return NULL if the variable
838    doesn't exist, or only has a function as a value.  Don't cons a new
839    string. */
840 char *
841 get_string_value (var_name)
842      char *var_name;
843 {
844   SHELL_VAR *var = find_variable (var_name);
845
846   if (!var)
847     return (char *)NULL;
848   else
849     return (var->value);
850 }
851
852 /* Create a local variable referenced by NAME. */
853 SHELL_VAR *
854 make_local_variable (name)
855      char *name;
856 {
857   SHELL_VAR *new_var, *old_var;
858   BUCKET_CONTENTS *elt;
859
860   /* local foo; local foo;  is a no-op. */
861   old_var = find_variable (name);
862   if (old_var && old_var->context == variable_context)
863     return (old_var);
864
865   elt = remove_hash_item (name, shell_variables);
866   if (elt)
867     {
868       old_var = (SHELL_VAR *)elt->data;
869       free (elt->key);
870       free (elt);
871     }
872   else
873     old_var = (SHELL_VAR *)NULL;
874
875   /* If a variable does not already exist with this name, then
876      just make a new one. */
877   if (!old_var)
878     {
879       new_var = bind_variable (name, "");
880     }
881   else
882     {
883       new_var = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
884
885       new_var->name = savestring (name);
886       new_var->value = savestring ("");
887
888       new_var->dynamic_value = (DYNAMIC_FUNC *)NULL;
889       new_var->assign_func = (DYNAMIC_FUNC *)NULL;
890
891       new_var->attributes = 0;
892
893       if (exported_p (old_var))
894         new_var->attributes |= att_exported;
895
896       new_var->prev_context = old_var;
897       elt = add_hash_item (savestring (name), shell_variables);
898       elt->data = (char *)new_var;
899     }
900
901   new_var->context = variable_context;
902
903   /* XXX */
904   if (local_variable_stack_size <= variable_context)
905     {
906       int old_size = local_variable_stack_size;
907       while (local_variable_stack_size <= variable_context)
908         local_variable_stack_size += 8;
909       have_local_variables =
910         xrealloc (have_local_variables, local_variable_stack_size);
911       bzero ((char *)have_local_variables + old_size,
912              local_variable_stack_size - old_size);
913     }
914   have_local_variables[variable_context] = 1;           /* XXX */
915
916   return (new_var);
917 }
918
919 /* Bind a variable NAME to VALUE.  This conses up the name
920    and value strings. */
921 SHELL_VAR *
922 bind_variable (name, value)
923      char *name, *value;
924 {
925   SHELL_VAR *entry = var_lookup (name, shell_variables);
926   BUCKET_CONTENTS *elt;
927
928   if (!entry)
929     {
930       /* Make a new entry for this variable.  Then do the binding. */
931       entry = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
932
933       entry->attributes = 0;
934       entry->name = savestring (name);
935
936       if (value)
937         {
938           if (*value)
939             entry->value = savestring (value);
940           else
941             {
942               entry->value = xmalloc (1);
943               entry->value[0] = '\0';
944             }
945         }
946       else
947         entry->value = (char *)NULL;
948
949       entry->dynamic_value = (DYNAMIC_FUNC *)NULL;
950       entry->assign_func = (DYNAMIC_FUNC *)NULL;
951
952       /* Always assume variables are to be made at toplevel!
953          make_local_variable has the responsibilty of changing the
954          variable context. */
955       entry->context = 0;
956       entry->prev_context = (SHELL_VAR *)NULL;
957
958       elt = add_hash_item (savestring (name), shell_variables);
959       elt->data = (char *)entry;
960     }
961   else if (entry->assign_func)
962     return ((*(entry->assign_func)) (entry, value));
963   else
964     {
965       if (readonly_p (entry))
966         {
967           report_error ("%s: read-only variable", name);
968           return (entry);
969         }
970
971       /* Variables which are bound are visible. */
972       entry->attributes &= ~att_invisible;
973
974       /* If this variable has had its type set to integer (via `declare -i'),
975          then do expression evaluation on it and store the result.  The
976          functions in expr.c (evalexp and bind_int_variable) are responsible
977          for turning off the integer flag if they don't want further
978          evaluation done. */
979       if (integer_p (entry))
980         {
981           long val;
982
983           val = evalexp (value);
984           /* We cannot free () entry->value before this; what if the string
985              we are working is `even=even+2'?  We need the original value
986              around while we are doing the evaluation to handle any possible
987              recursion. */
988           FREE (entry->value);
989           entry->value = itos (val);
990         }
991       else
992         {
993           FREE (entry->value);
994
995           if (value)
996             {
997               if (*value)
998                 entry->value = savestring (value);
999               else
1000                 {
1001                   entry->value = xmalloc (1);
1002                   entry->value[0] = '\0';
1003                 }
1004             }
1005           else
1006             entry->value = (char *)NULL;
1007         }
1008     }
1009
1010   if (mark_modified_vars)
1011     entry->attributes |= att_exported;
1012
1013   if (exported_p (entry))
1014     array_needs_making = 1;
1015
1016   return (entry);
1017 }
1018
1019 /* Dispose of the information attached to VAR. */
1020 void
1021 dispose_variable (var)
1022      SHELL_VAR *var;
1023 {
1024   if (!var)
1025     return;
1026
1027   if (function_p (var))
1028     dispose_command ((COMMAND *)var->value);
1029   else if (var->value)
1030     free (var->value);
1031
1032   free (var->name);
1033
1034   if (exported_p (var))
1035     array_needs_making = 1;
1036
1037   free (var);
1038 }
1039
1040 /* Unset the variable referenced by NAME. */
1041 unbind_variable (name)
1042      char *name;
1043 {
1044   SHELL_VAR *var = find_variable (name);
1045
1046   if (!var)
1047     return (-1);
1048
1049   if (var->value)
1050     {
1051       free (var->value);
1052       var->value = (char *)NULL;
1053     }
1054
1055   makunbound (name, shell_variables);
1056
1057   return (0);
1058 }
1059
1060 /* Make the variable associated with NAME go away.  HASH_LIST is the
1061    hash table from which this variable should be deleted (either
1062    shell_variables or shell_functions).
1063    Returns non-zero if the variable couldn't be found. */
1064 makunbound (name, hash_list)
1065      char *name;
1066      HASH_TABLE *hash_list;
1067 {
1068   BUCKET_CONTENTS *elt;
1069   SHELL_VAR *old_var, *new_var;
1070   char *t;
1071
1072   elt = remove_hash_item (name, hash_list);
1073
1074   if (!elt)
1075     return (-1);
1076
1077   old_var = (SHELL_VAR *)elt->data;
1078   new_var = old_var->prev_context;
1079
1080   if (old_var && exported_p (old_var))
1081     array_needs_making++;
1082
1083   if (new_var)
1084     {
1085       /* Has to be a variable, functions don't have previous contexts. */
1086       BUCKET_CONTENTS *new_elt;
1087
1088       new_elt = add_hash_item (savestring (new_var->name), hash_list);
1089       new_elt->data = (char *)new_var;
1090
1091       if (exported_p (new_var))
1092         set_var_auto_export (new_var->name);
1093     }
1094
1095   /* Have to save a copy of name here, because it might refer to
1096      old_var->name.  If so, stupidly_hack_special_variables will
1097      reference freed memory. */
1098   t = savestring (name);
1099
1100   free (elt->key);
1101   free (elt);
1102
1103   dispose_variable (old_var);
1104   stupidly_hack_special_variables (t);
1105   free (t);
1106   return (0);
1107 }
1108
1109 /* Remove the variable with NAME if it is a local variable in the
1110    current context. */
1111 kill_local_variable (name)
1112      char *name;
1113 {
1114   SHELL_VAR *temp = find_variable (name);
1115
1116   if (temp && (temp->context == variable_context))
1117     {
1118       makunbound (name, shell_variables);
1119       return (0);
1120     }
1121   return (-1);
1122 }
1123
1124 /* Get rid of all of the variables in the current context. */
1125 int
1126 variable_in_context (var)
1127      SHELL_VAR *var;
1128 {
1129   return (var && var->context == variable_context);
1130 }
1131
1132 void
1133 kill_all_local_variables ()
1134 {
1135   register int i, pass;
1136   register SHELL_VAR *var, **list;
1137   HASH_TABLE *varlist;
1138
1139   /* XXX */
1140   if (!have_local_variables || have_local_variables[variable_context] == 0)
1141     return;
1142
1143   for (pass = 0; pass < 2; pass++)
1144     {
1145       varlist = pass ? shell_functions : shell_variables;
1146
1147       list = map_over (variable_in_context, varlist);
1148
1149       if (list)
1150         {
1151           for (i = 0; var = list[i]; i++)
1152             makunbound (var->name, varlist);
1153
1154           free (list);
1155         }
1156     }
1157
1158   have_local_variables[variable_context] = 0;           /* XXX */
1159 }
1160
1161 /* Delete the entire contents of the hash table. */
1162 void
1163 delete_all_variables (hashed_vars)
1164      HASH_TABLE *hashed_vars;
1165 {
1166   register int i;
1167   register BUCKET_CONTENTS *bucket;
1168
1169   for (i = 0; i < hashed_vars->nbuckets; i++)
1170     {
1171       bucket = hashed_vars->bucket_array[i];
1172
1173       while (bucket)
1174         {
1175           BUCKET_CONTENTS *temp = bucket;
1176           SHELL_VAR *var, *prev;
1177
1178           bucket = bucket->next;
1179
1180           var = (SHELL_VAR *)temp->data;
1181
1182           while (var)
1183             {
1184               prev = var->prev_context;
1185               dispose_variable (var);
1186
1187               var = prev;
1188             }
1189
1190           free (temp->key);
1191           free (temp);
1192         }
1193       hashed_vars->bucket_array[i] = (BUCKET_CONTENTS *)NULL;
1194     }
1195 }
1196
1197 static SHELL_VAR *
1198 new_shell_variable (name)
1199      char *name;
1200 {
1201   SHELL_VAR *var;
1202
1203   var = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
1204
1205   bzero ((char *)var, sizeof (SHELL_VAR));
1206   var->name = savestring (name);
1207   return (var);
1208 }
1209
1210 /* Do a function binding to a variable.  You pass the name and
1211    the command to bind to.  This conses the name and command. */
1212 SHELL_VAR *
1213 bind_function (name, value)
1214      char *name;
1215      COMMAND *value;
1216 {
1217   SHELL_VAR *entry = find_function (name);
1218
1219   if (!entry)
1220     {
1221       BUCKET_CONTENTS *elt;
1222
1223       elt = add_hash_item (savestring (name), shell_functions);
1224
1225       elt->data = (char *)new_shell_variable (name);
1226       entry = (SHELL_VAR *)elt->data;
1227       entry->dynamic_value = (DYNAMIC_FUNC *)NULL;
1228       entry->assign_func = (DYNAMIC_FUNC *)NULL;
1229
1230       /* Functions are always made at the top level.  This allows a
1231          function to define another function (like autoload). */
1232       entry->context = 0;
1233     }
1234
1235   if (entry->value)
1236     dispose_command ((COMMAND *)entry->value);
1237
1238   if (value)    /* I don't think this can happen anymore */
1239     entry->value = (char *)copy_command (value);
1240   else
1241     entry->value = (char *)NULL;
1242
1243   entry->attributes |= att_function;
1244
1245   if (mark_modified_vars)
1246     entry->attributes |= att_exported;
1247
1248   entry->attributes &= ~att_invisible;  /* Just to be sure */
1249
1250   array_needs_making = 1;
1251
1252   return (entry);
1253 }
1254
1255 /* Copy VAR to a new data structure and return that structure. */
1256 SHELL_VAR *
1257 copy_variable (var)
1258      SHELL_VAR *var;
1259 {
1260   SHELL_VAR *copy = (SHELL_VAR *)NULL;
1261
1262   if (var)
1263     {
1264       copy = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
1265
1266       copy->attributes = var->attributes;
1267       copy->name = savestring (var->name);
1268
1269       if (function_p (var))
1270         copy->value = (char *)copy_command ((COMMAND *)var->value);
1271       else if (var->value)
1272         copy->value = savestring (var->value);
1273       else
1274         copy->value = (char *)NULL;
1275
1276       copy->dynamic_value = var->dynamic_value;
1277       copy->assign_func = var->assign_func;
1278
1279       copy->context = var->context;
1280
1281       /* Don't bother copying previous contexts along with this variable. */
1282       copy->prev_context = (SHELL_VAR *)NULL;
1283     }
1284   return (copy);
1285 }
1286
1287 /* Make the variable associated with NAME be read-only.
1288    If NAME does not exist yet, create it. */
1289 void
1290 set_var_read_only (name)
1291      char *name;
1292 {
1293   SHELL_VAR *entry = find_variable (name);
1294
1295   if (!entry)
1296     {
1297       entry = bind_variable (name, "");
1298       if (!no_invisible_vars)
1299         entry->attributes |= att_invisible;
1300     }
1301   entry->attributes |= att_readonly;
1302 }
1303
1304 /* Make the function associated with NAME be read-only.
1305    If NAME does not exist, we just punt, like auto_export code below. */
1306 void
1307 set_func_read_only (name)
1308      char *name;
1309 {
1310   SHELL_VAR *entry = find_function (name);
1311
1312   if (entry)
1313     entry->attributes |= att_readonly;
1314 }
1315
1316 /* Make the variable associated with NAME be auto-exported.
1317    If NAME does not exist yet, create it. */
1318 void
1319 set_var_auto_export (name)
1320      char *name;
1321 {
1322   SHELL_VAR *entry = find_variable (name);
1323
1324   if (!entry)
1325     {
1326       entry = bind_variable (name, "");
1327       if (!no_invisible_vars)
1328         entry->attributes |= att_invisible;
1329     }
1330
1331   set_auto_export (entry);
1332 }
1333
1334 /* Make the function associated with NAME be auto-exported. */
1335 void
1336 set_func_auto_export (name)
1337      char *name;
1338 {
1339   SHELL_VAR *entry = find_function (name);
1340
1341   if (entry)
1342     {
1343       entry->attributes |= att_exported;
1344       array_needs_making = 1;
1345     }
1346 }
1347
1348 /* Returns non-zero if STRING is an assignment statement.  The returned value
1349    is the index of the `=' sign. */
1350 assignment (string)
1351      char *string;
1352 {
1353   register int c, indx = 0;
1354
1355   c = string[indx];
1356
1357   if (!isletter (c) && c != '_')
1358     return (0);
1359
1360   while (c = string[indx])
1361     {
1362       /* The following is safe.  Note that '=' at the start of a word
1363          is not an assignment statement. */
1364       if (c == '=')
1365         return (indx);
1366
1367       if (!isletter (c) && !digit (c) && c != '_')
1368         return (0);
1369
1370       indx++;
1371     }
1372   return (0);
1373 }
1374
1375 static int
1376 visible_var (var)
1377      SHELL_VAR *var;
1378 {
1379   return (!invisible_p (var));
1380 }
1381
1382 SHELL_VAR **
1383 all_visible_variables ()
1384 {
1385   SHELL_VAR **list;
1386
1387   list = map_over (visible_var, shell_variables);
1388
1389   if (list)
1390     sort_variables (list);
1391
1392   return (list);
1393 }
1394
1395 SHELL_VAR **
1396 all_visible_functions ()
1397 {
1398   SHELL_VAR **list;
1399
1400   list = map_over (visible_var, shell_functions);
1401
1402   if (list)
1403     sort_variables (list);
1404
1405   return (list);
1406 }
1407
1408 /* Return non-zero if the variable VAR is visible and exported. */
1409 static int
1410 visible_and_exported (var)
1411      SHELL_VAR *var;
1412 {
1413   return (!invisible_p (var) && exported_p (var));
1414 }
1415
1416 /* Make an array of assignment statements from the hash table
1417    HASHED_VARS which contains SHELL_VARs.  Only visible, exported
1418    variables are eligible. */
1419 char **
1420 make_var_array (hashed_vars)
1421      HASH_TABLE *hashed_vars;
1422 {
1423   register int i, list_index;
1424   register SHELL_VAR *var;
1425   char **list = (char **)NULL;
1426   SHELL_VAR **vars;
1427
1428   vars = map_over (visible_and_exported, hashed_vars);
1429
1430   if (!vars)
1431     return (char **)NULL;
1432
1433   list = (char **)xmalloc ((1 + array_len ((char **)vars)) * sizeof (char *));
1434
1435   for (i = 0, list_index = 0; var = vars[i]; i++)
1436     {
1437       char *value;
1438
1439       if (function_p (var))
1440         value = named_function_string
1441           ((char *)NULL, (COMMAND *)function_cell (var), 0);
1442       else
1443         value = value_cell (var);
1444
1445       if (value)
1446         {
1447           int name_len = strlen (var->name);
1448           int value_len = strlen (value);
1449           char  *p;
1450
1451           p = list[list_index] = xmalloc (2 + name_len + value_len);
1452           strcpy (p, var->name);
1453           p[name_len] = '=';
1454           strcpy (p + name_len + 1, value);
1455           list_index++;
1456         }
1457     }
1458
1459   free (vars);
1460   list[list_index] = (char *)NULL;
1461   return (list);
1462 }
1463
1464 /* Add STRING to the array of foo=bar strings that we already
1465    have to add to the environment.  */
1466 assign_in_env (string)
1467      char *string;
1468 {
1469   int size;
1470
1471   int offset = assignment (string);
1472   char *name = savestring (string);
1473   char *temp, *value = (char *)NULL;
1474   int nlen, vlen;
1475
1476   if (name[offset] == '=')
1477     {
1478       WORD_LIST *list;
1479
1480       name[offset] = 0;
1481       temp = name + offset + 1;
1482       temp = tilde_expand (temp);
1483
1484       list = expand_string_unsplit (temp, 0);
1485       value = string_list (list);
1486
1487       if (list)
1488         dispose_words (list);
1489
1490       free (temp);
1491     }
1492
1493   if (!value)
1494     value = savestring ("");
1495
1496   nlen = strlen (name);
1497   vlen = strlen (value);
1498   temp = xmalloc (2 + nlen + vlen);
1499   strcpy (temp, name);
1500   temp[nlen] = '=';
1501   strcpy (temp + nlen + 1, value);
1502   free (name);
1503   free (value);
1504
1505   if (!temporary_env)
1506     {
1507       temporary_env = (char **)xmalloc (sizeof (char *));
1508       temporary_env [0] = (char *)NULL;
1509     }
1510
1511   size = array_len (temporary_env);
1512   temporary_env = (char **)
1513     xrealloc (temporary_env, (size + 2) * (sizeof (char *)));
1514
1515   temporary_env[size] = (temp);
1516   temporary_env[size + 1] = (char *)NULL;
1517   array_needs_making = 1;
1518
1519   if (echo_command_at_execute)
1520     {
1521       /* The K*rn shell prints the `+ ' in front of assignment statements,
1522          so we do too. */
1523       fprintf (stderr, "%s%s\n", indirection_level_string (), temp);
1524       fflush (stderr);
1525     }
1526
1527   return 1;
1528 }
1529
1530 /* Search for NAME in ARRAY, an array of strings in the same format as the
1531    environment array (i.e, name=value).  If NAME is present, make a new
1532    variable and return it.  Otherwise, return NULL. */
1533 static SHELL_VAR *
1534 find_name_in_env_array (name, array)
1535      char *name;
1536      char **array;
1537 {
1538   register int i, l = strlen (name);
1539
1540   if (!array)
1541     return ((SHELL_VAR *)NULL);
1542
1543   for (i = 0; array[i]; i++)
1544     {
1545       if (STREQN (array[i], name, l) && array[i][l] == '=')
1546         {
1547           SHELL_VAR *temp;
1548
1549           temp = new_shell_variable (name);
1550
1551           if (array[i][l + 1])
1552             temp->value = savestring (&array[i][l + 1]);
1553           else
1554             temp->value = (char *) NULL;
1555
1556           temp->attributes = att_exported;
1557           temp->context = 0;
1558           temp->prev_context = (SHELL_VAR *)NULL;
1559
1560           temp->dynamic_value = (DYNAMIC_FUNC *)NULL;
1561           temp->assign_func = (DYNAMIC_FUNC *)NULL;
1562
1563           return (temp);
1564         }
1565     }
1566   return ((SHELL_VAR *)NULL);
1567 }
1568
1569 /* Find a variable in the temporary environment that is named NAME.
1570    The temporary environment can be either the environment provided
1571    to a simple command, or the environment provided to a shell function.
1572    We only search the function environment if we are currently executing
1573    a shell function body (variable_context > 0).  Return a consed variable,
1574    or NULL if not found. */
1575 SHELL_VAR *
1576 find_tempenv_variable (name)
1577      char *name;
1578 {
1579   SHELL_VAR *var = (SHELL_VAR *)NULL;
1580
1581   if (temporary_env)
1582     var = find_name_in_env_array (name, temporary_env);
1583
1584   /* We don't check this_shell_builtin because the command that needs the
1585      value from builtin_env may be a disk command run inside a script run
1586      with `.' and a temporary env. */
1587   if (!var && builtin_env)
1588     var = find_name_in_env_array (name, builtin_env);
1589
1590   if (!var && variable_context && function_env)
1591     var = find_name_in_env_array (name, function_env);
1592
1593   return (var);
1594 }
1595
1596 /* Free the storage allocated to the string array pointed to by ARRAYP, and
1597    make that variable have a null pointer as a value. */
1598 static void
1599 dispose_temporary_vars (arrayp)
1600      char ***arrayp;
1601 {
1602   if (!*arrayp)
1603     return;
1604
1605   free_array (*arrayp);
1606   *arrayp = (char **)NULL;
1607   array_needs_making = 1;
1608 }
1609
1610 /* Free the storage used in the variable array for temporary
1611    environment variables. */
1612 void
1613 dispose_used_env_vars ()
1614 {
1615   dispose_temporary_vars (&temporary_env);
1616 }
1617
1618 /* Free the storage used for temporary environment variables given to
1619    commands when executing inside of a function body. */
1620 void
1621 dispose_function_env ()
1622 {
1623   dispose_temporary_vars (&function_env);
1624 }
1625
1626 /* Free the storage used for temporary environment variables given to
1627    commands when executing a builtin command such as "source". */
1628 void
1629 dispose_builtin_env ()
1630 {
1631   dispose_temporary_vars (&builtin_env);
1632 }
1633
1634 /* Sort ARRAY, a null terminated array of pointers to strings. */
1635 void
1636 sort_char_array (array)
1637      char **array;
1638 {
1639   qsort (array, array_len (array), sizeof (char *),
1640          (Function *)qsort_string_compare);
1641 }
1642
1643 #define ISFUNC(s, o) ((s[o + 1] == '(')  && (s[o + 2] == ')'))
1644
1645 /* Add ASSIGN to ARRAY, or supercede a previous assignment in the
1646    array with the same left-hand side.  Return the new array. */
1647 char **
1648 add_or_supercede (assign, array)
1649      char *assign;
1650      register char **array;
1651 {
1652   register int i;
1653   int equal_offset = assignment (assign);
1654
1655   if (!equal_offset)
1656     return (array);
1657
1658   /* If this is a function, then only supercede the function definition.
1659      We do this by including the `=(' in the comparison.  */
1660   if (assign[equal_offset + 1] == '(')
1661     equal_offset++;
1662
1663   for (i = 0; array && array[i]; i++)
1664     {
1665       if (STREQN (assign, array[i], equal_offset + 1))
1666         {
1667           free (array[i]);
1668           array[i] = savestring (assign);
1669           return (array);
1670         }
1671     }
1672   array = (char **)xrealloc (array, ((2 + i) * sizeof (char *)));
1673   array[i++] = savestring (assign);
1674   array[i] = (char *)NULL;
1675   return (array);
1676 }
1677
1678 /* Make the environment array for the command about to be executed.  If the
1679    array needs making.  Otherwise, do nothing.  If a shell action could
1680    change the array that commands receive for their environment, then the
1681    code should `array_needs_making++'. */
1682 void
1683 maybe_make_export_env ()
1684 {
1685   register int i;
1686   register char **temp_array;
1687
1688   if (array_needs_making)
1689     {
1690       if (export_env)
1691         free_array (export_env);
1692
1693 #ifdef SHADOWED_ENV
1694       export_env =
1695         (char **)xmalloc ((1 + array_len (shell_environment)) * sizeof (char *));
1696
1697       for (i = 0; shell_environment[i]; i++)
1698         export_env[i] = savestring (shell_environment[i]);
1699       export_env[i] = (char *)NULL;
1700
1701 #else /* !SHADOWED_ENV */
1702
1703       export_env = (char **)xmalloc (sizeof (char *));
1704       export_env[0] = (char *)NULL;
1705
1706 #endif /* SHADOWED_ENV */
1707
1708       temp_array = make_var_array (shell_variables);
1709       for (i = 0; temp_array && temp_array[i]; i++)
1710         export_env = add_or_supercede (temp_array[i], export_env);
1711       free_array (temp_array);
1712
1713       temp_array = make_var_array (shell_functions);
1714       for (i = 0; temp_array && temp_array[i]; i++)
1715         export_env = add_or_supercede (temp_array[i], export_env);
1716       free_array (temp_array);
1717
1718       if (function_env)
1719         for (i = 0; function_env[i]; i++)
1720           export_env = add_or_supercede (function_env[i], export_env);
1721
1722       if (temporary_env)
1723         for (i = 0; temporary_env[i]; i++)
1724           export_env = add_or_supercede (temporary_env[i], export_env);
1725
1726       /* If we changed the array, then sort it alphabetically. */
1727       if (temporary_env || function_env)
1728         sort_char_array (export_env);
1729
1730       array_needs_making = 0;
1731     }
1732 }
1733
1734 /* We always put _ in the environment as the name of this command. */
1735 void
1736 put_command_name_into_env (command_name)
1737      char *command_name;
1738 {
1739   char *dummy;
1740
1741   dummy = xmalloc (4 + strlen (command_name));
1742
1743   /* These three statements replace a call to sprintf */
1744   dummy[0] = '_';
1745   dummy[1] = '=';
1746   strcpy (dummy + 2, command_name);
1747   export_env = add_or_supercede (dummy, export_env);
1748   free (dummy);
1749 }
1750
1751 /* We supply our own version of getenv () because we want library
1752    routines to get the changed values of exported variables. */
1753
1754 /* The NeXT C library has getenv () defined and used in the same file.
1755    This screws our scheme.  However, Bash will run on the NeXT using
1756    the C library getenv (), since right now the only environment variable
1757    that we care about is HOME, and that is already defined.  */
1758 #if !defined (NeXT) && !defined (HPOSF1)
1759 static char *last_tempenv_value = (char *)NULL;
1760 extern char **environ;
1761
1762 char *
1763 getenv (name)
1764 #if defined (Linux) || defined (__bsdi__) || defined (convex)
1765      const char *name;
1766 #else
1767      char const *name;
1768 #endif /* !Linux */
1769 {
1770   SHELL_VAR *var = find_tempenv_variable ((char *)name);
1771
1772   if (var)
1773     {
1774       FREE (last_tempenv_value);
1775
1776       last_tempenv_value = savestring (value_cell (var));
1777       dispose_variable (var);
1778       return (last_tempenv_value);
1779     }
1780   else if (shell_variables)
1781     {
1782       var = find_variable ((char *)name);
1783       if (var && exported_p (var))
1784         return (value_cell (var));
1785     }
1786   else
1787     {
1788       register int i, len = strlen (name);
1789
1790       /* In some cases, s5r3 invokes getenv() before main(); BSD systems
1791          using gprof also exhibit this behavior.  This means that
1792          shell_variables will be 0 when this is invoked.  We look up the
1793          variable in the real environment in that case. */
1794
1795       for (i = 0; environ[i]; i++)
1796         {
1797           if ((STREQN (environ[i], name, len)) && (environ[i][len] == '='))
1798             return (environ[i] + len + 1);
1799         }
1800     }
1801
1802   return ((char *)NULL);
1803 }
1804 #endif /* !NeXT && !HPOSF1 */