Patch-ID: bash40-013
[bash.git] / variables.c
blob8920bad1dd398c43f2b33d7264a96efe94767971
1 /* variables.c -- Functions for hacking shell variables. */
3 /* Copyright (C) 1987-2009 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
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 Bash is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Bash. If not, see <http://www.gnu.org/licenses/>.
21 #include "config.h"
23 #include "bashtypes.h"
24 #include "posixstat.h"
25 #include "posixtime.h"
27 #if defined (__QNX__)
28 # if defined (__QNXNTO__)
29 # include <sys/netmgr.h>
30 # else
31 # include <sys/vc.h>
32 # endif /* !__QNXNTO__ */
33 #endif /* __QNX__ */
35 #if defined (HAVE_UNISTD_H)
36 # include <unistd.h>
37 #endif
39 #include <stdio.h>
40 #include "chartypes.h"
41 #if defined (HAVE_PWD_H)
42 # include <pwd.h>
43 #endif
44 #include "bashansi.h"
45 #include "bashintl.h"
47 #include "shell.h"
48 #include "flags.h"
49 #include "execute_cmd.h"
50 #include "findcmd.h"
51 #include "mailcheck.h"
52 #include "input.h"
53 #include "hashcmd.h"
54 #include "pathexp.h"
55 #include "alias.h"
57 #include "builtins/getopt.h"
58 #include "builtins/common.h"
60 #if defined (READLINE)
61 # include "bashline.h"
62 # include <readline/readline.h>
63 #else
64 # include <tilde/tilde.h>
65 #endif
67 #if defined (HISTORY)
68 # include "bashhist.h"
69 # include <readline/history.h>
70 #endif /* HISTORY */
72 #if defined (PROGRAMMABLE_COMPLETION)
73 # include "pcomplete.h"
74 #endif
76 #define TEMPENV_HASH_BUCKETS 4 /* must be power of two */
78 #define ifsname(s) ((s)[0] == 'I' && (s)[1] == 'F' && (s)[2] == 'S' && (s)[3] == '\0')
80 extern char **environ;
82 /* Variables used here and defined in other files. */
83 extern int posixly_correct;
84 extern int line_number;
85 extern int subshell_environment, indirection_level, subshell_level;
86 extern int build_version, patch_level;
87 extern int expanding_redir;
88 extern char *dist_version, *release_status;
89 extern char *shell_name;
90 extern char *primary_prompt, *secondary_prompt;
91 extern char *current_host_name;
92 extern sh_builtin_func_t *this_shell_builtin;
93 extern SHELL_VAR *this_shell_function;
94 extern char *the_printed_command_except_trap;
95 extern char *this_command_name;
96 extern char *command_execution_string;
97 extern time_t shell_start_time;
98 extern int assigning_in_environment;
99 extern int executing_builtin;
101 #if defined (READLINE)
102 extern int no_line_editing;
103 extern int perform_hostname_completion;
104 #endif
106 /* The list of shell variables that the user has created at the global
107 scope, or that came from the environment. */
108 VAR_CONTEXT *global_variables = (VAR_CONTEXT *)NULL;
110 /* The current list of shell variables, including function scopes */
111 VAR_CONTEXT *shell_variables = (VAR_CONTEXT *)NULL;
113 /* The list of shell functions that the user has created, or that came from
114 the environment. */
115 HASH_TABLE *shell_functions = (HASH_TABLE *)NULL;
117 #if defined (DEBUGGER)
118 /* The table of shell function definitions that the user defined or that
119 came from the environment. */
120 HASH_TABLE *shell_function_defs = (HASH_TABLE *)NULL;
121 #endif
123 /* The current variable context. This is really a count of how deep into
124 executing functions we are. */
125 int variable_context = 0;
127 /* The set of shell assignments which are made only in the environment
128 for a single command. */
129 HASH_TABLE *temporary_env = (HASH_TABLE *)NULL;
131 /* Set to non-zero if an assignment error occurs while putting variables
132 into the temporary environment. */
133 int tempenv_assign_error;
135 /* Some funky variables which are known about specially. Here is where
136 "$*", "$1", and all the cruft is kept. */
137 char *dollar_vars[10];
138 WORD_LIST *rest_of_args = (WORD_LIST *)NULL;
140 /* The value of $$. */
141 pid_t dollar_dollar_pid;
143 /* Non-zero means that we have to remake EXPORT_ENV. */
144 int array_needs_making = 1;
146 /* The number of times BASH has been executed. This is set
147 by initialize_variables (). */
148 int shell_level = 0;
150 /* An array which is passed to commands as their environment. It is
151 manufactured from the union of the initial environment and the
152 shell variables that are marked for export. */
153 char **export_env = (char **)NULL;
154 static int export_env_index;
155 static int export_env_size;
157 #if defined (READLINE)
158 static int winsize_assignment; /* currently assigning to LINES or COLUMNS */
159 static int winsize_assigned; /* assigned to LINES or COLUMNS */
160 #endif
162 /* Some forward declarations. */
163 static void create_variable_tables __P((void));
165 static void set_machine_vars __P((void));
166 static void set_home_var __P((void));
167 static void set_shell_var __P((void));
168 static char *get_bash_name __P((void));
169 static void initialize_shell_level __P((void));
170 static void uidset __P((void));
171 #if defined (ARRAY_VARS)
172 static void make_vers_array __P((void));
173 #endif
175 static SHELL_VAR *null_assign __P((SHELL_VAR *, char *, arrayind_t, char *));
176 #if defined (ARRAY_VARS)
177 static SHELL_VAR *null_array_assign __P((SHELL_VAR *, char *, arrayind_t, char *));
178 #endif
179 static SHELL_VAR *get_self __P((SHELL_VAR *));
181 #if defined (ARRAY_VARS)
182 static SHELL_VAR *init_dynamic_array_var __P((char *, sh_var_value_func_t *, sh_var_assign_func_t *, int));
183 static SHELL_VAR *init_dynamic_assoc_var __P((char *, sh_var_value_func_t *, sh_var_assign_func_t *, int));
184 #endif
186 static SHELL_VAR *assign_seconds __P((SHELL_VAR *, char *, arrayind_t, char *));
187 static SHELL_VAR *get_seconds __P((SHELL_VAR *));
188 static SHELL_VAR *init_seconds_var __P((void));
190 static int brand __P((void));
191 static void sbrand __P((unsigned long)); /* set bash random number generator. */
192 static void seedrand __P((void)); /* seed generator randomly */
193 static SHELL_VAR *assign_random __P((SHELL_VAR *, char *, arrayind_t, char *));
194 static SHELL_VAR *get_random __P((SHELL_VAR *));
196 static SHELL_VAR *assign_lineno __P((SHELL_VAR *, char *, arrayind_t, char *));
197 static SHELL_VAR *get_lineno __P((SHELL_VAR *));
199 static SHELL_VAR *assign_subshell __P((SHELL_VAR *, char *, arrayind_t, char *));
200 static SHELL_VAR *get_subshell __P((SHELL_VAR *));
202 static SHELL_VAR *get_bashpid __P((SHELL_VAR *));
204 #if defined (HISTORY)
205 static SHELL_VAR *get_histcmd __P((SHELL_VAR *));
206 #endif
208 #if defined (READLINE)
209 static SHELL_VAR *get_comp_wordbreaks __P((SHELL_VAR *));
210 static SHELL_VAR *assign_comp_wordbreaks __P((SHELL_VAR *, char *, arrayind_t, char *));
211 #endif
213 #if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
214 static SHELL_VAR *assign_dirstack __P((SHELL_VAR *, char *, arrayind_t, char *));
215 static SHELL_VAR *get_dirstack __P((SHELL_VAR *));
216 #endif
218 #if defined (ARRAY_VARS)
219 static SHELL_VAR *get_groupset __P((SHELL_VAR *));
221 static SHELL_VAR *build_hashcmd __P((SHELL_VAR *));
222 static SHELL_VAR *get_hashcmd __P((SHELL_VAR *));
223 static SHELL_VAR *assign_hashcmd __P((SHELL_VAR *, char *, arrayind_t, char *));
224 static SHELL_VAR *build_aliasvar __P((SHELL_VAR *));
225 static SHELL_VAR *get_aliasvar __P((SHELL_VAR *));
226 static SHELL_VAR *assign_aliasvar __P((SHELL_VAR *, char *, arrayind_t, char *));
227 #endif
229 static SHELL_VAR *get_funcname __P((SHELL_VAR *));
230 static SHELL_VAR *init_funcname_var __P((void));
232 static void initialize_dynamic_variables __P((void));
234 static SHELL_VAR *hash_lookup __P((const char *, HASH_TABLE *));
235 static SHELL_VAR *new_shell_variable __P((const char *));
236 static SHELL_VAR *make_new_variable __P((const char *, HASH_TABLE *));
237 static SHELL_VAR *bind_variable_internal __P((const char *, char *, HASH_TABLE *, int, int));
239 static void dispose_variable_value __P((SHELL_VAR *));
240 static void free_variable_hash_data __P((PTR_T));
242 static VARLIST *vlist_alloc __P((int));
243 static VARLIST *vlist_realloc __P((VARLIST *, int));
244 static void vlist_add __P((VARLIST *, SHELL_VAR *, int));
246 static void flatten __P((HASH_TABLE *, sh_var_map_func_t *, VARLIST *, int));
248 static int qsort_var_comp __P((SHELL_VAR **, SHELL_VAR **));
250 static SHELL_VAR **vapply __P((sh_var_map_func_t *));
251 static SHELL_VAR **fapply __P((sh_var_map_func_t *));
253 static int visible_var __P((SHELL_VAR *));
254 static int visible_and_exported __P((SHELL_VAR *));
255 static int local_and_exported __P((SHELL_VAR *));
256 static int variable_in_context __P((SHELL_VAR *));
257 #if defined (ARRAY_VARS)
258 static int visible_array_vars __P((SHELL_VAR *));
259 #endif
261 static SHELL_VAR *bind_tempenv_variable __P((const char *, char *));
262 static void push_temp_var __P((PTR_T));
263 static void propagate_temp_var __P((PTR_T));
264 static void dispose_temporary_env __P((sh_free_func_t *));
266 static inline char *mk_env_string __P((const char *, const char *));
267 static char **make_env_array_from_var_list __P((SHELL_VAR **));
268 static char **make_var_export_array __P((VAR_CONTEXT *));
269 static char **make_func_export_array __P((void));
270 static void add_temp_array_to_env __P((char **, int, int));
272 static int n_shell_variables __P((void));
273 static int set_context __P((SHELL_VAR *));
275 static void push_func_var __P((PTR_T));
276 static void push_exported_var __P((PTR_T));
278 static inline int find_special_var __P((const char *));
280 static void
281 create_variable_tables ()
283 if (shell_variables == 0)
285 shell_variables = global_variables = new_var_context ((char *)NULL, 0);
286 shell_variables->scope = 0;
287 shell_variables->table = hash_create (0);
290 if (shell_functions == 0)
291 shell_functions = hash_create (0);
293 #if defined (DEBUGGER)
294 if (shell_function_defs == 0)
295 shell_function_defs = hash_create (0);
296 #endif
299 /* Initialize the shell variables from the current environment.
300 If PRIVMODE is nonzero, don't import functions from ENV or
301 parse $SHELLOPTS. */
302 void
303 initialize_shell_variables (env, privmode)
304 char **env;
305 int privmode;
307 char *name, *string, *temp_string;
308 int c, char_index, string_index, string_length;
309 SHELL_VAR *temp_var;
311 create_variable_tables ();
313 for (string_index = 0; string = env[string_index++]; )
315 char_index = 0;
316 name = string;
317 while ((c = *string++) && c != '=')
319 if (string[-1] == '=')
320 char_index = string - name - 1;
322 /* If there are weird things in the environment, like `=xxx' or a
323 string without an `=', just skip them. */
324 if (char_index == 0)
325 continue;
327 /* ASSERT(name[char_index] == '=') */
328 name[char_index] = '\0';
329 /* Now, name = env variable name, string = env variable value, and
330 char_index == strlen (name) */
332 temp_var = (SHELL_VAR *)NULL;
334 /* If exported function, define it now. Don't import functions from
335 the environment in privileged mode. */
336 if (privmode == 0 && read_but_dont_execute == 0 && STREQN ("() {", string, 4))
338 string_length = strlen (string);
339 temp_string = (char *)xmalloc (3 + string_length + char_index);
341 strcpy (temp_string, name);
342 temp_string[char_index] = ' ';
343 strcpy (temp_string + char_index + 1, string);
345 parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST);
347 /* Ancient backwards compatibility. Old versions of bash exported
348 functions like name()=() {...} */
349 if (name[char_index - 1] == ')' && name[char_index - 2] == '(')
350 name[char_index - 2] = '\0';
352 if (temp_var = find_function (name))
354 VSETATTR (temp_var, (att_exported|att_imported));
355 array_needs_making = 1;
357 else
358 report_error (_("error importing function definition for `%s'"), name);
360 /* ( */
361 if (name[char_index - 1] == ')' && name[char_index - 2] == '\0')
362 name[char_index - 2] = '('; /* ) */
364 #if defined (ARRAY_VARS)
365 # if 0
366 /* Array variables may not yet be exported. */
367 else if (*string == '(' && string[1] == '[' && string[strlen (string) - 1] == ')')
369 string_length = 1;
370 temp_string = extract_array_assignment_list (string, &string_length);
371 temp_var = assign_array_from_string (name, temp_string);
372 FREE (temp_string);
373 VSETATTR (temp_var, (att_exported | att_imported));
374 array_needs_making = 1;
376 # endif
377 #endif
378 else if (legal_identifier (name))
380 temp_var = bind_variable (name, string, 0);
381 VSETATTR (temp_var, (att_exported | att_imported));
382 array_needs_making = 1;
385 name[char_index] = '=';
386 /* temp_var can be NULL if it was an exported function with a syntax
387 error (a different bug, but it still shouldn't dump core). */
388 if (temp_var && function_p (temp_var) == 0) /* XXX not yet */
390 CACHE_IMPORTSTR (temp_var, name);
394 set_pwd ();
396 /* Set up initial value of $_ */
397 temp_var = set_if_not ("_", dollar_vars[0]);
399 /* Remember this pid. */
400 dollar_dollar_pid = getpid ();
402 /* Now make our own defaults in case the vars that we think are
403 important are missing. */
404 temp_var = set_if_not ("PATH", DEFAULT_PATH_VALUE);
405 #if 0
406 set_auto_export (temp_var); /* XXX */
407 #endif
409 temp_var = set_if_not ("TERM", "dumb");
410 #if 0
411 set_auto_export (temp_var); /* XXX */
412 #endif
414 #if defined (__QNX__)
415 /* set node id -- don't import it from the environment */
417 char node_name[22];
418 # if defined (__QNXNTO__)
419 netmgr_ndtostr(ND2S_LOCAL_STR, ND_LOCAL_NODE, node_name, sizeof(node_name));
420 # else
421 qnx_nidtostr (getnid (), node_name, sizeof (node_name));
422 # endif
423 temp_var = bind_variable ("NODE", node_name, 0);
424 set_auto_export (temp_var);
426 #endif
428 /* set up the prompts. */
429 if (interactive_shell)
431 #if defined (PROMPT_STRING_DECODE)
432 set_if_not ("PS1", primary_prompt);
433 #else
434 if (current_user.uid == -1)
435 get_current_user_info ();
436 set_if_not ("PS1", current_user.euid == 0 ? "# " : primary_prompt);
437 #endif
438 set_if_not ("PS2", secondary_prompt);
440 set_if_not ("PS4", "+ ");
442 /* Don't allow IFS to be imported from the environment. */
443 temp_var = bind_variable ("IFS", " \t\n", 0);
444 setifs (temp_var);
446 /* Magic machine types. Pretty convenient. */
447 set_machine_vars ();
449 /* Default MAILCHECK for interactive shells. Defer the creation of a
450 default MAILPATH until the startup files are read, because MAIL
451 names a mail file if MAILPATH is not set, and we should provide a
452 default only if neither is set. */
453 if (interactive_shell)
455 temp_var = set_if_not ("MAILCHECK", posixly_correct ? "600" : "60");
456 VSETATTR (temp_var, att_integer);
459 /* Do some things with shell level. */
460 initialize_shell_level ();
462 set_ppid ();
464 /* Initialize the `getopts' stuff. */
465 temp_var = bind_variable ("OPTIND", "1", 0);
466 VSETATTR (temp_var, att_integer);
467 getopts_reset (0);
468 bind_variable ("OPTERR", "1", 0);
469 sh_opterr = 1;
471 if (login_shell == 1 && posixly_correct == 0)
472 set_home_var ();
474 /* Get the full pathname to THIS shell, and set the BASH variable
475 to it. */
476 name = get_bash_name ();
477 temp_var = bind_variable ("BASH", name, 0);
478 free (name);
480 /* Make the exported environment variable SHELL be the user's login
481 shell. Note that the `tset' command looks at this variable
482 to determine what style of commands to output; if it ends in "csh",
483 then C-shell commands are output, else Bourne shell commands. */
484 set_shell_var ();
486 /* Make a variable called BASH_VERSION which contains the version info. */
487 bind_variable ("BASH_VERSION", shell_version_string (), 0);
488 #if defined (ARRAY_VARS)
489 make_vers_array ();
490 #endif
492 if (command_execution_string)
493 bind_variable ("BASH_EXECUTION_STRING", command_execution_string, 0);
495 /* Find out if we're supposed to be in Posix.2 mode via an
496 environment variable. */
497 temp_var = find_variable ("POSIXLY_CORRECT");
498 if (!temp_var)
499 temp_var = find_variable ("POSIX_PEDANTIC");
500 if (temp_var && imported_p (temp_var))
501 sv_strict_posix (temp_var->name);
503 #if defined (HISTORY)
504 /* Set history variables to defaults, and then do whatever we would
505 do if the variable had just been set. Do this only in the case
506 that we are remembering commands on the history list. */
507 if (remember_on_history)
509 name = bash_tilde_expand (posixly_correct ? "~/.sh_history" : "~/.bash_history", 0);
511 set_if_not ("HISTFILE", name);
512 free (name);
514 #if 0
515 set_if_not ("HISTSIZE", "500");
516 sv_histsize ("HISTSIZE");
517 #endif
519 #endif /* HISTORY */
521 /* Seed the random number generator. */
522 seedrand ();
524 /* Handle some "special" variables that we may have inherited from a
525 parent shell. */
526 if (interactive_shell)
528 temp_var = find_variable ("IGNOREEOF");
529 if (!temp_var)
530 temp_var = find_variable ("ignoreeof");
531 if (temp_var && imported_p (temp_var))
532 sv_ignoreeof (temp_var->name);
535 #if defined (HISTORY)
536 if (interactive_shell && remember_on_history)
538 sv_history_control ("HISTCONTROL");
539 sv_histignore ("HISTIGNORE");
540 sv_histtimefmt ("HISTTIMEFORMAT");
542 #endif /* HISTORY */
544 #if defined (READLINE) && defined (STRICT_POSIX)
545 /* POSIXLY_CORRECT will only be 1 here if the shell was compiled
546 -DSTRICT_POSIX */
547 if (interactive_shell && posixly_correct && no_line_editing == 0)
548 rl_prefer_env_winsize = 1;
549 #endif /* READLINE && STRICT_POSIX */
552 * 24 October 2001
554 * I'm tired of the arguing and bug reports. Bash now leaves SSH_CLIENT
555 * and SSH2_CLIENT alone. I'm going to rely on the shell_level check in
556 * isnetconn() to avoid running the startup files more often than wanted.
557 * That will, of course, only work if the user's login shell is bash, so
558 * I've made that behavior conditional on SSH_SOURCE_BASHRC being defined
559 * in config-top.h.
561 #if 0
562 temp_var = find_variable ("SSH_CLIENT");
563 if (temp_var && imported_p (temp_var))
565 VUNSETATTR (temp_var, att_exported);
566 array_needs_making = 1;
568 temp_var = find_variable ("SSH2_CLIENT");
569 if (temp_var && imported_p (temp_var))
571 VUNSETATTR (temp_var, att_exported);
572 array_needs_making = 1;
574 #endif
576 /* Get the user's real and effective user ids. */
577 uidset ();
579 /* Initialize the dynamic variables, and seed their values. */
580 initialize_dynamic_variables ();
583 /* **************************************************************** */
584 /* */
585 /* Setting values for special shell variables */
586 /* */
587 /* **************************************************************** */
589 static void
590 set_machine_vars ()
592 SHELL_VAR *temp_var;
594 temp_var = set_if_not ("HOSTTYPE", HOSTTYPE);
595 temp_var = set_if_not ("OSTYPE", OSTYPE);
596 temp_var = set_if_not ("MACHTYPE", MACHTYPE);
598 temp_var = set_if_not ("HOSTNAME", current_host_name);
601 /* Set $HOME to the information in the password file if we didn't get
602 it from the environment. */
604 /* This function is not static so the tilde and readline libraries can
605 use it. */
606 char *
607 sh_get_home_dir ()
609 if (current_user.home_dir == 0)
610 get_current_user_info ();
611 return current_user.home_dir;
614 static void
615 set_home_var ()
617 SHELL_VAR *temp_var;
619 temp_var = find_variable ("HOME");
620 if (temp_var == 0)
621 temp_var = bind_variable ("HOME", sh_get_home_dir (), 0);
622 #if 0
623 VSETATTR (temp_var, att_exported);
624 #endif
627 /* Set $SHELL to the user's login shell if it is not already set. Call
628 get_current_user_info if we haven't already fetched the shell. */
629 static void
630 set_shell_var ()
632 SHELL_VAR *temp_var;
634 temp_var = find_variable ("SHELL");
635 if (temp_var == 0)
637 if (current_user.shell == 0)
638 get_current_user_info ();
639 temp_var = bind_variable ("SHELL", current_user.shell, 0);
641 #if 0
642 VSETATTR (temp_var, att_exported);
643 #endif
646 static char *
647 get_bash_name ()
649 char *name;
651 if ((login_shell == 1) && RELPATH(shell_name))
653 if (current_user.shell == 0)
654 get_current_user_info ();
655 name = savestring (current_user.shell);
657 else if (ABSPATH(shell_name))
658 name = savestring (shell_name);
659 else if (shell_name[0] == '.' && shell_name[1] == '/')
661 /* Fast path for common case. */
662 char *cdir;
663 int len;
665 cdir = get_string_value ("PWD");
666 if (cdir)
668 len = strlen (cdir);
669 name = (char *)xmalloc (len + strlen (shell_name) + 1);
670 strcpy (name, cdir);
671 strcpy (name + len, shell_name + 1);
673 else
674 name = savestring (shell_name);
676 else
678 char *tname;
679 int s;
681 tname = find_user_command (shell_name);
683 if (tname == 0)
685 /* Try the current directory. If there is not an executable
686 there, just punt and use the login shell. */
687 s = file_status (shell_name);
688 if (s & FS_EXECABLE)
690 tname = make_absolute (shell_name, get_string_value ("PWD"));
691 if (*shell_name == '.')
693 name = sh_canonpath (tname, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
694 if (name == 0)
695 name = tname;
696 else
697 free (tname);
699 else
700 name = tname;
702 else
704 if (current_user.shell == 0)
705 get_current_user_info ();
706 name = savestring (current_user.shell);
709 else
711 name = full_pathname (tname);
712 free (tname);
716 return (name);
719 void
720 adjust_shell_level (change)
721 int change;
723 char new_level[5], *old_SHLVL;
724 intmax_t old_level;
725 SHELL_VAR *temp_var;
727 old_SHLVL = get_string_value ("SHLVL");
728 if (old_SHLVL == 0 || *old_SHLVL == '\0' || legal_number (old_SHLVL, &old_level) == 0)
729 old_level = 0;
731 shell_level = old_level + change;
732 if (shell_level < 0)
733 shell_level = 0;
734 else if (shell_level > 1000)
736 internal_warning (_("shell level (%d) too high, resetting to 1"), shell_level);
737 shell_level = 1;
740 /* We don't need the full generality of itos here. */
741 if (shell_level < 10)
743 new_level[0] = shell_level + '0';
744 new_level[1] = '\0';
746 else if (shell_level < 100)
748 new_level[0] = (shell_level / 10) + '0';
749 new_level[1] = (shell_level % 10) + '0';
750 new_level[2] = '\0';
752 else if (shell_level < 1000)
754 new_level[0] = (shell_level / 100) + '0';
755 old_level = shell_level % 100;
756 new_level[1] = (old_level / 10) + '0';
757 new_level[2] = (old_level % 10) + '0';
758 new_level[3] = '\0';
761 temp_var = bind_variable ("SHLVL", new_level, 0);
762 set_auto_export (temp_var);
765 static void
766 initialize_shell_level ()
768 adjust_shell_level (1);
771 /* If we got PWD from the environment, update our idea of the current
772 working directory. In any case, make sure that PWD exists before
773 checking it. It is possible for getcwd () to fail on shell startup,
774 and in that case, PWD would be undefined. If this is an interactive
775 login shell, see if $HOME is the current working directory, and if
776 that's not the same string as $PWD, set PWD=$HOME. */
778 void
779 set_pwd ()
781 SHELL_VAR *temp_var, *home_var;
782 char *temp_string, *home_string;
784 home_var = find_variable ("HOME");
785 home_string = home_var ? value_cell (home_var) : (char *)NULL;
787 temp_var = find_variable ("PWD");
788 if (temp_var && imported_p (temp_var) &&
789 (temp_string = value_cell (temp_var)) &&
790 same_file (temp_string, ".", (struct stat *)NULL, (struct stat *)NULL))
791 set_working_directory (temp_string);
792 else if (home_string && interactive_shell && login_shell &&
793 same_file (home_string, ".", (struct stat *)NULL, (struct stat *)NULL))
795 set_working_directory (home_string);
796 temp_var = bind_variable ("PWD", home_string, 0);
797 set_auto_export (temp_var);
799 else
801 temp_string = get_working_directory ("shell-init");
802 if (temp_string)
804 temp_var = bind_variable ("PWD", temp_string, 0);
805 set_auto_export (temp_var);
806 free (temp_string);
810 /* According to the Single Unix Specification, v2, $OLDPWD is an
811 `environment variable' and therefore should be auto-exported.
812 Make a dummy invisible variable for OLDPWD, and mark it as exported. */
813 temp_var = bind_variable ("OLDPWD", (char *)NULL, 0);
814 VSETATTR (temp_var, (att_exported | att_invisible));
817 /* Make a variable $PPID, which holds the pid of the shell's parent. */
818 void
819 set_ppid ()
821 char namebuf[INT_STRLEN_BOUND(pid_t) + 1], *name;
822 SHELL_VAR *temp_var;
824 name = inttostr (getppid (), namebuf, sizeof(namebuf));
825 temp_var = find_variable ("PPID");
826 if (temp_var)
827 VUNSETATTR (temp_var, (att_readonly | att_exported));
828 temp_var = bind_variable ("PPID", name, 0);
829 VSETATTR (temp_var, (att_readonly | att_integer));
832 static void
833 uidset ()
835 char buff[INT_STRLEN_BOUND(uid_t) + 1], *b;
836 register SHELL_VAR *v;
838 b = inttostr (current_user.uid, buff, sizeof (buff));
839 v = find_variable ("UID");
840 if (v == 0)
842 v = bind_variable ("UID", b, 0);
843 VSETATTR (v, (att_readonly | att_integer));
846 if (current_user.euid != current_user.uid)
847 b = inttostr (current_user.euid, buff, sizeof (buff));
849 v = find_variable ("EUID");
850 if (v == 0)
852 v = bind_variable ("EUID", b, 0);
853 VSETATTR (v, (att_readonly | att_integer));
857 #if defined (ARRAY_VARS)
858 static void
859 make_vers_array ()
861 SHELL_VAR *vv;
862 ARRAY *av;
863 char *s, d[32], b[INT_STRLEN_BOUND(int) + 1];
865 unbind_variable ("BASH_VERSINFO");
867 vv = make_new_array_variable ("BASH_VERSINFO");
868 av = array_cell (vv);
869 strcpy (d, dist_version);
870 s = xstrchr (d, '.');
871 if (s)
872 *s++ = '\0';
873 array_insert (av, 0, d);
874 array_insert (av, 1, s);
875 s = inttostr (patch_level, b, sizeof (b));
876 array_insert (av, 2, s);
877 s = inttostr (build_version, b, sizeof (b));
878 array_insert (av, 3, s);
879 array_insert (av, 4, release_status);
880 array_insert (av, 5, MACHTYPE);
882 VSETATTR (vv, att_readonly);
884 #endif /* ARRAY_VARS */
886 /* Set the environment variables $LINES and $COLUMNS in response to
887 a window size change. */
888 void
889 sh_set_lines_and_columns (lines, cols)
890 int lines, cols;
892 char val[INT_STRLEN_BOUND(int) + 1], *v;
894 #if defined (READLINE)
895 /* If we are currently assigning to LINES or COLUMNS, don't do anything. */
896 if (winsize_assignment)
897 return;
898 #endif
900 v = inttostr (lines, val, sizeof (val));
901 bind_variable ("LINES", v, 0);
903 v = inttostr (cols, val, sizeof (val));
904 bind_variable ("COLUMNS", v, 0);
907 /* **************************************************************** */
908 /* */
909 /* Printing variables and values */
910 /* */
911 /* **************************************************************** */
913 /* Print LIST (a list of shell variables) to stdout in such a way that
914 they can be read back in. */
915 void
916 print_var_list (list)
917 register SHELL_VAR **list;
919 register int i;
920 register SHELL_VAR *var;
922 for (i = 0; list && (var = list[i]); i++)
923 if (invisible_p (var) == 0)
924 print_assignment (var);
927 /* Print LIST (a list of shell functions) to stdout in such a way that
928 they can be read back in. */
929 void
930 print_func_list (list)
931 register SHELL_VAR **list;
933 register int i;
934 register SHELL_VAR *var;
936 for (i = 0; list && (var = list[i]); i++)
938 printf ("%s ", var->name);
939 print_var_function (var);
940 printf ("\n");
944 /* Print the value of a single SHELL_VAR. No newline is
945 output, but the variable is printed in such a way that
946 it can be read back in. */
947 void
948 print_assignment (var)
949 SHELL_VAR *var;
951 if (var_isset (var) == 0)
952 return;
954 if (function_p (var))
956 printf ("%s", var->name);
957 print_var_function (var);
958 printf ("\n");
960 #if defined (ARRAY_VARS)
961 else if (array_p (var))
962 print_array_assignment (var, 0);
963 else if (assoc_p (var))
964 print_assoc_assignment (var, 0);
965 #endif /* ARRAY_VARS */
966 else
968 printf ("%s=", var->name);
969 print_var_value (var, 1);
970 printf ("\n");
974 /* Print the value cell of VAR, a shell variable. Do not print
975 the name, nor leading/trailing newline. If QUOTE is non-zero,
976 and the value contains shell metacharacters, quote the value
977 in such a way that it can be read back in. */
978 void
979 print_var_value (var, quote)
980 SHELL_VAR *var;
981 int quote;
983 char *t;
985 if (var_isset (var) == 0)
986 return;
988 if (quote && posixly_correct == 0 && ansic_shouldquote (value_cell (var)))
990 t = ansic_quote (value_cell (var), 0, (int *)0);
991 printf ("%s", t);
992 free (t);
994 else if (quote && sh_contains_shell_metas (value_cell (var)))
996 t = sh_single_quote (value_cell (var));
997 printf ("%s", t);
998 free (t);
1000 else
1001 printf ("%s", value_cell (var));
1004 /* Print the function cell of VAR, a shell variable. Do not
1005 print the name, nor leading/trailing newline. */
1006 void
1007 print_var_function (var)
1008 SHELL_VAR *var;
1010 char *x;
1012 if (function_p (var) && var_isset (var))
1014 x = named_function_string ((char *)NULL, function_cell(var), FUNC_MULTILINE|FUNC_EXTERNAL);
1015 printf ("%s", x);
1019 /* **************************************************************** */
1020 /* */
1021 /* Dynamic Variables */
1022 /* */
1023 /* **************************************************************** */
1025 /* DYNAMIC VARIABLES
1027 These are variables whose values are generated anew each time they are
1028 referenced. These are implemented using a pair of function pointers
1029 in the struct variable: assign_func, which is called from bind_variable
1030 and, if arrays are compiled into the shell, some of the functions in
1031 arrayfunc.c, and dynamic_value, which is called from find_variable.
1033 assign_func is called from bind_variable_internal, if
1034 bind_variable_internal discovers that the variable being assigned to
1035 has such a function. The function is called as
1036 SHELL_VAR *temp = (*(entry->assign_func)) (entry, value, ind)
1037 and the (SHELL_VAR *)temp is returned as the value of bind_variable. It
1038 is usually ENTRY (self). IND is an index for an array variable, and
1039 unused otherwise.
1041 dynamic_value is called from find_variable_internal to return a `new'
1042 value for the specified dynamic varible. If this function is NULL,
1043 the variable is treated as a `normal' shell variable. If it is not,
1044 however, then this function is called like this:
1045 tempvar = (*(var->dynamic_value)) (var);
1047 Sometimes `tempvar' will replace the value of `var'. Other times, the
1048 shell will simply use the string value. Pretty object-oriented, huh?
1050 Be warned, though: if you `unset' a special variable, it loses its
1051 special meaning, even if you subsequently set it.
1053 The special assignment code would probably have been better put in
1054 subst.c: do_assignment_internal, in the same style as
1055 stupidly_hack_special_variables, but I wanted the changes as
1056 localized as possible. */
1058 #define INIT_DYNAMIC_VAR(var, val, gfunc, afunc) \
1059 do \
1061 v = bind_variable (var, (val), 0); \
1062 v->dynamic_value = gfunc; \
1063 v->assign_func = afunc; \
1065 while (0)
1067 #define INIT_DYNAMIC_ARRAY_VAR(var, gfunc, afunc) \
1068 do \
1070 v = make_new_array_variable (var); \
1071 v->dynamic_value = gfunc; \
1072 v->assign_func = afunc; \
1074 while (0)
1076 #define INIT_DYNAMIC_ASSOC_VAR(var, gfunc, afunc) \
1077 do \
1079 v = make_new_assoc_variable (var); \
1080 v->dynamic_value = gfunc; \
1081 v->assign_func = afunc; \
1083 while (0)
1085 static SHELL_VAR *
1086 null_assign (self, value, unused, key)
1087 SHELL_VAR *self;
1088 char *value;
1089 arrayind_t unused;
1090 char *key;
1092 return (self);
1095 #if defined (ARRAY_VARS)
1096 static SHELL_VAR *
1097 null_array_assign (self, value, ind, key)
1098 SHELL_VAR *self;
1099 char *value;
1100 arrayind_t ind;
1101 char *key;
1103 return (self);
1105 #endif
1107 /* Degenerate `dynamic_value' function; just returns what's passed without
1108 manipulation. */
1109 static SHELL_VAR *
1110 get_self (self)
1111 SHELL_VAR *self;
1113 return (self);
1116 #if defined (ARRAY_VARS)
1117 /* A generic dynamic array variable initializer. Intialize array variable
1118 NAME with dynamic value function GETFUNC and assignment function SETFUNC. */
1119 static SHELL_VAR *
1120 init_dynamic_array_var (name, getfunc, setfunc, attrs)
1121 char *name;
1122 sh_var_value_func_t *getfunc;
1123 sh_var_assign_func_t *setfunc;
1124 int attrs;
1126 SHELL_VAR *v;
1128 v = find_variable (name);
1129 if (v)
1130 return (v);
1131 INIT_DYNAMIC_ARRAY_VAR (name, getfunc, setfunc);
1132 if (attrs)
1133 VSETATTR (v, attrs);
1134 return v;
1137 static SHELL_VAR *
1138 init_dynamic_assoc_var (name, getfunc, setfunc, attrs)
1139 char *name;
1140 sh_var_value_func_t *getfunc;
1141 sh_var_assign_func_t *setfunc;
1142 int attrs;
1144 SHELL_VAR *v;
1146 v = find_variable (name);
1147 if (v)
1148 return (v);
1149 INIT_DYNAMIC_ASSOC_VAR (name, getfunc, setfunc);
1150 if (attrs)
1151 VSETATTR (v, attrs);
1152 return v;
1154 #endif
1156 /* The value of $SECONDS. This is the number of seconds since shell
1157 invocation, or, the number of seconds since the last assignment + the
1158 value of the last assignment. */
1159 static intmax_t seconds_value_assigned;
1161 static SHELL_VAR *
1162 assign_seconds (self, value, unused, key)
1163 SHELL_VAR *self;
1164 char *value;
1165 arrayind_t unused;
1166 char *key;
1168 if (legal_number (value, &seconds_value_assigned) == 0)
1169 seconds_value_assigned = 0;
1170 shell_start_time = NOW;
1171 return (self);
1174 static SHELL_VAR *
1175 get_seconds (var)
1176 SHELL_VAR *var;
1178 time_t time_since_start;
1179 char *p;
1181 time_since_start = NOW - shell_start_time;
1182 p = itos(seconds_value_assigned + time_since_start);
1184 FREE (value_cell (var));
1186 VSETATTR (var, att_integer);
1187 var_setvalue (var, p);
1188 return (var);
1191 static SHELL_VAR *
1192 init_seconds_var ()
1194 SHELL_VAR *v;
1196 v = find_variable ("SECONDS");
1197 if (v)
1199 if (legal_number (value_cell(v), &seconds_value_assigned) == 0)
1200 seconds_value_assigned = 0;
1202 INIT_DYNAMIC_VAR ("SECONDS", (v ? value_cell (v) : (char *)NULL), get_seconds, assign_seconds);
1203 return v;
1206 /* The random number seed. You can change this by setting RANDOM. */
1207 static unsigned long rseed = 1;
1208 static int last_random_value;
1209 static int seeded_subshell = 0;
1211 /* A linear congruential random number generator based on the example
1212 one in the ANSI C standard. This one isn't very good, but a more
1213 complicated one is overkill. */
1215 /* Returns a pseudo-random number between 0 and 32767. */
1216 static int
1217 brand ()
1219 #if 0
1220 rseed = rseed * 1103515245 + 12345;
1221 return ((unsigned int)((rseed >> 16) & 32767)); /* was % 32768 */
1222 #else
1223 /* From "Random number generators: good ones are hard to find",
1224 Park and Miller, Communications of the ACM, vol. 31, no. 10,
1225 October 1988, p. 1195. filtered through FreeBSD */
1226 long h, l;
1228 if (rseed == 0)
1229 seedrand ();
1230 h = rseed / 127773;
1231 l = rseed % 127773;
1232 rseed = 16807 * l - 2836 * h;
1233 #if 0
1234 if (rseed < 0)
1235 rseed += 0x7fffffff;
1236 #endif
1237 return ((unsigned int)(rseed & 32767)); /* was % 32768 */
1238 #endif
1241 /* Set the random number generator seed to SEED. */
1242 static void
1243 sbrand (seed)
1244 unsigned long seed;
1246 rseed = seed;
1247 last_random_value = 0;
1250 static void
1251 seedrand ()
1253 struct timeval tv;
1255 gettimeofday (&tv, NULL);
1256 sbrand (tv.tv_sec ^ tv.tv_usec ^ getpid ());
1259 static SHELL_VAR *
1260 assign_random (self, value, unused, key)
1261 SHELL_VAR *self;
1262 char *value;
1263 arrayind_t unused;
1264 char *key;
1266 sbrand (strtoul (value, (char **)NULL, 10));
1267 if (subshell_environment)
1268 seeded_subshell = getpid ();
1269 return (self);
1273 get_random_number ()
1275 int rv, pid;
1277 /* Reset for command and process substitution. */
1278 pid = getpid ();
1279 if (subshell_environment && seeded_subshell != pid)
1281 seedrand ();
1282 seeded_subshell = pid;
1286 rv = brand ();
1287 while (rv == last_random_value);
1288 return rv;
1291 static SHELL_VAR *
1292 get_random (var)
1293 SHELL_VAR *var;
1295 int rv;
1296 char *p;
1298 rv = get_random_number ();
1299 last_random_value = rv;
1300 p = itos (rv);
1302 FREE (value_cell (var));
1304 VSETATTR (var, att_integer);
1305 var_setvalue (var, p);
1306 return (var);
1309 static SHELL_VAR *
1310 assign_lineno (var, value, unused, key)
1311 SHELL_VAR *var;
1312 char *value;
1313 arrayind_t unused;
1314 char *key;
1316 intmax_t new_value;
1318 if (value == 0 || *value == '\0' || legal_number (value, &new_value) == 0)
1319 new_value = 0;
1320 line_number = new_value;
1321 return var;
1324 /* Function which returns the current line number. */
1325 static SHELL_VAR *
1326 get_lineno (var)
1327 SHELL_VAR *var;
1329 char *p;
1330 int ln;
1332 ln = executing_line_number ();
1333 p = itos (ln);
1334 FREE (value_cell (var));
1335 var_setvalue (var, p);
1336 return (var);
1339 static SHELL_VAR *
1340 assign_subshell (var, value, unused, key)
1341 SHELL_VAR *var;
1342 char *value;
1343 arrayind_t unused;
1344 char *key;
1346 intmax_t new_value;
1348 if (value == 0 || *value == '\0' || legal_number (value, &new_value) == 0)
1349 new_value = 0;
1350 subshell_level = new_value;
1351 return var;
1354 static SHELL_VAR *
1355 get_subshell (var)
1356 SHELL_VAR *var;
1358 char *p;
1360 p = itos (subshell_level);
1361 FREE (value_cell (var));
1362 var_setvalue (var, p);
1363 return (var);
1366 static SHELL_VAR *
1367 get_bashpid (var)
1368 SHELL_VAR *var;
1370 int pid;
1371 char *p;
1373 pid = getpid ();
1374 p = itos (pid);
1376 FREE (value_cell (var));
1377 VSETATTR (var, att_integer|att_readonly);
1378 var_setvalue (var, p);
1379 return (var);
1382 static SHELL_VAR *
1383 get_bash_command (var)
1384 SHELL_VAR *var;
1386 char *p;
1388 if (the_printed_command_except_trap)
1389 p = savestring (the_printed_command_except_trap);
1390 else
1392 p = (char *)xmalloc (1);
1393 p[0] = '\0';
1395 FREE (value_cell (var));
1396 var_setvalue (var, p);
1397 return (var);
1400 #if defined (HISTORY)
1401 static SHELL_VAR *
1402 get_histcmd (var)
1403 SHELL_VAR *var;
1405 char *p;
1407 p = itos (history_number ());
1408 FREE (value_cell (var));
1409 var_setvalue (var, p);
1410 return (var);
1412 #endif
1414 #if defined (READLINE)
1415 /* When this function returns, VAR->value points to malloced memory. */
1416 static SHELL_VAR *
1417 get_comp_wordbreaks (var)
1418 SHELL_VAR *var;
1420 /* If we don't have anything yet, assign a default value. */
1421 if (rl_completer_word_break_characters == 0 && bash_readline_initialized == 0)
1422 enable_hostname_completion (perform_hostname_completion);
1424 FREE (value_cell (var));
1425 var_setvalue (var, savestring (rl_completer_word_break_characters));
1427 return (var);
1430 /* When this function returns, rl_completer_word_break_characters points to
1431 malloced memory. */
1432 static SHELL_VAR *
1433 assign_comp_wordbreaks (self, value, unused, key)
1434 SHELL_VAR *self;
1435 char *value;
1436 arrayind_t unused;
1437 char *key;
1439 if (rl_completer_word_break_characters &&
1440 rl_completer_word_break_characters != rl_basic_word_break_characters)
1441 free (rl_completer_word_break_characters);
1443 rl_completer_word_break_characters = savestring (value);
1444 return self;
1446 #endif /* READLINE */
1448 #if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
1449 static SHELL_VAR *
1450 assign_dirstack (self, value, ind, key)
1451 SHELL_VAR *self;
1452 char *value;
1453 arrayind_t ind;
1454 char *key;
1456 set_dirstack_element (ind, 1, value);
1457 return self;
1460 static SHELL_VAR *
1461 get_dirstack (self)
1462 SHELL_VAR *self;
1464 ARRAY *a;
1465 WORD_LIST *l;
1467 l = get_directory_stack (0);
1468 a = array_from_word_list (l);
1469 array_dispose (array_cell (self));
1470 dispose_words (l);
1471 var_setarray (self, a);
1472 return self;
1474 #endif /* PUSHD AND POPD && ARRAY_VARS */
1476 #if defined (ARRAY_VARS)
1477 /* We don't want to initialize the group set with a call to getgroups()
1478 unless we're asked to, but we only want to do it once. */
1479 static SHELL_VAR *
1480 get_groupset (self)
1481 SHELL_VAR *self;
1483 register int i;
1484 int ng;
1485 ARRAY *a;
1486 static char **group_set = (char **)NULL;
1488 if (group_set == 0)
1490 group_set = get_group_list (&ng);
1491 a = array_cell (self);
1492 for (i = 0; i < ng; i++)
1493 array_insert (a, i, group_set[i]);
1495 return (self);
1498 static SHELL_VAR *
1499 build_hashcmd (self)
1500 SHELL_VAR *self;
1502 HASH_TABLE *h;
1503 int i;
1504 char *k, *v;
1505 BUCKET_CONTENTS *item;
1507 h = assoc_cell (self);
1508 if (h)
1509 assoc_dispose (h);
1511 if (hashed_filenames == 0 || HASH_ENTRIES (hashed_filenames) == 0)
1513 var_setvalue (self, (char *)NULL);
1514 return self;
1517 h = assoc_create (hashed_filenames->nbuckets);
1518 for (i = 0; i < hashed_filenames->nbuckets; i++)
1520 for (item = hash_items (i, hashed_filenames); item; item = item->next)
1522 k = savestring (item->key);
1523 v = pathdata(item)->path;
1524 assoc_insert (h, k, v);
1528 var_setvalue (self, (char *)h);
1529 return self;
1532 static SHELL_VAR *
1533 get_hashcmd (self)
1534 SHELL_VAR *self;
1536 build_hashcmd (self);
1537 return (self);
1540 static SHELL_VAR *
1541 assign_hashcmd (self, value, ind, key)
1542 SHELL_VAR *self;
1543 char *value;
1544 arrayind_t ind;
1545 char *key;
1547 phash_insert (key, value, 0, 0);
1548 return (build_hashcmd (self));
1551 static SHELL_VAR *
1552 build_aliasvar (self)
1553 SHELL_VAR *self;
1555 HASH_TABLE *h;
1556 int i;
1557 char *k, *v;
1558 BUCKET_CONTENTS *item;
1560 h = assoc_cell (self);
1561 if (h)
1562 assoc_dispose (h);
1564 if (aliases == 0 || HASH_ENTRIES (aliases) == 0)
1566 var_setvalue (self, (char *)NULL);
1567 return self;
1570 h = assoc_create (aliases->nbuckets);
1571 for (i = 0; i < aliases->nbuckets; i++)
1573 for (item = hash_items (i, aliases); item; item = item->next)
1575 k = savestring (item->key);
1576 v = ((alias_t *)(item->data))->value;
1577 assoc_insert (h, k, v);
1581 var_setvalue (self, (char *)h);
1582 return self;
1585 static SHELL_VAR *
1586 get_aliasvar (self)
1587 SHELL_VAR *self;
1589 build_aliasvar (self);
1590 return (self);
1593 static SHELL_VAR *
1594 assign_aliasvar (self, value, ind, key)
1595 SHELL_VAR *self;
1596 char *value;
1597 arrayind_t ind;
1598 char *key;
1600 add_alias (key, value);
1601 return (build_aliasvar (self));
1603 #endif /* ARRAY_VARS */
1605 /* If ARRAY_VARS is not defined, this just returns the name of any
1606 currently-executing function. If we have arrays, it's a call stack. */
1607 static SHELL_VAR *
1608 get_funcname (self)
1609 SHELL_VAR *self;
1611 #if ! defined (ARRAY_VARS)
1612 char *t;
1613 if (variable_context && this_shell_function)
1615 FREE (value_cell (self));
1616 t = savestring (this_shell_function->name);
1617 var_setvalue (self, t);
1619 #endif
1620 return (self);
1623 void
1624 make_funcname_visible (on_or_off)
1625 int on_or_off;
1627 SHELL_VAR *v;
1629 v = find_variable ("FUNCNAME");
1630 if (v == 0 || v->dynamic_value == 0)
1631 return;
1633 if (on_or_off)
1634 VUNSETATTR (v, att_invisible);
1635 else
1636 VSETATTR (v, att_invisible);
1639 static SHELL_VAR *
1640 init_funcname_var ()
1642 SHELL_VAR *v;
1644 v = find_variable ("FUNCNAME");
1645 if (v)
1646 return v;
1647 #if defined (ARRAY_VARS)
1648 INIT_DYNAMIC_ARRAY_VAR ("FUNCNAME", get_funcname, null_array_assign);
1649 #else
1650 INIT_DYNAMIC_VAR ("FUNCNAME", (char *)NULL, get_funcname, null_assign);
1651 #endif
1652 VSETATTR (v, att_invisible|att_noassign);
1653 return v;
1656 static void
1657 initialize_dynamic_variables ()
1659 SHELL_VAR *v;
1661 v = init_seconds_var ();
1663 INIT_DYNAMIC_VAR ("BASH_COMMAND", (char *)NULL, get_bash_command, (sh_var_assign_func_t *)NULL);
1664 INIT_DYNAMIC_VAR ("BASH_SUBSHELL", (char *)NULL, get_subshell, assign_subshell);
1666 INIT_DYNAMIC_VAR ("RANDOM", (char *)NULL, get_random, assign_random);
1667 VSETATTR (v, att_integer);
1668 INIT_DYNAMIC_VAR ("LINENO", (char *)NULL, get_lineno, assign_lineno);
1669 VSETATTR (v, att_integer);
1671 INIT_DYNAMIC_VAR ("BASHPID", (char *)NULL, get_bashpid, null_assign);
1672 VSETATTR (v, att_integer|att_readonly);
1674 #if defined (HISTORY)
1675 INIT_DYNAMIC_VAR ("HISTCMD", (char *)NULL, get_histcmd, (sh_var_assign_func_t *)NULL);
1676 VSETATTR (v, att_integer);
1677 #endif
1679 #if defined (READLINE)
1680 INIT_DYNAMIC_VAR ("COMP_WORDBREAKS", (char *)NULL, get_comp_wordbreaks, assign_comp_wordbreaks);
1681 #endif
1683 #if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
1684 v = init_dynamic_array_var ("DIRSTACK", get_dirstack, assign_dirstack, 0);
1685 #endif /* PUSHD_AND_POPD && ARRAY_VARS */
1687 #if defined (ARRAY_VARS)
1688 v = init_dynamic_array_var ("GROUPS", get_groupset, null_array_assign, att_noassign);
1690 # if defined (DEBUGGER)
1691 v = init_dynamic_array_var ("BASH_ARGC", get_self, null_array_assign, att_noassign|att_nounset);
1692 v = init_dynamic_array_var ("BASH_ARGV", get_self, null_array_assign, att_noassign|att_nounset);
1693 # endif /* DEBUGGER */
1694 v = init_dynamic_array_var ("BASH_SOURCE", get_self, null_array_assign, att_noassign|att_nounset);
1695 v = init_dynamic_array_var ("BASH_LINENO", get_self, null_array_assign, att_noassign|att_nounset);
1697 v = init_dynamic_assoc_var ("BASH_CMDS", get_hashcmd, assign_hashcmd, att_nofree);
1698 v = init_dynamic_assoc_var ("BASH_ALIASES", get_aliasvar, assign_aliasvar, att_nofree);
1699 #endif
1701 v = init_funcname_var ();
1704 /* **************************************************************** */
1705 /* */
1706 /* Retrieving variables and values */
1707 /* */
1708 /* **************************************************************** */
1710 /* How to get a pointer to the shell variable or function named NAME.
1711 HASHED_VARS is a pointer to the hash table containing the list
1712 of interest (either variables or functions). */
1714 static SHELL_VAR *
1715 hash_lookup (name, hashed_vars)
1716 const char *name;
1717 HASH_TABLE *hashed_vars;
1719 BUCKET_CONTENTS *bucket;
1721 bucket = hash_search (name, hashed_vars, 0);
1722 return (bucket ? (SHELL_VAR *)bucket->data : (SHELL_VAR *)NULL);
1725 SHELL_VAR *
1726 var_lookup (name, vcontext)
1727 const char *name;
1728 VAR_CONTEXT *vcontext;
1730 VAR_CONTEXT *vc;
1731 SHELL_VAR *v;
1733 v = (SHELL_VAR *)NULL;
1734 for (vc = vcontext; vc; vc = vc->down)
1735 if (v = hash_lookup (name, vc->table))
1736 break;
1738 return v;
1741 /* Look up the variable entry named NAME. If SEARCH_TEMPENV is non-zero,
1742 then also search the temporarily built list of exported variables.
1743 The lookup order is:
1744 temporary_env
1745 shell_variables list
1748 SHELL_VAR *
1749 find_variable_internal (name, force_tempenv)
1750 const char *name;
1751 int force_tempenv;
1753 SHELL_VAR *var;
1754 int search_tempenv;
1756 var = (SHELL_VAR *)NULL;
1758 /* If explicitly requested, first look in the temporary environment for
1759 the variable. This allows constructs such as "foo=x eval 'echo $foo'"
1760 to get the `exported' value of $foo. This happens if we are executing
1761 a function or builtin, or if we are looking up a variable in a
1762 "subshell environment". */
1763 search_tempenv = force_tempenv || (expanding_redir == 0 && subshell_environment);
1765 if (search_tempenv && temporary_env)
1766 var = hash_lookup (name, temporary_env);
1768 if (var == 0)
1769 var = var_lookup (name, shell_variables);
1771 if (var == 0)
1772 return ((SHELL_VAR *)NULL);
1774 return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var);
1777 /* Look up the variable entry named NAME. Returns the entry or NULL. */
1778 SHELL_VAR *
1779 find_variable (name)
1780 const char *name;
1782 return (find_variable_internal (name, (expanding_redir == 0 && (assigning_in_environment || executing_builtin))));
1785 /* Look up the function entry whose name matches STRING.
1786 Returns the entry or NULL. */
1787 SHELL_VAR *
1788 find_function (name)
1789 const char *name;
1791 return (hash_lookup (name, shell_functions));
1794 /* Find the function definition for the shell function named NAME. Returns
1795 the entry or NULL. */
1796 FUNCTION_DEF *
1797 find_function_def (name)
1798 const char *name;
1800 #if defined (DEBUGGER)
1801 return ((FUNCTION_DEF *)hash_lookup (name, shell_function_defs));
1802 #else
1803 return ((FUNCTION_DEF *)0);
1804 #endif
1807 /* Return the value of VAR. VAR is assumed to have been the result of a
1808 lookup without any subscript, if arrays are compiled into the shell. */
1809 char *
1810 get_variable_value (var)
1811 SHELL_VAR *var;
1813 if (var == 0)
1814 return ((char *)NULL);
1815 #if defined (ARRAY_VARS)
1816 else if (array_p (var))
1817 return (array_reference (array_cell (var), 0));
1818 else if (assoc_p (var))
1819 return (assoc_reference (assoc_cell (var), "0"));
1820 #endif
1821 else
1822 return (value_cell (var));
1825 /* Return the string value of a variable. Return NULL if the variable
1826 doesn't exist. Don't cons a new string. This is a potential memory
1827 leak if the variable is found in the temporary environment. Since
1828 functions and variables have separate name spaces, returns NULL if
1829 var_name is a shell function only. */
1830 char *
1831 get_string_value (var_name)
1832 const char *var_name;
1834 SHELL_VAR *var;
1836 var = find_variable (var_name);
1837 return ((var) ? get_variable_value (var) : (char *)NULL);
1840 /* This is present for use by the tilde and readline libraries. */
1841 char *
1842 sh_get_env_value (v)
1843 const char *v;
1845 return get_string_value (v);
1848 /* **************************************************************** */
1849 /* */
1850 /* Creating and setting variables */
1851 /* */
1852 /* **************************************************************** */
1854 /* Set NAME to VALUE if NAME has no value. */
1855 SHELL_VAR *
1856 set_if_not (name, value)
1857 char *name, *value;
1859 SHELL_VAR *v;
1861 if (shell_variables == 0)
1862 create_variable_tables ();
1864 v = find_variable (name);
1865 if (v == 0)
1866 v = bind_variable_internal (name, value, global_variables->table, HASH_NOSRCH, 0);
1867 return (v);
1870 /* Create a local variable referenced by NAME. */
1871 SHELL_VAR *
1872 make_local_variable (name)
1873 const char *name;
1875 SHELL_VAR *new_var, *old_var;
1876 VAR_CONTEXT *vc;
1877 int was_tmpvar;
1878 char *tmp_value;
1880 /* local foo; local foo; is a no-op. */
1881 old_var = find_variable (name);
1882 if (old_var && local_p (old_var) && old_var->context == variable_context)
1884 VUNSETATTR (old_var, att_invisible);
1885 return (old_var);
1888 was_tmpvar = old_var && tempvar_p (old_var);
1889 if (was_tmpvar)
1890 tmp_value = value_cell (old_var);
1892 for (vc = shell_variables; vc; vc = vc->down)
1893 if (vc_isfuncenv (vc) && vc->scope == variable_context)
1894 break;
1896 if (vc == 0)
1898 internal_error (_("make_local_variable: no function context at current scope"));
1899 return ((SHELL_VAR *)NULL);
1901 else if (vc->table == 0)
1902 vc->table = hash_create (TEMPENV_HASH_BUCKETS);
1904 /* Since this is called only from the local/declare/typeset code, we can
1905 call builtin_error here without worry (of course, it will also work
1906 for anything that sets this_command_name). Variables with the `noassign'
1907 attribute may not be made local. The test against old_var's context
1908 level is to disallow local copies of readonly global variables (since I
1909 believe that this could be a security hole). Readonly copies of calling
1910 function local variables are OK. */
1911 if (old_var && (noassign_p (old_var) ||
1912 (readonly_p (old_var) && old_var->context == 0)))
1914 if (readonly_p (old_var))
1915 sh_readonly (name);
1916 return ((SHELL_VAR *)NULL);
1919 if (old_var == 0)
1920 new_var = make_new_variable (name, vc->table);
1921 else
1923 new_var = make_new_variable (name, vc->table);
1925 /* If we found this variable in one of the temporary environments,
1926 inherit its value. Watch to see if this causes problems with
1927 things like `x=4 local x'. */
1928 if (was_tmpvar)
1929 var_setvalue (new_var, savestring (tmp_value));
1931 new_var->attributes = exported_p (old_var) ? att_exported : 0;
1934 vc->flags |= VC_HASLOCAL;
1936 new_var->context = variable_context;
1937 VSETATTR (new_var, att_local);
1939 if (ifsname (name))
1940 setifs (new_var);
1942 return (new_var);
1945 /* Create a new shell variable with name NAME. */
1946 static SHELL_VAR *
1947 new_shell_variable (name)
1948 const char *name;
1950 SHELL_VAR *entry;
1952 entry = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
1954 entry->name = savestring (name);
1955 var_setvalue (entry, (char *)NULL);
1956 CLEAR_EXPORTSTR (entry);
1958 entry->dynamic_value = (sh_var_value_func_t *)NULL;
1959 entry->assign_func = (sh_var_assign_func_t *)NULL;
1961 entry->attributes = 0;
1963 /* Always assume variables are to be made at toplevel!
1964 make_local_variable has the responsibilty of changing the
1965 variable context. */
1966 entry->context = 0;
1968 return (entry);
1971 /* Create a new shell variable with name NAME and add it to the hash table
1972 TABLE. */
1973 static SHELL_VAR *
1974 make_new_variable (name, table)
1975 const char *name;
1976 HASH_TABLE *table;
1978 SHELL_VAR *entry;
1979 BUCKET_CONTENTS *elt;
1981 entry = new_shell_variable (name);
1983 /* Make sure we have a shell_variables hash table to add to. */
1984 if (shell_variables == 0)
1985 create_variable_tables ();
1987 elt = hash_insert (savestring (name), table, HASH_NOSRCH);
1988 elt->data = (PTR_T)entry;
1990 return entry;
1993 #if defined (ARRAY_VARS)
1994 SHELL_VAR *
1995 make_new_array_variable (name)
1996 char *name;
1998 SHELL_VAR *entry;
1999 ARRAY *array;
2001 entry = make_new_variable (name, global_variables->table);
2002 array = array_create ();
2004 var_setarray (entry, array);
2005 VSETATTR (entry, att_array);
2006 return entry;
2009 SHELL_VAR *
2010 make_local_array_variable (name)
2011 char *name;
2013 SHELL_VAR *var;
2014 ARRAY *array;
2016 var = make_local_variable (name);
2017 if (var == 0 || array_p (var))
2018 return var;
2020 array = array_create ();
2022 dispose_variable_value (var);
2023 var_setarray (var, array);
2024 VSETATTR (var, att_array);
2025 return var;
2028 SHELL_VAR *
2029 make_new_assoc_variable (name)
2030 char *name;
2032 SHELL_VAR *entry;
2033 HASH_TABLE *hash;
2035 entry = make_new_variable (name, global_variables->table);
2036 hash = assoc_create (0);
2038 var_setassoc (entry, hash);
2039 VSETATTR (entry, att_assoc);
2040 return entry;
2043 SHELL_VAR *
2044 make_local_assoc_variable (name)
2045 char *name;
2047 SHELL_VAR *var;
2048 HASH_TABLE *hash;
2050 var = make_local_variable (name);
2051 if (var == 0 || assoc_p (var))
2052 return var;
2054 dispose_variable_value (var);
2055 hash = assoc_create (0);
2057 var_setassoc (var, hash);
2058 VSETATTR (var, att_assoc);
2059 return var;
2061 #endif
2063 char *
2064 make_variable_value (var, value, flags)
2065 SHELL_VAR *var;
2066 char *value;
2067 int flags;
2069 char *retval, *oval;
2070 intmax_t lval, rval;
2071 int expok, olen, op;
2073 /* If this variable has had its type set to integer (via `declare -i'),
2074 then do expression evaluation on it and store the result. The
2075 functions in expr.c (evalexp()) and bind_int_variable() are responsible
2076 for turning off the integer flag if they don't want further
2077 evaluation done. */
2078 if (integer_p (var))
2080 if (flags & ASS_APPEND)
2082 oval = value_cell (var);
2083 lval = evalexp (oval, &expok); /* ksh93 seems to do this */
2084 if (expok == 0)
2086 top_level_cleanup ();
2087 jump_to_top_level (DISCARD);
2090 rval = evalexp (value, &expok);
2091 if (expok == 0)
2093 top_level_cleanup ();
2094 jump_to_top_level (DISCARD);
2096 if (flags & ASS_APPEND)
2097 rval += lval;
2098 retval = itos (rval);
2100 #if defined (CASEMOD_ATTRS)
2101 else if (capcase_p (var) || uppercase_p (var) || lowercase_p (var))
2103 if (flags & ASS_APPEND)
2105 oval = get_variable_value (var);
2106 if (oval == 0) /* paranoia */
2107 oval = "";
2108 olen = STRLEN (oval);
2109 retval = (char *)xmalloc (olen + (value ? STRLEN (value) : 0) + 1);
2110 strcpy (retval, oval);
2111 if (value)
2112 strcpy (retval+olen, value);
2114 else if (*value)
2115 retval = savestring (value);
2116 else
2118 retval = (char *)xmalloc (1);
2119 retval[0] = '\0';
2121 op = capcase_p (var) ? CASE_CAPITALIZE
2122 : (uppercase_p (var) ? CASE_UPPER : CASE_LOWER);
2123 oval = sh_modcase (retval, (char *)0, op);
2124 free (retval);
2125 retval = oval;
2127 #endif /* CASEMOD_ATTRS */
2128 else if (value)
2130 if (flags & ASS_APPEND)
2132 oval = get_variable_value (var);
2133 if (oval == 0) /* paranoia */
2134 oval = "";
2135 olen = STRLEN (oval);
2136 retval = (char *)xmalloc (olen + (value ? STRLEN (value) : 0) + 1);
2137 strcpy (retval, oval);
2138 if (value)
2139 strcpy (retval+olen, value);
2141 else if (*value)
2142 retval = savestring (value);
2143 else
2145 retval = (char *)xmalloc (1);
2146 retval[0] = '\0';
2149 else
2150 retval = (char *)NULL;
2152 return retval;
2155 /* Bind a variable NAME to VALUE in the HASH_TABLE TABLE, which may be the
2156 temporary environment (but usually is not). */
2157 static SHELL_VAR *
2158 bind_variable_internal (name, value, table, hflags, aflags)
2159 const char *name;
2160 char *value;
2161 HASH_TABLE *table;
2162 int hflags, aflags;
2164 char *newval;
2165 SHELL_VAR *entry;
2167 entry = (hflags & HASH_NOSRCH) ? (SHELL_VAR *)NULL : hash_lookup (name, table);
2169 if (entry == 0)
2171 entry = make_new_variable (name, table);
2172 var_setvalue (entry, make_variable_value (entry, value, 0)); /* XXX */
2174 else if (entry->assign_func) /* array vars have assign functions now */
2176 INVALIDATE_EXPORTSTR (entry);
2177 newval = (aflags & ASS_APPEND) ? make_variable_value (entry, value, aflags) : value;
2178 entry = (*(entry->assign_func)) (entry, newval, -1, 0);
2179 if (newval != value)
2180 free (newval);
2181 return (entry);
2183 else
2185 if (readonly_p (entry) || noassign_p (entry))
2187 if (readonly_p (entry))
2188 err_readonly (name);
2189 return (entry);
2192 /* Variables which are bound are visible. */
2193 VUNSETATTR (entry, att_invisible);
2195 newval = make_variable_value (entry, value, aflags); /* XXX */
2197 /* Invalidate any cached export string */
2198 INVALIDATE_EXPORTSTR (entry);
2200 #if defined (ARRAY_VARS)
2201 /* XXX -- this bears looking at again -- XXX */
2202 /* If an existing array variable x is being assigned to with x=b or
2203 `read x' or something of that nature, silently convert it to
2204 x[0]=b or `read x[0]'. */
2205 if (array_p (entry))
2207 array_insert (array_cell (entry), 0, newval);
2208 free (newval);
2210 else if (assoc_p (entry))
2212 assoc_insert (assoc_cell (entry), "0", newval);
2213 free (newval);
2215 else
2216 #endif
2218 FREE (value_cell (entry));
2219 var_setvalue (entry, newval);
2223 if (mark_modified_vars)
2224 VSETATTR (entry, att_exported);
2226 if (exported_p (entry))
2227 array_needs_making = 1;
2229 return (entry);
2232 /* Bind a variable NAME to VALUE. This conses up the name
2233 and value strings. If we have a temporary environment, we bind there
2234 first, then we bind into shell_variables. */
2236 SHELL_VAR *
2237 bind_variable (name, value, flags)
2238 const char *name;
2239 char *value;
2240 int flags;
2242 SHELL_VAR *v;
2243 VAR_CONTEXT *vc;
2245 if (shell_variables == 0)
2246 create_variable_tables ();
2248 /* If we have a temporary environment, look there first for the variable,
2249 and, if found, modify the value there before modifying it in the
2250 shell_variables table. This allows sourced scripts to modify values
2251 given to them in a temporary environment while modifying the variable
2252 value that the caller sees. */
2253 if (temporary_env)
2254 bind_tempenv_variable (name, value);
2256 /* XXX -- handle local variables here. */
2257 for (vc = shell_variables; vc; vc = vc->down)
2259 if (vc_isfuncenv (vc) || vc_isbltnenv (vc))
2261 v = hash_lookup (name, vc->table);
2262 if (v)
2263 return (bind_variable_internal (name, value, vc->table, 0, flags));
2266 return (bind_variable_internal (name, value, global_variables->table, 0, flags));
2269 /* Make VAR, a simple shell variable, have value VALUE. Once assigned a
2270 value, variables are no longer invisible. This is a duplicate of part
2271 of the internals of bind_variable. If the variable is exported, or
2272 all modified variables should be exported, mark the variable for export
2273 and note that the export environment needs to be recreated. */
2274 SHELL_VAR *
2275 bind_variable_value (var, value, aflags)
2276 SHELL_VAR *var;
2277 char *value;
2278 int aflags;
2280 char *t;
2282 VUNSETATTR (var, att_invisible);
2284 if (var->assign_func)
2286 /* If we're appending, we need the old value, so use
2287 make_variable_value */
2288 t = (aflags & ASS_APPEND) ? make_variable_value (var, value, aflags) : value;
2289 (*(var->assign_func)) (var, t, -1, 0);
2290 if (t != value && t)
2291 free (t);
2293 else
2295 t = make_variable_value (var, value, aflags);
2296 FREE (value_cell (var));
2297 var_setvalue (var, t);
2300 INVALIDATE_EXPORTSTR (var);
2302 if (mark_modified_vars)
2303 VSETATTR (var, att_exported);
2305 if (exported_p (var))
2306 array_needs_making = 1;
2308 return (var);
2311 /* Bind/create a shell variable with the name LHS to the RHS.
2312 This creates or modifies a variable such that it is an integer.
2314 This used to be in expr.c, but it is here so that all of the
2315 variable binding stuff is localized. Since we don't want any
2316 recursive evaluation from bind_variable() (possible without this code,
2317 since bind_variable() calls the evaluator for variables with the integer
2318 attribute set), we temporarily turn off the integer attribute for each
2319 variable we set here, then turn it back on after binding as necessary. */
2321 SHELL_VAR *
2322 bind_int_variable (lhs, rhs)
2323 char *lhs, *rhs;
2325 register SHELL_VAR *v;
2326 int isint, isarr;
2328 isint = isarr = 0;
2329 #if defined (ARRAY_VARS)
2330 if (valid_array_reference (lhs))
2332 isarr = 1;
2333 v = array_variable_part (lhs, (char **)0, (int *)0);
2335 else
2336 #endif
2337 v = find_variable (lhs);
2339 if (v)
2341 isint = integer_p (v);
2342 VUNSETATTR (v, att_integer);
2345 #if defined (ARRAY_VARS)
2346 if (isarr)
2347 v = assign_array_element (lhs, rhs, 0);
2348 else
2349 #endif
2350 v = bind_variable (lhs, rhs, 0);
2352 if (isint)
2353 VSETATTR (v, att_integer);
2355 return (v);
2358 SHELL_VAR *
2359 bind_var_to_int (var, val)
2360 char *var;
2361 intmax_t val;
2363 char ibuf[INT_STRLEN_BOUND (intmax_t) + 1], *p;
2365 p = fmtulong (val, 10, ibuf, sizeof (ibuf), 0);
2366 return (bind_int_variable (var, p));
2369 /* Do a function binding to a variable. You pass the name and
2370 the command to bind to. This conses the name and command. */
2371 SHELL_VAR *
2372 bind_function (name, value)
2373 const char *name;
2374 COMMAND *value;
2376 SHELL_VAR *entry;
2378 entry = find_function (name);
2379 if (entry == 0)
2381 BUCKET_CONTENTS *elt;
2383 elt = hash_insert (savestring (name), shell_functions, HASH_NOSRCH);
2384 entry = new_shell_variable (name);
2385 elt->data = (PTR_T)entry;
2387 else
2388 INVALIDATE_EXPORTSTR (entry);
2390 if (var_isset (entry))
2391 dispose_command (function_cell (entry));
2393 if (value)
2394 var_setfunc (entry, copy_command (value));
2395 else
2396 var_setfunc (entry, 0);
2398 VSETATTR (entry, att_function);
2400 if (mark_modified_vars)
2401 VSETATTR (entry, att_exported);
2403 VUNSETATTR (entry, att_invisible); /* Just to be sure */
2405 if (exported_p (entry))
2406 array_needs_making = 1;
2408 #if defined (PROGRAMMABLE_COMPLETION)
2409 set_itemlist_dirty (&it_functions);
2410 #endif
2412 return (entry);
2415 #if defined (DEBUGGER)
2416 /* Bind a function definition, which includes source file and line number
2417 information in addition to the command, into the FUNCTION_DEF hash table.*/
2418 void
2419 bind_function_def (name, value)
2420 const char *name;
2421 FUNCTION_DEF *value;
2423 FUNCTION_DEF *entry;
2424 BUCKET_CONTENTS *elt;
2425 COMMAND *cmd;
2427 entry = find_function_def (name);
2428 if (entry)
2430 dispose_function_def_contents (entry);
2431 entry = copy_function_def_contents (value, entry);
2433 else
2435 cmd = value->command;
2436 value->command = 0;
2437 entry = copy_function_def (value);
2438 value->command = cmd;
2440 elt = hash_insert (savestring (name), shell_function_defs, HASH_NOSRCH);
2441 elt->data = (PTR_T *)entry;
2444 #endif /* DEBUGGER */
2446 /* Add STRING, which is of the form foo=bar, to the temporary environment
2447 HASH_TABLE (temporary_env). The functions in execute_cmd.c are
2448 responsible for moving the main temporary env to one of the other
2449 temporary environments. The expansion code in subst.c calls this. */
2451 assign_in_env (word)
2452 WORD_DESC *word;
2454 int offset;
2455 char *name, *temp, *value;
2456 SHELL_VAR *var;
2457 const char *string;
2459 string = word->word;
2461 offset = assignment (string, 0);
2462 name = savestring (string);
2463 value = (char *)NULL;
2465 if (name[offset] == '=')
2467 name[offset] = 0;
2469 /* ignore the `+' when assigning temporary environment */
2470 if (name[offset - 1] == '+')
2471 name[offset - 1] = '\0';
2473 var = find_variable (name);
2474 if (var && (readonly_p (var) || noassign_p (var)))
2476 if (readonly_p (var))
2477 err_readonly (name);
2478 free (name);
2479 return (0);
2482 temp = name + offset + 1;
2483 value = expand_assignment_string_to_string (temp, 0);
2486 if (temporary_env == 0)
2487 temporary_env = hash_create (TEMPENV_HASH_BUCKETS);
2489 var = hash_lookup (name, temporary_env);
2490 if (var == 0)
2491 var = make_new_variable (name, temporary_env);
2492 else
2493 FREE (value_cell (var));
2495 if (value == 0)
2497 value = (char *)xmalloc (1); /* like do_assignment_internal */
2498 value[0] = '\0';
2501 var_setvalue (var, value);
2502 var->attributes |= (att_exported|att_tempvar);
2503 var->context = variable_context; /* XXX */
2505 INVALIDATE_EXPORTSTR (var);
2506 var->exportstr = mk_env_string (name, value);
2508 array_needs_making = 1;
2510 if (ifsname (name))
2511 setifs (var);
2513 if (echo_command_at_execute)
2514 /* The Korn shell prints the `+ ' in front of assignment statements,
2515 so we do too. */
2516 xtrace_print_assignment (name, value, 0, 1);
2518 free (name);
2519 return 1;
2522 /* **************************************************************** */
2523 /* */
2524 /* Copying variables */
2525 /* */
2526 /* **************************************************************** */
2528 #ifdef INCLUDE_UNUSED
2529 /* Copy VAR to a new data structure and return that structure. */
2530 SHELL_VAR *
2531 copy_variable (var)
2532 SHELL_VAR *var;
2534 SHELL_VAR *copy = (SHELL_VAR *)NULL;
2536 if (var)
2538 copy = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
2540 copy->attributes = var->attributes;
2541 copy->name = savestring (var->name);
2543 if (function_p (var))
2544 var_setfunc (copy, copy_command (function_cell (var)));
2545 #if defined (ARRAY_VARS)
2546 else if (array_p (var))
2547 var_setarray (copy, array_copy (array_cell (var)));
2548 else if (assoc_p (var))
2549 var_setassoc (copy, assoc_copy (assoc_cell (var)));
2550 #endif
2551 else if (value_cell (var))
2552 var_setvalue (copy, savestring (value_cell (var)));
2553 else
2554 var_setvalue (copy, (char *)NULL);
2556 copy->dynamic_value = var->dynamic_value;
2557 copy->assign_func = var->assign_func;
2559 copy->exportstr = COPY_EXPORTSTR (var);
2561 copy->context = var->context;
2563 return (copy);
2565 #endif
2567 /* **************************************************************** */
2568 /* */
2569 /* Deleting and unsetting variables */
2570 /* */
2571 /* **************************************************************** */
2573 /* Dispose of the information attached to VAR. */
2574 static void
2575 dispose_variable_value (var)
2576 SHELL_VAR *var;
2578 if (function_p (var))
2579 dispose_command (function_cell (var));
2580 #if defined (ARRAY_VARS)
2581 else if (array_p (var))
2582 array_dispose (array_cell (var));
2583 else if (assoc_p (var))
2584 assoc_dispose (assoc_cell (var));
2585 #endif
2586 else
2587 FREE (value_cell (var));
2590 void
2591 dispose_variable (var)
2592 SHELL_VAR *var;
2594 if (var == 0)
2595 return;
2597 if (nofree_p (var) == 0)
2598 dispose_variable_value (var);
2600 FREE_EXPORTSTR (var);
2602 free (var->name);
2604 if (exported_p (var))
2605 array_needs_making = 1;
2607 free (var);
2610 /* Unset the shell variable referenced by NAME. */
2612 unbind_variable (name)
2613 const char *name;
2615 return makunbound (name, shell_variables);
2618 /* Unset the shell function named NAME. */
2620 unbind_func (name)
2621 const char *name;
2623 BUCKET_CONTENTS *elt;
2624 SHELL_VAR *func;
2626 elt = hash_remove (name, shell_functions, 0);
2628 if (elt == 0)
2629 return -1;
2631 #if defined (PROGRAMMABLE_COMPLETION)
2632 set_itemlist_dirty (&it_functions);
2633 #endif
2635 func = (SHELL_VAR *)elt->data;
2636 if (func)
2638 if (exported_p (func))
2639 array_needs_making++;
2640 dispose_variable (func);
2643 free (elt->key);
2644 free (elt);
2646 return 0;
2649 #if defined (DEBUGGER)
2651 unbind_function_def (name)
2652 const char *name;
2654 BUCKET_CONTENTS *elt;
2655 FUNCTION_DEF *funcdef;
2657 elt = hash_remove (name, shell_function_defs, 0);
2659 if (elt == 0)
2660 return -1;
2662 funcdef = (FUNCTION_DEF *)elt->data;
2663 if (funcdef)
2664 dispose_function_def (funcdef);
2666 free (elt->key);
2667 free (elt);
2669 return 0;
2671 #endif /* DEBUGGER */
2673 /* Make the variable associated with NAME go away. HASH_LIST is the
2674 hash table from which this variable should be deleted (either
2675 shell_variables or shell_functions).
2676 Returns non-zero if the variable couldn't be found. */
2678 makunbound (name, vc)
2679 const char *name;
2680 VAR_CONTEXT *vc;
2682 BUCKET_CONTENTS *elt, *new_elt;
2683 SHELL_VAR *old_var;
2684 VAR_CONTEXT *v;
2685 char *t;
2687 for (elt = (BUCKET_CONTENTS *)NULL, v = vc; v; v = v->down)
2688 if (elt = hash_remove (name, v->table, 0))
2689 break;
2691 if (elt == 0)
2692 return (-1);
2694 old_var = (SHELL_VAR *)elt->data;
2696 if (old_var && exported_p (old_var))
2697 array_needs_making++;
2699 /* If we're unsetting a local variable and we're still executing inside
2700 the function, just mark the variable as invisible. The function
2701 eventually called by pop_var_context() will clean it up later. This
2702 must be done so that if the variable is subsequently assigned a new
2703 value inside the function, the `local' attribute is still present.
2704 We also need to add it back into the correct hash table. */
2705 if (old_var && local_p (old_var) && variable_context == old_var->context)
2707 if (nofree_p (old_var))
2708 var_setvalue (old_var, (char *)NULL);
2709 #if defined (ARRAY_VARS)
2710 else if (array_p (old_var))
2711 array_dispose (array_cell (old_var));
2712 else if (assoc_p (old_var))
2713 assoc_dispose (assoc_cell (old_var));
2714 #endif
2715 else
2716 FREE (value_cell (old_var));
2717 /* Reset the attributes. Preserve the export attribute if the variable
2718 came from a temporary environment. Make sure it stays local, and
2719 make it invisible. */
2720 old_var->attributes = (exported_p (old_var) && tempvar_p (old_var)) ? att_exported : 0;
2721 VSETATTR (old_var, att_local);
2722 VSETATTR (old_var, att_invisible);
2723 var_setvalue (old_var, (char *)NULL);
2724 INVALIDATE_EXPORTSTR (old_var);
2726 new_elt = hash_insert (savestring (old_var->name), v->table, 0);
2727 new_elt->data = (PTR_T)old_var;
2728 stupidly_hack_special_variables (old_var->name);
2730 free (elt->key);
2731 free (elt);
2732 return (0);
2735 /* Have to save a copy of name here, because it might refer to
2736 old_var->name. If so, stupidly_hack_special_variables will
2737 reference freed memory. */
2738 t = savestring (name);
2740 free (elt->key);
2741 free (elt);
2743 dispose_variable (old_var);
2744 stupidly_hack_special_variables (t);
2745 free (t);
2747 return (0);
2750 /* Get rid of all of the variables in the current context. */
2751 void
2752 kill_all_local_variables ()
2754 VAR_CONTEXT *vc;
2756 for (vc = shell_variables; vc; vc = vc->down)
2757 if (vc_isfuncenv (vc) && vc->scope == variable_context)
2758 break;
2759 if (vc == 0)
2760 return; /* XXX */
2762 if (vc->table && vc_haslocals (vc))
2764 delete_all_variables (vc->table);
2765 hash_dispose (vc->table);
2767 vc->table = (HASH_TABLE *)NULL;
2770 static void
2771 free_variable_hash_data (data)
2772 PTR_T data;
2774 SHELL_VAR *var;
2776 var = (SHELL_VAR *)data;
2777 dispose_variable (var);
2780 /* Delete the entire contents of the hash table. */
2781 void
2782 delete_all_variables (hashed_vars)
2783 HASH_TABLE *hashed_vars;
2785 hash_flush (hashed_vars, free_variable_hash_data);
2788 /* **************************************************************** */
2789 /* */
2790 /* Setting variable attributes */
2791 /* */
2792 /* **************************************************************** */
2794 #define FIND_OR_MAKE_VARIABLE(name, entry) \
2795 do \
2797 entry = find_variable (name); \
2798 if (!entry) \
2800 entry = bind_variable (name, "", 0); \
2801 if (!no_invisible_vars) entry->attributes |= att_invisible; \
2804 while (0)
2806 /* Make the variable associated with NAME be readonly.
2807 If NAME does not exist yet, create it. */
2808 void
2809 set_var_read_only (name)
2810 char *name;
2812 SHELL_VAR *entry;
2814 FIND_OR_MAKE_VARIABLE (name, entry);
2815 VSETATTR (entry, att_readonly);
2818 #ifdef INCLUDE_UNUSED
2819 /* Make the function associated with NAME be readonly.
2820 If NAME does not exist, we just punt, like auto_export code below. */
2821 void
2822 set_func_read_only (name)
2823 const char *name;
2825 SHELL_VAR *entry;
2827 entry = find_function (name);
2828 if (entry)
2829 VSETATTR (entry, att_readonly);
2832 /* Make the variable associated with NAME be auto-exported.
2833 If NAME does not exist yet, create it. */
2834 void
2835 set_var_auto_export (name)
2836 char *name;
2838 SHELL_VAR *entry;
2840 FIND_OR_MAKE_VARIABLE (name, entry);
2841 set_auto_export (entry);
2844 /* Make the function associated with NAME be auto-exported. */
2845 void
2846 set_func_auto_export (name)
2847 const char *name;
2849 SHELL_VAR *entry;
2851 entry = find_function (name);
2852 if (entry)
2853 set_auto_export (entry);
2855 #endif
2857 /* **************************************************************** */
2858 /* */
2859 /* Creating lists of variables */
2860 /* */
2861 /* **************************************************************** */
2863 static VARLIST *
2864 vlist_alloc (nentries)
2865 int nentries;
2867 VARLIST *vlist;
2869 vlist = (VARLIST *)xmalloc (sizeof (VARLIST));
2870 vlist->list = (SHELL_VAR **)xmalloc ((nentries + 1) * sizeof (SHELL_VAR *));
2871 vlist->list_size = nentries;
2872 vlist->list_len = 0;
2873 vlist->list[0] = (SHELL_VAR *)NULL;
2875 return vlist;
2878 static VARLIST *
2879 vlist_realloc (vlist, n)
2880 VARLIST *vlist;
2881 int n;
2883 if (vlist == 0)
2884 return (vlist = vlist_alloc (n));
2885 if (n > vlist->list_size)
2887 vlist->list_size = n;
2888 vlist->list = (SHELL_VAR **)xrealloc (vlist->list, (vlist->list_size + 1) * sizeof (SHELL_VAR *));
2890 return vlist;
2893 static void
2894 vlist_add (vlist, var, flags)
2895 VARLIST *vlist;
2896 SHELL_VAR *var;
2897 int flags;
2899 register int i;
2901 for (i = 0; i < vlist->list_len; i++)
2902 if (STREQ (var->name, vlist->list[i]->name))
2903 break;
2904 if (i < vlist->list_len)
2905 return;
2907 if (i >= vlist->list_size)
2908 vlist = vlist_realloc (vlist, vlist->list_size + 16);
2910 vlist->list[vlist->list_len++] = var;
2911 vlist->list[vlist->list_len] = (SHELL_VAR *)NULL;
2914 /* Map FUNCTION over the variables in VAR_HASH_TABLE. Return an array of the
2915 variables for which FUNCTION returns a non-zero value. A NULL value
2916 for FUNCTION means to use all variables. */
2917 SHELL_VAR **
2918 map_over (function, vc)
2919 sh_var_map_func_t *function;
2920 VAR_CONTEXT *vc;
2922 VAR_CONTEXT *v;
2923 VARLIST *vlist;
2924 SHELL_VAR **ret;
2925 int nentries;
2927 for (nentries = 0, v = vc; v; v = v->down)
2928 nentries += HASH_ENTRIES (v->table);
2930 if (nentries == 0)
2931 return (SHELL_VAR **)NULL;
2933 vlist = vlist_alloc (nentries);
2935 for (v = vc; v; v = v->down)
2936 flatten (v->table, function, vlist, 0);
2938 ret = vlist->list;
2939 free (vlist);
2940 return ret;
2943 SHELL_VAR **
2944 map_over_funcs (function)
2945 sh_var_map_func_t *function;
2947 VARLIST *vlist;
2948 SHELL_VAR **ret;
2950 if (shell_functions == 0 || HASH_ENTRIES (shell_functions) == 0)
2951 return ((SHELL_VAR **)NULL);
2953 vlist = vlist_alloc (HASH_ENTRIES (shell_functions));
2955 flatten (shell_functions, function, vlist, 0);
2957 ret = vlist->list;
2958 free (vlist);
2959 return ret;
2962 /* Flatten VAR_HASH_TABLE, applying FUNC to each member and adding those
2963 elements for which FUNC succeeds to VLIST->list. FLAGS is reserved
2964 for future use. Only unique names are added to VLIST. If FUNC is
2965 NULL, each variable in VAR_HASH_TABLE is added to VLIST. If VLIST is
2966 NULL, FUNC is applied to each SHELL_VAR in VAR_HASH_TABLE. If VLIST
2967 and FUNC are both NULL, nothing happens. */
2968 static void
2969 flatten (var_hash_table, func, vlist, flags)
2970 HASH_TABLE *var_hash_table;
2971 sh_var_map_func_t *func;
2972 VARLIST *vlist;
2973 int flags;
2975 register int i;
2976 register BUCKET_CONTENTS *tlist;
2977 int r;
2978 SHELL_VAR *var;
2980 if (var_hash_table == 0 || (HASH_ENTRIES (var_hash_table) == 0) || (vlist == 0 && func == 0))
2981 return;
2983 for (i = 0; i < var_hash_table->nbuckets; i++)
2985 for (tlist = hash_items (i, var_hash_table); tlist; tlist = tlist->next)
2987 var = (SHELL_VAR *)tlist->data;
2989 r = func ? (*func) (var) : 1;
2990 if (r && vlist)
2991 vlist_add (vlist, var, flags);
2996 void
2997 sort_variables (array)
2998 SHELL_VAR **array;
3000 qsort (array, strvec_len ((char **)array), sizeof (SHELL_VAR *), (QSFUNC *)qsort_var_comp);
3003 static int
3004 qsort_var_comp (var1, var2)
3005 SHELL_VAR **var1, **var2;
3007 int result;
3009 if ((result = (*var1)->name[0] - (*var2)->name[0]) == 0)
3010 result = strcmp ((*var1)->name, (*var2)->name);
3012 return (result);
3015 /* Apply FUNC to each variable in SHELL_VARIABLES, adding each one for
3016 which FUNC succeeds to an array of SHELL_VAR *s. Returns the array. */
3017 static SHELL_VAR **
3018 vapply (func)
3019 sh_var_map_func_t *func;
3021 SHELL_VAR **list;
3023 list = map_over (func, shell_variables);
3024 if (list /* && posixly_correct */)
3025 sort_variables (list);
3026 return (list);
3029 /* Apply FUNC to each variable in SHELL_FUNCTIONS, adding each one for
3030 which FUNC succeeds to an array of SHELL_VAR *s. Returns the array. */
3031 static SHELL_VAR **
3032 fapply (func)
3033 sh_var_map_func_t *func;
3035 SHELL_VAR **list;
3037 list = map_over_funcs (func);
3038 if (list /* && posixly_correct */)
3039 sort_variables (list);
3040 return (list);
3043 /* Create a NULL terminated array of all the shell variables. */
3044 SHELL_VAR **
3045 all_shell_variables ()
3047 return (vapply ((sh_var_map_func_t *)NULL));
3050 /* Create a NULL terminated array of all the shell functions. */
3051 SHELL_VAR **
3052 all_shell_functions ()
3054 return (fapply ((sh_var_map_func_t *)NULL));
3057 static int
3058 visible_var (var)
3059 SHELL_VAR *var;
3061 return (invisible_p (var) == 0);
3064 SHELL_VAR **
3065 all_visible_functions ()
3067 return (fapply (visible_var));
3070 SHELL_VAR **
3071 all_visible_variables ()
3073 return (vapply (visible_var));
3076 /* Return non-zero if the variable VAR is visible and exported. Array
3077 variables cannot be exported. */
3078 static int
3079 visible_and_exported (var)
3080 SHELL_VAR *var;
3082 return (invisible_p (var) == 0 && exported_p (var));
3085 /* Return non-zero if VAR is a local variable in the current context and
3086 is exported. */
3087 static int
3088 local_and_exported (var)
3089 SHELL_VAR *var;
3091 return (invisible_p (var) == 0 && local_p (var) && var->context == variable_context && exported_p (var));
3094 SHELL_VAR **
3095 all_exported_variables ()
3097 return (vapply (visible_and_exported));
3100 SHELL_VAR **
3101 local_exported_variables ()
3103 return (vapply (local_and_exported));
3106 static int
3107 variable_in_context (var)
3108 SHELL_VAR *var;
3110 return (invisible_p (var) == 0 && local_p (var) && var->context == variable_context);
3113 SHELL_VAR **
3114 all_local_variables ()
3116 VARLIST *vlist;
3117 SHELL_VAR **ret;
3118 VAR_CONTEXT *vc;
3120 vc = shell_variables;
3121 for (vc = shell_variables; vc; vc = vc->down)
3122 if (vc_isfuncenv (vc) && vc->scope == variable_context)
3123 break;
3125 if (vc == 0)
3127 internal_error (_("all_local_variables: no function context at current scope"));
3128 return (SHELL_VAR **)NULL;
3130 if (vc->table == 0 || HASH_ENTRIES (vc->table) == 0 || vc_haslocals (vc) == 0)
3131 return (SHELL_VAR **)NULL;
3133 vlist = vlist_alloc (HASH_ENTRIES (vc->table));
3135 flatten (vc->table, variable_in_context, vlist, 0);
3137 ret = vlist->list;
3138 free (vlist);
3139 if (ret)
3140 sort_variables (ret);
3141 return ret;
3144 #if defined (ARRAY_VARS)
3145 /* Return non-zero if the variable VAR is visible and an array. */
3146 static int
3147 visible_array_vars (var)
3148 SHELL_VAR *var;
3150 return (invisible_p (var) == 0 && array_p (var));
3153 SHELL_VAR **
3154 all_array_variables ()
3156 return (vapply (visible_array_vars));
3158 #endif /* ARRAY_VARS */
3160 char **
3161 all_variables_matching_prefix (prefix)
3162 const char *prefix;
3164 SHELL_VAR **varlist;
3165 char **rlist;
3166 int vind, rind, plen;
3168 plen = STRLEN (prefix);
3169 varlist = all_visible_variables ();
3170 for (vind = 0; varlist && varlist[vind]; vind++)
3172 if (varlist == 0 || vind == 0)
3173 return ((char **)NULL);
3174 rlist = strvec_create (vind + 1);
3175 for (vind = rind = 0; varlist[vind]; vind++)
3177 if (plen == 0 || STREQN (prefix, varlist[vind]->name, plen))
3178 rlist[rind++] = savestring (varlist[vind]->name);
3180 rlist[rind] = (char *)0;
3181 free (varlist);
3183 return rlist;
3186 /* **************************************************************** */
3187 /* */
3188 /* Managing temporary variable scopes */
3189 /* */
3190 /* **************************************************************** */
3192 /* Make variable NAME have VALUE in the temporary environment. */
3193 static SHELL_VAR *
3194 bind_tempenv_variable (name, value)
3195 const char *name;
3196 char *value;
3198 SHELL_VAR *var;
3200 var = temporary_env ? hash_lookup (name, temporary_env) : (SHELL_VAR *)NULL;
3202 if (var)
3204 FREE (value_cell (var));
3205 var_setvalue (var, savestring (value));
3206 INVALIDATE_EXPORTSTR (var);
3209 return (var);
3212 /* Find a variable in the temporary environment that is named NAME.
3213 Return the SHELL_VAR *, or NULL if not found. */
3214 SHELL_VAR *
3215 find_tempenv_variable (name)
3216 const char *name;
3218 return (temporary_env ? hash_lookup (name, temporary_env) : (SHELL_VAR *)NULL);
3221 /* Push the variable described by (SHELL_VAR *)DATA down to the next
3222 variable context from the temporary environment. */
3223 static void
3224 push_temp_var (data)
3225 PTR_T data;
3227 SHELL_VAR *var, *v;
3228 HASH_TABLE *binding_table;
3230 var = (SHELL_VAR *)data;
3232 binding_table = shell_variables->table;
3233 if (binding_table == 0)
3235 if (shell_variables == global_variables)
3236 /* shouldn't happen */
3237 binding_table = shell_variables->table = global_variables->table = hash_create (0);
3238 else
3239 binding_table = shell_variables->table = hash_create (TEMPENV_HASH_BUCKETS);
3242 v = bind_variable_internal (var->name, value_cell (var), binding_table, 0, 0);
3244 /* XXX - should we set the context here? It shouldn't matter because of how
3245 assign_in_env works, but might want to check. */
3246 if (binding_table == global_variables->table) /* XXX */
3247 var->attributes &= ~(att_tempvar|att_propagate);
3248 else
3250 var->attributes |= att_propagate;
3251 if (binding_table == shell_variables->table)
3252 shell_variables->flags |= VC_HASTMPVAR;
3254 v->attributes |= var->attributes;
3256 dispose_variable (var);
3259 static void
3260 propagate_temp_var (data)
3261 PTR_T data;
3263 SHELL_VAR *var;
3265 var = (SHELL_VAR *)data;
3266 if (tempvar_p (var) && (var->attributes & att_propagate))
3267 push_temp_var (data);
3268 else
3269 dispose_variable (var);
3272 /* Free the storage used in the hash table for temporary
3273 environment variables. PUSHF is a function to be called
3274 to free each hash table entry. It takes care of pushing variables
3275 to previous scopes if appropriate. */
3276 static void
3277 dispose_temporary_env (pushf)
3278 sh_free_func_t *pushf;
3280 hash_flush (temporary_env, pushf);
3281 hash_dispose (temporary_env);
3282 temporary_env = (HASH_TABLE *)NULL;
3284 array_needs_making = 1;
3286 sv_ifs ("IFS"); /* XXX here for now */
3289 void
3290 dispose_used_env_vars ()
3292 if (temporary_env)
3294 dispose_temporary_env (propagate_temp_var);
3295 maybe_make_export_env ();
3299 /* Take all of the shell variables in the temporary environment HASH_TABLE
3300 and make shell variables from them at the current variable context. */
3301 void
3302 merge_temporary_env ()
3304 if (temporary_env)
3305 dispose_temporary_env (push_temp_var);
3308 /* **************************************************************** */
3309 /* */
3310 /* Creating and manipulating the environment */
3311 /* */
3312 /* **************************************************************** */
3314 static inline char *
3315 mk_env_string (name, value)
3316 const char *name, *value;
3318 int name_len, value_len;
3319 char *p;
3321 name_len = strlen (name);
3322 value_len = STRLEN (value);
3323 p = (char *)xmalloc (2 + name_len + value_len);
3324 strcpy (p, name);
3325 p[name_len] = '=';
3326 if (value && *value)
3327 strcpy (p + name_len + 1, value);
3328 else
3329 p[name_len + 1] = '\0';
3330 return (p);
3333 #ifdef DEBUG
3334 /* Debugging */
3335 static int
3336 valid_exportstr (v)
3337 SHELL_VAR *v;
3339 char *s;
3341 s = v->exportstr;
3342 if (legal_variable_starter ((unsigned char)*s) == 0)
3344 internal_error (_("invalid character %d in exportstr for %s"), *s, v->name);
3345 return (0);
3347 for (s = v->exportstr + 1; s && *s; s++)
3349 if (*s == '=')
3350 break;
3351 if (legal_variable_char ((unsigned char)*s) == 0)
3353 internal_error (_("invalid character %d in exportstr for %s"), *s, v->name);
3354 return (0);
3357 if (*s != '=')
3359 internal_error (_("no `=' in exportstr for %s"), v->name);
3360 return (0);
3362 return (1);
3364 #endif
3366 static char **
3367 make_env_array_from_var_list (vars)
3368 SHELL_VAR **vars;
3370 register int i, list_index;
3371 register SHELL_VAR *var;
3372 char **list, *value;
3374 list = strvec_create ((1 + strvec_len ((char **)vars)));
3376 #define USE_EXPORTSTR (value == var->exportstr)
3378 for (i = 0, list_index = 0; var = vars[i]; i++)
3380 #if defined (__CYGWIN__)
3381 /* We don't use the exportstr stuff on Cygwin at all. */
3382 INVALIDATE_EXPORTSTR (var);
3383 #endif
3384 if (var->exportstr)
3385 value = var->exportstr;
3386 else if (function_p (var))
3387 value = named_function_string ((char *)NULL, function_cell (var), 0);
3388 #if defined (ARRAY_VARS)
3389 else if (array_p (var))
3390 # if 0
3391 value = array_to_assignment_string (array_cell (var));
3392 # else
3393 continue; /* XXX array vars cannot yet be exported */
3394 # endif
3395 else if (assoc_p (var))
3396 # if 0
3397 value = assoc_to_assignment_string (assoc_cell (var));
3398 # else
3399 continue; /* XXX associative array vars cannot yet be exported */
3400 # endif
3401 #endif
3402 else
3403 value = value_cell (var);
3405 if (value)
3407 /* Gee, I'd like to get away with not using savestring() if we're
3408 using the cached exportstr... */
3409 list[list_index] = USE_EXPORTSTR ? savestring (value)
3410 : mk_env_string (var->name, value);
3412 if (USE_EXPORTSTR == 0)
3413 SAVE_EXPORTSTR (var, list[list_index]);
3415 list_index++;
3416 #undef USE_EXPORTSTR
3418 #if 0 /* not yet */
3419 #if defined (ARRAY_VARS)
3420 if (array_p (var) || assoc_p (var))
3421 free (value);
3422 #endif
3423 #endif
3427 list[list_index] = (char *)NULL;
3428 return (list);
3431 /* Make an array of assignment statements from the hash table
3432 HASHED_VARS which contains SHELL_VARs. Only visible, exported
3433 variables are eligible. */
3434 static char **
3435 make_var_export_array (vcxt)
3436 VAR_CONTEXT *vcxt;
3438 char **list;
3439 SHELL_VAR **vars;
3441 vars = map_over (visible_and_exported, vcxt);
3443 if (vars == 0)
3444 return (char **)NULL;
3446 list = make_env_array_from_var_list (vars);
3448 free (vars);
3449 return (list);
3452 static char **
3453 make_func_export_array ()
3455 char **list;
3456 SHELL_VAR **vars;
3458 vars = map_over_funcs (visible_and_exported);
3459 if (vars == 0)
3460 return (char **)NULL;
3462 list = make_env_array_from_var_list (vars);
3464 free (vars);
3465 return (list);
3468 /* Add ENVSTR to the end of the exported environment, EXPORT_ENV. */
3469 #define add_to_export_env(envstr,do_alloc) \
3470 do \
3472 if (export_env_index >= (export_env_size - 1)) \
3474 export_env_size += 16; \
3475 export_env = strvec_resize (export_env, export_env_size); \
3476 environ = export_env; \
3478 export_env[export_env_index++] = (do_alloc) ? savestring (envstr) : envstr; \
3479 export_env[export_env_index] = (char *)NULL; \
3480 } while (0)
3482 /* Add ASSIGN to EXPORT_ENV, or supercede a previous assignment in the
3483 array with the same left-hand side. Return the new EXPORT_ENV. */
3484 char **
3485 add_or_supercede_exported_var (assign, do_alloc)
3486 char *assign;
3487 int do_alloc;
3489 register int i;
3490 int equal_offset;
3492 equal_offset = assignment (assign, 0);
3493 if (equal_offset == 0)
3494 return (export_env);
3496 /* If this is a function, then only supersede the function definition.
3497 We do this by including the `=() {' in the comparison, like
3498 initialize_shell_variables does. */
3499 if (assign[equal_offset + 1] == '(' &&
3500 strncmp (assign + equal_offset + 2, ") {", 3) == 0) /* } */
3501 equal_offset += 4;
3503 for (i = 0; i < export_env_index; i++)
3505 if (STREQN (assign, export_env[i], equal_offset + 1))
3507 free (export_env[i]);
3508 export_env[i] = do_alloc ? savestring (assign) : assign;
3509 return (export_env);
3512 add_to_export_env (assign, do_alloc);
3513 return (export_env);
3516 static void
3517 add_temp_array_to_env (temp_array, do_alloc, do_supercede)
3518 char **temp_array;
3519 int do_alloc, do_supercede;
3521 register int i;
3523 if (temp_array == 0)
3524 return;
3526 for (i = 0; temp_array[i]; i++)
3528 if (do_supercede)
3529 export_env = add_or_supercede_exported_var (temp_array[i], do_alloc);
3530 else
3531 add_to_export_env (temp_array[i], do_alloc);
3534 free (temp_array);
3537 /* Make the environment array for the command about to be executed, if the
3538 array needs making. Otherwise, do nothing. If a shell action could
3539 change the array that commands receive for their environment, then the
3540 code should `array_needs_making++'.
3542 The order to add to the array is:
3543 temporary_env
3544 list of var contexts whose head is shell_variables
3545 shell_functions
3547 This is the shell variable lookup order. We add only new variable
3548 names at each step, which allows local variables and variables in
3549 the temporary environments to shadow variables in the global (or
3550 any previous) scope.
3553 static int
3554 n_shell_variables ()
3556 VAR_CONTEXT *vc;
3557 int n;
3559 for (n = 0, vc = shell_variables; vc; vc = vc->down)
3560 n += HASH_ENTRIES (vc->table);
3561 return n;
3564 void
3565 maybe_make_export_env ()
3567 register char **temp_array;
3568 int new_size;
3569 VAR_CONTEXT *tcxt;
3571 if (array_needs_making)
3573 if (export_env)
3574 strvec_flush (export_env);
3576 /* Make a guess based on how many shell variables and functions we
3577 have. Since there will always be array variables, and array
3578 variables are not (yet) exported, this will always be big enough
3579 for the exported variables and functions. */
3580 new_size = n_shell_variables () + HASH_ENTRIES (shell_functions) + 1 +
3581 HASH_ENTRIES (temporary_env);
3582 if (new_size > export_env_size)
3584 export_env_size = new_size;
3585 export_env = strvec_resize (export_env, export_env_size);
3586 environ = export_env;
3588 export_env[export_env_index = 0] = (char *)NULL;
3590 /* Make a dummy variable context from the temporary_env, stick it on
3591 the front of shell_variables, call make_var_export_array on the
3592 whole thing to flatten it, and convert the list of SHELL_VAR *s
3593 to the form needed by the environment. */
3594 if (temporary_env)
3596 tcxt = new_var_context ((char *)NULL, 0);
3597 tcxt->table = temporary_env;
3598 tcxt->down = shell_variables;
3600 else
3601 tcxt = shell_variables;
3603 temp_array = make_var_export_array (tcxt);
3604 if (temp_array)
3605 add_temp_array_to_env (temp_array, 0, 0);
3607 if (tcxt != shell_variables)
3608 free (tcxt);
3610 #if defined (RESTRICTED_SHELL)
3611 /* Restricted shells may not export shell functions. */
3612 temp_array = restricted ? (char **)0 : make_func_export_array ();
3613 #else
3614 temp_array = make_func_export_array ();
3615 #endif
3616 if (temp_array)
3617 add_temp_array_to_env (temp_array, 0, 0);
3619 array_needs_making = 0;
3623 /* This is an efficiency hack. PWD and OLDPWD are auto-exported, so
3624 we will need to remake the exported environment every time we
3625 change directories. `_' is always put into the environment for
3626 every external command, so without special treatment it will always
3627 cause the environment to be remade.
3629 If there is no other reason to make the exported environment, we can
3630 just update the variables in place and mark the exported environment
3631 as no longer needing a remake. */
3632 void
3633 update_export_env_inplace (env_prefix, preflen, value)
3634 char *env_prefix;
3635 int preflen;
3636 char *value;
3638 char *evar;
3640 evar = (char *)xmalloc (STRLEN (value) + preflen + 1);
3641 strcpy (evar, env_prefix);
3642 if (value)
3643 strcpy (evar + preflen, value);
3644 export_env = add_or_supercede_exported_var (evar, 0);
3647 /* We always put _ in the environment as the name of this command. */
3648 void
3649 put_command_name_into_env (command_name)
3650 char *command_name;
3652 update_export_env_inplace ("_=", 2, command_name);
3655 #if 0 /* UNUSED -- it caused too many problems */
3656 void
3657 put_gnu_argv_flags_into_env (pid, flags_string)
3658 intmax_t pid;
3659 char *flags_string;
3661 char *dummy, *pbuf;
3662 int l, fl;
3664 pbuf = itos (pid);
3665 l = strlen (pbuf);
3667 fl = strlen (flags_string);
3669 dummy = (char *)xmalloc (l + fl + 30);
3670 dummy[0] = '_';
3671 strcpy (dummy + 1, pbuf);
3672 strcpy (dummy + 1 + l, "_GNU_nonoption_argv_flags_");
3673 dummy[l + 27] = '=';
3674 strcpy (dummy + l + 28, flags_string);
3676 free (pbuf);
3678 export_env = add_or_supercede_exported_var (dummy, 0);
3680 #endif
3682 /* **************************************************************** */
3683 /* */
3684 /* Managing variable contexts */
3685 /* */
3686 /* **************************************************************** */
3688 /* Allocate and return a new variable context with NAME and FLAGS.
3689 NAME can be NULL. */
3691 VAR_CONTEXT *
3692 new_var_context (name, flags)
3693 char *name;
3694 int flags;
3696 VAR_CONTEXT *vc;
3698 vc = (VAR_CONTEXT *)xmalloc (sizeof (VAR_CONTEXT));
3699 vc->name = name ? savestring (name) : (char *)NULL;
3700 vc->scope = variable_context;
3701 vc->flags = flags;
3703 vc->up = vc->down = (VAR_CONTEXT *)NULL;
3704 vc->table = (HASH_TABLE *)NULL;
3706 return vc;
3709 /* Free a variable context and its data, including the hash table. Dispose
3710 all of the variables. */
3711 void
3712 dispose_var_context (vc)
3713 VAR_CONTEXT *vc;
3715 FREE (vc->name);
3717 if (vc->table)
3719 delete_all_variables (vc->table);
3720 hash_dispose (vc->table);
3723 free (vc);
3726 /* Set VAR's scope level to the current variable context. */
3727 static int
3728 set_context (var)
3729 SHELL_VAR *var;
3731 return (var->context = variable_context);
3734 /* Make a new variable context with NAME and FLAGS and a HASH_TABLE of
3735 temporary variables, and push it onto shell_variables. This is
3736 for shell functions. */
3737 VAR_CONTEXT *
3738 push_var_context (name, flags, tempvars)
3739 char *name;
3740 int flags;
3741 HASH_TABLE *tempvars;
3743 VAR_CONTEXT *vc;
3745 vc = new_var_context (name, flags);
3746 vc->table = tempvars;
3747 if (tempvars)
3749 /* Have to do this because the temp environment was created before
3750 variable_context was incremented. */
3751 flatten (tempvars, set_context, (VARLIST *)NULL, 0);
3752 vc->flags |= VC_HASTMPVAR;
3754 vc->down = shell_variables;
3755 shell_variables->up = vc;
3757 return (shell_variables = vc);
3760 static void
3761 push_func_var (data)
3762 PTR_T data;
3764 SHELL_VAR *var, *v;
3766 var = (SHELL_VAR *)data;
3768 if (tempvar_p (var) && (posixly_correct || (var->attributes & att_propagate)))
3770 /* XXX - should we set v->context here? */
3771 v = bind_variable_internal (var->name, value_cell (var), shell_variables->table, 0, 0);
3772 if (shell_variables == global_variables)
3773 var->attributes &= ~(att_tempvar|att_propagate);
3774 else
3775 shell_variables->flags |= VC_HASTMPVAR;
3776 v->attributes |= var->attributes;
3778 else
3779 stupidly_hack_special_variables (var->name); /* XXX */
3781 dispose_variable (var);
3784 /* Pop the top context off of VCXT and dispose of it, returning the rest of
3785 the stack. */
3786 void
3787 pop_var_context ()
3789 VAR_CONTEXT *ret, *vcxt;
3791 vcxt = shell_variables;
3792 if (vc_isfuncenv (vcxt) == 0)
3794 internal_error (_("pop_var_context: head of shell_variables not a function context"));
3795 return;
3798 if (ret = vcxt->down)
3800 ret->up = (VAR_CONTEXT *)NULL;
3801 shell_variables = ret;
3802 if (vcxt->table)
3803 hash_flush (vcxt->table, push_func_var);
3804 dispose_var_context (vcxt);
3806 else
3807 internal_error (_("pop_var_context: no global_variables context"));
3810 /* Delete the HASH_TABLEs for all variable contexts beginning at VCXT, and
3811 all of the VAR_CONTEXTs except GLOBAL_VARIABLES. */
3812 void
3813 delete_all_contexts (vcxt)
3814 VAR_CONTEXT *vcxt;
3816 VAR_CONTEXT *v, *t;
3818 for (v = vcxt; v != global_variables; v = t)
3820 t = v->down;
3821 dispose_var_context (v);
3824 delete_all_variables (global_variables->table);
3825 shell_variables = global_variables;
3828 /* **************************************************************** */
3829 /* */
3830 /* Pushing and Popping temporary variable scopes */
3831 /* */
3832 /* **************************************************************** */
3834 VAR_CONTEXT *
3835 push_scope (flags, tmpvars)
3836 int flags;
3837 HASH_TABLE *tmpvars;
3839 return (push_var_context ((char *)NULL, flags, tmpvars));
3842 static void
3843 push_exported_var (data)
3844 PTR_T data;
3846 SHELL_VAR *var, *v;
3848 var = (SHELL_VAR *)data;
3850 /* If a temp var had its export attribute set, or it's marked to be
3851 propagated, bind it in the previous scope before disposing it. */
3852 /* XXX - This isn't exactly right, because all tempenv variables have the
3853 export attribute set. */
3854 #if 0
3855 if (exported_p (var) || (var->attributes & att_propagate))
3856 #else
3857 if (tempvar_p (var) && exported_p (var) && (var->attributes & att_propagate))
3858 #endif
3860 var->attributes &= ~att_tempvar; /* XXX */
3861 v = bind_variable_internal (var->name, value_cell (var), shell_variables->table, 0, 0);
3862 if (shell_variables == global_variables)
3863 var->attributes &= ~att_propagate;
3864 v->attributes |= var->attributes;
3866 else
3867 stupidly_hack_special_variables (var->name); /* XXX */
3869 dispose_variable (var);
3872 void
3873 pop_scope (is_special)
3874 int is_special;
3876 VAR_CONTEXT *vcxt, *ret;
3878 vcxt = shell_variables;
3879 if (vc_istempscope (vcxt) == 0)
3881 internal_error (_("pop_scope: head of shell_variables not a temporary environment scope"));
3882 return;
3885 ret = vcxt->down;
3886 if (ret)
3887 ret->up = (VAR_CONTEXT *)NULL;
3889 shell_variables = ret;
3891 /* Now we can take care of merging variables in VCXT into set of scopes
3892 whose head is RET (shell_variables). */
3893 FREE (vcxt->name);
3894 if (vcxt->table)
3896 if (is_special)
3897 hash_flush (vcxt->table, push_func_var);
3898 else
3899 hash_flush (vcxt->table, push_exported_var);
3900 hash_dispose (vcxt->table);
3902 free (vcxt);
3904 sv_ifs ("IFS"); /* XXX here for now */
3907 /* **************************************************************** */
3908 /* */
3909 /* Pushing and Popping function contexts */
3910 /* */
3911 /* **************************************************************** */
3913 static WORD_LIST **dollar_arg_stack = (WORD_LIST **)NULL;
3914 static int dollar_arg_stack_slots;
3915 static int dollar_arg_stack_index;
3917 /* XXX - we might want to consider pushing and popping the `getopts' state
3918 when we modify the positional parameters. */
3919 void
3920 push_context (name, is_subshell, tempvars)
3921 char *name; /* function name */
3922 int is_subshell;
3923 HASH_TABLE *tempvars;
3925 if (is_subshell == 0)
3926 push_dollar_vars ();
3927 variable_context++;
3928 push_var_context (name, VC_FUNCENV, tempvars);
3931 /* Only called when subshell == 0, so we don't need to check, and can
3932 unconditionally pop the dollar vars off the stack. */
3933 void
3934 pop_context ()
3936 pop_dollar_vars ();
3937 variable_context--;
3938 pop_var_context ();
3940 sv_ifs ("IFS"); /* XXX here for now */
3943 /* Save the existing positional parameters on a stack. */
3944 void
3945 push_dollar_vars ()
3947 if (dollar_arg_stack_index + 2 > dollar_arg_stack_slots)
3949 dollar_arg_stack = (WORD_LIST **)
3950 xrealloc (dollar_arg_stack, (dollar_arg_stack_slots += 10)
3951 * sizeof (WORD_LIST **));
3953 dollar_arg_stack[dollar_arg_stack_index++] = list_rest_of_args ();
3954 dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
3957 /* Restore the positional parameters from our stack. */
3958 void
3959 pop_dollar_vars ()
3961 if (!dollar_arg_stack || dollar_arg_stack_index == 0)
3962 return;
3964 remember_args (dollar_arg_stack[--dollar_arg_stack_index], 1);
3965 dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
3966 dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
3967 set_dollar_vars_unchanged ();
3970 void
3971 dispose_saved_dollar_vars ()
3973 if (!dollar_arg_stack || dollar_arg_stack_index == 0)
3974 return;
3976 dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
3977 dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
3980 /* Manipulate the special BASH_ARGV and BASH_ARGC variables. */
3982 void
3983 push_args (list)
3984 WORD_LIST *list;
3986 #if defined (ARRAY_VARS) && defined (DEBUGGER)
3987 SHELL_VAR *bash_argv_v, *bash_argc_v;
3988 ARRAY *bash_argv_a, *bash_argc_a;
3989 WORD_LIST *l;
3990 arrayind_t i;
3991 char *t;
3993 GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a);
3994 GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
3996 for (l = list, i = 0; l; l = l->next, i++)
3997 array_push (bash_argv_a, l->word->word);
3999 t = itos (i);
4000 array_push (bash_argc_a, t);
4001 free (t);
4002 #endif /* ARRAY_VARS && DEBUGGER */
4005 /* Remove arguments from BASH_ARGV array. Pop top element off BASH_ARGC
4006 array and use that value as the count of elements to remove from
4007 BASH_ARGV. */
4008 void
4009 pop_args ()
4011 #if defined (ARRAY_VARS) && defined (DEBUGGER)
4012 SHELL_VAR *bash_argv_v, *bash_argc_v;
4013 ARRAY *bash_argv_a, *bash_argc_a;
4014 ARRAY_ELEMENT *ce;
4015 intmax_t i;
4017 GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a);
4018 GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
4020 ce = array_shift (bash_argc_a, 1, 0);
4021 if (ce == 0 || legal_number (element_value (ce), &i) == 0)
4022 i = 0;
4024 for ( ; i > 0; i--)
4025 array_pop (bash_argv_a);
4026 array_dispose_element (ce);
4027 #endif /* ARRAY_VARS && DEBUGGER */
4030 /*************************************************
4032 * Functions to manage special variables *
4034 *************************************************/
4036 /* Extern declarations for variables this code has to manage. */
4037 extern int eof_encountered, eof_encountered_limit, ignoreeof;
4039 #if defined (READLINE)
4040 extern int hostname_list_initialized;
4041 #endif
4043 /* An alist of name.function for each special variable. Most of the
4044 functions don't do much, and in fact, this would be faster with a
4045 switch statement, but by the end of this file, I am sick of switch
4046 statements. */
4048 #define SET_INT_VAR(name, intvar) intvar = find_variable (name) != 0
4050 /* This table will be sorted with qsort() the first time it's accessed. */
4051 struct name_and_function {
4052 char *name;
4053 sh_sv_func_t *function;
4056 static struct name_and_function special_vars[] = {
4057 #if defined (READLINE)
4058 # if defined (STRICT_POSIX)
4059 { "COLUMNS", sv_winsize },
4060 # endif
4061 { "COMP_WORDBREAKS", sv_comp_wordbreaks },
4062 #endif
4064 { "GLOBIGNORE", sv_globignore },
4066 #if defined (HISTORY)
4067 { "HISTCONTROL", sv_history_control },
4068 { "HISTFILESIZE", sv_histsize },
4069 { "HISTIGNORE", sv_histignore },
4070 { "HISTSIZE", sv_histsize },
4071 { "HISTTIMEFORMAT", sv_histtimefmt },
4072 #endif
4074 #if defined (__CYGWIN__)
4075 { "HOME", sv_home },
4076 #endif
4078 #if defined (READLINE)
4079 { "HOSTFILE", sv_hostfile },
4080 #endif
4082 { "IFS", sv_ifs },
4083 { "IGNOREEOF", sv_ignoreeof },
4085 { "LANG", sv_locale },
4086 { "LC_ALL", sv_locale },
4087 { "LC_COLLATE", sv_locale },
4088 { "LC_CTYPE", sv_locale },
4089 { "LC_MESSAGES", sv_locale },
4090 { "LC_NUMERIC", sv_locale },
4091 { "LC_TIME", sv_locale },
4093 #if defined (READLINE) && defined (STRICT_POSIX)
4094 { "LINES", sv_winsize },
4095 #endif
4097 { "MAIL", sv_mail },
4098 { "MAILCHECK", sv_mail },
4099 { "MAILPATH", sv_mail },
4101 { "OPTERR", sv_opterr },
4102 { "OPTIND", sv_optind },
4104 { "PATH", sv_path },
4105 { "POSIXLY_CORRECT", sv_strict_posix },
4107 #if defined (READLINE)
4108 { "TERM", sv_terminal },
4109 { "TERMCAP", sv_terminal },
4110 { "TERMINFO", sv_terminal },
4111 #endif /* READLINE */
4113 { "TEXTDOMAIN", sv_locale },
4114 { "TEXTDOMAINDIR", sv_locale },
4116 #if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE)
4117 { "TZ", sv_tz },
4118 #endif
4120 #if defined (HISTORY) && defined (BANG_HISTORY)
4121 { "histchars", sv_histchars },
4122 #endif /* HISTORY && BANG_HISTORY */
4124 { "ignoreeof", sv_ignoreeof },
4126 { (char *)0, (sh_sv_func_t *)0 }
4129 #define N_SPECIAL_VARS (sizeof (special_vars) / sizeof (special_vars[0]) - 1)
4131 static int
4132 sv_compare (sv1, sv2)
4133 struct name_and_function *sv1, *sv2;
4135 int r;
4137 if ((r = sv1->name[0] - sv2->name[0]) == 0)
4138 r = strcmp (sv1->name, sv2->name);
4139 return r;
4142 static inline int
4143 find_special_var (name)
4144 const char *name;
4146 register int i, r;
4148 for (i = 0; special_vars[i].name; i++)
4150 r = special_vars[i].name[0] - name[0];
4151 if (r == 0)
4152 r = strcmp (special_vars[i].name, name);
4153 if (r == 0)
4154 return i;
4155 else if (r > 0)
4156 /* Can't match any of rest of elements in sorted list. Take this out
4157 if it causes problems in certain environments. */
4158 break;
4160 return -1;
4163 /* The variable in NAME has just had its state changed. Check to see if it
4164 is one of the special ones where something special happens. */
4165 void
4166 stupidly_hack_special_variables (name)
4167 char *name;
4169 static int sv_sorted = 0;
4170 int i;
4172 if (sv_sorted == 0) /* shouldn't need, but it's fairly cheap. */
4174 qsort (special_vars, N_SPECIAL_VARS, sizeof (special_vars[0]),
4175 (QSFUNC *)sv_compare);
4176 sv_sorted = 1;
4179 i = find_special_var (name);
4180 if (i != -1)
4181 (*(special_vars[i].function)) (name);
4184 /* Special variables that need hooks to be run when they are unset as part
4185 of shell reinitialization should have their sv_ functions run here. */
4186 void
4187 reinit_special_variables ()
4189 #if defined (READLINE)
4190 sv_comp_wordbreaks ("COMP_WORDBREAKS");
4191 #endif
4192 sv_globignore ("GLOBIGNORE");
4193 sv_opterr ("OPTERR");
4196 void
4197 sv_ifs (name)
4198 char *name;
4200 SHELL_VAR *v;
4202 v = find_variable ("IFS");
4203 setifs (v);
4206 /* What to do just after the PATH variable has changed. */
4207 void
4208 sv_path (name)
4209 char *name;
4211 /* hash -r */
4212 phash_flush ();
4215 /* What to do just after one of the MAILxxxx variables has changed. NAME
4216 is the name of the variable. This is called with NAME set to one of
4217 MAIL, MAILCHECK, or MAILPATH. */
4218 void
4219 sv_mail (name)
4220 char *name;
4222 /* If the time interval for checking the files has changed, then
4223 reset the mail timer. Otherwise, one of the pathname vars
4224 to the users mailbox has changed, so rebuild the array of
4225 filenames. */
4226 if (name[4] == 'C') /* if (strcmp (name, "MAILCHECK") == 0) */
4227 reset_mail_timer ();
4228 else
4230 free_mail_files ();
4231 remember_mail_dates ();
4235 /* What to do when GLOBIGNORE changes. */
4236 void
4237 sv_globignore (name)
4238 char *name;
4240 if (privileged_mode == 0)
4241 setup_glob_ignore (name);
4244 #if defined (READLINE)
4245 void
4246 sv_comp_wordbreaks (name)
4247 char *name;
4249 SHELL_VAR *sv;
4251 sv = find_variable (name);
4252 if (sv == 0)
4253 reset_completer_word_break_chars ();
4256 /* What to do just after one of the TERMxxx variables has changed.
4257 If we are an interactive shell, then try to reset the terminal
4258 information in readline. */
4259 void
4260 sv_terminal (name)
4261 char *name;
4263 if (interactive_shell && no_line_editing == 0)
4264 rl_reset_terminal (get_string_value ("TERM"));
4267 void
4268 sv_hostfile (name)
4269 char *name;
4271 SHELL_VAR *v;
4273 v = find_variable (name);
4274 if (v == 0)
4275 clear_hostname_list ();
4276 else
4277 hostname_list_initialized = 0;
4280 #if defined (STRICT_POSIX)
4281 /* In strict posix mode, we allow assignments to LINES and COLUMNS (and values
4282 found in the initial environment) to override the terminal size reported by
4283 the kernel. */
4284 void
4285 sv_winsize (name)
4286 char *name;
4288 SHELL_VAR *v;
4289 intmax_t xd;
4290 int d;
4292 if (posixly_correct == 0 || interactive_shell == 0 || no_line_editing)
4293 return;
4295 v = find_variable (name);
4296 if (v == 0 || var_isnull (v))
4297 rl_reset_screen_size ();
4298 else
4300 if (legal_number (value_cell (v), &xd) == 0)
4301 return;
4302 winsize_assignment = winsize_assigned = 1;
4303 d = xd; /* truncate */
4304 if (name[0] == 'L') /* LINES */
4305 rl_set_screen_size (d, -1);
4306 else /* COLUMNS */
4307 rl_set_screen_size (-1, d);
4308 winsize_assignment = 0;
4311 #endif /* STRICT_POSIX */
4312 #endif /* READLINE */
4314 /* Update the value of HOME in the export environment so tilde expansion will
4315 work on cygwin. */
4316 #if defined (__CYGWIN__)
4317 sv_home (name)
4318 char *name;
4320 array_needs_making = 1;
4321 maybe_make_export_env ();
4323 #endif
4325 #if defined (HISTORY)
4326 /* What to do after the HISTSIZE or HISTFILESIZE variables change.
4327 If there is a value for this HISTSIZE (and it is numeric), then stifle
4328 the history. Otherwise, if there is NO value for this variable,
4329 unstifle the history. If name is HISTFILESIZE, and its value is
4330 numeric, truncate the history file to hold no more than that many
4331 lines. */
4332 void
4333 sv_histsize (name)
4334 char *name;
4336 char *temp;
4337 intmax_t num;
4338 int hmax;
4340 temp = get_string_value (name);
4342 if (temp && *temp)
4344 if (legal_number (temp, &num))
4346 hmax = num;
4347 if (name[4] == 'S')
4349 stifle_history (hmax);
4350 hmax = where_history ();
4351 if (history_lines_this_session > hmax)
4352 history_lines_this_session = hmax;
4354 else
4356 history_truncate_file (get_string_value ("HISTFILE"), hmax);
4357 if (hmax <= history_lines_in_file)
4358 history_lines_in_file = hmax;
4362 else if (name[4] == 'S')
4363 unstifle_history ();
4366 /* What to do after the HISTIGNORE variable changes. */
4367 void
4368 sv_histignore (name)
4369 char *name;
4371 setup_history_ignore (name);
4374 /* What to do after the HISTCONTROL variable changes. */
4375 void
4376 sv_history_control (name)
4377 char *name;
4379 char *temp;
4380 char *val;
4381 int tptr;
4383 history_control = 0;
4384 temp = get_string_value (name);
4386 if (temp == 0 || *temp == 0)
4387 return;
4389 tptr = 0;
4390 while (val = extract_colon_unit (temp, &tptr))
4392 if (STREQ (val, "ignorespace"))
4393 history_control |= HC_IGNSPACE;
4394 else if (STREQ (val, "ignoredups"))
4395 history_control |= HC_IGNDUPS;
4396 else if (STREQ (val, "ignoreboth"))
4397 history_control |= HC_IGNBOTH;
4398 else if (STREQ (val, "erasedups"))
4399 history_control |= HC_ERASEDUPS;
4401 free (val);
4405 #if defined (BANG_HISTORY)
4406 /* Setting/unsetting of the history expansion character. */
4407 void
4408 sv_histchars (name)
4409 char *name;
4411 char *temp;
4413 temp = get_string_value (name);
4414 if (temp)
4416 history_expansion_char = *temp;
4417 if (temp[0] && temp[1])
4419 history_subst_char = temp[1];
4420 if (temp[2])
4421 history_comment_char = temp[2];
4424 else
4426 history_expansion_char = '!';
4427 history_subst_char = '^';
4428 history_comment_char = '#';
4431 #endif /* BANG_HISTORY */
4433 void
4434 sv_histtimefmt (name)
4435 char *name;
4437 SHELL_VAR *v;
4439 v = find_variable (name);
4440 history_write_timestamps = (v != 0);
4442 #endif /* HISTORY */
4444 #if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE)
4445 void
4446 sv_tz (name)
4447 char *name;
4449 tzset ();
4451 #endif
4453 /* If the variable exists, then the value of it can be the number
4454 of times we actually ignore the EOF. The default is small,
4455 (smaller than csh, anyway). */
4456 void
4457 sv_ignoreeof (name)
4458 char *name;
4460 SHELL_VAR *tmp_var;
4461 char *temp;
4463 eof_encountered = 0;
4465 tmp_var = find_variable (name);
4466 ignoreeof = tmp_var != 0;
4467 temp = tmp_var ? value_cell (tmp_var) : (char *)NULL;
4468 if (temp)
4469 eof_encountered_limit = (*temp && all_digits (temp)) ? atoi (temp) : 10;
4470 set_shellopts (); /* make sure `ignoreeof' is/is not in $SHELLOPTS */
4473 void
4474 sv_optind (name)
4475 char *name;
4477 char *tt;
4478 int s;
4480 tt = get_string_value ("OPTIND");
4481 if (tt && *tt)
4483 s = atoi (tt);
4485 /* According to POSIX, setting OPTIND=1 resets the internal state
4486 of getopt (). */
4487 if (s < 0 || s == 1)
4488 s = 0;
4490 else
4491 s = 0;
4492 getopts_reset (s);
4495 void
4496 sv_opterr (name)
4497 char *name;
4499 char *tt;
4501 tt = get_string_value ("OPTERR");
4502 sh_opterr = (tt && *tt) ? atoi (tt) : 1;
4505 void
4506 sv_strict_posix (name)
4507 char *name;
4509 SET_INT_VAR (name, posixly_correct);
4510 posix_initialize (posixly_correct);
4511 #if defined (READLINE)
4512 if (interactive_shell)
4513 posix_readline_initialize (posixly_correct);
4514 #endif /* READLINE */
4515 set_shellopts (); /* make sure `posix' is/is not in $SHELLOPTS */
4518 void
4519 sv_locale (name)
4520 char *name;
4522 char *v;
4524 v = get_string_value (name);
4525 if (name[0] == 'L' && name[1] == 'A') /* LANG */
4526 set_lang (name, v);
4527 else
4528 set_locale_var (name, v); /* LC_*, TEXTDOMAIN* */
4531 #if defined (ARRAY_VARS)
4532 void
4533 set_pipestatus_array (ps, nproc)
4534 int *ps;
4535 int nproc;
4537 SHELL_VAR *v;
4538 ARRAY *a;
4539 ARRAY_ELEMENT *ae;
4540 register int i;
4541 char *t, tbuf[INT_STRLEN_BOUND(int) + 1];
4543 v = find_variable ("PIPESTATUS");
4544 if (v == 0)
4545 v = make_new_array_variable ("PIPESTATUS");
4546 if (array_p (v) == 0)
4547 return; /* Do nothing if not an array variable. */
4548 a = array_cell (v);
4550 if (a == 0 || array_num_elements (a) == 0)
4552 for (i = 0; i < nproc; i++) /* was ps[i] != -1, not i < nproc */
4554 t = inttostr (ps[i], tbuf, sizeof (tbuf));
4555 array_insert (a, i, t);
4557 return;
4560 /* Fast case */
4561 if (array_num_elements (a) == nproc && nproc == 1)
4563 ae = element_forw (a->head);
4564 free (element_value (ae));
4565 ae->value = itos (ps[0]);
4567 else if (array_num_elements (a) <= nproc)
4569 /* modify in array_num_elements members in place, then add */
4570 ae = a->head;
4571 for (i = 0; i < array_num_elements (a); i++)
4573 ae = element_forw (ae);
4574 free (element_value (ae));
4575 ae->value = itos (ps[i]);
4577 /* add any more */
4578 for ( ; i < nproc; i++)
4580 t = inttostr (ps[i], tbuf, sizeof (tbuf));
4581 array_insert (a, i, t);
4584 else
4586 /* deleting elements. it's faster to rebuild the array. */
4587 array_flush (a);
4588 for (i = 0; ps[i] != -1; i++)
4590 t = inttostr (ps[i], tbuf, sizeof (tbuf));
4591 array_insert (a, i, t);
4595 #endif
4597 void
4598 set_pipestatus_from_exit (s)
4599 int s;
4601 #if defined (ARRAY_VARS)
4602 static int v[2] = { 0, -1 };
4604 v[0] = s;
4605 set_pipestatus_array (v, 1);
4606 #endif