1 /* variables.c -- Functions for hacking shell variables. */
3 /* Copyright (C) 1987,1989 Free Software Foundation, Inc.
5 This file is part of GNU Bash, the Bourne Again SHell.
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)
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.
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. */
23 #include "bashtypes.h"
24 #include "posixstat.h"
30 #if defined (HAVE_UNISTD_H)
41 #include "execute_cmd.h"
42 #include "mailcheck.h"
45 #include "builtins/getopt.h"
46 #include "builtins/common.h"
47 #include <tilde/tilde.h>
50 # include "bashhist.h"
53 /* Variables used here and defined in other files. */
54 extern int posixly_correct
;
55 extern int variable_context
, line_number
;
56 extern int interactive
, interactive_shell
, login_shell
;
57 extern int subshell_environment
, indirection_level
;
58 extern int build_version
, patch_level
;
59 extern char *dist_version
, *release_status
;
60 extern char *shell_name
;
61 extern char *primary_prompt
, *secondary_prompt
;
62 extern char *current_host_name
;
63 extern Function
*this_shell_builtin
;
64 extern char *this_command_name
;
65 extern time_t shell_start_time
;
67 /* The list of shell variables that the user has created, or that came from
69 HASH_TABLE
*shell_variables
= (HASH_TABLE
*)NULL
;
71 /* The list of shell functions that the user has created, or that came from
73 HASH_TABLE
*shell_functions
= (HASH_TABLE
*)NULL
;
75 /* The current variable context. This is really a count of how deep into
76 executing functions we are. */
77 int variable_context
= 0;
79 /* The array of shell assignments which are made only in the environment
80 for a single command. */
81 char **temporary_env
= (char **)NULL
;
83 /* The array of shell assignments which are in the environment for the
84 execution of a shell function. */
85 char **function_env
= (char **)NULL
;
87 /* The array of shell assignments which are made only in the environment
88 for the execution of a shell builtin command which may cause more than
89 one command to be executed (e.g., "source"). */
90 char **builtin_env
= (char **)NULL
;
92 /* Some funky variables which are known about specially. Here is where
93 "$*", "$1", and all the cruft is kept. */
94 char *dollar_vars
[10];
95 WORD_LIST
*rest_of_args
= (WORD_LIST
*)NULL
;
97 /* The value of $$. */
98 int dollar_dollar_pid
;
100 /* An array which is passed to commands as their environment. It is
101 manufactured from the union of the initial environment and the
102 shell variables that are marked for export. */
103 char **export_env
= (char **)NULL
;
104 static int export_env_index
;
105 static int export_env_size
;
107 /* Non-zero means that we have to remake EXPORT_ENV. */
108 int array_needs_making
= 1;
110 /* The number of times BASH has been executed. This is set
111 by initialize_variables (). */
114 static char *have_local_variables
;
115 static int local_variable_stack_size
;
117 /* Some forward declarations. */
118 static void set_home_var ();
119 static void set_shell_var ();
120 static char *get_bash_name ();
121 static void initialize_shell_level ();
122 static void uidset ();
123 static void initialize_dynamic_variables ();
124 static void make_vers_array ();
125 static void sbrand (); /* set bash random number generator. */
126 static int qsort_var_comp ();
128 /* Make VAR be auto-exported. VAR is a pointer to a SHELL_VAR. */
129 #define set_auto_export(var) \
130 do { var->attributes |= att_exported; array_needs_making = 1; } while (0)
132 /* Initialize the shell variables from the current environment. */
134 initialize_shell_variables (env
, no_functions
)
136 int no_functions
; /* If set, don't import functions from ENV. */
138 char *name
, *string
, *temp_string
;
139 int c
, char_index
, string_index
, string_length
;
142 if (!shell_variables
)
143 shell_variables
= make_hash_table (0);
145 if (!shell_functions
)
146 shell_functions
= make_hash_table (0);
148 for (string_index
= 0; string
= env
[string_index
++]; )
152 while ((c
= *string
++) && c
!= '=')
154 if (string
[-1] == '=')
155 char_index
= string
- name
- 1;
157 /* If there are weird things in the environment, like `=xxx' or a
158 string without an `=', just skip them. */
162 /* ASSERT(name[char_index] == '=') */
163 name
[char_index
] = '\0';
164 /* Now, name = env variable name, string = env variable value, and
165 char_index == strlen (name) */
167 /* If exported function, define it now. */
168 if (no_functions
== 0 && STREQN ("() {", string
, 4))
170 string_length
= strlen (string
);
171 temp_string
= xmalloc (3 + string_length
+ char_index
);
173 strcpy (temp_string
, name
);
174 temp_string
[char_index
] = ' ';
175 strcpy (temp_string
+ char_index
+ 1, string
);
177 sprintf (temp_string
, "%s %s", name
, string
);
180 parse_and_execute (temp_string
, name
, SEVAL_NONINT
|SEVAL_NOHIST
);
182 /* Ancient backwards compatibility. Old versions of bash exported
183 functions like name()=() {...} */
184 if (name
[char_index
- 1] == ')' && name
[char_index
- 2] == '(')
185 name
[char_index
- 2] = '\0';
187 if (temp_var
= find_function (name
))
189 temp_var
->attributes
|= (att_exported
| att_imported
);
190 array_needs_making
= 1;
193 report_error ("error importing function definition for `%s'", name
);
195 if (name
[char_index
- 1] == ')' && name
[char_index
- 2] == '\0')
196 name
[char_index
- 2] = '(';
198 #if defined (ARRAY_VARS)
200 /* Array variables may not yet be exported. */
201 else if (*string
== '(' && string
[1] == '[' && strchr (string
, ')'))
204 temp_string
= extract_array_assignment_list (string
, &string_length
);
205 temp_var
= assign_array_from_string (name
, temp_string
);
207 temp_var
->attributes
|= (att_exported
| att_imported
);
208 array_needs_making
= 1;
214 temp_var
= bind_variable (name
, string
);
215 temp_var
->attributes
|= (att_exported
| att_imported
);
216 array_needs_making
= 1;
219 name
[char_index
] = '=';
222 /* If we got PWD from the environment, update our idea of the current
223 working directory. In any case, make sure that PWD exists before
224 checking it. It is possible for getcwd () to fail on shell startup,
225 and in that case, PWD would be undefined. */
226 temp_var
= find_variable ("PWD");
227 if (temp_var
&& imported_p (temp_var
) &&
228 (temp_string
= value_cell (temp_var
)) &&
229 same_file (temp_string
, ".", (struct stat
*)NULL
, (struct stat
*)NULL
))
230 set_working_directory (temp_string
);
233 temp_string
= get_working_directory ("shell-init");
236 bind_variable ("PWD", temp_string
);
241 /* Set up initial value of $_ */
242 temp_var
= bind_variable ("_", dollar_vars
[0]);
244 /* Remember this pid. */
245 dollar_dollar_pid
= (int)getpid ();
247 /* Now make our own defaults in case the vars that we think are
248 important are missing. */
249 temp_var
= set_if_not ("PATH", DEFAULT_PATH_VALUE
);
250 set_auto_export (temp_var
);
252 temp_var
= set_if_not ("TERM", "dumb");
253 set_auto_export (temp_var
);
256 /* set node id -- don't import it from the environment */
259 qnx_nidtostr (getnid (), node_name
, sizeof (node_name
));
260 temp_var
= bind_variable ("NODE", node_name
);
261 set_auto_export (temp_var
);
265 /* set up the prompts. */
266 if (interactive_shell
)
268 set_if_not ("PS1", primary_prompt
);
269 set_if_not ("PS2", secondary_prompt
);
271 set_if_not ("PS4", "+ ");
273 /* Don't allow IFS to be imported from the environment. */
274 temp_var
= bind_variable ("IFS", " \t\n");
276 /* Magic machine types. Pretty convenient. */
277 temp_var
= bind_variable ("HOSTTYPE", HOSTTYPE
);
278 set_auto_export (temp_var
);
279 temp_var
= bind_variable ("OSTYPE", OSTYPE
);
280 set_auto_export (temp_var
);
281 temp_var
= bind_variable ("MACHTYPE", MACHTYPE
);
282 set_auto_export (temp_var
);
283 temp_var
= bind_variable ("HOSTNAME", current_host_name
);
284 set_auto_export (temp_var
);
286 /* Default MAILCHECK for interactive shells. Defer the creation of a
287 default MAILPATH until the startup files are read, because MAIL
288 names a mail file if MAILCHECK is not set, and we should provide a
289 default only if neither is set. */
290 if (interactive_shell
)
291 set_if_not ("MAILCHECK", "60");
293 /* Do some things with shell level. */
294 initialize_shell_level ();
296 /* Make a variable $PPID, which holds the pid of the shell's parent. */
297 name
= itos ((int) getppid ());
298 temp_var
= find_variable ("PPID");
300 temp_var
->attributes
&= ~(att_readonly
| att_exported
);
301 temp_var
= bind_variable ("PPID", name
);
302 temp_var
->attributes
|= (att_readonly
| att_integer
);
305 /* Initialize the `getopts' stuff. */
306 bind_variable ("OPTIND", "1");
308 bind_variable ("OPTERR", "1");
311 if (login_shell
== 1)
314 /* Get the full pathname to THIS shell, and set the BASH variable
316 name
= get_bash_name ();
317 temp_var
= bind_variable ("BASH", name
);
320 /* Make the exported environment variable SHELL be the user's login
321 shell. Note that the `tset' command looks at this variable
322 to determine what style of commands to output; if it ends in "csh",
323 then C-shell commands are output, else Bourne shell commands. */
326 /* Make a variable called BASH_VERSION which contains the version info. */
327 bind_variable ("BASH_VERSION", shell_version_string ());
328 #if defined (ARRAY_VARS)
332 /* Find out if we're supposed to be in Posix.2 mode via an
333 environment variable. */
334 temp_var
= find_variable ("POSIXLY_CORRECT");
336 temp_var
= find_variable ("POSIX_PEDANTIC");
337 if (temp_var
&& imported_p (temp_var
))
338 sv_strict_posix (temp_var
->name
);
340 #if defined (HISTORY)
341 /* Set history variables to defaults, and then do whatever we would
342 do if the variable had just been set. Do this only in the case
343 that we are remembering commands on the history list. */
344 if (remember_on_history
)
346 name
= bash_tilde_expand (posixly_correct
? "~/.sh_history" : "~/.bash_history");
348 set_if_not ("HISTFILE", name
);
351 set_if_not ("HISTSIZE", "500");
352 sv_histsize ("HISTSIZE");
356 /* Seed the random number generator. */
357 sbrand (dollar_dollar_pid
+ (long)shell_start_time
);
359 /* Handle some "special" variables that we may have inherited from a
361 if (interactive_shell
)
363 temp_var
= find_variable ("IGNOREEOF");
365 temp_var
= find_variable ("ignoreeof");
366 if (temp_var
&& imported_p (temp_var
))
367 sv_ignoreeof (temp_var
->name
);
370 #if defined (HISTORY)
371 if (interactive_shell
&& remember_on_history
)
373 sv_history_control ("HISTCONTROL");
374 sv_histignore ("HISTIGNORE");
378 /* Get the user's real and effective user ids. */
381 /* Initialize the dynamic variables, and seed their values. */
382 initialize_dynamic_variables ();
385 /* Set $HOME to the information in the password file if we didn't get
386 it from the environment. */
392 temp_var
= find_variable ("HOME");
395 if (current_user
.home_dir
== 0)
396 get_current_user_info ();
397 temp_var
= bind_variable ("HOME", current_user
.home_dir
);
399 temp_var
->attributes
|= att_exported
;
402 /* Set $SHELL to the user's login shell if it is not already set. Call
403 get_current_user_info if we haven't already fetched the shell. */
409 temp_var
= find_variable ("SHELL");
412 if (current_user
.shell
== 0)
413 get_current_user_info ();
414 temp_var
= bind_variable ("SHELL", current_user
.shell
);
416 temp_var
->attributes
|= att_exported
;
424 if ((login_shell
== 1) && (*shell_name
!= '/'))
426 if (current_user
.shell
== 0)
427 get_current_user_info ();
428 name
= savestring (current_user
.shell
);
430 else if (*shell_name
== '/')
431 name
= savestring (shell_name
);
432 else if (shell_name
[0] == '.' && shell_name
[1] == '/')
434 /* Fast path for common case. */
438 cdir
= get_string_value ("PWD");
440 name
= xmalloc (len
+ strlen (shell_name
) + 1);
442 strcpy (name
+ len
, shell_name
+ 1);
449 tname
= find_user_command (shell_name
);
453 /* Try the current directory. If there is not an executable
454 there, just punt and use the login shell. */
455 s
= file_status (shell_name
);
458 tname
= make_absolute (shell_name
, get_string_value ("PWD"));
459 if (*shell_name
== '.')
461 name
= canonicalize_pathname (tname
);
472 if (current_user
.shell
== 0)
473 get_current_user_info ();
474 name
= savestring (current_user
.shell
);
479 name
= full_pathname (tname
);
488 adjust_shell_level (change
)
491 char new_level
[5], *old_SHLVL
;
495 old_SHLVL
= get_string_value ("SHLVL");
496 old_level
= old_SHLVL
? atoi (old_SHLVL
) : 0;
498 shell_level
= old_level
+ change
;
501 else if (shell_level
> 1000)
503 internal_error ("warning: shell level (%d) too high, resetting to 1", shell_level
);
507 /* We don't need the full generality of itos here. */
508 if (shell_level
< 10)
510 new_level
[0] = shell_level
+ '0';
513 else if (shell_level
< 100)
515 new_level
[0] = (shell_level
/ 10) + '0';
516 new_level
[1] = (shell_level
% 10) + '0';
519 else if (shell_level
< 1000)
521 new_level
[0] = (shell_level
/ 100) + '0';
522 old_level
= shell_level
% 100;
523 new_level
[1] = (old_level
/ 10) + '0';
524 new_level
[2] = (old_level
% 10) + '0';
528 temp_var
= bind_variable ("SHLVL", new_level
);
529 set_auto_export (temp_var
);
533 initialize_shell_level ()
538 temp_var
= set_if_not ("SHLVL", "0");
539 set_auto_export (temp_var
);
541 adjust_shell_level (1);
548 register SHELL_VAR
*v
;
550 buff
= itos (current_user
.uid
);
551 v
= find_variable ("UID");
553 v
->attributes
&= ~att_readonly
;
555 v
= bind_variable ("UID", buff
);
556 v
->attributes
|= (att_readonly
| att_integer
);
558 if (current_user
.euid
!= current_user
.uid
)
561 buff
= itos (current_user
.euid
);
564 v
= find_variable ("EUID");
566 v
->attributes
&= ~att_readonly
;
568 v
= bind_variable ("EUID", buff
);
569 v
->attributes
|= (att_readonly
| att_integer
);
573 #if defined (ARRAY_VARS)
581 makunbound ("BASH_VERSINFO", shell_variables
);
583 vv
= make_new_array_variable ("BASH_VERSINFO");
584 av
= array_cell (vv
);
585 strcpy (d
, dist_version
);
589 array_add_element (av
, 0, d
);
590 array_add_element (av
, 1, s
);
591 s
= itos (patch_level
);
592 array_add_element (av
, 2, s
);
594 s
= itos (build_version
);
595 array_add_element (av
, 3, s
);
597 array_add_element (av
, 4, release_status
);
598 array_add_element (av
, 5, MACHTYPE
);
600 vv
->attributes
|= att_readonly
;
602 #endif /* ARRAY_VARS */
604 /* Set the environment variables $LINES and $COLUMNS in response to
605 a window size change. */
607 set_lines_and_columns (lines
, cols
)
613 bind_variable ("LINES", val
);
617 bind_variable ("COLUMNS", val
);
621 /* Set NAME to VALUE if NAME has no value. */
623 set_if_not (name
, value
)
628 v
= find_variable (name
);
630 v
= bind_variable (name
, value
);
634 /* Map FUNCTION over the variables in VARIABLES. Return an array of the
635 variables for which FUNCTION returns a non-zero value. A NULL value
636 for FUNCTION means to use all variables. */
638 map_over (function
, var_hash_table
)
640 HASH_TABLE
* var_hash_table
;
643 register BUCKET_CONTENTS
*tlist
;
644 SHELL_VAR
*var
, **list
;
645 int list_index
, list_size
;
647 list
= (SHELL_VAR
**)NULL
;
648 for (i
= list_index
= list_size
= 0; i
< var_hash_table
->nbuckets
; i
++)
650 tlist
= get_hash_bucket (i
, var_hash_table
);
654 var
= (SHELL_VAR
*)tlist
->data
;
656 if (!function
|| (*function
) (var
))
658 if (list_index
+ 1 >= list_size
)
659 list
= (SHELL_VAR
**)
660 xrealloc (list
, (list_size
+= 20) * sizeof (SHELL_VAR
*));
662 list
[list_index
++] = var
;
663 list
[list_index
] = (SHELL_VAR
*)NULL
;
672 sort_variables (array
)
675 qsort (array
, array_len ((char **)array
), sizeof (SHELL_VAR
*), qsort_var_comp
);
679 qsort_var_comp (var1
, var2
)
680 SHELL_VAR
**var1
, **var2
;
684 if ((result
= (*var1
)->name
[0] - (*var2
)->name
[0]) == 0)
685 result
= strcmp ((*var1
)->name
, (*var2
)->name
);
690 /* Create a NULL terminated array of all the shell variables in TABLE. */
697 list
= map_over ((Function
*)NULL
, table
);
698 if (list
/* && posixly_correct */)
699 sort_variables (list
);
703 /* Create a NULL terminated array of all the shell variables. */
705 all_shell_variables ()
707 return (all_vars (shell_variables
));
710 /* Create a NULL terminated array of all the shell functions. */
712 all_shell_functions ()
714 return (all_vars (shell_functions
));
717 /* Print VARS to stdout in such a way that they can be read back in. */
719 print_var_list (list
)
720 register SHELL_VAR
**list
;
723 register SHELL_VAR
*var
;
725 for (i
= 0; list
&& (var
= list
[i
]); i
++)
726 if (!invisible_p (var
))
727 print_assignment (var
);
731 /* Print LIST (a linked list of shell variables) to stdout
732 by printing the names, without the values. Used to support the
735 print_vars_no_values (list
)
736 register SHELL_VAR
**list
;
739 register SHELL_VAR
*var
;
741 for (i
= 0; list
&& (var
= list
[i
]); i
++)
742 if (!invisible_p (var
))
743 printf ("%s\n", var
->name
);
747 /* Print the value of a single SHELL_VAR. No newline is
748 output, but the variable is printed in such a way that
749 it can be read back in. */
751 print_assignment (var
)
754 if (function_p (var
) && var
->value
)
756 printf ("%s=", var
->name
);
757 print_var_function (var
);
760 #if defined (ARRAY_VARS)
761 else if (array_p (var
) && var
->value
)
762 print_array_assignment (var
, 0);
763 #endif /* ARRAY_VARS */
766 printf ("%s=", var
->name
);
767 print_var_value (var
, 1);
772 /* Print the value cell of VAR, a shell variable. Do not print
773 the name, nor leading/trailing newline. If QUOTE is non-zero,
774 and the value contains shell metacharacters, quote the value
775 in such a way that it can be read back in. */
777 print_var_value (var
, quote
)
785 if (quote
&& contains_shell_metas (var
->value
))
787 t
= single_quote (var
->value
);
792 printf ("%s", var
->value
);
796 /* Print the function cell of VAR, a shell variable. Do not
797 print the name, nor leading/trailing newline. */
799 print_var_function (var
)
802 if (function_p (var
) && var
->value
)
803 printf ("%s", named_function_string ((char *)NULL
, function_cell(var
), 1));
806 #if defined (ARRAY_VARS)
808 print_array_assignment (var
, quoted
)
815 vstr
= quoted_array_assignment_string (array_cell (var
));
817 vstr
= array_to_assignment_string (array_cell (var
));
820 printf ("%s=%s\n", var
->name
, quoted
? "'()'" : "()");
823 printf ("%s=%s\n", var
->name
, vstr
);
827 #endif /* ARRAY_VARS */
829 /* **************************************************************** */
831 /* Dynamic Variable Extension */
833 /* **************************************************************** */
837 These are variables whose values are generated anew each time they are
838 referenced. These are implemented using a pair of function pointers
839 in the struct variable: assign_func, which is called from bind_variable,
840 and dynamic_value, which is called from find_variable.
842 assign_func is called from bind_variable, if bind_variable discovers
843 that the variable being assigned to has such a function. The function
845 SHELL_VAR *temp = (*(entry->assign_func)) (entry, value)
846 and the (SHELL_VAR *)temp is returned as the value of bind_variable. It
847 is usually ENTRY (self).
849 dynamic_value is called from find_variable to return a `new' value for
850 the specified dynamic varible. If this function is NULL, the variable
851 is treated as a `normal' shell variable. If it is not, however, then
852 this function is called like this:
853 tempvar = (*(var->dynamic_value)) (var);
855 Sometimes `tempvar' will replace the value of `var'. Other times, the
856 shell will simply use the string value. Pretty object-oriented, huh?
858 Be warned, though: if you `unset' a special variable, it loses its
859 special meaning, even if you subsequently set it.
861 The special assignment code would probably have been better put in
862 subst.c: do_assignment, in the same style as
863 stupidly_hack_special_variables, but I wanted the changes as
864 localized as possible. */
866 /* The value of $SECONDS. This is the number of seconds since shell
867 invocation, or, the number of seconds since the last assignment + the
868 value of the last assignment. */
869 static long seconds_value_assigned
;
872 assign_seconds (self
, value
)
876 seconds_value_assigned
= string_to_long (value
);
877 shell_start_time
= NOW
;
885 time_t time_since_start
;
888 time_since_start
= NOW
- shell_start_time
;
889 p
= itos((int) seconds_value_assigned
+ time_since_start
);
893 var
->attributes
|= att_integer
;
898 /* The random number seed. You can change this by setting RANDOM. */
899 static unsigned long rseed
= 1;
900 static unsigned long last_random_value
;
902 /* A linear congruential random number generator based on the ANSI
903 C standard. A more complicated one is overkill. */
905 /* Returns a pseudo-random number between 0 and 32767. */
909 rseed
= rseed
* 1103515245 + 12345;
911 return ((unsigned int)(rseed
/ 65536) % 32768);
913 return ((unsigned int)(rseed
% 32768));
917 /* Set the random number generator seed to SEED. */
923 last_random_value
= 0;
927 assign_random (self
, value
)
931 sbrand (atoi (value
));
942 /* Reset for command and process substitution. */
943 if (subshell_environment
)
944 sbrand (rseed
+ (int)(getpid() + NOW
));
948 while (rv
== (int)last_random_value
);
950 last_random_value
= rv
;
955 var
->attributes
|= att_integer
;
960 /* Function which returns the current line number. */
968 ln
= executing_line_number ();
976 assign_lineno (var
, value
)
980 line_number
= atoi (value
);
984 #if defined (HISTORY)
991 p
= itos (history_number ());
998 #if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
1006 l
= get_directory_stack ();
1007 a
= word_list_to_array (l
);
1008 dispose_array (array_cell (self
));
1010 self
->value
= (char *)a
;
1015 assign_dirstack (self
, ind
, value
)
1020 set_dirstack_element (ind
, 1, value
);
1023 #endif /* PUSHD AND POPD && ARRAY_VARS */
1025 #if defined (ARRAY_VARS)
1026 /* We don't want to initialize the group set with a call to getgroups()
1027 unless we're asked to, but we only want to do it once. */
1035 static char **group_set
= (char **)NULL
;
1039 group_set
= get_group_list (&ng
);
1040 a
= array_cell (self
);
1041 for (i
= 0; i
< ng
; i
++)
1042 array_add_element (a
, i
, group_set
[i
]);
1046 #endif /* ARRAY_VARS */
1049 initialize_dynamic_variables ()
1053 v
= bind_variable ("SECONDS", (char *)NULL
);
1054 v
->dynamic_value
= get_seconds
;
1055 v
->assign_func
= assign_seconds
;
1057 v
= bind_variable ("RANDOM", (char *)NULL
);
1058 v
->dynamic_value
= get_random
;
1059 v
->assign_func
= assign_random
;
1061 v
= bind_variable ("LINENO", (char *)NULL
);
1062 v
->dynamic_value
= get_lineno
;
1063 v
->assign_func
= assign_lineno
;
1065 #if defined (HISTORY)
1066 v
= bind_variable ("HISTCMD", (char *)NULL
);
1067 v
->dynamic_value
= get_histcmd
;
1068 v
->assign_func
= (DYNAMIC_FUNC
*)NULL
;
1071 #if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
1072 v
= make_new_array_variable ("DIRSTACK");
1073 v
->dynamic_value
= get_dirstack
;
1074 v
->assign_func
= assign_dirstack
;
1075 #endif /* PUSHD_AND_POPD && ARRAY_VARS */
1077 #if defined (ARRAY_VARS)
1078 v
= make_new_array_variable ("GROUPS");
1079 v
->dynamic_value
= get_groupset
;
1080 v
->assign_func
= (DYNAMIC_FUNC
*)NULL
;
1081 v
->attributes
|= att_readonly
;
1085 /* How to get a pointer to the shell variable or function named NAME.
1086 HASHED_VARS is a pointer to the hash table containing the list
1087 of interest (either variables or functions). */
1089 var_lookup (name
, hashed_vars
)
1091 HASH_TABLE
*hashed_vars
;
1093 BUCKET_CONTENTS
*bucket
;
1095 bucket
= find_hash_item (name
, hashed_vars
);
1096 return (bucket
? (SHELL_VAR
*)bucket
->data
: (SHELL_VAR
*)NULL
);
1099 /* Look up the variable entry named NAME. If SEARCH_TEMPENV is non-zero,
1100 then also search the temporarily built list of exported variables. */
1102 find_variable_internal (name
, search_tempenv
)
1106 SHELL_VAR
*var
= (SHELL_VAR
*)NULL
;
1108 /* If explicitly requested, first look in the temporary environment for
1109 the variable. This allows constructs such as "foo=x eval 'echo $foo'"
1110 to get the `exported' value of $foo. This happens if we are executing
1111 a function or builtin, or if we are looking up a variable in a
1112 "subshell environment". */
1113 if ((search_tempenv
|| subshell_environment
) &&
1114 (temporary_env
|| builtin_env
|| function_env
))
1115 var
= find_tempenv_variable (name
);
1118 var
= var_lookup (name
, shell_variables
);
1121 return ((SHELL_VAR
*)NULL
);
1123 return (var
->dynamic_value
? (*(var
->dynamic_value
)) (var
) : var
);
1126 /* Look up the variable entry named NAME. Returns the entry or NULL. */
1128 find_variable (name
)
1131 return (find_variable_internal
1132 (name
, (variable_context
|| this_shell_builtin
|| builtin_env
)));
1135 /* Look up the function entry whose name matches STRING.
1136 Returns the entry or NULL. */
1138 find_function (name
)
1141 return (var_lookup (name
, shell_functions
));
1144 /* Return the string value of a variable. Return NULL if the variable
1145 doesn't exist, or only has a function as a value. Don't cons a new
1148 get_string_value (var_name
)
1153 var
= find_variable (var_name
);
1156 return (char *)NULL
;
1157 #if defined (ARRAY_VARS)
1158 else if (array_p (var
))
1159 return (array_reference (array_cell (var
), 0));
1162 return (var
->value
);
1165 /* Create a local variable referenced by NAME. */
1167 make_local_variable (name
)
1170 SHELL_VAR
*new_var
, *old_var
;
1171 BUCKET_CONTENTS
*elt
;
1173 /* local foo; local foo; is a no-op. */
1174 old_var
= find_variable (name
);
1175 if (old_var
&& old_var
->context
== variable_context
)
1178 elt
= remove_hash_item (name
, shell_variables
);
1181 old_var
= (SHELL_VAR
*)elt
->data
;
1186 old_var
= (SHELL_VAR
*)NULL
;
1188 /* If a variable does not already exist with this name, then
1189 just make a new one. */
1191 new_var
= bind_variable (name
, "");
1194 new_var
= (SHELL_VAR
*)xmalloc (sizeof (SHELL_VAR
));
1196 new_var
->name
= savestring (name
);
1197 new_var
->value
= xmalloc (1);
1198 new_var
->value
[0] = '\0';
1200 new_var
->dynamic_value
= (DYNAMIC_FUNC
*)NULL
;
1201 new_var
->assign_func
= (DYNAMIC_FUNC
*)NULL
;
1203 new_var
->attributes
= exported_p (old_var
) ? att_exported
: 0;
1205 new_var
->prev_context
= old_var
;
1206 elt
= add_hash_item (savestring (name
), shell_variables
);
1207 elt
->data
= (char *)new_var
;
1210 new_var
->context
= variable_context
;
1211 new_var
->attributes
|= att_local
;
1214 if (variable_context
>= local_variable_stack_size
)
1216 int old_size
= local_variable_stack_size
;
1217 RESIZE_MALLOCED_BUFFER (have_local_variables
, variable_context
, 1,
1218 local_variable_stack_size
, 8);
1219 bzero ((char *)have_local_variables
+ old_size
,
1220 local_variable_stack_size
- old_size
);
1222 have_local_variables
[variable_context
] = 1; /* XXX */
1227 #if defined (ARRAY_VARS)
1229 make_local_array_variable (name
)
1235 var
= make_local_variable (name
);
1236 array
= new_array ();
1238 FREE (value_cell(var
));
1239 var
->value
= (char *)array
;
1240 var
->attributes
|= att_array
;
1243 #endif /* ARRAY_VARS */
1245 /* Create a new shell variable with name NAME and add it to the hash table
1246 of shell variables. */
1249 make_new_variable (name
)
1253 BUCKET_CONTENTS
*elt
;
1255 entry
= (SHELL_VAR
*)xmalloc (sizeof (SHELL_VAR
));
1257 entry
->attributes
= 0;
1258 entry
->name
= savestring (name
);
1259 entry
->value
= (char *)NULL
;
1261 entry
->dynamic_value
= (DYNAMIC_FUNC
*)NULL
;
1262 entry
->assign_func
= (DYNAMIC_FUNC
*)NULL
;
1264 /* Always assume variables are to be made at toplevel!
1265 make_local_variable has the responsibilty of changing the
1266 variable context. */
1268 entry
->prev_context
= (SHELL_VAR
*)NULL
;
1270 elt
= add_hash_item (savestring (name
), shell_variables
);
1271 elt
->data
= (char *)entry
;
1276 #if defined (ARRAY_VARS)
1278 make_new_array_variable (name
)
1284 entry
= make_new_variable (name
);
1285 array
= new_array ();
1286 entry
->value
= (char *)array
;
1287 entry
->attributes
|= att_array
;
1293 make_variable_value (var
, value
)
1301 /* If this variable has had its type set to integer (via `declare -i'),
1302 then do expression evaluation on it and store the result. The
1303 functions in expr.c (evalexp and bind_int_variable) are responsible
1304 for turning off the integer flag if they don't want further
1306 if (integer_p (var
))
1308 lval
= evalexp (value
, &expok
);
1310 jump_to_top_level (DISCARD
);
1311 retval
= itos (lval
);
1316 retval
= savestring (value
);
1319 retval
= xmalloc (1);
1324 retval
= (char *)NULL
;
1329 /* Bind a variable NAME to VALUE. This conses up the name
1330 and value strings. */
1332 bind_variable (name
, value
)
1338 entry
= var_lookup (name
, shell_variables
);
1342 entry
= make_new_variable (name
);
1343 entry
->value
= make_variable_value (entry
, value
);
1345 #if defined (ARRAY_VARS)
1346 else if (entry
->assign_func
&& array_p (entry
) == 0)
1348 else if (entry
->assign_func
)
1350 return ((*(entry
->assign_func
)) (entry
, value
));
1353 if (readonly_p (entry
))
1355 report_error ("%s: readonly variable", name
);
1359 /* Variables which are bound are visible. */
1360 entry
->attributes
&= ~att_invisible
;
1362 newval
= make_variable_value (entry
, value
);
1364 #if defined (ARRAY_VARS)
1365 /* XXX -- this bears looking at again -- XXX */
1366 /* If an existing array variable x is being assigned to with x=b or
1367 `read x' or something of that nature, silently convert it to
1368 x[0]=b or `read x[0]'. */
1369 if (array_p (entry
))
1371 array_add_element (array_cell (entry
), 0, newval
);
1376 FREE (entry
->value
);
1377 entry
->value
= newval
;
1380 FREE (entry
->value
);
1381 entry
->value
= newval
;
1385 if (mark_modified_vars
)
1386 entry
->attributes
|= att_exported
;
1388 if (exported_p (entry
))
1389 array_needs_making
= 1;
1394 #if defined (ARRAY_VARS)
1395 /* Convert a shell variable to an array variable. The original value is
1396 saved as array[0]. */
1398 convert_var_to_array (var
)
1404 oldval
= value_cell (var
);
1405 array
= new_array ();
1406 array_add_element (array
, 0, oldval
);
1407 FREE (value_cell (var
));
1408 var
->value
= (char *)array
;
1409 var
->attributes
|= att_array
;
1410 var
->attributes
&= ~att_invisible
;
1415 /* Perform an array assignment name[ind]=value. If NAME already exists and
1416 is not an array, and IND is 0, perform name=value instead. If NAME exists
1417 and is not an array, and IND is not 0, convert it into an array with the
1418 existing value as name[0].
1420 If NAME does not exist, just create an array variable, no matter what
1421 IND's value may be. */
1423 bind_array_variable (name
, ind
, value
)
1431 entry
= var_lookup (name
, shell_variables
);
1433 if (entry
== (SHELL_VAR
*) 0)
1434 entry
= make_new_array_variable (name
);
1435 else if (readonly_p (entry
))
1437 report_error ("%s: readonly variable", name
);
1440 else if (array_p (entry
) == 0)
1441 entry
= convert_var_to_array (entry
);
1443 /* ENTRY is an array variable, and ARRAY points to the value. */
1444 newval
= make_variable_value (entry
, value
);
1445 if (entry
->assign_func
)
1446 (*entry
->assign_func
) (entry
, ind
, newval
);
1448 array_add_element (array_cell (entry
), ind
, newval
);
1455 assign_array_from_string (name
, value
)
1460 var
= find_variable (name
);
1462 var
= make_new_array_variable (name
);
1463 else if (readonly_p (var
))
1465 report_error ("%s: readonly variable", name
);
1466 return ((SHELL_VAR
*)NULL
);
1468 else if (array_p (var
) == 0)
1469 var
= convert_var_to_array (var
);
1472 empty_array (array_cell (var
));
1475 return (assign_array_var_from_string (var
, value
));
1479 assign_array_var_from_word_list (var
, list
)
1484 register WORD_LIST
*l
;
1487 for (a
= array_cell (var
), l
= list
, i
= 0; l
; l
= l
->next
, i
++)
1488 if (var
->assign_func
)
1489 (*var
->assign_func
) (var
, i
, l
->word
->word
);
1491 array_add_element (a
, i
, l
->word
->word
);
1496 assign_array_var_from_string (var
, value
)
1501 WORD_LIST
*list
, *nlist
;
1502 char *w
, *val
, *nval
;
1503 int ni
, len
, ind
, last_ind
;
1505 a
= array_cell (var
);
1507 /* Expand the value string into a list of words, performing all the
1508 shell expansions including word splitting. */
1512 val
= extract_array_assignment_list (value
, &ni
);
1515 nlist
= expand_string (val
, 0);
1519 nlist
= expand_string (value
, 0);
1522 /* Now that we are ready to assign values to the array, kill the existing
1528 for (last_ind
= 0, list
= nlist
; list
; list
= list
->next
)
1530 w
= list
->word
->word
;
1532 /* We have a word of the form [ind]=value */
1535 len
= skipsubscript (w
, 0);
1537 if (w
[len
] != ']' || w
[len
+1] != '=')
1539 nval
= make_variable_value (var
, w
);
1540 if (var
->assign_func
)
1541 (*var
->assign_func
) (var
, last_ind
, nval
);
1543 array_add_element (a
, last_ind
, nval
);
1551 report_error ("%s: bad array subscript", w
);
1555 if (ALL_ELEMENT_SUB (w
[1]) && len
== 2)
1557 report_error ("%s: cannot assign to non-numeric index", w
);
1561 ind
= array_expand_index (w
+ 1, len
);
1564 report_error ("%s: bad array subscript", w
);
1570 else /* No [ind]=value, just a stray `=' */
1576 if (integer_p (var
))
1577 this_command_name
= (char *)NULL
; /* no command name for errors */
1578 nval
= make_variable_value (var
, val
);
1579 if (var
->assign_func
)
1580 (*var
->assign_func
) (var
, ind
, nval
);
1582 array_add_element (a
, ind
, nval
);
1587 dispose_words (nlist
);
1590 #endif /* ARRAY_VARS */
1592 /* Dispose of the information attached to VAR. */
1594 dispose_variable (var
)
1600 if (function_p (var
))
1601 dispose_command (function_cell (var
));
1602 #if defined (ARRAY_VARS)
1603 else if (array_p (var
))
1604 dispose_array (array_cell (var
));
1607 FREE (value_cell (var
));
1611 if (exported_p (var
))
1612 array_needs_making
= 1;
1617 #if defined (ARRAY_VARS)
1618 /* This function is called with SUB pointing to just after the beginning
1619 `[' of an array subscript. */
1621 unbind_array_element (var
, sub
)
1628 len
= skipsubscript (sub
, 0);
1629 if (sub
[len
] != ']' || len
== 0)
1631 builtin_error ("%s[%s: bad array subscript", var
->name
, sub
);
1636 if (ALL_ELEMENT_SUB (sub
[0]) && sub
[1] == 0)
1638 makunbound (var
->name
, shell_variables
);
1641 ind
= array_expand_index (sub
, len
+1);
1644 builtin_error ("[%s]: bad array subscript", sub
);
1647 ae
= array_delete_element (array_cell (var
), ind
);
1649 destroy_array_element (ae
);
1654 /* Unset the variable referenced by NAME. */
1656 unbind_variable (name
)
1659 SHELL_VAR
*var
= find_variable (name
);
1664 /* This function should never be called with an array variable name. */
1665 #if defined (ARRAY_VARS)
1666 if (array_p (var
) == 0 && var
->value
)
1672 var
->value
= (char *)NULL
;
1675 makunbound (name
, shell_variables
);
1680 /* Make the variable associated with NAME go away. HASH_LIST is the
1681 hash table from which this variable should be deleted (either
1682 shell_variables or shell_functions).
1683 Returns non-zero if the variable couldn't be found. */
1685 makunbound (name
, hash_list
)
1687 HASH_TABLE
*hash_list
;
1689 BUCKET_CONTENTS
*elt
, *new_elt
;
1690 SHELL_VAR
*old_var
, *new_var
;
1693 elt
= remove_hash_item (name
, hash_list
);
1698 old_var
= (SHELL_VAR
*)elt
->data
;
1699 new_var
= old_var
->prev_context
;
1701 if (old_var
&& exported_p (old_var
))
1702 array_needs_making
++;
1704 /* If we're unsetting a local variable and we're still executing inside
1705 the function, just mark the variable as invisible.
1706 kill_all_local_variables will clean it up later. This must be done
1707 so that if the variable is subsequently assigned a new value inside
1708 the function, the `local' attribute is still present. We also need
1709 to add it back into the correct hash table. */
1710 if (old_var
&& local_p (old_var
) && variable_context
== old_var
->context
)
1712 old_var
->attributes
|= att_invisible
;
1713 new_elt
= add_hash_item (savestring (old_var
->name
), hash_list
);
1714 new_elt
->data
= (char *)old_var
;
1715 stupidly_hack_special_variables (old_var
->name
);
1723 /* Has to be a variable, functions don't have previous contexts. */
1724 new_elt
= add_hash_item (savestring (new_var
->name
), hash_list
);
1725 new_elt
->data
= (char *)new_var
;
1727 if (exported_p (new_var
))
1728 set_auto_export (new_var
);
1731 /* Have to save a copy of name here, because it might refer to
1732 old_var->name. If so, stupidly_hack_special_variables will
1733 reference freed memory. */
1734 t
= savestring (name
);
1739 dispose_variable (old_var
);
1740 stupidly_hack_special_variables (t
);
1745 #ifdef INCLUDE_UNUSED
1746 /* Remove the variable with NAME if it is a local variable in the
1749 kill_local_variable (name
)
1754 temp
= find_variable (name
);
1755 if (temp
&& temp
->context
== variable_context
)
1757 makunbound (name
, shell_variables
);
1764 /* Get rid of all of the variables in the current context. */
1766 variable_in_context (var
)
1769 return (var
&& var
->context
== variable_context
);
1773 kill_all_local_variables ()
1775 register int i
, pass
;
1776 register SHELL_VAR
*var
, **list
;
1777 HASH_TABLE
*varlist
;
1779 /* If HAVE_LOCAL_VARIABLES == 0, it means that we don't have any local
1780 variables at all. If VARIABLE_CONTEXT >= LOCAL_VARIABLE_STACK_SIZE,
1781 it means that we have some local variables, but not in this variable
1782 context (level of function nesting). Also, if
1783 HAVE_LOCAL_VARIABLES[VARIABLE_CONTEXT] == 0, we have no local variables
1785 if (have_local_variables
== 0 ||
1786 variable_context
>= local_variable_stack_size
||
1787 have_local_variables
[variable_context
] == 0)
1790 for (pass
= 0; pass
< 2; pass
++)
1792 varlist
= pass
? shell_functions
: shell_variables
;
1794 list
= map_over (variable_in_context
, varlist
);
1798 for (i
= 0; var
= list
[i
]; i
++)
1800 var
->attributes
&= ~att_local
;
1801 makunbound (var
->name
, varlist
);
1807 have_local_variables
[variable_context
] = 0; /* XXX */
1811 free_variable_hash_data (data
)
1814 SHELL_VAR
*var
, *prev
;
1816 var
= (SHELL_VAR
*)data
;
1819 prev
= var
->prev_context
;
1820 dispose_variable (var
);
1825 /* Delete the entire contents of the hash table. */
1827 delete_all_variables (hashed_vars
)
1828 HASH_TABLE
*hashed_vars
;
1830 flush_hash_table (hashed_vars
, free_variable_hash_data
);
1834 new_shell_variable (name
)
1839 var
= (SHELL_VAR
*)xmalloc (sizeof (SHELL_VAR
));
1841 bzero ((char *)var
, sizeof (SHELL_VAR
));
1842 var
->name
= savestring (name
);
1846 /* Do a function binding to a variable. You pass the name and
1847 the command to bind to. This conses the name and command. */
1849 bind_function (name
, value
)
1855 entry
= find_function (name
);
1858 BUCKET_CONTENTS
*elt
;
1860 elt
= add_hash_item (savestring (name
), shell_functions
);
1862 elt
->data
= (char *)new_shell_variable (name
);
1863 entry
= (SHELL_VAR
*)elt
->data
;
1864 entry
->dynamic_value
= entry
->assign_func
= (DYNAMIC_FUNC
*)NULL
;
1866 /* Functions are always made at the top level. This allows a
1867 function to define another function (like autoload). */
1872 dispose_command ((COMMAND
*)entry
->value
);
1874 entry
->value
= value
? (char *)copy_command (value
) : (char *)NULL
;
1875 entry
->attributes
|= att_function
;
1877 if (mark_modified_vars
)
1878 entry
->attributes
|= att_exported
;
1880 entry
->attributes
&= ~att_invisible
; /* Just to be sure */
1882 if (exported_p (entry
))
1883 array_needs_making
= 1;
1888 #ifdef INCLUDE_UNUSED
1889 /* Copy VAR to a new data structure and return that structure. */
1894 SHELL_VAR
*copy
= (SHELL_VAR
*)NULL
;
1898 copy
= (SHELL_VAR
*)xmalloc (sizeof (SHELL_VAR
));
1900 copy
->attributes
= var
->attributes
;
1901 copy
->name
= savestring (var
->name
);
1903 if (function_p (var
))
1904 copy
->value
= (char *)copy_command (function_cell (var
));
1905 #if defined (ARRAY_VARS)
1906 else if (array_p (var
))
1907 copy
->value
= (char *)dup_array (array_cell (var
));
1909 else if (value_cell (var
))
1910 copy
->value
= savestring (value_cell (var
));
1912 copy
->value
= (char *)NULL
;
1914 copy
->dynamic_value
= var
->dynamic_value
;
1915 copy
->assign_func
= var
->assign_func
;
1917 copy
->context
= var
->context
;
1919 /* Don't bother copying previous contexts along with this variable. */
1920 copy
->prev_context
= (SHELL_VAR
*)NULL
;
1926 #define FIND_OR_MAKE_VARIABLE(name, entry) \
1929 entry = find_variable (name); \
1932 entry = bind_variable (name, ""); \
1933 if (!no_invisible_vars) entry->attributes |= att_invisible; \
1938 /* Make the variable associated with NAME be readonly.
1939 If NAME does not exist yet, create it. */
1941 set_var_read_only (name
)
1946 FIND_OR_MAKE_VARIABLE (name
, entry
);
1947 entry
->attributes
|= att_readonly
;
1950 /* Make the function associated with NAME be readonly.
1951 If NAME does not exist, we just punt, like auto_export code below. */
1953 set_func_read_only (name
)
1958 entry
= find_function (name
);
1960 entry
->attributes
|= att_readonly
;
1963 /* Make the variable associated with NAME be auto-exported.
1964 If NAME does not exist yet, create it. */
1966 set_var_auto_export (name
)
1971 FIND_OR_MAKE_VARIABLE (name
, entry
);
1972 set_auto_export (entry
);
1975 /* Make the function associated with NAME be auto-exported. */
1977 set_func_auto_export (name
)
1982 entry
= find_function (name
);
1984 set_auto_export (entry
);
1987 #if defined (ARRAY_VARS)
1988 /* This function assumes s[i] == '['; returns with s[ret] == ']' if
1989 an array subscript is correctly parsed. */
1991 skipsubscript (s
, i
)
1997 for (count
= 1; count
&& (c
= s
[++i
]); )
2006 #endif /* ARRAY_VARS */
2008 /* Returns non-zero if STRING is an assignment statement. The returned value
2009 is the index of the `=' sign. */
2014 register int c
, newi
, indx
;
2016 c
= string
[indx
= 0];
2018 if (legal_variable_starter (c
) == 0)
2021 while (c
= string
[indx
])
2023 /* The following is safe. Note that '=' at the start of a word
2024 is not an assignment statement. */
2028 #if defined (ARRAY_VARS)
2031 newi
= skipsubscript (string
, indx
);
2032 if (string
[newi
++] != ']')
2034 return ((string
[newi
] == '=') ? newi
: 0);
2036 #endif /* ARRAY_VARS */
2038 /* Variable names in assignment statements may contain only letters,
2040 if (legal_variable_char (c
) == 0)
2052 return (invisible_p (var
) == 0);
2056 _visible_names (table
)
2061 list
= map_over (visible_var
, table
);
2063 if (list
/* && posixly_correct */)
2064 sort_variables (list
);
2070 all_visible_variables ()
2072 return (_visible_names (shell_variables
));
2076 all_visible_functions ()
2078 return (_visible_names (shell_functions
));
2081 /* Return non-zero if the variable VAR is visible and exported. Array
2082 variables cannot be exported. */
2084 visible_and_exported (var
)
2087 return (invisible_p (var
) == 0 && exported_p (var
));
2090 /* Make an array of assignment statements from the hash table
2091 HASHED_VARS which contains SHELL_VARs. Only visible, exported
2092 variables are eligible. */
2094 make_var_array (hashed_vars
)
2095 HASH_TABLE
*hashed_vars
;
2097 register int i
, list_index
;
2098 register SHELL_VAR
*var
;
2099 char **list
, *value
;
2102 vars
= map_over (visible_and_exported
, hashed_vars
);
2105 return (char **)NULL
;
2107 list
= (char **)xmalloc ((1 + array_len ((char **)vars
)) * sizeof (char *));
2109 for (i
= 0, list_index
= 0; var
= vars
[i
]; i
++)
2111 if (function_p (var
))
2112 value
= named_function_string ((char *)NULL
, function_cell (var
), 0);
2113 #if defined (ARRAY_VARS)
2114 else if (array_p (var
))
2116 value
= array_to_assignment_string (array_cell (var
));
2118 continue; /* XXX array vars cannot yet be exported */
2122 value
= value_cell (var
);
2126 int name_len
, value_len
;
2129 name_len
= strlen (var
->name
);
2130 value_len
= strlen (value
);
2131 p
= list
[list_index
] = xmalloc (2 + name_len
+ value_len
);
2132 strcpy (p
, var
->name
);
2134 strcpy (p
+ name_len
+ 1, value
);
2136 #if defined (ARRAY_VARS)
2144 list
[list_index
] = (char *)NULL
;
2148 /* Add STRING to the array of foo=bar strings that we already
2149 have to add to the environment. */
2151 assign_in_env (string
)
2155 char *name
, *temp
, *value
;
2160 offset
= assignment (string
);
2161 name
= savestring (string
);
2162 value
= (char *)NULL
;
2164 #define freetemp nlen
2165 if (name
[offset
] == '=')
2169 var
= find_variable (name
);
2170 if (var
&& readonly_p (var
))
2172 report_error ("%s: readonly variable", name
);
2176 temp
= name
+ offset
+ 1;
2177 freetemp
= strchr (temp
, '~') != 0;
2179 temp
= bash_tilde_expand (temp
);
2181 list
= expand_string_unsplit (temp
, 0);
2182 value
= string_list (list
);
2185 dispose_words (list
);
2192 nlen
= strlen (name
);
2193 vlen
= value
? strlen (value
) : 0;
2194 temp
= xmalloc (2 + nlen
+ vlen
);
2195 strcpy (temp
, name
);
2197 temp
[nlen
+ 1] = '\0';
2201 strcpy (temp
+ nlen
+ 1, value
);
2206 if (temporary_env
== 0)
2208 temporary_env
= (char **)xmalloc (sizeof (char *));
2209 temporary_env
[0] = (char *)NULL
;
2212 size
= array_len (temporary_env
);
2213 temporary_env
= (char **)
2214 xrealloc (temporary_env
, (size
+ 2) * (sizeof (char *)));
2216 temporary_env
[size
] = temp
;
2217 temporary_env
[size
+ 1] = (char *)NULL
;
2218 array_needs_making
= 1;
2220 if (echo_command_at_execute
)
2222 /* The Korn shell prints the `+ ' in front of assignment statements,
2224 fprintf (stderr
, "%s%s\n", indirection_level_string (), temp
);
2231 /* Search for NAME in ARRAY, an array of strings in the same format as the
2232 environment array (i.e, name=value). If NAME is present, make a new
2233 variable and return it. Otherwise, return NULL. */
2235 find_name_in_env_array (name
, array
)
2242 return ((SHELL_VAR
*)NULL
);
2244 for (i
= 0, l
= strlen (name
); array
[i
]; i
++)
2246 if (STREQN (array
[i
], name
, l
) && array
[i
][l
] == '=')
2251 temp
= new_shell_variable (name
); /* XXX memory leak here */
2252 w
= array
[i
] + l
+ 1;
2254 temp
->value
= *w
? savestring (w
) : (char *)NULL
;
2256 temp
->attributes
= att_exported
;
2258 temp
->prev_context
= (SHELL_VAR
*)NULL
;
2260 temp
->dynamic_value
= temp
->assign_func
= (DYNAMIC_FUNC
*)NULL
;
2265 return ((SHELL_VAR
*)NULL
);
2268 /* Find a variable in the temporary environment that is named NAME.
2269 The temporary environment can be either the environment provided
2270 to a simple command, or the environment provided to a shell function.
2271 We only search the function environment if we are currently executing
2272 a shell function body (variable_context > 0). Return a consed variable,
2273 or NULL if not found. */
2275 find_tempenv_variable (name
)
2278 SHELL_VAR
*var
= (SHELL_VAR
*)NULL
;
2281 var
= find_name_in_env_array (name
, temporary_env
);
2283 /* We don't check this_shell_builtin because the command that needs the
2284 value from builtin_env may be a disk command run inside a script run
2285 with `.' and a temporary env. */
2286 if (!var
&& builtin_env
)
2287 var
= find_name_in_env_array (name
, builtin_env
);
2289 if (!var
&& variable_context
&& function_env
)
2290 var
= find_name_in_env_array (name
, function_env
);
2295 /* Free the storage allocated to the string array pointed to by ARRAYP, and
2296 make that variable have a null pointer as a value. */
2298 dispose_temporary_vars (arrayp
)
2304 free_array (*arrayp
);
2305 *arrayp
= (char **)NULL
;
2306 array_needs_making
= 1;
2309 /* Free the storage used in the variable array for temporary
2310 environment variables. */
2312 dispose_used_env_vars ()
2314 dispose_temporary_vars (&temporary_env
);
2317 /* Free the storage used for temporary environment variables given to
2318 commands when executing inside of a function body. */
2320 dispose_function_env ()
2322 dispose_temporary_vars (&function_env
);
2325 /* Free the storage used for temporary environment variables given to
2326 commands when executing a builtin command such as "source". */
2328 dispose_builtin_env ()
2330 dispose_temporary_vars (&builtin_env
);
2333 /* Take all of the shell variables in ENV_ARRAY and make shell variables
2334 from them at the current variable context. */
2336 merge_env_array (env_array
)
2346 for (i
= 0; env_array
[i
]; i
++)
2348 l
= assignment (env_array
[i
]);
2349 name
= env_array
[i
];
2350 val
= env_array
[i
] + l
+ 1;
2352 temp
= bind_variable (name
, val
);
2358 merge_temporary_env ()
2360 merge_env_array (temporary_env
);
2364 merge_builtin_env ()
2366 merge_env_array (builtin_env
);
2369 /* Add ENVSTR to the end of the exported environment, EXPORT_ENV. */
2370 #define add_to_export_env(envstr,do_alloc) \
2373 if (export_env_index >= (export_env_size - 1)) \
2375 export_env_size += 16; \
2376 export_env = (char **)xrealloc (export_env, export_env_size * sizeof (char *)); \
2378 export_env[export_env_index++] = (do_alloc) ? savestring (envstr) : envstr; \
2379 export_env[export_env_index] = (char *)NULL; \
2382 #define ISFUNC(s, o) ((s[o + 1] == '(') && (s[o + 2] == ')'))
2384 /* Add ASSIGN to EXPORT_ENV, or supercede a previous assignment in the
2385 array with the same left-hand side. Return the new EXPORT_ENV. */
2387 add_or_supercede_exported_var (assign
, do_alloc
)
2394 equal_offset
= assignment (assign
);
2395 if (equal_offset
== 0)
2396 return (export_env
);
2398 /* If this is a function, then only supercede the function definition.
2399 We do this by including the `=(' in the comparison. */
2400 if (assign
[equal_offset
+ 1] == '(')
2403 for (i
= 0; i
< export_env_index
; i
++)
2405 if (STREQN (assign
, export_env
[i
], equal_offset
+ 1))
2407 free (export_env
[i
]);
2408 export_env
[i
] = do_alloc
? savestring (assign
) : assign
;
2409 return (export_env
);
2412 add_to_export_env (assign
, do_alloc
);
2413 return (export_env
);
2416 /* Make the environment array for the command about to be executed, if the
2417 array needs making. Otherwise, do nothing. If a shell action could
2418 change the array that commands receive for their environment, then the
2419 code should `array_needs_making++'. */
2421 maybe_make_export_env ()
2424 register char **temp_array
;
2427 if (array_needs_making
)
2430 free_array_members (export_env
);
2432 /* Make a guess based on how many shell variables and functions we
2433 have. Since there will always be array variables, and array
2434 variables are not (yet) exported, this will always be big enough
2435 for the exported variables and functions, without any temporary
2436 or function environments. */
2437 new_size
= shell_variables
->nentries
+ shell_functions
->nentries
+ 1;
2438 if (new_size
> export_env_size
)
2440 export_env_size
= new_size
;
2441 export_env
= (char **)xrealloc (export_env
, export_env_size
* sizeof (char *));
2443 export_env
[export_env_index
= 0] = (char *)NULL
;
2445 temp_array
= make_var_array (shell_variables
);
2448 for (i
= 0; temp_array
[i
]; i
++)
2449 add_to_export_env (temp_array
[i
], 0);
2453 temp_array
= make_var_array (shell_functions
);
2456 for (i
= 0; temp_array
[i
]; i
++)
2457 add_to_export_env (temp_array
[i
], 0);
2462 for (i
= 0; function_env
[i
]; i
++)
2463 export_env
= add_or_supercede_exported_var (function_env
[i
], 1);
2466 for (i
= 0; temporary_env
[i
]; i
++)
2467 export_env
= add_or_supercede_exported_var (temporary_env
[i
], 1);
2470 /* If we changed the array, then sort it alphabetically. */
2471 if (posixly_correct
== 0 && (temporary_env
|| function_env
))
2472 sort_char_array (export_env
);
2475 array_needs_making
= 0;
2479 /* We always put _ in the environment as the name of this command. */
2481 put_command_name_into_env (command_name
)
2486 dummy
= xmalloc (4 + strlen (command_name
));
2488 /* These three statements replace a call to sprintf */
2491 strcpy (dummy
+ 2, command_name
);
2492 export_env
= add_or_supercede_exported_var (dummy
, 0);
2496 put_gnu_argv_flags_into_env (pid
, flags_string
)
2506 fl
= strlen (flags_string
);
2508 dummy
= xmalloc (l
+ fl
+ 30);
2510 strcpy (dummy
+ 1, pbuf
);
2511 strcpy (dummy
+ 1 + l
, "_GNU_nonoption_argv_flags_");
2512 dummy
[l
+ 27] = '=';
2513 strcpy (dummy
+ l
+ 28, flags_string
);
2517 export_env
= add_or_supercede_exported_var (dummy
, 0);
2520 /* Return a string denoting what our indirection level is. */
2521 static char indirection_string
[100];
2524 indirection_level_string ()
2529 indirection_string
[0] = '\0';
2530 ps4
= get_string_value ("PS4");
2532 if (ps4
== 0 || *ps4
== '\0')
2533 return (indirection_string
);
2535 ps4
= decode_prompt_string (ps4
);
2537 for (i
= 0; *ps4
&& i
< indirection_level
&& i
< 99; i
++)
2538 indirection_string
[i
] = *ps4
;
2540 for (j
= 1; *ps4
&& ps4
[j
] && i
< 99; i
++, j
++)
2541 indirection_string
[i
] = ps4
[j
];
2543 indirection_string
[i
] = '\0';
2545 return (indirection_string
);