1 /* variables.c -- Functions for hacking shell variables. */
3 /* Copyright (C) 1987-2005 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 2, 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, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
23 #include "bashtypes.h"
24 #include "posixstat.h"
25 #include "posixtime.h"
29 # include <sy/netmgr.h>
35 #if defined (HAVE_UNISTD_H)
40 #include "chartypes.h"
47 #include "execute_cmd.h"
49 #include "mailcheck.h"
54 #include "builtins/getopt.h"
55 #include "builtins/common.h"
57 #if defined (READLINE)
58 # include "bashline.h"
59 # include <readline/readline.h>
61 # include <tilde/tilde.h>
65 # include "bashhist.h"
66 # include <readline/history.h>
69 #if defined (PROGRAMMABLE_COMPLETION)
70 # include "pcomplete.h"
73 #define TEMPENV_HASH_BUCKETS 4 /* must be power of two */
75 #define ifsname(s) ((s)[0] == 'I' && (s)[1] == 'F' && (s)[2] == 'S' && (s)[3] == '\0')
77 extern char **environ;
79 /* Variables used here and defined in other files. */
80 extern int posixly_correct;
81 extern int line_number;
82 extern int subshell_environment, indirection_level, subshell_level;
83 extern int build_version, patch_level;
84 extern int expanding_redir;
85 extern char *dist_version, *release_status;
86 extern char *shell_name;
87 extern char *primary_prompt, *secondary_prompt;
88 extern char *current_host_name;
89 extern sh_builtin_func_t *this_shell_builtin;
90 extern SHELL_VAR *this_shell_function;
91 extern char *the_printed_command_except_trap;
92 extern char *this_command_name;
93 extern char *command_execution_string;
94 extern time_t shell_start_time;
96 #if defined (READLINE)
97 extern int no_line_editing;
98 extern int perform_hostname_completion;
101 /* The list of shell variables that the user has created at the global
102 scope, or that came from the environment. */
103 VAR_CONTEXT *global_variables = (VAR_CONTEXT *)NULL;
105 /* The current list of shell variables, including function scopes */
106 VAR_CONTEXT *shell_variables = (VAR_CONTEXT *)NULL;
108 /* The list of shell functions that the user has created, or that came from
110 HASH_TABLE *shell_functions = (HASH_TABLE *)NULL;
112 #if defined (DEBUGGER)
113 /* The table of shell function definitions that the user defined or that
114 came from the environment. */
115 HASH_TABLE *shell_function_defs = (HASH_TABLE *)NULL;
118 /* The current variable context. This is really a count of how deep into
119 executing functions we are. */
120 int variable_context = 0;
122 /* The set of shell assignments which are made only in the environment
123 for a single command. */
124 HASH_TABLE *temporary_env = (HASH_TABLE *)NULL;
126 /* Set to non-zero if an assignment error occurs while putting variables
127 into the temporary environment. */
128 int tempenv_assign_error;
130 /* Some funky variables which are known about specially. Here is where
131 "$*", "$1", and all the cruft is kept. */
132 char *dollar_vars[10];
133 WORD_LIST *rest_of_args = (WORD_LIST *)NULL;
135 /* The value of $$. */
136 pid_t dollar_dollar_pid;
138 /* An array which is passed to commands as their environment. It is
139 manufactured from the union of the initial environment and the
140 shell variables that are marked for export. */
141 char **export_env = (char **)NULL;
142 static int export_env_index;
143 static int export_env_size;
145 #if defined (READLINE)
146 static int winsize_assignment; /* currently assigning to LINES or COLUMNS */
147 static int winsize_assigned; /* assigned to LINES or COLUMNS */
150 /* Non-zero means that we have to remake EXPORT_ENV. */
151 int array_needs_making = 1;
153 /* The number of times BASH has been executed. This is set
154 by initialize_variables (). */
157 /* Some forward declarations. */
158 static void set_machine_vars __P((void));
159 static void set_home_var __P((void));
160 static void set_shell_var __P((void));
161 static char *get_bash_name __P((void));
162 static void initialize_shell_level __P((void));
163 static void uidset __P((void));
164 #if defined (ARRAY_VARS)
165 static void make_vers_array __P((void));
168 static SHELL_VAR *null_assign __P((SHELL_VAR *, char *, arrayind_t));
169 #if defined (ARRAY_VARS)
170 static SHELL_VAR *null_array_assign __P((SHELL_VAR *, char *, arrayind_t));
172 static SHELL_VAR *get_self __P((SHELL_VAR *));
174 #if defined (ARRAY_VARS)
175 static SHELL_VAR *init_dynamic_array_var __P((char *, sh_var_value_func_t *, sh_var_assign_func_t *, int));
178 static SHELL_VAR *assign_seconds __P((SHELL_VAR *, char *, arrayind_t));
179 static SHELL_VAR *get_seconds __P((SHELL_VAR *));
180 static SHELL_VAR *init_seconds_var __P((void));
182 static int brand __P((void));
183 static void sbrand __P((unsigned long)); /* set bash random number generator. */
184 static SHELL_VAR *assign_random __P((SHELL_VAR *, char *, arrayind_t));
185 static SHELL_VAR *get_random __P((SHELL_VAR *));
187 static SHELL_VAR *assign_lineno __P((SHELL_VAR *, char *, arrayind_t));
188 static SHELL_VAR *get_lineno __P((SHELL_VAR *));
190 static SHELL_VAR *assign_subshell __P((SHELL_VAR *, char *, arrayind_t));
191 static SHELL_VAR *get_subshell __P((SHELL_VAR *));
193 #if defined (HISTORY)
194 static SHELL_VAR *get_histcmd __P((SHELL_VAR *));
197 #if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
198 static SHELL_VAR *assign_dirstack __P((SHELL_VAR *, char *, arrayind_t));
199 static SHELL_VAR *get_dirstack __P((SHELL_VAR *));
202 #if defined (ARRAY_VARS)
203 static SHELL_VAR *get_groupset __P((SHELL_VAR *));
206 static SHELL_VAR *get_funcname __P((SHELL_VAR *));
207 static SHELL_VAR *init_funcname_var __P((void));
209 static void initialize_dynamic_variables __P((void));
211 static SHELL_VAR *hash_lookup __P((const char *, HASH_TABLE *));
212 static SHELL_VAR *new_shell_variable __P((const char *));
213 static SHELL_VAR *make_new_variable __P((const char *, HASH_TABLE *));
214 static SHELL_VAR *bind_variable_internal __P((const char *, char *, HASH_TABLE *, int, int));
216 static void free_variable_hash_data __P((PTR_T));
218 static VARLIST *vlist_alloc __P((int));
219 static VARLIST *vlist_realloc __P((VARLIST *, int));
220 static void vlist_add __P((VARLIST *, SHELL_VAR *, int));
222 static void flatten __P((HASH_TABLE *, sh_var_map_func_t *, VARLIST *, int));
224 static int qsort_var_comp __P((SHELL_VAR **, SHELL_VAR **));
226 static SHELL_VAR **vapply __P((sh_var_map_func_t *));
227 static SHELL_VAR **fapply __P((sh_var_map_func_t *));
229 static int visible_var __P((SHELL_VAR *));
230 static int visible_and_exported __P((SHELL_VAR *));
231 static int local_and_exported __P((SHELL_VAR *));
232 static int variable_in_context __P((SHELL_VAR *));
233 #if defined (ARRAY_VARS)
234 static int visible_array_vars __P((SHELL_VAR *));
237 static SHELL_VAR *bind_tempenv_variable __P((const char *, char *));
238 static void push_temp_var __P((PTR_T));
239 static void propagate_temp_var __P((PTR_T));
240 static void dispose_temporary_env __P((sh_free_func_t *));
242 static inline char *mk_env_string __P((const char *, const char *));
243 static char **make_env_array_from_var_list __P((SHELL_VAR **));
244 static char **make_var_export_array __P((VAR_CONTEXT *));
245 static char **make_func_export_array __P((void));
246 static void add_temp_array_to_env __P((char **, int, int));
248 static int n_shell_variables __P((void));
249 static int set_context __P((SHELL_VAR *));
251 static void push_func_var __P((PTR_T));
252 static void push_exported_var __P((PTR_T));
254 static inline int find_special_var __P((const char *));
256 /* Initialize the shell variables from the current environment.
257 If PRIVMODE is nonzero, don't import functions from ENV or
260 initialize_shell_variables (env, privmode)
264 char *name, *string, *temp_string;
265 int c, char_index, string_index, string_length;
268 if (shell_variables == 0)
270 shell_variables = global_variables = new_var_context ((char *)NULL, 0);
271 shell_variables->scope = 0;
272 shell_variables->table = hash_create (0);
275 if (shell_functions == 0)
276 shell_functions = hash_create (0);
278 #if defined (DEBUGGER)
279 if (shell_function_defs == 0)
280 shell_function_defs = hash_create (0);
283 for (string_index = 0; string = env[string_index++]; )
287 while ((c = *string++) && c != '=')
289 if (string[-1] == '=')
290 char_index = string - name - 1;
292 /* If there are weird things in the environment, like `=xxx' or a
293 string without an `=', just skip them. */
297 /* ASSERT(name[char_index] == '=') */
298 name[char_index] = '\0';
299 /* Now, name = env variable name, string = env variable value, and
300 char_index == strlen (name) */
302 /* If exported function, define it now. Don't import functions from
303 the environment in privileged mode. */
304 if (privmode == 0 && read_but_dont_execute == 0 && STREQN ("() {", string, 4))
306 string_length = strlen (string);
307 temp_string = (char *)xmalloc (3 + string_length + char_index);
309 strcpy (temp_string, name);
310 temp_string[char_index] = ' ';
311 strcpy (temp_string + char_index + 1, string);
313 parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST);
315 /* Ancient backwards compatibility. Old versions of bash exported
316 functions like name()=() {...} */
317 if (name[char_index - 1] == ')' && name[char_index - 2] == '(')
318 name[char_index - 2] = '\0';
320 if (temp_var = find_function (name))
322 VSETATTR (temp_var, (att_exported|att_imported));
323 array_needs_making = 1;
326 report_error (_("error importing function definition for `%s'"), name);
329 if (name[char_index - 1] == ')' && name[char_index - 2] == '\0')
330 name[char_index - 2] = '('; /* ) */
332 #if defined (ARRAY_VARS)
334 /* Array variables may not yet be exported. */
335 else if (*string == '(' && string[1] == '[' && string[strlen (string) - 1] == ')')
338 temp_string = extract_array_assignment_list (string, &string_length);
339 temp_var = assign_array_from_string (name, temp_string);
341 VSETATTR (temp_var, (att_exported | att_imported));
342 array_needs_making = 1;
348 temp_var = bind_variable (name, string, 0);
349 VSETATTR (temp_var, (att_exported | att_imported));
350 array_needs_making = 1;
353 name[char_index] = '=';
354 /* temp_var can be NULL if it was an exported function with a syntax
355 error (a different bug, but it still shouldn't dump core). */
356 if (temp_var && function_p (temp_var) == 0) /* XXX not yet */
358 CACHE_IMPORTSTR (temp_var, name);
364 /* Set up initial value of $_ */
366 temp_var = bind_variable ("_", dollar_vars[0], 0);
368 temp_var = set_if_not ("_", dollar_vars[0]);
371 /* Remember this pid. */
372 dollar_dollar_pid = getpid ();
374 /* Now make our own defaults in case the vars that we think are
375 important are missing. */
376 temp_var = set_if_not ("PATH", DEFAULT_PATH_VALUE);
378 set_auto_export (temp_var); /* XXX */
381 temp_var = set_if_not ("TERM", "dumb");
383 set_auto_export (temp_var); /* XXX */
387 /* set node id -- don't import it from the environment */
391 netmgr_ndtostr(ND2S_LOCAL_STR, ND_LOCAL_NODE, node_name, sizeof(node_name));
393 qnx_nidtostr (getnid (), node_name, sizeof (node_name));
395 temp_var = bind_variable ("NODE", node_name, 0);
396 set_auto_export (temp_var);
400 /* set up the prompts. */
401 if (interactive_shell)
403 #if defined (PROMPT_STRING_DECODE)
404 set_if_not ("PS1", primary_prompt);
406 if (current_user.uid == -1)
407 get_current_user_info ();
408 set_if_not ("PS1", current_user.euid == 0 ? "# " : primary_prompt);
410 set_if_not ("PS2", secondary_prompt);
412 set_if_not ("PS4", "+ ");
414 /* Don't allow IFS to be imported from the environment. */
415 temp_var = bind_variable ("IFS", " \t\n", 0);
418 /* Magic machine types. Pretty convenient. */
421 /* Default MAILCHECK for interactive shells. Defer the creation of a
422 default MAILPATH until the startup files are read, because MAIL
423 names a mail file if MAILPATH is not set, and we should provide a
424 default only if neither is set. */
425 if (interactive_shell)
427 temp_var = set_if_not ("MAILCHECK", posixly_correct ? "600" : "60");
428 VSETATTR (temp_var, att_integer);
431 /* Do some things with shell level. */
432 initialize_shell_level ();
436 /* Initialize the `getopts' stuff. */
437 temp_var = bind_variable ("OPTIND", "1", 0);
438 VSETATTR (temp_var, att_integer);
440 bind_variable ("OPTERR", "1", 0);
443 if (login_shell == 1)
446 /* Get the full pathname to THIS shell, and set the BASH variable
448 name = get_bash_name ();
449 temp_var = bind_variable ("BASH", name, 0);
452 /* Make the exported environment variable SHELL be the user's login
453 shell. Note that the `tset' command looks at this variable
454 to determine what style of commands to output; if it ends in "csh",
455 then C-shell commands are output, else Bourne shell commands. */
458 /* Make a variable called BASH_VERSION which contains the version info. */
459 bind_variable ("BASH_VERSION", shell_version_string (), 0);
460 #if defined (ARRAY_VARS)
464 if (command_execution_string)
465 bind_variable ("BASH_EXECUTION_STRING", command_execution_string, 0);
467 /* Find out if we're supposed to be in Posix.2 mode via an
468 environment variable. */
469 temp_var = find_variable ("POSIXLY_CORRECT");
471 temp_var = find_variable ("POSIX_PEDANTIC");
472 if (temp_var && imported_p (temp_var))
473 sv_strict_posix (temp_var->name);
475 #if defined (HISTORY)
476 /* Set history variables to defaults, and then do whatever we would
477 do if the variable had just been set. Do this only in the case
478 that we are remembering commands on the history list. */
479 if (remember_on_history)
481 name = bash_tilde_expand (posixly_correct ? "~/.sh_history" : "~/.bash_history", 0);
483 set_if_not ("HISTFILE", name);
486 set_if_not ("HISTSIZE", "500");
487 sv_histsize ("HISTSIZE");
491 /* Seed the random number generator. */
492 sbrand (dollar_dollar_pid + shell_start_time);
494 /* Handle some "special" variables that we may have inherited from a
496 if (interactive_shell)
498 temp_var = find_variable ("IGNOREEOF");
500 temp_var = find_variable ("ignoreeof");
501 if (temp_var && imported_p (temp_var))
502 sv_ignoreeof (temp_var->name);
505 #if defined (HISTORY)
506 if (interactive_shell && remember_on_history)
508 sv_history_control ("HISTCONTROL");
509 sv_histignore ("HISTIGNORE");
513 #if defined (READLINE) && defined (STRICT_POSIX)
514 /* POSIXLY_CORRECT will only be 1 here if the shell was compiled
516 if (interactive_shell && posixly_correct && no_line_editing == 0)
517 rl_prefer_env_winsize = 1;
518 #endif /* READLINE && STRICT_POSIX */
523 * I'm tired of the arguing and bug reports. Bash now leaves SSH_CLIENT
524 * and SSH2_CLIENT alone. I'm going to rely on the shell_level check in
525 * isnetconn() to avoid running the startup files more often than wanted.
526 * That will, of course, only work if the user's login shell is bash, so
527 * I've made that behavior conditional on SSH_SOURCE_BASHRC being defined
531 temp_var = find_variable ("SSH_CLIENT");
532 if (temp_var && imported_p (temp_var))
534 VUNSETATTR (temp_var, att_exported);
535 array_needs_making = 1;
537 temp_var = find_variable ("SSH2_CLIENT");
538 if (temp_var && imported_p (temp_var))
540 VUNSETATTR (temp_var, att_exported);
541 array_needs_making = 1;
545 /* Get the user's real and effective user ids. */
548 /* Initialize the dynamic variables, and seed their values. */
549 initialize_dynamic_variables ();
552 /* **************************************************************** */
554 /* Setting values for special shell variables */
556 /* **************************************************************** */
563 temp_var = set_if_not ("HOSTTYPE", HOSTTYPE);
564 temp_var = set_if_not ("OSTYPE", OSTYPE);
565 temp_var = set_if_not ("MACHTYPE", MACHTYPE);
567 temp_var = set_if_not ("HOSTNAME", current_host_name);
570 /* Set $HOME to the information in the password file if we didn't get
571 it from the environment. */
573 /* This function is not static so the tilde and readline libraries can
578 if (current_user.home_dir == 0)
579 get_current_user_info ();
580 return current_user.home_dir;
588 temp_var = find_variable ("HOME");
590 temp_var = bind_variable ("HOME", sh_get_home_dir (), 0);
592 VSETATTR (temp_var, att_exported);
596 /* Set $SHELL to the user's login shell if it is not already set. Call
597 get_current_user_info if we haven't already fetched the shell. */
603 temp_var = find_variable ("SHELL");
606 if (current_user.shell == 0)
607 get_current_user_info ();
608 temp_var = bind_variable ("SHELL", current_user.shell, 0);
611 VSETATTR (temp_var, att_exported);
620 if ((login_shell == 1) && RELPATH(shell_name))
622 if (current_user.shell == 0)
623 get_current_user_info ();
624 name = savestring (current_user.shell);
626 else if (ABSPATH(shell_name))
627 name = savestring (shell_name);
628 else if (shell_name[0] == '.' && shell_name[1] == '/')
630 /* Fast path for common case. */
634 cdir = get_string_value ("PWD");
638 name = (char *)xmalloc (len + strlen (shell_name) + 1);
640 strcpy (name + len, shell_name + 1);
643 name = savestring (shell_name);
650 tname = find_user_command (shell_name);
654 /* Try the current directory. If there is not an executable
655 there, just punt and use the login shell. */
656 s = file_status (shell_name);
659 tname = make_absolute (shell_name, get_string_value ("PWD"));
660 if (*shell_name == '.')
662 name = sh_canonpath (tname, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
673 if (current_user.shell == 0)
674 get_current_user_info ();
675 name = savestring (current_user.shell);
680 name = full_pathname (tname);
689 adjust_shell_level (change)
692 char new_level[5], *old_SHLVL;
696 old_SHLVL = get_string_value ("SHLVL");
697 if (old_SHLVL == 0 || *old_SHLVL == '\0' || legal_number (old_SHLVL, &old_level) == 0)
700 shell_level = old_level + change;
703 else if (shell_level > 1000)
705 internal_warning (_("shell level (%d) too high, resetting to 1"), shell_level);
709 /* We don't need the full generality of itos here. */
710 if (shell_level < 10)
712 new_level[0] = shell_level + '0';
715 else if (shell_level < 100)
717 new_level[0] = (shell_level / 10) + '0';
718 new_level[1] = (shell_level % 10) + '0';
721 else if (shell_level < 1000)
723 new_level[0] = (shell_level / 100) + '0';
724 old_level = shell_level % 100;
725 new_level[1] = (old_level / 10) + '0';
726 new_level[2] = (old_level % 10) + '0';
730 temp_var = bind_variable ("SHLVL", new_level, 0);
731 set_auto_export (temp_var);
735 initialize_shell_level ()
737 adjust_shell_level (1);
740 /* If we got PWD from the environment, update our idea of the current
741 working directory. In any case, make sure that PWD exists before
742 checking it. It is possible for getcwd () to fail on shell startup,
743 and in that case, PWD would be undefined. If this is an interactive
744 login shell, see if $HOME is the current working directory, and if
745 that's not the same string as $PWD, set PWD=$HOME. */
750 SHELL_VAR *temp_var, *home_var;
751 char *temp_string, *home_string;
753 home_var = find_variable ("HOME");
754 home_string = home_var ? value_cell (home_var) : (char *)NULL;
756 temp_var = find_variable ("PWD");
757 if (temp_var && imported_p (temp_var) &&
758 (temp_string = value_cell (temp_var)) &&
759 same_file (temp_string, ".", (struct stat *)NULL, (struct stat *)NULL))
760 set_working_directory (temp_string);
761 else if (home_string && interactive_shell && login_shell &&
762 same_file (home_string, ".", (struct stat *)NULL, (struct stat *)NULL))
764 set_working_directory (home_string);
765 temp_var = bind_variable ("PWD", home_string, 0);
766 set_auto_export (temp_var);
770 temp_string = get_working_directory ("shell-init");
773 temp_var = bind_variable ("PWD", temp_string, 0);
774 set_auto_export (temp_var);
779 /* According to the Single Unix Specification, v2, $OLDPWD is an
780 `environment variable' and therefore should be auto-exported.
781 Make a dummy invisible variable for OLDPWD, and mark it as exported. */
782 temp_var = bind_variable ("OLDPWD", (char *)NULL, 0);
783 VSETATTR (temp_var, (att_exported | att_invisible));
786 /* Make a variable $PPID, which holds the pid of the shell's parent. */
790 char namebuf[INT_STRLEN_BOUND(pid_t) + 1], *name;
793 name = inttostr (getppid (), namebuf, sizeof(namebuf));
794 temp_var = find_variable ("PPID");
796 VUNSETATTR (temp_var, (att_readonly | att_exported));
797 temp_var = bind_variable ("PPID", name, 0);
798 VSETATTR (temp_var, (att_readonly | att_integer));
804 char buff[INT_STRLEN_BOUND(uid_t) + 1], *b;
805 register SHELL_VAR *v;
807 b = inttostr (current_user.uid, buff, sizeof (buff));
808 v = find_variable ("UID");
811 v = bind_variable ("UID", b, 0);
812 VSETATTR (v, (att_readonly | att_integer));
815 if (current_user.euid != current_user.uid)
816 b = inttostr (current_user.euid, buff, sizeof (buff));
818 v = find_variable ("EUID");
821 v = bind_variable ("EUID", b, 0);
822 VSETATTR (v, (att_readonly | att_integer));
826 #if defined (ARRAY_VARS)
832 char *s, d[32], b[INT_STRLEN_BOUND(int) + 1];
834 unbind_variable ("BASH_VERSINFO");
836 vv = make_new_array_variable ("BASH_VERSINFO");
837 av = array_cell (vv);
838 strcpy (d, dist_version);
839 s = xstrchr (d, '.');
842 array_insert (av, 0, d);
843 array_insert (av, 1, s);
844 s = inttostr (patch_level, b, sizeof (b));
845 array_insert (av, 2, s);
846 s = inttostr (build_version, b, sizeof (b));
847 array_insert (av, 3, s);
848 array_insert (av, 4, release_status);
849 array_insert (av, 5, MACHTYPE);
851 VSETATTR (vv, att_readonly);
853 #endif /* ARRAY_VARS */
855 /* Set the environment variables $LINES and $COLUMNS in response to
856 a window size change. */
858 sh_set_lines_and_columns (lines, cols)
861 char val[INT_STRLEN_BOUND(int) + 1], *v;
863 /* If we are currently assigning to LINES or COLUMNS, don't do anything. */
864 if (winsize_assignment)
867 v = inttostr (lines, val, sizeof (val));
868 bind_variable ("LINES", v, 0);
870 v = inttostr (cols, val, sizeof (val));
871 bind_variable ("COLUMNS", v, 0);
874 /* **************************************************************** */
876 /* Printing variables and values */
878 /* **************************************************************** */
880 /* Print LIST (a list of shell variables) to stdout in such a way that
881 they can be read back in. */
883 print_var_list (list)
884 register SHELL_VAR **list;
887 register SHELL_VAR *var;
889 for (i = 0; list && (var = list[i]); i++)
890 if (invisible_p (var) == 0)
891 print_assignment (var);
894 /* Print LIST (a list of shell functions) to stdout in such a way that
895 they can be read back in. */
897 print_func_list (list)
898 register SHELL_VAR **list;
901 register SHELL_VAR *var;
903 for (i = 0; list && (var = list[i]); i++)
905 printf ("%s ", var->name);
906 print_var_function (var);
911 /* Print the value of a single SHELL_VAR. No newline is
912 output, but the variable is printed in such a way that
913 it can be read back in. */
915 print_assignment (var)
918 if (var_isset (var) == 0)
921 if (function_p (var))
923 printf ("%s", var->name);
924 print_var_function (var);
927 #if defined (ARRAY_VARS)
928 else if (array_p (var))
929 print_array_assignment (var, 0);
930 #endif /* ARRAY_VARS */
933 printf ("%s=", var->name);
934 print_var_value (var, 1);
939 /* Print the value cell of VAR, a shell variable. Do not print
940 the name, nor leading/trailing newline. If QUOTE is non-zero,
941 and the value contains shell metacharacters, quote the value
942 in such a way that it can be read back in. */
944 print_var_value (var, quote)
950 if (var_isset (var) == 0)
953 if (quote && posixly_correct == 0 && ansic_shouldquote (value_cell (var)))
955 t = ansic_quote (value_cell (var), 0, (int *)0);
959 else if (quote && sh_contains_shell_metas (value_cell (var)))
961 t = sh_single_quote (value_cell (var));
966 printf ("%s", value_cell (var));
969 /* Print the function cell of VAR, a shell variable. Do not
970 print the name, nor leading/trailing newline. */
972 print_var_function (var)
975 if (function_p (var) && var_isset (var))
976 printf ("%s", named_function_string ((char *)NULL, function_cell(var), 1));
979 /* **************************************************************** */
981 /* Dynamic Variables */
983 /* **************************************************************** */
987 These are variables whose values are generated anew each time they are
988 referenced. These are implemented using a pair of function pointers
989 in the struct variable: assign_func, which is called from bind_variable
990 and, if arrays are compiled into the shell, some of the functions in
991 arrayfunc.c, and dynamic_value, which is called from find_variable.
993 assign_func is called from bind_variable_internal, if
994 bind_variable_internal discovers that the variable being assigned to
995 has such a function. The function is called as
996 SHELL_VAR *temp = (*(entry->assign_func)) (entry, value, ind)
997 and the (SHELL_VAR *)temp is returned as the value of bind_variable. It
998 is usually ENTRY (self). IND is an index for an array variable, and
1001 dynamic_value is called from find_variable_internal to return a `new'
1002 value for the specified dynamic varible. If this function is NULL,
1003 the variable is treated as a `normal' shell variable. If it is not,
1004 however, then this function is called like this:
1005 tempvar = (*(var->dynamic_value)) (var);
1007 Sometimes `tempvar' will replace the value of `var'. Other times, the
1008 shell will simply use the string value. Pretty object-oriented, huh?
1010 Be warned, though: if you `unset' a special variable, it loses its
1011 special meaning, even if you subsequently set it.
1013 The special assignment code would probably have been better put in
1014 subst.c: do_assignment_internal, in the same style as
1015 stupidly_hack_special_variables, but I wanted the changes as
1016 localized as possible. */
1018 #define INIT_DYNAMIC_VAR(var, val, gfunc, afunc) \
1021 v = bind_variable (var, (val), 0); \
1022 v->dynamic_value = gfunc; \
1023 v->assign_func = afunc; \
1027 #define INIT_DYNAMIC_ARRAY_VAR(var, gfunc, afunc) \
1030 v = make_new_array_variable (var); \
1031 v->dynamic_value = gfunc; \
1032 v->assign_func = afunc; \
1037 null_assign (self, value, unused)
1045 #if defined (ARRAY_VARS)
1047 null_array_assign (self, value, ind)
1056 /* Degenerate `dynamic_value' function; just returns what's passed without
1065 #if defined (ARRAY_VARS)
1066 /* A generic dynamic array variable initializer. Intialize array variable
1067 NAME with dynamic value function GETFUNC and assignment function SETFUNC. */
1069 init_dynamic_array_var (name, getfunc, setfunc, attrs)
1071 sh_var_value_func_t *getfunc;
1072 sh_var_assign_func_t *setfunc;
1077 v = find_variable (name);
1080 INIT_DYNAMIC_ARRAY_VAR (name, getfunc, setfunc);
1082 VSETATTR (v, attrs);
1088 /* The value of $SECONDS. This is the number of seconds since shell
1089 invocation, or, the number of seconds since the last assignment + the
1090 value of the last assignment. */
1091 static intmax_t seconds_value_assigned;
1094 assign_seconds (self, value, unused)
1099 if (legal_number (value, &seconds_value_assigned) == 0)
1100 seconds_value_assigned = 0;
1101 shell_start_time = NOW;
1109 time_t time_since_start;
1112 time_since_start = NOW - shell_start_time;
1113 p = itos(seconds_value_assigned + time_since_start);
1115 FREE (value_cell (var));
1117 VSETATTR (var, att_integer);
1118 var_setvalue (var, p);
1127 v = find_variable ("SECONDS");
1130 if (legal_number (value_cell(v), &seconds_value_assigned) == 0)
1131 seconds_value_assigned = 0;
1133 INIT_DYNAMIC_VAR ("SECONDS", (v ? value_cell (v) : (char *)NULL), get_seconds, assign_seconds);
1137 /* The random number seed. You can change this by setting RANDOM. */
1138 static unsigned long rseed = 1;
1139 static int last_random_value;
1140 static int seeded_subshell = 0;
1142 /* A linear congruential random number generator based on the example
1143 one in the ANSI C standard. This one isn't very good, but a more
1144 complicated one is overkill. */
1146 /* Returns a pseudo-random number between 0 and 32767. */
1150 rseed = rseed * 1103515245 + 12345;
1151 return ((unsigned int)((rseed >> 16) & 32767)); /* was % 32768 */
1154 /* Set the random number generator seed to SEED. */
1160 last_random_value = 0;
1164 assign_random (self, value, unused)
1169 sbrand (strtoul (value, (char **)NULL, 10));
1170 if (subshell_environment)
1171 seeded_subshell = 1;
1176 get_random_number ()
1180 /* Reset for command and process substitution. */
1181 if (subshell_environment && seeded_subshell == 0)
1183 sbrand (rseed + getpid() + NOW);
1184 seeded_subshell = 1;
1189 while (rv == last_random_value);
1200 rv = get_random_number ();
1201 last_random_value = rv;
1204 FREE (value_cell (var));
1206 VSETATTR (var, att_integer);
1207 var_setvalue (var, p);
1212 assign_lineno (var, value, unused)
1219 if (value == 0 || *value == '\0' || legal_number (value, &new_value) == 0)
1221 line_number = new_value;
1225 /* Function which returns the current line number. */
1233 ln = executing_line_number ();
1235 FREE (value_cell (var));
1236 var_setvalue (var, p);
1241 assign_subshell (var, value, unused)
1248 if (value == 0 || *value == '\0' || legal_number (value, &new_value) == 0)
1250 subshell_level = new_value;
1260 p = itos (subshell_level);
1261 FREE (value_cell (var));
1262 var_setvalue (var, p);
1267 get_bash_command (var)
1273 if (the_printed_command_except_trap)
1274 p = savestring (the_printed_command_except_trap);
1277 p = (char *)xmalloc (1);
1280 FREE (value_cell (var));
1281 var_setvalue (var, p);
1285 #if defined (HISTORY)
1292 p = itos (history_number ());
1293 FREE (value_cell (var));
1294 var_setvalue (var, p);
1299 #if defined (READLINE)
1300 /* When this function returns, VAR->value points to malloced memory. */
1302 get_comp_wordbreaks (var)
1307 /* If we don't have anything yet, assign a default value. */
1308 if (rl_completer_word_break_characters == 0 && bash_readline_initialized == 0)
1309 enable_hostname_completion (perform_hostname_completion);
1312 FREE (value_cell (var));
1313 p = savestring (rl_completer_word_break_characters);
1315 var_setvalue (var, p);
1317 var_setvalue (var, rl_completer_word_break_characters);
1323 /* When this function returns, rl_completer_word_break_characters points to
1326 assign_comp_wordbreaks (self, value, unused)
1331 if (rl_completer_word_break_characters &&
1332 rl_completer_word_break_characters != rl_basic_word_break_characters)
1333 free (rl_completer_word_break_characters);
1335 rl_completer_word_break_characters = savestring (value);
1338 #endif /* READLINE */
1340 #if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
1342 assign_dirstack (self, value, ind)
1347 set_dirstack_element (ind, 1, value);
1358 l = get_directory_stack ();
1359 a = array_from_word_list (l);
1360 array_dispose (array_cell (self));
1362 var_setarray (self, a);
1365 #endif /* PUSHD AND POPD && ARRAY_VARS */
1367 #if defined (ARRAY_VARS)
1368 /* We don't want to initialize the group set with a call to getgroups()
1369 unless we're asked to, but we only want to do it once. */
1377 static char **group_set = (char **)NULL;
1381 group_set = get_group_list (&ng);
1382 a = array_cell (self);
1383 for (i = 0; i < ng; i++)
1384 array_insert (a, i, group_set[i]);
1388 #endif /* ARRAY_VARS */
1390 /* If ARRAY_VARS is not defined, this just returns the name of any
1391 currently-executing function. If we have arrays, it's a call stack. */
1396 #if ! defined (ARRAY_VARS)
1398 if (variable_context && this_shell_function)
1400 FREE (value_cell (self));
1401 t = savestring (this_shell_function->name);
1402 var_setvalue (self, t);
1409 make_funcname_visible (on_or_off)
1414 v = find_variable ("FUNCNAME");
1415 if (v == 0 || v->dynamic_value == 0)
1419 VUNSETATTR (v, att_invisible);
1421 VSETATTR (v, att_invisible);
1425 init_funcname_var ()
1429 v = find_variable ("FUNCNAME");
1432 #if defined (ARRAY_VARS)
1433 INIT_DYNAMIC_ARRAY_VAR ("FUNCNAME", get_funcname, null_array_assign);
1435 INIT_DYNAMIC_VAR ("FUNCNAME", (char *)NULL, get_funcname, null_assign);
1437 VSETATTR (v, att_invisible|att_noassign);
1442 initialize_dynamic_variables ()
1446 v = init_seconds_var ();
1448 INIT_DYNAMIC_VAR ("BASH_COMMAND", (char *)NULL, get_bash_command, (sh_var_assign_func_t *)NULL);
1449 INIT_DYNAMIC_VAR ("BASH_SUBSHELL", (char *)NULL, get_subshell, assign_subshell);
1451 INIT_DYNAMIC_VAR ("RANDOM", (char *)NULL, get_random, assign_random);
1452 VSETATTR (v, att_integer);
1453 INIT_DYNAMIC_VAR ("LINENO", (char *)NULL, get_lineno, assign_lineno);
1454 VSETATTR (v, att_integer);
1456 #if defined (HISTORY)
1457 INIT_DYNAMIC_VAR ("HISTCMD", (char *)NULL, get_histcmd, (sh_var_assign_func_t *)NULL);
1458 VSETATTR (v, att_integer);
1461 #if defined (READLINE)
1462 INIT_DYNAMIC_VAR ("COMP_WORDBREAKS", (char *)NULL, get_comp_wordbreaks, assign_comp_wordbreaks);
1465 #if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
1466 v = init_dynamic_array_var ("DIRSTACK", get_dirstack, assign_dirstack, 0);
1467 #endif /* PUSHD_AND_POPD && ARRAY_VARS */
1469 #if defined (ARRAY_VARS)
1470 v = init_dynamic_array_var ("GROUPS", get_groupset, null_array_assign, att_noassign);
1472 # if defined (DEBUGGER)
1473 v = init_dynamic_array_var ("BASH_ARGC", get_self, null_array_assign, att_noassign|att_nounset);
1474 v = init_dynamic_array_var ("BASH_ARGV", get_self, null_array_assign, att_noassign|att_nounset);
1475 # endif /* DEBUGGER */
1476 v = init_dynamic_array_var ("BASH_SOURCE", get_self, null_array_assign, att_noassign|att_nounset);
1477 v = init_dynamic_array_var ("BASH_LINENO", get_self, null_array_assign, att_noassign|att_nounset);
1480 v = init_funcname_var ();
1483 /* **************************************************************** */
1485 /* Retrieving variables and values */
1487 /* **************************************************************** */
1489 /* How to get a pointer to the shell variable or function named NAME.
1490 HASHED_VARS is a pointer to the hash table containing the list
1491 of interest (either variables or functions). */
1494 hash_lookup (name, hashed_vars)
1496 HASH_TABLE *hashed_vars;
1498 BUCKET_CONTENTS *bucket;
1500 bucket = hash_search (name, hashed_vars, 0);
1501 return (bucket ? (SHELL_VAR *)bucket->data : (SHELL_VAR *)NULL);
1505 var_lookup (name, vcontext)
1507 VAR_CONTEXT *vcontext;
1512 v = (SHELL_VAR *)NULL;
1513 for (vc = vcontext; vc; vc = vc->down)
1514 if (v = hash_lookup (name, vc->table))
1520 /* Look up the variable entry named NAME. If SEARCH_TEMPENV is non-zero,
1521 then also search the temporarily built list of exported variables.
1522 The lookup order is:
1524 shell_variables list
1528 find_variable_internal (name, force_tempenv)
1535 var = (SHELL_VAR *)NULL;
1537 /* If explicitly requested, first look in the temporary environment for
1538 the variable. This allows constructs such as "foo=x eval 'echo $foo'"
1539 to get the `exported' value of $foo. This happens if we are executing
1540 a function or builtin, or if we are looking up a variable in a
1541 "subshell environment". */
1542 search_tempenv = force_tempenv || (expanding_redir == 0 && subshell_environment);
1544 if (search_tempenv && temporary_env)
1545 var = hash_lookup (name, temporary_env);
1548 var = var_lookup (name, shell_variables);
1551 return ((SHELL_VAR *)NULL);
1553 return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var);
1556 /* Look up the variable entry named NAME. Returns the entry or NULL. */
1558 find_variable (name)
1561 return (find_variable_internal (name, (expanding_redir == 0 && this_shell_builtin != 0)));
1564 /* Look up the function entry whose name matches STRING.
1565 Returns the entry or NULL. */
1567 find_function (name)
1570 return (hash_lookup (name, shell_functions));
1573 /* Find the function definition for the shell function named NAME. Returns
1574 the entry or NULL. */
1576 find_function_def (name)
1579 return ((FUNCTION_DEF *)hash_lookup (name, shell_function_defs));
1582 /* Return the value of VAR. VAR is assumed to have been the result of a
1583 lookup without any subscript, if arrays are compiled into the shell. */
1585 get_variable_value (var)
1589 return ((char *)NULL);
1590 #if defined (ARRAY_VARS)
1591 else if (array_p (var))
1592 return (array_reference (array_cell (var), 0));
1595 return (value_cell (var));
1598 /* Return the string value of a variable. Return NULL if the variable
1599 doesn't exist. Don't cons a new string. This is a potential memory
1600 leak if the variable is found in the temporary environment. Since
1601 functions and variables have separate name spaces, returns NULL if
1602 var_name is a shell function only. */
1604 get_string_value (var_name)
1605 const char *var_name;
1609 var = find_variable (var_name);
1610 return ((var) ? get_variable_value (var) : (char *)NULL);
1613 /* This is present for use by the tilde and readline libraries. */
1615 sh_get_env_value (v)
1618 return get_string_value (v);
1621 /* **************************************************************** */
1623 /* Creating and setting variables */
1625 /* **************************************************************** */
1627 /* Set NAME to VALUE if NAME has no value. */
1629 set_if_not (name, value)
1634 v = find_variable (name);
1636 v = bind_variable_internal (name, value, global_variables->table, HASH_NOSRCH, 0);
1640 /* Create a local variable referenced by NAME. */
1642 make_local_variable (name)
1645 SHELL_VAR *new_var, *old_var;
1650 /* local foo; local foo; is a no-op. */
1651 old_var = find_variable (name);
1652 if (old_var && local_p (old_var) && old_var->context == variable_context)
1654 VUNSETATTR (old_var, att_invisible);
1658 was_tmpvar = old_var && tempvar_p (old_var);
1660 tmp_value = value_cell (old_var);
1662 for (vc = shell_variables; vc; vc = vc->down)
1663 if (vc_isfuncenv (vc) && vc->scope == variable_context)
1668 internal_error (_("make_local_variable: no function context at current scope"));
1669 return ((SHELL_VAR *)NULL);
1671 else if (vc->table == 0)
1672 vc->table = hash_create (TEMPENV_HASH_BUCKETS);
1674 /* Since this is called only from the local/declare/typeset code, we can
1675 call builtin_error here without worry (of course, it will also work
1676 for anything that sets this_command_name). Variables with the `noassign'
1677 attribute may not be made local. The test against old_var's context
1678 level is to disallow local copies of readonly global variables (since I
1679 believe that this could be a security hole). Readonly copies of calling
1680 function local variables are OK. */
1681 if (old_var && (noassign_p (old_var) ||
1682 (readonly_p (old_var) && old_var->context == 0)))
1684 if (readonly_p (old_var))
1686 return ((SHELL_VAR *)NULL);
1690 new_var = bind_variable_internal (name, "", vc->table, HASH_NOSRCH, 0);
1693 new_var = make_new_variable (name, vc->table);
1695 /* If we found this variable in one of the temporary environments,
1696 inherit its value. Watch to see if this causes problems with
1697 things like `x=4 local x'. */
1699 var_setvalue (new_var, savestring (tmp_value));
1701 new_var->attributes = exported_p (old_var) ? att_exported : 0;
1704 vc->flags |= VC_HASLOCAL;
1706 new_var->context = variable_context;
1707 VSETATTR (new_var, att_local);
1715 #if defined (ARRAY_VARS)
1717 make_local_array_variable (name)
1723 var = make_local_variable (name);
1724 if (var == 0 || array_p (var))
1727 array = array_create ();
1729 FREE (value_cell(var));
1730 var_setarray (var, array);
1731 VSETATTR (var, att_array);
1734 #endif /* ARRAY_VARS */
1736 /* Create a new shell variable with name NAME. */
1738 new_shell_variable (name)
1743 entry = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
1745 entry->name = savestring (name);
1746 var_setvalue (entry, (char *)NULL);
1747 CLEAR_EXPORTSTR (entry);
1749 entry->dynamic_value = (sh_var_value_func_t *)NULL;
1750 entry->assign_func = (sh_var_assign_func_t *)NULL;
1752 entry->attributes = 0;
1754 /* Always assume variables are to be made at toplevel!
1755 make_local_variable has the responsibilty of changing the
1756 variable context. */
1762 /* Create a new shell variable with name NAME and add it to the hash table
1765 make_new_variable (name, table)
1770 BUCKET_CONTENTS *elt;
1772 entry = new_shell_variable (name);
1774 /* Make sure we have a shell_variables hash table to add to. */
1775 if (shell_variables == 0)
1777 shell_variables = global_variables = new_var_context ((char *)NULL, 0);
1778 shell_variables->scope = 0;
1779 shell_variables->table = hash_create (0);
1782 elt = hash_insert (savestring (name), table, HASH_NOSRCH);
1783 elt->data = (PTR_T)entry;
1788 #if defined (ARRAY_VARS)
1790 make_new_array_variable (name)
1796 entry = make_new_variable (name, global_variables->table);
1797 array = array_create ();
1798 var_setarray (entry, array);
1799 VSETATTR (entry, att_array);
1805 make_variable_value (var, value, flags)
1810 char *retval, *oval;
1811 intmax_t lval, rval;
1814 /* If this variable has had its type set to integer (via `declare -i'),
1815 then do expression evaluation on it and store the result. The
1816 functions in expr.c (evalexp()) and bind_int_variable() are responsible
1817 for turning off the integer flag if they don't want further
1819 if (integer_p (var))
1821 if (flags & ASS_APPEND)
1823 oval = value_cell (var);
1824 lval = evalexp (oval, &expok); /* ksh93 seems to do this */
1826 jump_to_top_level (DISCARD);
1828 rval = evalexp (value, &expok);
1830 jump_to_top_level (DISCARD);
1831 if (flags & ASS_APPEND)
1833 retval = itos (rval);
1837 if (flags & ASS_APPEND)
1839 oval = get_variable_value (var);
1840 if (oval == 0) /* paranoia */
1842 olen = STRLEN (oval);
1843 retval = (char *)xmalloc (olen + (value ? STRLEN (value) : 0) + 1);
1844 strcpy (retval, oval);
1846 strcpy (retval+olen, value);
1849 retval = savestring (value);
1852 retval = (char *)xmalloc (1);
1857 retval = (char *)NULL;
1862 /* Bind a variable NAME to VALUE in the HASH_TABLE TABLE, which may be the
1863 temporary environment (but usually is not). */
1865 bind_variable_internal (name, value, table, hflags, aflags)
1874 entry = (hflags & HASH_NOSRCH) ? (SHELL_VAR *)NULL : hash_lookup (name, table);
1878 entry = make_new_variable (name, table);
1879 var_setvalue (entry, make_variable_value (entry, value, 0)); /* XXX */
1881 else if (entry->assign_func) /* array vars have assign functions now */
1883 INVALIDATE_EXPORTSTR (entry);
1884 newval = (aflags & ASS_APPEND) ? make_variable_value (entry, value, aflags) : value;
1885 entry = (*(entry->assign_func)) (entry, newval, -1);
1886 if (newval != value)
1892 if (readonly_p (entry) || noassign_p (entry))
1894 if (readonly_p (entry))
1895 err_readonly (name);
1899 /* Variables which are bound are visible. */
1900 VUNSETATTR (entry, att_invisible);
1902 newval = make_variable_value (entry, value, aflags); /* XXX */
1904 /* Invalidate any cached export string */
1905 INVALIDATE_EXPORTSTR (entry);
1907 #if defined (ARRAY_VARS)
1908 /* XXX -- this bears looking at again -- XXX */
1909 /* If an existing array variable x is being assigned to with x=b or
1910 `read x' or something of that nature, silently convert it to
1911 x[0]=b or `read x[0]'. */
1912 if (array_p (entry))
1914 array_insert (array_cell (entry), 0, newval);
1920 FREE (value_cell (entry));
1921 var_setvalue (entry, newval);
1925 if (mark_modified_vars)
1926 VSETATTR (entry, att_exported);
1928 if (exported_p (entry))
1929 array_needs_making = 1;
1934 /* Bind a variable NAME to VALUE. This conses up the name
1935 and value strings. If we have a temporary environment, we bind there
1936 first, then we bind into shell_variables. */
1939 bind_variable (name, value, flags)
1947 if (shell_variables == 0)
1949 shell_variables = global_variables = new_var_context ((char *)NULL, 0);
1950 shell_variables->scope = 0;
1951 shell_variables->table = hash_create (0);
1954 /* If we have a temporary environment, look there first for the variable,
1955 and, if found, modify the value there before modifying it in the
1956 shell_variables table. This allows sourced scripts to modify values
1957 given to them in a temporary environment while modifying the variable
1958 value that the caller sees. */
1960 bind_tempenv_variable (name, value);
1962 /* XXX -- handle local variables here. */
1963 for (vc = shell_variables; vc; vc = vc->down)
1965 if (vc_isfuncenv (vc) || vc_isbltnenv (vc))
1967 v = hash_lookup (name, vc->table);
1969 return (bind_variable_internal (name, value, vc->table, 0, flags));
1972 return (bind_variable_internal (name, value, global_variables->table, 0, flags));
1975 /* Make VAR, a simple shell variable, have value VALUE. Once assigned a
1976 value, variables are no longer invisible. This is a duplicate of part
1977 of the internals of bind_variable. If the variable is exported, or
1978 all modified variables should be exported, mark the variable for export
1979 and note that the export environment needs to be recreated. */
1981 bind_variable_value (var, value, aflags)
1988 VUNSETATTR (var, att_invisible);
1990 if (var->assign_func)
1992 /* If we're appending, we need the old value, so use
1993 make_variable_value */
1994 t = (aflags & ASS_APPEND) ? make_variable_value (var, value, aflags) : value;
1995 (*(var->assign_func)) (var, t, -1);
1996 if (t != value && t)
2001 t = make_variable_value (var, value, aflags);
2002 FREE (value_cell (var));
2003 var_setvalue (var, t);
2006 INVALIDATE_EXPORTSTR (var);
2008 if (mark_modified_vars)
2009 VSETATTR (var, att_exported);
2011 if (exported_p (var))
2012 array_needs_making = 1;
2017 /* Bind/create a shell variable with the name LHS to the RHS.
2018 This creates or modifies a variable such that it is an integer.
2020 This used to be in expr.c, but it is here so that all of the
2021 variable binding stuff is localized. Since we don't want any
2022 recursive evaluation from bind_variable() (possible without this code,
2023 since bind_variable() calls the evaluator for variables with the integer
2024 attribute set), we temporarily turn off the integer attribute for each
2025 variable we set here, then turn it back on after binding as necessary. */
2028 bind_int_variable (lhs, rhs)
2031 register SHELL_VAR *v;
2036 #if defined (ARRAY_VARS)
2038 if (t = xstrchr (lhs, '[')) /*]*/
2040 if (valid_array_reference (lhs))
2044 v = array_variable_part (lhs, (char **)0, (int *)0);
2048 v = find_variable (lhs);
2052 isint = integer_p (v);
2053 VUNSETATTR (v, att_integer);
2056 #if defined (ARRAY_VARS)
2058 v = assign_array_element (lhs, rhs, 0);
2061 v = bind_variable (lhs, rhs, 0);
2064 VSETATTR (v, att_integer);
2070 bind_var_to_int (var, val)
2074 char ibuf[INT_STRLEN_BOUND (intmax_t) + 1], *p;
2076 p = fmtulong (val, 10, ibuf, sizeof (ibuf), 0);
2077 return (bind_int_variable (var, p));
2080 /* Do a function binding to a variable. You pass the name and
2081 the command to bind to. This conses the name and command. */
2083 bind_function (name, value)
2089 entry = find_function (name);
2092 BUCKET_CONTENTS *elt;
2094 elt = hash_insert (savestring (name), shell_functions, HASH_NOSRCH);
2095 entry = new_shell_variable (name);
2096 elt->data = (PTR_T)entry;
2099 INVALIDATE_EXPORTSTR (entry);
2101 if (var_isset (entry))
2102 dispose_command (function_cell (entry));
2105 var_setfunc (entry, copy_command (value));
2107 var_setfunc (entry, 0);
2109 VSETATTR (entry, att_function);
2111 if (mark_modified_vars)
2112 VSETATTR (entry, att_exported);
2114 VUNSETATTR (entry, att_invisible); /* Just to be sure */
2116 if (exported_p (entry))
2117 array_needs_making = 1;
2119 #if defined (PROGRAMMABLE_COMPLETION)
2120 set_itemlist_dirty (&it_functions);
2126 /* Bind a function definition, which includes source file and line number
2127 information in addition to the command, into the FUNCTION_DEF hash table.*/
2129 bind_function_def (name, value)
2131 FUNCTION_DEF *value;
2133 FUNCTION_DEF *entry;
2134 BUCKET_CONTENTS *elt;
2137 entry = find_function_def (name);
2140 dispose_function_def_contents (entry);
2141 entry = copy_function_def_contents (value, entry);
2145 cmd = value->command;
2147 entry = copy_function_def (value);
2148 value->command = cmd;
2150 elt = hash_insert (savestring (name), shell_function_defs, HASH_NOSRCH);
2151 elt->data = (PTR_T *)entry;
2155 /* Add STRING, which is of the form foo=bar, to the temporary environment
2156 HASH_TABLE (temporary_env). The functions in execute_cmd.c are
2157 responsible for moving the main temporary env to one of the other
2158 temporary environments. The expansion code in subst.c calls this. */
2160 assign_in_env (word)
2164 char *name, *temp, *value;
2168 string = word->word;
2170 offset = assignment (string, 0);
2171 name = savestring (string);
2172 value = (char *)NULL;
2174 if (name[offset] == '=')
2178 /* ignore the `+' when assigning temporary environment */
2179 if (name[offset - 1] == '+')
2180 name[offset - 1] = '\0';
2182 var = find_variable (name);
2183 if (var && (readonly_p (var) || noassign_p (var)))
2185 if (readonly_p (var))
2186 err_readonly (name);
2191 temp = name + offset + 1;
2193 temp = (xstrchr (temp, '~') != 0) ? bash_tilde_expand (temp, 1) : savestring (temp);
2194 value = expand_string_unsplit_to_string (temp, 0);
2197 value = expand_assignment_string_to_string (temp, 0);
2201 if (temporary_env == 0)
2202 temporary_env = hash_create (TEMPENV_HASH_BUCKETS);
2204 var = hash_lookup (name, temporary_env);
2206 var = make_new_variable (name, temporary_env);
2208 FREE (value_cell (var));
2212 value = (char *)xmalloc (1); /* like do_assignment_internal */
2216 var_setvalue (var, value);
2217 var->attributes |= (att_exported|att_tempvar);
2218 var->context = variable_context; /* XXX */
2220 INVALIDATE_EXPORTSTR (var);
2221 var->exportstr = mk_env_string (name, value);
2223 array_needs_making = 1;
2228 if (echo_command_at_execute)
2229 /* The Korn shell prints the `+ ' in front of assignment statements,
2231 xtrace_print_assignment (name, value, 0, 1);
2237 /* **************************************************************** */
2239 /* Copying variables */
2241 /* **************************************************************** */
2243 #ifdef INCLUDE_UNUSED
2244 /* Copy VAR to a new data structure and return that structure. */
2249 SHELL_VAR *copy = (SHELL_VAR *)NULL;
2253 copy = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
2255 copy->attributes = var->attributes;
2256 copy->name = savestring (var->name);
2258 if (function_p (var))
2259 var_setfunc (copy, copy_command (function_cell (var)));
2260 #if defined (ARRAY_VARS)
2261 else if (array_p (var))
2262 var_setarray (copy, dup_array (array_cell (var)));
2264 else if (value_cell (var))
2265 var_setvalue (copy, savestring (value_cell (var)));
2267 var_setvalue (copy, (char *)NULL);
2269 copy->dynamic_value = var->dynamic_value;
2270 copy->assign_func = var->assign_func;
2272 copy->exportstr = COPY_EXPORTSTR (var);
2274 copy->context = var->context;
2280 /* **************************************************************** */
2282 /* Deleting and unsetting variables */
2284 /* **************************************************************** */
2286 /* Dispose of the information attached to VAR. */
2288 dispose_variable (var)
2294 if (function_p (var))
2295 dispose_command (function_cell (var));
2296 #if defined (ARRAY_VARS)
2297 else if (array_p (var))
2298 array_dispose (array_cell (var));
2301 FREE (value_cell (var));
2303 FREE_EXPORTSTR (var);
2307 if (exported_p (var))
2308 array_needs_making = 1;
2313 /* Unset the shell variable referenced by NAME. */
2315 unbind_variable (name)
2318 return makunbound (name, shell_variables);
2321 /* Unset the shell function named NAME. */
2326 BUCKET_CONTENTS *elt;
2329 elt = hash_remove (name, shell_functions, 0);
2334 #if defined (PROGRAMMABLE_COMPLETION)
2335 set_itemlist_dirty (&it_functions);
2338 func = (SHELL_VAR *)elt->data;
2341 if (exported_p (func))
2342 array_needs_making++;
2343 dispose_variable (func);
2353 unbind_function_def (name)
2356 BUCKET_CONTENTS *elt;
2357 FUNCTION_DEF *funcdef;
2359 elt = hash_remove (name, shell_function_defs, 0);
2364 funcdef = (FUNCTION_DEF *)elt->data;
2366 dispose_function_def (funcdef);
2374 /* Make the variable associated with NAME go away. HASH_LIST is the
2375 hash table from which this variable should be deleted (either
2376 shell_variables or shell_functions).
2377 Returns non-zero if the variable couldn't be found. */
2379 makunbound (name, vc)
2383 BUCKET_CONTENTS *elt, *new_elt;
2388 for (elt = (BUCKET_CONTENTS *)NULL, v = vc; v; v = v->down)
2389 if (elt = hash_remove (name, v->table, 0))
2395 old_var = (SHELL_VAR *)elt->data;
2397 if (old_var && exported_p (old_var))
2398 array_needs_making++;
2400 /* If we're unsetting a local variable and we're still executing inside
2401 the function, just mark the variable as invisible. The function
2402 eventually called by pop_var_context() will clean it up later. This
2403 must be done so that if the variable is subsequently assigned a new
2404 value inside the function, the `local' attribute is still present.
2405 We also need to add it back into the correct hash table. */
2406 if (old_var && local_p (old_var) && variable_context == old_var->context)
2408 #if defined (ARRAY_VARS)
2409 if (array_p (old_var))
2410 array_dispose (array_cell (old_var));
2413 FREE (value_cell (old_var));
2414 /* Reset the attributes. Preserve the export attribute if the variable
2415 came from a temporary environment. Make sure it stays local, and
2416 make it invisible. */
2417 old_var->attributes = (exported_p (old_var) && tempvar_p (old_var)) ? att_exported : 0;
2418 VSETATTR (old_var, att_local);
2419 VSETATTR (old_var, att_invisible);
2420 var_setvalue (old_var, (char *)NULL);
2421 INVALIDATE_EXPORTSTR (old_var);
2423 new_elt = hash_insert (savestring (old_var->name), v->table, 0);
2424 new_elt->data = (PTR_T)old_var;
2425 stupidly_hack_special_variables (old_var->name);
2432 /* Have to save a copy of name here, because it might refer to
2433 old_var->name. If so, stupidly_hack_special_variables will
2434 reference freed memory. */
2435 t = savestring (name);
2440 dispose_variable (old_var);
2441 stupidly_hack_special_variables (t);
2447 /* Get rid of all of the variables in the current context. */
2449 kill_all_local_variables ()
2453 for (vc = shell_variables; vc; vc = vc->down)
2454 if (vc_isfuncenv (vc) && vc->scope == variable_context)
2459 if (vc->table && vc_haslocals (vc))
2461 delete_all_variables (vc->table);
2462 hash_dispose (vc->table);
2464 vc->table = (HASH_TABLE *)NULL;
2468 free_variable_hash_data (data)
2473 var = (SHELL_VAR *)data;
2474 dispose_variable (var);
2477 /* Delete the entire contents of the hash table. */
2479 delete_all_variables (hashed_vars)
2480 HASH_TABLE *hashed_vars;
2482 hash_flush (hashed_vars, free_variable_hash_data);
2485 /* **************************************************************** */
2487 /* Setting variable attributes */
2489 /* **************************************************************** */
2491 #define FIND_OR_MAKE_VARIABLE(name, entry) \
2494 entry = find_variable (name); \
2497 entry = bind_variable (name, "", 0); \
2498 if (!no_invisible_vars) entry->attributes |= att_invisible; \
2503 /* Make the variable associated with NAME be readonly.
2504 If NAME does not exist yet, create it. */
2506 set_var_read_only (name)
2511 FIND_OR_MAKE_VARIABLE (name, entry);
2512 VSETATTR (entry, att_readonly);
2515 #ifdef INCLUDE_UNUSED
2516 /* Make the function associated with NAME be readonly.
2517 If NAME does not exist, we just punt, like auto_export code below. */
2519 set_func_read_only (name)
2524 entry = find_function (name);
2526 VSETATTR (entry, att_readonly);
2529 /* Make the variable associated with NAME be auto-exported.
2530 If NAME does not exist yet, create it. */
2532 set_var_auto_export (name)
2537 FIND_OR_MAKE_VARIABLE (name, entry);
2538 set_auto_export (entry);
2541 /* Make the function associated with NAME be auto-exported. */
2543 set_func_auto_export (name)
2548 entry = find_function (name);
2550 set_auto_export (entry);
2554 /* **************************************************************** */
2556 /* Creating lists of variables */
2558 /* **************************************************************** */
2561 vlist_alloc (nentries)
2566 vlist = (VARLIST *)xmalloc (sizeof (VARLIST));
2567 vlist->list = (SHELL_VAR **)xmalloc ((nentries + 1) * sizeof (SHELL_VAR *));
2568 vlist->list_size = nentries;
2569 vlist->list_len = 0;
2570 vlist->list[0] = (SHELL_VAR *)NULL;
2576 vlist_realloc (vlist, n)
2581 return (vlist = vlist_alloc (n));
2582 if (n > vlist->list_size)
2584 vlist->list_size = n;
2585 vlist->list = (SHELL_VAR **)xrealloc (vlist->list, (vlist->list_size + 1) * sizeof (SHELL_VAR *));
2591 vlist_add (vlist, var, flags)
2598 for (i = 0; i < vlist->list_len; i++)
2599 if (STREQ (var->name, vlist->list[i]->name))
2601 if (i < vlist->list_len)
2604 if (i >= vlist->list_size)
2605 vlist = vlist_realloc (vlist, vlist->list_size + 16);
2607 vlist->list[vlist->list_len++] = var;
2608 vlist->list[vlist->list_len] = (SHELL_VAR *)NULL;
2611 /* Map FUNCTION over the variables in VAR_HASH_TABLE. Return an array of the
2612 variables for which FUNCTION returns a non-zero value. A NULL value
2613 for FUNCTION means to use all variables. */
2615 map_over (function, vc)
2616 sh_var_map_func_t *function;
2624 for (nentries = 0, v = vc; v; v = v->down)
2625 nentries += HASH_ENTRIES (v->table);
2628 return (SHELL_VAR **)NULL;
2630 vlist = vlist_alloc (nentries);
2632 for (v = vc; v; v = v->down)
2633 flatten (v->table, function, vlist, 0);
2641 map_over_funcs (function)
2642 sh_var_map_func_t *function;
2647 if (shell_functions == 0 || HASH_ENTRIES (shell_functions) == 0)
2648 return ((SHELL_VAR **)NULL);
2650 vlist = vlist_alloc (HASH_ENTRIES (shell_functions));
2652 flatten (shell_functions, function, vlist, 0);
2659 /* Flatten VAR_HASH_TABLE, applying FUNC to each member and adding those
2660 elements for which FUNC succeeds to VLIST->list. FLAGS is reserved
2661 for future use. Only unique names are added to VLIST. If FUNC is
2662 NULL, each variable in VAR_HASH_TABLE is added to VLIST. If VLIST is
2663 NULL, FUNC is applied to each SHELL_VAR in VAR_HASH_TABLE. If VLIST
2664 and FUNC are both NULL, nothing happens. */
2666 flatten (var_hash_table, func, vlist, flags)
2667 HASH_TABLE *var_hash_table;
2668 sh_var_map_func_t *func;
2673 register BUCKET_CONTENTS *tlist;
2677 if (var_hash_table == 0 || (HASH_ENTRIES (var_hash_table) == 0) || (vlist == 0 && func == 0))
2680 for (i = 0; i < var_hash_table->nbuckets; i++)
2682 for (tlist = hash_items (i, var_hash_table); tlist; tlist = tlist->next)
2684 var = (SHELL_VAR *)tlist->data;
2686 r = func ? (*func) (var) : 1;
2688 vlist_add (vlist, var, flags);
2694 sort_variables (array)
2697 qsort (array, strvec_len ((char **)array), sizeof (SHELL_VAR *), (QSFUNC *)qsort_var_comp);
2701 qsort_var_comp (var1, var2)
2702 SHELL_VAR **var1, **var2;
2706 if ((result = (*var1)->name[0] - (*var2)->name[0]) == 0)
2707 result = strcmp ((*var1)->name, (*var2)->name);
2712 /* Apply FUNC to each variable in SHELL_VARIABLES, adding each one for
2713 which FUNC succeeds to an array of SHELL_VAR *s. Returns the array. */
2716 sh_var_map_func_t *func;
2720 list = map_over (func, shell_variables);
2721 if (list /* && posixly_correct */)
2722 sort_variables (list);
2726 /* Apply FUNC to each variable in SHELL_FUNCTIONS, adding each one for
2727 which FUNC succeeds to an array of SHELL_VAR *s. Returns the array. */
2730 sh_var_map_func_t *func;
2734 list = map_over_funcs (func);
2735 if (list /* && posixly_correct */)
2736 sort_variables (list);
2740 /* Create a NULL terminated array of all the shell variables. */
2742 all_shell_variables ()
2744 return (vapply ((sh_var_map_func_t *)NULL));
2747 /* Create a NULL terminated array of all the shell functions. */
2749 all_shell_functions ()
2751 return (fapply ((sh_var_map_func_t *)NULL));
2758 return (invisible_p (var) == 0);
2762 all_visible_functions ()
2764 return (fapply (visible_var));
2768 all_visible_variables ()
2770 return (vapply (visible_var));
2773 /* Return non-zero if the variable VAR is visible and exported. Array
2774 variables cannot be exported. */
2776 visible_and_exported (var)
2779 return (invisible_p (var) == 0 && exported_p (var));
2782 /* Return non-zero if VAR is a local variable in the current context and
2785 local_and_exported (var)
2788 return (invisible_p (var) == 0 && local_p (var) && var->context == variable_context && exported_p (var));
2792 all_exported_variables ()
2794 return (vapply (visible_and_exported));
2798 local_exported_variables ()
2800 return (vapply (local_and_exported));
2804 variable_in_context (var)
2807 return (invisible_p (var) == 0 && local_p (var) && var->context == variable_context);
2811 all_local_variables ()
2817 vc = shell_variables;
2818 for (vc = shell_variables; vc; vc = vc->down)
2819 if (vc_isfuncenv (vc) && vc->scope == variable_context)
2824 internal_error (_("all_local_variables: no function context at current scope"));
2825 return (SHELL_VAR **)NULL;
2827 if (vc->table == 0 || HASH_ENTRIES (vc->table) == 0 || vc_haslocals (vc) == 0)
2828 return (SHELL_VAR **)NULL;
2830 vlist = vlist_alloc (HASH_ENTRIES (vc->table));
2832 flatten (vc->table, variable_in_context, vlist, 0);
2837 sort_variables (ret);
2841 #if defined (ARRAY_VARS)
2842 /* Return non-zero if the variable VAR is visible and an array. */
2844 visible_array_vars (var)
2847 return (invisible_p (var) == 0 && array_p (var));
2851 all_array_variables ()
2853 return (vapply (visible_array_vars));
2855 #endif /* ARRAY_VARS */
2858 all_variables_matching_prefix (prefix)
2861 SHELL_VAR **varlist;
2863 int vind, rind, plen;
2865 plen = STRLEN (prefix);
2866 varlist = all_visible_variables ();
2867 for (vind = 0; varlist && varlist[vind]; vind++)
2869 if (varlist == 0 || vind == 0)
2870 return ((char **)NULL);
2871 rlist = strvec_create (vind + 1);
2872 for (vind = rind = 0; varlist[vind]; vind++)
2874 if (plen == 0 || STREQN (prefix, varlist[vind]->name, plen))
2875 rlist[rind++] = savestring (varlist[vind]->name);
2877 rlist[rind] = (char *)0;
2883 /* **************************************************************** */
2885 /* Managing temporary variable scopes */
2887 /* **************************************************************** */
2889 /* Make variable NAME have VALUE in the temporary environment. */
2891 bind_tempenv_variable (name, value)
2897 var = temporary_env ? hash_lookup (name, temporary_env) : (SHELL_VAR *)NULL;
2901 FREE (value_cell (var));
2902 var_setvalue (var, savestring (value));
2903 INVALIDATE_EXPORTSTR (var);
2909 /* Find a variable in the temporary environment that is named NAME.
2910 Return the SHELL_VAR *, or NULL if not found. */
2912 find_tempenv_variable (name)
2915 return (temporary_env ? hash_lookup (name, temporary_env) : (SHELL_VAR *)NULL);
2918 /* Push the variable described by (SHELL_VAR *)DATA down to the next
2919 variable context from the temporary environment. */
2921 push_temp_var (data)
2925 HASH_TABLE *binding_table;
2927 var = (SHELL_VAR *)data;
2929 binding_table = shell_variables->table;
2930 if (binding_table == 0)
2932 if (shell_variables == global_variables)
2933 /* shouldn't happen */
2934 binding_table = shell_variables->table = global_variables->table = hash_create (0);
2936 binding_table = shell_variables->table = hash_create (TEMPENV_HASH_BUCKETS);
2939 v = bind_variable_internal (var->name, value_cell (var), binding_table, 0, 0);
2941 /* XXX - should we set the context here? It shouldn't matter because of how
2942 assign_in_env works, but might want to check. */
2943 if (binding_table == global_variables->table) /* XXX */
2944 var->attributes &= ~(att_tempvar|att_propagate);
2947 var->attributes |= att_propagate;
2948 if (binding_table == shell_variables->table)
2949 shell_variables->flags |= VC_HASTMPVAR;
2951 v->attributes |= var->attributes;
2953 dispose_variable (var);
2957 propagate_temp_var (data)
2962 var = (SHELL_VAR *)data;
2963 if (tempvar_p (var) && (var->attributes & att_propagate))
2964 push_temp_var (data);
2966 dispose_variable (var);
2969 /* Free the storage used in the hash table for temporary
2970 environment variables. PUSHF is a function to be called
2971 to free each hash table entry. It takes care of pushing variables
2972 to previous scopes if appropriate. */
2974 dispose_temporary_env (pushf)
2975 sh_free_func_t *pushf;
2977 hash_flush (temporary_env, pushf);
2978 hash_dispose (temporary_env);
2979 temporary_env = (HASH_TABLE *)NULL;
2981 array_needs_making = 1;
2983 sv_ifs ("IFS"); /* XXX here for now */
2987 dispose_used_env_vars ()
2990 dispose_temporary_env (propagate_temp_var);
2993 /* Take all of the shell variables in the temporary environment HASH_TABLE
2994 and make shell variables from them at the current variable context. */
2996 merge_temporary_env ()
2999 dispose_temporary_env (push_temp_var);
3002 /* **************************************************************** */
3004 /* Creating and manipulating the environment */
3006 /* **************************************************************** */
3008 static inline char *
3009 mk_env_string (name, value)
3010 const char *name, *value;
3012 int name_len, value_len;
3015 name_len = strlen (name);
3016 value_len = STRLEN (value);
3017 p = (char *)xmalloc (2 + name_len + value_len);
3020 if (value && *value)
3021 strcpy (p + name_len + 1, value);
3023 p[name_len + 1] = '\0';
3036 if (legal_variable_starter ((unsigned char)*s) == 0)
3038 internal_error (_("invalid character %d in exportstr for %s"), *s, v->name);
3041 for (s = v->exportstr + 1; s && *s; s++)
3045 if (legal_variable_char ((unsigned char)*s) == 0)
3047 internal_error (_("invalid character %d in exportstr for %s"), *s, v->name);
3053 internal_error (_("no `=' in exportstr for %s"), v->name);
3061 make_env_array_from_var_list (vars)
3064 register int i, list_index;
3065 register SHELL_VAR *var;
3066 char **list, *value;
3068 list = strvec_create ((1 + strvec_len ((char **)vars)));
3070 #define USE_EXPORTSTR (value == var->exportstr)
3072 for (i = 0, list_index = 0; var = vars[i]; i++)
3074 #if defined (__CYGWIN__)
3075 /* We don't use the exportstr stuff on Cygwin at all. */
3076 INVALIDATE_EXPORTSTR (var);
3079 value = var->exportstr;
3080 else if (function_p (var))
3081 value = named_function_string ((char *)NULL, function_cell (var), 0);
3082 #if defined (ARRAY_VARS)
3083 else if (array_p (var))
3085 value = array_to_assignment_string (array_cell (var));
3087 continue; /* XXX array vars cannot yet be exported */
3091 value = value_cell (var);
3095 /* Gee, I'd like to get away with not using savestring() if we're
3096 using the cached exportstr... */
3097 list[list_index] = USE_EXPORTSTR ? savestring (value)
3098 : mk_env_string (var->name, value);
3100 if (USE_EXPORTSTR == 0)
3101 SAVE_EXPORTSTR (var, list[list_index]);
3104 #undef USE_EXPORTSTR
3107 #if defined (ARRAY_VARS)
3115 list[list_index] = (char *)NULL;
3119 /* Make an array of assignment statements from the hash table
3120 HASHED_VARS which contains SHELL_VARs. Only visible, exported
3121 variables are eligible. */
3123 make_var_export_array (vcxt)
3129 vars = map_over (visible_and_exported, vcxt);
3132 return (char **)NULL;
3134 list = make_env_array_from_var_list (vars);
3141 make_func_export_array ()
3146 vars = map_over_funcs (visible_and_exported);
3148 return (char **)NULL;
3150 list = make_env_array_from_var_list (vars);
3156 /* Add ENVSTR to the end of the exported environment, EXPORT_ENV. */
3157 #define add_to_export_env(envstr,do_alloc) \
3160 if (export_env_index >= (export_env_size - 1)) \
3162 export_env_size += 16; \
3163 export_env = strvec_resize (export_env, export_env_size); \
3164 environ = export_env; \
3166 export_env[export_env_index++] = (do_alloc) ? savestring (envstr) : envstr; \
3167 export_env[export_env_index] = (char *)NULL; \
3170 /* Add ASSIGN to EXPORT_ENV, or supercede a previous assignment in the
3171 array with the same left-hand side. Return the new EXPORT_ENV. */
3173 add_or_supercede_exported_var (assign, do_alloc)
3180 equal_offset = assignment (assign, 0);
3181 if (equal_offset == 0)
3182 return (export_env);
3184 /* If this is a function, then only supersede the function definition.
3185 We do this by including the `=() {' in the comparison, like
3186 initialize_shell_variables does. */
3187 if (assign[equal_offset + 1] == '(' &&
3188 strncmp (assign + equal_offset + 2, ") {", 3) == 0) /* } */
3191 for (i = 0; i < export_env_index; i++)
3193 if (STREQN (assign, export_env[i], equal_offset + 1))
3195 free (export_env[i]);
3196 export_env[i] = do_alloc ? savestring (assign) : assign;
3197 return (export_env);
3200 add_to_export_env (assign, do_alloc);
3201 return (export_env);
3205 add_temp_array_to_env (temp_array, do_alloc, do_supercede)
3207 int do_alloc, do_supercede;
3211 if (temp_array == 0)
3214 for (i = 0; temp_array[i]; i++)
3217 export_env = add_or_supercede_exported_var (temp_array[i], do_alloc);
3219 add_to_export_env (temp_array[i], do_alloc);
3225 /* Make the environment array for the command about to be executed, if the
3226 array needs making. Otherwise, do nothing. If a shell action could
3227 change the array that commands receive for their environment, then the
3228 code should `array_needs_making++'.
3230 The order to add to the array is:
3232 list of var contexts whose head is shell_variables
3235 This is the shell variable lookup order. We add only new variable
3236 names at each step, which allows local variables and variables in
3237 the temporary environments to shadow variables in the global (or
3238 any previous) scope.
3242 n_shell_variables ()
3247 for (n = 0, vc = shell_variables; vc; vc = vc->down)
3248 n += HASH_ENTRIES (vc->table);
3253 maybe_make_export_env ()
3255 register char **temp_array;
3259 if (array_needs_making)
3262 strvec_flush (export_env);
3264 /* Make a guess based on how many shell variables and functions we
3265 have. Since there will always be array variables, and array
3266 variables are not (yet) exported, this will always be big enough
3267 for the exported variables and functions. */
3268 new_size = n_shell_variables () + HASH_ENTRIES (shell_functions) + 1 +
3269 HASH_ENTRIES (temporary_env);
3270 if (new_size > export_env_size)
3272 export_env_size = new_size;
3273 export_env = strvec_resize (export_env, export_env_size);
3274 environ = export_env;
3276 export_env[export_env_index = 0] = (char *)NULL;
3278 /* Make a dummy variable context from the temporary_env, stick it on
3279 the front of shell_variables, call make_var_export_array on the
3280 whole thing to flatten it, and convert the list of SHELL_VAR *s
3281 to the form needed by the environment. */
3284 tcxt = new_var_context ((char *)NULL, 0);
3285 tcxt->table = temporary_env;
3286 tcxt->down = shell_variables;
3289 tcxt = shell_variables;
3291 temp_array = make_var_export_array (tcxt);
3293 add_temp_array_to_env (temp_array, 0, 0);
3295 if (tcxt != shell_variables)
3298 #if defined (RESTRICTED_SHELL)
3299 /* Restricted shells may not export shell functions. */
3300 temp_array = restricted ? (char **)0 : make_func_export_array ();
3302 temp_array = make_func_export_array ();
3305 add_temp_array_to_env (temp_array, 0, 0);
3307 array_needs_making = 0;
3311 /* This is an efficiency hack. PWD and OLDPWD are auto-exported, so
3312 we will need to remake the exported environment every time we
3313 change directories. `_' is always put into the environment for
3314 every external command, so without special treatment it will always
3315 cause the environment to be remade.
3317 If there is no other reason to make the exported environment, we can
3318 just update the variables in place and mark the exported environment
3319 as no longer needing a remake. */
3321 update_export_env_inplace (env_prefix, preflen, value)
3328 evar = (char *)xmalloc (STRLEN (value) + preflen + 1);
3329 strcpy (evar, env_prefix);
3331 strcpy (evar + preflen, value);
3332 export_env = add_or_supercede_exported_var (evar, 0);
3335 /* We always put _ in the environment as the name of this command. */
3337 put_command_name_into_env (command_name)
3340 update_export_env_inplace ("_=", 2, command_name);
3343 #if 0 /* UNUSED -- it caused too many problems */
3345 put_gnu_argv_flags_into_env (pid, flags_string)
3355 fl = strlen (flags_string);
3357 dummy = (char *)xmalloc (l + fl + 30);
3359 strcpy (dummy + 1, pbuf);
3360 strcpy (dummy + 1 + l, "_GNU_nonoption_argv_flags_");
3361 dummy[l + 27] = '=';
3362 strcpy (dummy + l + 28, flags_string);
3366 export_env = add_or_supercede_exported_var (dummy, 0);
3370 /* **************************************************************** */
3372 /* Managing variable contexts */
3374 /* **************************************************************** */
3376 /* Allocate and return a new variable context with NAME and FLAGS.
3377 NAME can be NULL. */
3380 new_var_context (name, flags)
3386 vc = (VAR_CONTEXT *)xmalloc (sizeof (VAR_CONTEXT));
3387 vc->name = name ? savestring (name) : (char *)NULL;
3388 vc->scope = variable_context;
3391 vc->up = vc->down = (VAR_CONTEXT *)NULL;
3392 vc->table = (HASH_TABLE *)NULL;
3397 /* Free a variable context and its data, including the hash table. Dispose
3398 all of the variables. */
3400 dispose_var_context (vc)
3407 delete_all_variables (vc->table);
3408 hash_dispose (vc->table);
3414 /* Set VAR's scope level to the current variable context. */
3419 return (var->context = variable_context);
3422 /* Make a new variable context with NAME and FLAGS and a HASH_TABLE of
3423 temporary variables, and push it onto shell_variables. This is
3424 for shell functions. */
3426 push_var_context (name, flags, tempvars)
3429 HASH_TABLE *tempvars;
3433 vc = new_var_context (name, flags);
3434 vc->table = tempvars;
3437 /* Have to do this because the temp environment was created before
3438 variable_context was incremented. */
3439 flatten (tempvars, set_context, (VARLIST *)NULL, 0);
3440 vc->flags |= VC_HASTMPVAR;
3442 vc->down = shell_variables;
3443 shell_variables->up = vc;
3445 return (shell_variables = vc);
3449 push_func_var (data)
3454 var = (SHELL_VAR *)data;
3456 if (tempvar_p (var) && (posixly_correct || (var->attributes & att_propagate)))
3458 /* XXX - should we set v->context here? */
3459 v = bind_variable_internal (var->name, value_cell (var), shell_variables->table, 0, 0);
3460 if (shell_variables == global_variables)
3461 var->attributes &= ~(att_tempvar|att_propagate);
3463 shell_variables->flags |= VC_HASTMPVAR;
3464 v->attributes |= var->attributes;
3467 dispose_variable (var);
3470 /* Pop the top context off of VCXT and dispose of it, returning the rest of
3475 VAR_CONTEXT *ret, *vcxt;
3477 vcxt = shell_variables;
3478 if (vc_isfuncenv (vcxt) == 0)
3480 internal_error (_("pop_var_context: head of shell_variables not a function context"));
3484 if (ret = vcxt->down)
3486 ret->up = (VAR_CONTEXT *)NULL;
3487 shell_variables = ret;
3489 hash_flush (vcxt->table, push_func_var);
3490 dispose_var_context (vcxt);
3493 internal_error (_("pop_var_context: no global_variables context"));
3496 /* Delete the HASH_TABLEs for all variable contexts beginning at VCXT, and
3497 all of the VAR_CONTEXTs except GLOBAL_VARIABLES. */
3499 delete_all_contexts (vcxt)
3504 for (v = vcxt; v != global_variables; v = t)
3507 dispose_var_context (v);
3510 delete_all_variables (global_variables->table);
3511 shell_variables = global_variables;
3514 /* **************************************************************** */
3516 /* Pushing and Popping temporary variable scopes */
3518 /* **************************************************************** */
3521 push_scope (flags, tmpvars)
3523 HASH_TABLE *tmpvars;
3525 return (push_var_context ((char *)NULL, flags, tmpvars));
3529 push_exported_var (data)
3534 var = (SHELL_VAR *)data;
3536 /* If a temp var had its export attribute set, or it's marked to be
3537 propagated, bind it in the previous scope before disposing it. */
3538 /* XXX - This isn't exactly right, because all tempenv variables have the
3539 export attribute set. */
3541 if (exported_p (var) || (var->attributes & att_propagate))
3543 if (tempvar_p (var) && exported_p (var) && (var->attributes & att_propagate))
3546 var->attributes &= ~att_tempvar; /* XXX */
3547 v = bind_variable_internal (var->name, value_cell (var), shell_variables->table, 0, 0);
3548 if (shell_variables == global_variables)
3549 var->attributes &= ~att_propagate;
3550 v->attributes |= var->attributes;
3553 dispose_variable (var);
3557 pop_scope (is_special)
3560 VAR_CONTEXT *vcxt, *ret;
3562 vcxt = shell_variables;
3563 if (vc_istempscope (vcxt) == 0)
3565 internal_error (_("pop_scope: head of shell_variables not a temporary environment scope"));
3571 ret->up = (VAR_CONTEXT *)NULL;
3573 shell_variables = ret;
3575 /* Now we can take care of merging variables in VCXT into set of scopes
3576 whose head is RET (shell_variables). */
3581 hash_flush (vcxt->table, push_func_var);
3583 hash_flush (vcxt->table, push_exported_var);
3584 hash_dispose (vcxt->table);
3588 sv_ifs ("IFS"); /* XXX here for now */
3591 /* **************************************************************** */
3593 /* Pushing and Popping function contexts */
3595 /* **************************************************************** */
3597 static WORD_LIST **dollar_arg_stack = (WORD_LIST **)NULL;
3598 static int dollar_arg_stack_slots;
3599 static int dollar_arg_stack_index;
3601 /* XXX - we might want to consider pushing and popping the `getopts' state
3602 when we modify the positional parameters. */
3604 push_context (name, is_subshell, tempvars)
3605 char *name; /* function name */
3607 HASH_TABLE *tempvars;
3609 if (is_subshell == 0)
3610 push_dollar_vars ();
3612 push_var_context (name, VC_FUNCENV, tempvars);
3615 /* Only called when subshell == 0, so we don't need to check, and can
3616 unconditionally pop the dollar vars off the stack. */
3624 sv_ifs ("IFS"); /* XXX here for now */
3627 /* Save the existing positional parameters on a stack. */
3631 if (dollar_arg_stack_index + 2 > dollar_arg_stack_slots)
3633 dollar_arg_stack = (WORD_LIST **)
3634 xrealloc (dollar_arg_stack, (dollar_arg_stack_slots += 10)
3635 * sizeof (WORD_LIST **));
3637 dollar_arg_stack[dollar_arg_stack_index++] = list_rest_of_args ();
3638 dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
3641 /* Restore the positional parameters from our stack. */
3645 if (!dollar_arg_stack || dollar_arg_stack_index == 0)
3648 remember_args (dollar_arg_stack[--dollar_arg_stack_index], 1);
3649 dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
3650 dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
3651 set_dollar_vars_unchanged ();
3655 dispose_saved_dollar_vars ()
3657 if (!dollar_arg_stack || dollar_arg_stack_index == 0)
3660 dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
3661 dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
3664 /* Manipulate the special BASH_ARGV and BASH_ARGC variables. */
3670 #if defined (ARRAY_VARS) && defined (DEBUGGER)
3671 SHELL_VAR *bash_argv_v, *bash_argc_v;
3672 ARRAY *bash_argv_a, *bash_argc_a;
3677 GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a);
3678 GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
3680 for (l = list, i = 0; l; l = l->next, i++)
3681 array_push (bash_argv_a, l->word->word);
3684 array_push (bash_argc_a, t);
3686 #endif /* ARRAY_VARS && DEBUGGER */
3689 /* Remove arguments from BASH_ARGV array. Pop top element off BASH_ARGC
3690 array and use that value as the count of elements to remove from
3695 #if defined (ARRAY_VARS) && defined (DEBUGGER)
3696 SHELL_VAR *bash_argv_v, *bash_argc_v;
3697 ARRAY *bash_argv_a, *bash_argc_a;
3701 GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a);
3702 GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
3704 ce = array_shift (bash_argc_a, 1, 0);
3705 if (ce == 0 || legal_number (element_value (ce), &i) == 0)
3709 array_pop (bash_argv_a);
3710 array_dispose_element (ce);
3711 #endif /* ARRAY_VARS && DEBUGGER */
3714 /*************************************************
3716 * Functions to manage special variables *
3718 *************************************************/
3720 /* Extern declarations for variables this code has to manage. */
3721 extern int eof_encountered, eof_encountered_limit, ignoreeof;
3723 #if defined (READLINE)
3724 extern int hostname_list_initialized;
3727 /* An alist of name.function for each special variable. Most of the
3728 functions don't do much, and in fact, this would be faster with a
3729 switch statement, but by the end of this file, I am sick of switch
3732 #define SET_INT_VAR(name, intvar) intvar = find_variable (name) != 0
3734 /* This table will be sorted with qsort() the first time it's accessed. */
3735 struct name_and_function {
3737 sh_sv_func_t *function;
3740 static struct name_and_function special_vars[] = {
3741 #if defined (READLINE)
3742 # if defined (STRICT_POSIX)
3743 { "COLUMNS", sv_winsize },
3745 { "COMP_WORDBREAKS", sv_comp_wordbreaks },
3748 { "GLOBIGNORE", sv_globignore },
3750 #if defined (HISTORY)
3751 { "HISTCONTROL", sv_history_control },
3752 { "HISTFILESIZE", sv_histsize },
3753 { "HISTIGNORE", sv_histignore },
3754 { "HISTSIZE", sv_histsize },
3755 { "HISTTIMEFORMAT", sv_histtimefmt },
3758 #if defined (__CYGWIN__)
3759 { "HOME", sv_home },
3762 #if defined (READLINE)
3763 { "HOSTFILE", sv_hostfile },
3767 { "IGNOREEOF", sv_ignoreeof },
3769 { "LANG", sv_locale },
3770 { "LC_ALL", sv_locale },
3771 { "LC_COLLATE", sv_locale },
3772 { "LC_CTYPE", sv_locale },
3773 { "LC_MESSAGES", sv_locale },
3774 { "LC_NUMERIC", sv_locale },
3775 { "LC_TIME", sv_locale },
3777 #if defined (READLINE) && defined (STRICT_POSIX)
3778 { "LINES", sv_winsize },
3781 { "MAIL", sv_mail },
3782 { "MAILCHECK", sv_mail },
3783 { "MAILPATH", sv_mail },
3785 { "OPTERR", sv_opterr },
3786 { "OPTIND", sv_optind },
3788 { "PATH", sv_path },
3789 { "POSIXLY_CORRECT", sv_strict_posix },
3791 #if defined (READLINE)
3792 { "TERM", sv_terminal },
3793 { "TERMCAP", sv_terminal },
3794 { "TERMINFO", sv_terminal },
3795 #endif /* READLINE */
3797 { "TEXTDOMAIN", sv_locale },
3798 { "TEXTDOMAINDIR", sv_locale },
3800 #if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE)
3804 #if defined (HISTORY) && defined (BANG_HISTORY)
3805 { "histchars", sv_histchars },
3806 #endif /* HISTORY && BANG_HISTORY */
3808 { "ignoreeof", sv_ignoreeof },
3810 { (char *)0, (sh_sv_func_t *)0 }
3813 #define N_SPECIAL_VARS (sizeof (special_vars) / sizeof (special_vars[0]) - 1)
3816 sv_compare (sv1, sv2)
3817 struct name_and_function *sv1, *sv2;
3821 if ((r = sv1->name[0] - sv2->name[0]) == 0)
3822 r = strcmp (sv1->name, sv2->name);
3827 find_special_var (name)
3832 for (i = 0; special_vars[i].name; i++)
3834 r = special_vars[i].name[0] - name[0];
3836 r = strcmp (special_vars[i].name, name);
3840 /* Can't match any of rest of elements in sorted list. Take this out
3841 if it causes problems in certain environments. */
3847 /* The variable in NAME has just had its state changed. Check to see if it
3848 is one of the special ones where something special happens. */
3850 stupidly_hack_special_variables (name)
3853 static int sv_sorted = 0;
3856 if (sv_sorted == 0) /* shouldn't need, but it's fairly cheap. */
3858 qsort (special_vars, N_SPECIAL_VARS, sizeof (special_vars[0]),
3859 (QSFUNC *)sv_compare);
3863 i = find_special_var (name);
3865 (*(special_vars[i].function)) (name);
3874 v = find_variable ("IFS");
3878 /* What to do just after the PATH variable has changed. */
3887 /* What to do just after one of the MAILxxxx variables has changed. NAME
3888 is the name of the variable. This is called with NAME set to one of
3889 MAIL, MAILCHECK, or MAILPATH. */
3894 /* If the time interval for checking the files has changed, then
3895 reset the mail timer. Otherwise, one of the pathname vars
3896 to the users mailbox has changed, so rebuild the array of
3898 if (name[4] == 'C') /* if (strcmp (name, "MAILCHECK") == 0) */
3899 reset_mail_timer ();
3903 remember_mail_dates ();
3907 /* What to do when GLOBIGNORE changes. */
3909 sv_globignore (name)
3912 setup_glob_ignore (name);
3915 #if defined (READLINE)
3917 sv_comp_wordbreaks (name)
3922 sv = find_variable (name);
3924 rl_completer_word_break_characters = (char *)NULL;
3927 /* What to do just after one of the TERMxxx variables has changed.
3928 If we are an interactive shell, then try to reset the terminal
3929 information in readline. */
3934 if (interactive_shell && no_line_editing == 0)
3935 rl_reset_terminal (get_string_value ("TERM"));
3944 v = find_variable (name);
3946 clear_hostname_list ();
3948 hostname_list_initialized = 0;
3951 #if defined (STRICT_POSIX)
3952 /* In strict posix mode, we allow assignments to LINES and COLUMNS (and values
3953 found in the initial environment) to override the terminal size reported by
3963 if (posixly_correct == 0 || interactive_shell == 0 || no_line_editing)
3966 v = find_variable (name);
3967 if (v == 0 || var_isnull (v))
3968 rl_reset_screen_size ();
3971 if (legal_number (value_cell (v), &xd) == 0)
3973 winsize_assignment = winsize_assigned = 1;
3974 d = xd; /* truncate */
3975 if (name[0] == 'L') /* LINES */
3976 rl_set_screen_size (d, -1);
3978 rl_set_screen_size (-1, d);
3979 winsize_assignment = 0;
3982 #endif /* STRICT_POSIX */
3983 #endif /* READLINE */
3985 /* Update the value of HOME in the export environment so tilde expansion will
3987 #if defined (__CYGWIN__)
3991 array_needs_making = 1;
3992 maybe_make_export_env ();
3996 #if defined (HISTORY)
3997 /* What to do after the HISTSIZE or HISTFILESIZE variables change.
3998 If there is a value for this HISTSIZE (and it is numeric), then stifle
3999 the history. Otherwise, if there is NO value for this variable,
4000 unstifle the history. If name is HISTFILESIZE, and its value is
4001 numeric, truncate the history file to hold no more than that many
4011 temp = get_string_value (name);
4015 if (legal_number (temp, &num))
4020 stifle_history (hmax);
4021 num = where_history ();
4022 if (history_lines_this_session > num)
4023 history_lines_this_session = num;
4027 history_truncate_file (get_string_value ("HISTFILE"), (int)num);
4028 if (num <= history_lines_in_file)
4029 history_lines_in_file = num;
4033 else if (name[4] == 'S')
4034 unstifle_history ();
4037 /* What to do after the HISTIGNORE variable changes. */
4039 sv_histignore (name)
4042 setup_history_ignore (name);
4045 /* What to do after the HISTCONTROL variable changes. */
4047 sv_history_control (name)
4054 history_control = 0;
4055 temp = get_string_value (name);
4057 if (temp == 0 || *temp == 0)
4061 while (val = extract_colon_unit (temp, &tptr))
4063 if (STREQ (val, "ignorespace"))
4064 history_control |= HC_IGNSPACE;
4065 else if (STREQ (val, "ignoredups"))
4066 history_control |= HC_IGNDUPS;
4067 else if (STREQ (val, "ignoreboth"))
4068 history_control |= HC_IGNBOTH;
4069 else if (STREQ (val, "erasedups"))
4070 history_control |= HC_ERASEDUPS;
4076 #if defined (BANG_HISTORY)
4077 /* Setting/unsetting of the history expansion character. */
4084 temp = get_string_value (name);
4087 history_expansion_char = *temp;
4088 if (temp[0] && temp[1])
4090 history_subst_char = temp[1];
4092 history_comment_char = temp[2];
4097 history_expansion_char = '!';
4098 history_subst_char = '^';
4099 history_comment_char = '#';
4102 #endif /* BANG_HISTORY */
4105 sv_histtimefmt (name)
4110 v = find_variable (name);
4111 history_write_timestamps = (v != 0);
4113 #endif /* HISTORY */
4115 #if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE)
4124 /* If the variable exists, then the value of it can be the number
4125 of times we actually ignore the EOF. The default is small,
4126 (smaller than csh, anyway). */
4134 eof_encountered = 0;
4136 tmp_var = find_variable (name);
4137 ignoreeof = tmp_var != 0;
4138 temp = tmp_var ? value_cell (tmp_var) : (char *)NULL;
4140 eof_encountered_limit = (*temp && all_digits (temp)) ? atoi (temp) : 10;
4141 set_shellopts (); /* make sure `ignoreeof' is/is not in $SHELLOPTS */
4151 tt = get_string_value ("OPTIND");
4156 /* According to POSIX, setting OPTIND=1 resets the internal state
4158 if (s < 0 || s == 1)
4172 tt = get_string_value ("OPTERR");
4173 sh_opterr = (tt && *tt) ? atoi (tt) : 1;
4177 sv_strict_posix (name)
4180 SET_INT_VAR (name, posixly_correct);
4181 posix_initialize (posixly_correct);
4182 #if defined (READLINE)
4183 if (interactive_shell)
4184 posix_readline_initialize (posixly_correct);
4185 #endif /* READLINE */
4186 set_shellopts (); /* make sure `posix' is/is not in $SHELLOPTS */
4195 v = get_string_value (name);
4196 if (name[0] == 'L' && name[1] == 'A') /* LANG */
4199 set_locale_var (name, v); /* LC_*, TEXTDOMAIN* */
4202 #if defined (ARRAY_VARS)
4204 set_pipestatus_array (ps, nproc)
4212 char *t, tbuf[INT_STRLEN_BOUND(int) + 1];
4214 v = find_variable ("PIPESTATUS");
4216 v = make_new_array_variable ("PIPESTATUS");
4217 if (array_p (v) == 0)
4218 return; /* Do nothing if not an array variable. */
4221 if (a == 0 || array_num_elements (a) == 0)
4223 for (i = 0; i < nproc; i++) /* was ps[i] != -1, not i < nproc */
4225 t = inttostr (ps[i], tbuf, sizeof (tbuf));
4226 array_insert (a, i, t);
4232 if (array_num_elements (a) == nproc && nproc == 1)
4234 ae = element_forw (a->head);
4235 free (element_value (ae));
4236 ae->value = itos (ps[0]);
4238 else if (array_num_elements (a) <= nproc)
4240 /* modify in array_num_elements members in place, then add */
4242 for (i = 0; i < array_num_elements (a); i++)
4244 ae = element_forw (ae);
4245 free (element_value (ae));
4246 ae->value = itos (ps[i]);
4249 for ( ; i < nproc; i++)
4251 t = inttostr (ps[i], tbuf, sizeof (tbuf));
4252 array_insert (a, i, t);
4257 /* deleting elements. it's faster to rebuild the array. */
4259 for (i = 0; ps[i] != -1; i++)
4261 t = inttostr (ps[i], tbuf, sizeof (tbuf));
4262 array_insert (a, i, t);
4269 set_pipestatus_from_exit (s)
4272 #if defined (ARRAY_VARS)
4273 static int v[2] = { 0, -1 };
4276 set_pipestatus_array (v, 1);