init version.
[bush.git] / src / variables.c
blob0d40b2b2d2bb7c7d8b237cd04aff5bd0238dca5d
1 /* variables.c -- Functions for hacking shell variables. */
3 /* Copyright (C) 1987-2020 Free Software Foundation, Inc.
5 This file is part of GNU Bush, the Bourne Again SHell.
7 Bush 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 Bush 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 Bush. If not, see <http://www.gnu.org/licenses/>.
21 #include "config.h"
23 #include "bushtypes.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 "bushansi.h"
45 #include "bushintl.h"
46 #include "filecntl.h"
48 #define NEED_XTRACE_SET_DECL
50 #include "shell.h"
51 #include "parser.h"
52 #include "flags.h"
53 #include "execute_cmd.h"
54 #include "findcmd.h"
55 #include "mailcheck.h"
56 #include "input.h"
57 #include "hashcmd.h"
58 #include "pathexp.h"
59 #include "alias.h"
60 #include "jobs.h"
62 #include "version.h"
64 #include "builtins/getopt.h"
65 #include "builtins/common.h"
66 #include "builtins/builtext.h"
68 #if defined (READLINE)
69 # include "bushline.h"
70 # include <readline/readline.h>
71 #else
72 # include <tilde/tilde.h>
73 #endif
75 #if defined (HISTORY)
76 # include "bushhist.h"
77 # include <readline/history.h>
78 #endif /* HISTORY */
80 #if defined (PROGRAMMABLE_COMPLETION)
81 # include "pcomplete.h"
82 #endif
84 #define VARIABLES_HASH_BUCKETS 1024 /* must be power of two */
85 #define FUNCTIONS_HASH_BUCKETS 512
86 #define TEMPENV_HASH_BUCKETS 4 /* must be power of two */
88 #define BUSHFUNC_PREFIX "BUSH_FUNC_"
89 #define BUSHFUNC_PREFLEN 10 /* == strlen(BUSHFUNC_PREFIX */
90 #define BUSHFUNC_SUFFIX "%%"
91 #define BUSHFUNC_SUFFLEN 2 /* == strlen(BUSHFUNC_SUFFIX) */
93 /* flags for find_variable_internal */
95 #define FV_FORCETEMPENV 0x01
96 #define FV_SKIPINVISIBLE 0x02
97 #define FV_NODYNAMIC 0x04
99 extern char **environ;
101 /* Variables used here and defined in other files. */
102 extern time_t shell_start_time;
103 extern struct timeval shellstart;
105 /* The list of shell variables that the user has created at the global
106 scope, or that came from the environment. */
107 VAR_CONTEXT *global_variables = (VAR_CONTEXT *)NULL;
109 /* The current list of shell variables, including function scopes */
110 VAR_CONTEXT *shell_variables = (VAR_CONTEXT *)NULL;
112 /* The list of shell functions that the user has created, or that came from
113 the environment. */
114 HASH_TABLE *shell_functions = (HASH_TABLE *)NULL;
116 HASH_TABLE *invalid_env = (HASH_TABLE *)NULL;
118 #if defined (DEBUGGER)
119 /* The table of shell function definitions that the user defined or that
120 came from the environment. */
121 HASH_TABLE *shell_function_defs = (HASH_TABLE *)NULL;
122 #endif
124 /* The current variable context. This is really a count of how deep into
125 executing functions we are. */
126 int variable_context = 0;
128 /* If non-zero, local variables inherit values and attributes from a variable
129 with the same name at a previous scope. */
130 int localvar_inherit = 0;
132 /* If non-zero, calling `unset' on local variables in previous scopes marks
133 them as invisible so lookups find them unset. This is the same behavior
134 as local variables in the current local scope. */
135 int localvar_unset = 0;
137 /* The set of shell assignments which are made only in the environment
138 for a single command. */
139 HASH_TABLE *temporary_env = (HASH_TABLE *)NULL;
141 /* Set to non-zero if an assignment error occurs while putting variables
142 into the temporary environment. */
143 int tempenv_assign_error;
145 /* Some funky variables which are known about specially. Here is where
146 "$*", "$1", and all the cruft is kept. */
147 char *dollar_vars[10];
148 WORD_LIST *rest_of_args = (WORD_LIST *)NULL;
149 int posparam_count = 0;
151 /* The value of $$. */
152 pid_t dollar_dollar_pid;
154 /* Non-zero means that we have to remake EXPORT_ENV. */
155 int array_needs_making = 1;
157 /* The number of times BUSH has been executed. This is set
158 by initialize_variables (). */
159 int shell_level = 0;
161 /* An array which is passed to commands as their environment. It is
162 manufactured from the union of the initial environment and the
163 shell variables that are marked for export. */
164 char **export_env = (char **)NULL;
165 static int export_env_index;
166 static int export_env_size;
168 #if defined (READLINE)
169 static int winsize_assignment; /* currently assigning to LINES or COLUMNS */
170 #endif
172 SHELL_VAR nameref_invalid_value;
173 static SHELL_VAR nameref_maxloop_value;
175 static HASH_TABLE *last_table_searched; /* hash_lookup sets this */
176 static VAR_CONTEXT *last_context_searched;
178 /* Some forward declarations. */
179 static void create_variable_tables PARAMS((void));
181 static void set_machine_vars PARAMS((void));
182 static void set_home_var PARAMS((void));
183 static void set_shell_var PARAMS((void));
184 static char *get_bush_name PARAMS((void));
185 static void initialize_shell_level PARAMS((void));
186 static void uidset PARAMS((void));
187 #if defined (ARRAY_VARS)
188 static void make_vers_array PARAMS((void));
189 #endif
191 static SHELL_VAR *null_assign PARAMS((SHELL_VAR *, char *, arrayind_t, char *));
192 #if defined (ARRAY_VARS)
193 static SHELL_VAR *null_array_assign PARAMS((SHELL_VAR *, char *, arrayind_t, char *));
194 #endif
195 static SHELL_VAR *get_self PARAMS((SHELL_VAR *));
197 #if defined (ARRAY_VARS)
198 static SHELL_VAR *init_dynamic_array_var PARAMS((char *, sh_var_value_func_t *, sh_var_assign_func_t *, int));
199 static SHELL_VAR *init_dynamic_assoc_var PARAMS((char *, sh_var_value_func_t *, sh_var_assign_func_t *, int));
200 #endif
202 static SHELL_VAR *assign_seconds PARAMS((SHELL_VAR *, char *, arrayind_t, char *));
203 static SHELL_VAR *get_seconds PARAMS((SHELL_VAR *));
204 static SHELL_VAR *init_seconds_var PARAMS((void));
206 static SHELL_VAR *assign_random PARAMS((SHELL_VAR *, char *, arrayind_t, char *));
207 static SHELL_VAR *get_random PARAMS((SHELL_VAR *));
209 static SHELL_VAR *get_urandom PARAMS((SHELL_VAR *));
211 static SHELL_VAR *assign_lineno PARAMS((SHELL_VAR *, char *, arrayind_t, char *));
212 static SHELL_VAR *get_lineno PARAMS((SHELL_VAR *));
214 static SHELL_VAR *assign_subshell PARAMS((SHELL_VAR *, char *, arrayind_t, char *));
215 static SHELL_VAR *get_subshell PARAMS((SHELL_VAR *));
217 static SHELL_VAR *get_epochseconds PARAMS((SHELL_VAR *));
218 static SHELL_VAR *get_epochrealtime PARAMS((SHELL_VAR *));
220 static SHELL_VAR *get_bushpid PARAMS((SHELL_VAR *));
222 static SHELL_VAR *get_bush_argv0 PARAMS((SHELL_VAR *));
223 static SHELL_VAR *assign_bush_argv0 PARAMS((SHELL_VAR *, char *, arrayind_t, char *));
224 static void set_argv0 PARAMS((void));
226 #if defined (HISTORY)
227 static SHELL_VAR *get_histcmd PARAMS((SHELL_VAR *));
228 #endif
230 #if defined (READLINE)
231 static SHELL_VAR *get_comp_wordbreaks PARAMS((SHELL_VAR *));
232 static SHELL_VAR *assign_comp_wordbreaks PARAMS((SHELL_VAR *, char *, arrayind_t, char *));
233 #endif
235 #if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
236 static SHELL_VAR *assign_dirstack PARAMS((SHELL_VAR *, char *, arrayind_t, char *));
237 static SHELL_VAR *get_dirstack PARAMS((SHELL_VAR *));
238 #endif
240 #if defined (ARRAY_VARS)
241 static SHELL_VAR *get_groupset PARAMS((SHELL_VAR *));
242 # if defined (DEBUGGER)
243 static SHELL_VAR *get_bushargcv PARAMS((SHELL_VAR *));
244 # endif
245 static SHELL_VAR *build_hashcmd PARAMS((SHELL_VAR *));
246 static SHELL_VAR *get_hashcmd PARAMS((SHELL_VAR *));
247 static SHELL_VAR *assign_hashcmd PARAMS((SHELL_VAR *, char *, arrayind_t, char *));
248 # if defined (ALIAS)
249 static SHELL_VAR *build_aliasvar PARAMS((SHELL_VAR *));
250 static SHELL_VAR *get_aliasvar PARAMS((SHELL_VAR *));
251 static SHELL_VAR *assign_aliasvar PARAMS((SHELL_VAR *, char *, arrayind_t, char *));
252 # endif
253 #endif
255 static SHELL_VAR *get_funcname PARAMS((SHELL_VAR *));
256 static SHELL_VAR *init_funcname_var PARAMS((void));
258 static void initialize_dynamic_variables PARAMS((void));
260 static SHELL_VAR *bind_invalid_envvar PARAMS((const char *, char *, int));
262 static int var_sametype PARAMS((SHELL_VAR *, SHELL_VAR *));
264 static SHELL_VAR *hash_lookup PARAMS((const char *, HASH_TABLE *));
265 static SHELL_VAR *new_shell_variable PARAMS((const char *));
266 static SHELL_VAR *make_new_variable PARAMS((const char *, HASH_TABLE *));
267 static SHELL_VAR *bind_variable_internal PARAMS((const char *, char *, HASH_TABLE *, int, int));
269 static void dispose_variable_value PARAMS((SHELL_VAR *));
270 static void free_variable_hash_data PARAMS((PTR_T));
272 static VARLIST *vlist_alloc PARAMS((int));
273 static VARLIST *vlist_realloc PARAMS((VARLIST *, int));
274 static void vlist_add PARAMS((VARLIST *, SHELL_VAR *, int));
276 static void flatten PARAMS((HASH_TABLE *, sh_var_map_func_t *, VARLIST *, int));
278 static int qsort_var_comp PARAMS((SHELL_VAR **, SHELL_VAR **));
280 static SHELL_VAR **vapply PARAMS((sh_var_map_func_t *));
281 static SHELL_VAR **fapply PARAMS((sh_var_map_func_t *));
283 static int visible_var PARAMS((SHELL_VAR *));
284 static int visible_and_exported PARAMS((SHELL_VAR *));
285 static int export_environment_candidate PARAMS((SHELL_VAR *));
286 static int local_and_exported PARAMS((SHELL_VAR *));
287 static int visible_variable_in_context PARAMS((SHELL_VAR *));
288 static int variable_in_context PARAMS((SHELL_VAR *));
289 #if defined (ARRAY_VARS)
290 static int visible_array_vars PARAMS((SHELL_VAR *));
291 #endif
293 static SHELL_VAR *find_variable_internal PARAMS((const char *, int));
295 static SHELL_VAR *find_nameref_at_context PARAMS((SHELL_VAR *, VAR_CONTEXT *));
296 static SHELL_VAR *find_variable_nameref_context PARAMS((SHELL_VAR *, VAR_CONTEXT *, VAR_CONTEXT **));
297 static SHELL_VAR *find_variable_last_nameref_context PARAMS((SHELL_VAR *, VAR_CONTEXT *, VAR_CONTEXT **));
299 static SHELL_VAR *bind_tempenv_variable PARAMS((const char *, char *));
300 static void push_posix_temp_var PARAMS((PTR_T));
301 static void push_temp_var PARAMS((PTR_T));
302 static void propagate_temp_var PARAMS((PTR_T));
303 static void dispose_temporary_env PARAMS((sh_free_func_t *));
305 static inline char *mk_env_string PARAMS((const char *, const char *, int));
306 static char **make_env_array_from_var_list PARAMS((SHELL_VAR **));
307 static char **make_var_export_array PARAMS((VAR_CONTEXT *));
308 static char **make_func_export_array PARAMS((void));
309 static void add_temp_array_to_env PARAMS((char **, int, int));
311 static int n_shell_variables PARAMS((void));
312 static int set_context PARAMS((SHELL_VAR *));
314 static void push_func_var PARAMS((PTR_T));
315 static void push_builtin_var PARAMS((PTR_T));
316 static void push_exported_var PARAMS((PTR_T));
318 /* This needs to be looked at again. */
319 static inline void push_posix_tempvar_internal PARAMS((SHELL_VAR *, int));
321 static inline int find_special_var PARAMS((const char *));
323 static void
324 create_variable_tables ()
326 if (shell_variables == 0)
328 shell_variables = global_variables = new_var_context ((char *)NULL, 0);
329 shell_variables->scope = 0;
330 shell_variables->table = hash_create (VARIABLES_HASH_BUCKETS);
333 if (shell_functions == 0)
334 shell_functions = hash_create (FUNCTIONS_HASH_BUCKETS);
336 #if defined (DEBUGGER)
337 if (shell_function_defs == 0)
338 shell_function_defs = hash_create (FUNCTIONS_HASH_BUCKETS);
339 #endif
342 /* Initialize the shell variables from the current environment.
343 If PRIVMODE is nonzero, don't import functions from ENV or
344 parse $SHELLOPTS. */
345 void
346 initialize_shell_variables (env, privmode)
347 char **env;
348 int privmode;
350 char *name, *string, *temp_string;
351 int c, char_index, string_index, string_length, ro;
352 SHELL_VAR *temp_var;
354 create_variable_tables ();
356 for (string_index = 0; env && (string = env[string_index++]); )
358 char_index = 0;
359 name = string;
360 while ((c = *string++) && c != '=')
362 if (string[-1] == '=')
363 char_index = string - name - 1;
365 /* If there are weird things in the environment, like `=xxx' or a
366 string without an `=', just skip them. */
367 if (char_index == 0)
368 continue;
370 /* ASSERT(name[char_index] == '=') */
371 name[char_index] = '\0';
372 /* Now, name = env variable name, string = env variable value, and
373 char_index == strlen (name) */
375 temp_var = (SHELL_VAR *)NULL;
377 #if defined (FUNCTION_IMPORT)
378 /* If exported function, define it now. Don't import functions from
379 the environment in privileged mode. */
380 if (privmode == 0 && read_but_dont_execute == 0 &&
381 STREQN (BUSHFUNC_PREFIX, name, BUSHFUNC_PREFLEN) &&
382 STREQ (BUSHFUNC_SUFFIX, name + char_index - BUSHFUNC_SUFFLEN) &&
383 STREQN ("() {", string, 4))
385 size_t namelen;
386 char *tname; /* desired imported function name */
388 namelen = char_index - BUSHFUNC_PREFLEN - BUSHFUNC_SUFFLEN;
390 tname = name + BUSHFUNC_PREFLEN; /* start of func name */
391 tname[namelen] = '\0'; /* now tname == func name */
393 string_length = strlen (string);
394 temp_string = (char *)xmalloc (namelen + string_length + 2);
396 memcpy (temp_string, tname, namelen);
397 temp_string[namelen] = ' ';
398 memcpy (temp_string + namelen + 1, string, string_length + 1);
400 /* Don't import function names that are invalid identifiers from the
401 environment in posix mode, though we still allow them to be defined as
402 shell variables. */
403 if (absolute_program (tname) == 0 && (posixly_correct == 0 || legal_identifier (tname)))
404 parse_and_execute (temp_string, tname, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD);
405 else
406 free (temp_string); /* parse_and_execute does this */
408 if (temp_var = find_function (tname))
410 VSETATTR (temp_var, (att_exported|att_imported));
411 array_needs_making = 1;
413 else
415 if (temp_var = bind_invalid_envvar (name, string, 0))
417 VSETATTR (temp_var, (att_exported | att_imported | att_invisible));
418 array_needs_making = 1;
420 last_command_exit_value = EXECUTION_FAILURE;
421 report_error (_("error importing function definition for `%s'"), tname);
424 /* Restore original suffix */
425 tname[namelen] = BUSHFUNC_SUFFIX[0];
427 else
428 #endif /* FUNCTION_IMPORT */
429 #if defined (ARRAY_VARS)
430 # if ARRAY_EXPORT
431 /* Array variables may not yet be exported. */
432 if (*string == '(' && string[1] == '[' && string[strlen (string) - 1] == ')')
434 string_length = 1;
435 temp_string = extract_array_assignment_list (string, &string_length);
436 temp_var = assign_array_from_string (name, temp_string, 0);
437 FREE (temp_string);
438 VSETATTR (temp_var, (att_exported | att_imported));
439 array_needs_making = 1;
441 else
442 # endif /* ARRAY_EXPORT */
443 #endif
445 ro = 0;
446 /* If we processed a command-line option that caused SHELLOPTS to be
447 set, it may already be set (and read-only) by the time we process
448 the shell's environment. */
449 if (/* posixly_correct &&*/ STREQ (name, "SHELLOPTS"))
451 temp_var = find_variable ("SHELLOPTS");
452 ro = temp_var && readonly_p (temp_var);
453 if (temp_var)
454 VUNSETATTR (temp_var, att_readonly);
456 if (legal_identifier (name))
458 temp_var = bind_variable (name, string, 0);
459 if (temp_var)
461 VSETATTR (temp_var, (att_exported | att_imported));
462 if (ro)
463 VSETATTR (temp_var, att_readonly);
466 else
468 temp_var = bind_invalid_envvar (name, string, 0);
469 if (temp_var)
470 VSETATTR (temp_var, (att_exported | att_imported | att_invisible));
472 if (temp_var)
473 array_needs_making = 1;
476 name[char_index] = '=';
477 /* temp_var can be NULL if it was an exported function with a syntax
478 error (a different bug, but it still shouldn't dump core). */
479 if (temp_var && function_p (temp_var) == 0) /* XXX not yet */
481 CACHE_IMPORTSTR (temp_var, name);
485 set_pwd ();
487 /* Set up initial value of $_ */
488 temp_var = set_if_not ("_", dollar_vars[0]);
490 /* Remember this pid. */
491 dollar_dollar_pid = getpid ();
493 /* Now make our own defaults in case the vars that we think are
494 important are missing. */
495 temp_var = set_if_not ("PATH", DEFAULT_PATH_VALUE);
496 temp_var = set_if_not ("TERM", "dumb");
498 #if defined (__QNX__)
499 /* set node id -- don't import it from the environment */
501 char node_name[22];
502 # if defined (__QNXNTO__)
503 netmgr_ndtostr(ND2S_LOCAL_STR, ND_LOCAL_NODE, node_name, sizeof(node_name));
504 # else
505 qnx_nidtostr (getnid (), node_name, sizeof (node_name));
506 # endif
507 temp_var = bind_variable ("NODE", node_name, 0);
508 if (temp_var)
509 set_auto_export (temp_var);
511 #endif
513 /* set up the prompts. */
514 if (interactive_shell)
516 #if defined (PROMPT_STRING_DECODE)
517 set_if_not ("PS1", primary_prompt);
518 #else
519 if (current_user.uid == -1)
520 get_current_user_info ();
521 set_if_not ("PS1", current_user.euid == 0 ? "# " : primary_prompt);
522 #endif
523 set_if_not ("PS2", secondary_prompt);
526 if (current_user.euid == 0)
527 bind_variable ("PS4", "+ ", 0);
528 else
529 set_if_not ("PS4", "+ ");
531 /* Don't allow IFS to be imported from the environment. */
532 temp_var = bind_variable ("IFS", " \t\n", 0);
533 setifs (temp_var);
535 /* Magic machine types. Pretty convenient. */
536 set_machine_vars ();
538 /* Default MAILCHECK for interactive shells. Defer the creation of a
539 default MAILPATH until the startup files are read, because MAIL
540 names a mail file if MAILPATH is not set, and we should provide a
541 default only if neither is set. */
542 if (interactive_shell)
544 temp_var = set_if_not ("MAILCHECK", posixly_correct ? "600" : "60");
545 VSETATTR (temp_var, att_integer);
548 /* Do some things with shell level. */
549 initialize_shell_level ();
551 set_ppid ();
553 set_argv0 ();
555 /* Initialize the `getopts' stuff. */
556 temp_var = bind_variable ("OPTIND", "1", 0);
557 VSETATTR (temp_var, att_integer);
558 getopts_reset (0);
559 bind_variable ("OPTERR", "1", 0);
560 sh_opterr = 1;
562 if (login_shell == 1 && posixly_correct == 0)
563 set_home_var ();
565 /* Get the full pathname to THIS shell, and set the BUSH variable
566 to it. */
567 name = get_bush_name ();
568 temp_var = bind_variable ("BUSH", name, 0);
569 free (name);
571 /* Make the exported environment variable SHELL be the user's login
572 shell. Note that the `tset' command looks at this variable
573 to determine what style of commands to output; if it ends in "csh",
574 then C-shell commands are output, else Bourne shell commands. */
575 set_shell_var ();
577 /* Make a variable called BUSH_VERSION which contains the version info. */
578 bind_variable ("BUSH_VERSION", shell_version_string (), 0);
579 #if defined (ARRAY_VARS)
580 make_vers_array ();
581 #endif
583 if (command_execution_string)
584 bind_variable ("BUSH_EXECUTION_STRING", command_execution_string, 0);
586 /* Find out if we're supposed to be in Posix.2 mode via an
587 environment variable. */
588 temp_var = find_variable ("POSIXLY_CORRECT");
589 if (!temp_var)
590 temp_var = find_variable ("POSIX_PEDANTIC");
591 if (temp_var && imported_p (temp_var))
592 sv_strict_posix (temp_var->name);
594 #if defined (HISTORY)
595 /* Set history variables to defaults, and then do whatever we would
596 do if the variable had just been set. Do this only in the case
597 that we are remembering commands on the history list. */
598 if (remember_on_history)
600 name = bush_tilde_expand (posixly_correct ? "~/.sh_history" : "~/.bush_history", 0);
602 set_if_not ("HISTFILE", name);
603 free (name);
605 #endif /* HISTORY */
607 /* Seed the random number generators. */
608 seedrand ();
609 seedrand32 ();
611 /* Handle some "special" variables that we may have inherited from a
612 parent shell. */
613 if (interactive_shell)
615 temp_var = find_variable ("IGNOREEOF");
616 if (!temp_var)
617 temp_var = find_variable ("ignoreeof");
618 if (temp_var && imported_p (temp_var))
619 sv_ignoreeof (temp_var->name);
622 #if defined (HISTORY)
623 if (interactive_shell && remember_on_history)
625 sv_history_control ("HISTCONTROL");
626 sv_histignore ("HISTIGNORE");
627 sv_histtimefmt ("HISTTIMEFORMAT");
629 #endif /* HISTORY */
631 #if defined (READLINE) && defined (STRICT_POSIX)
632 /* POSIXLY_CORRECT will be 1 here if the shell was compiled
633 -DSTRICT_POSIX or if POSIXLY_CORRECT was supplied in the shell's
634 environment */
635 if (interactive_shell && posixly_correct && no_line_editing == 0)
636 rl_prefer_env_winsize = 1;
637 #endif /* READLINE && STRICT_POSIX */
640 * 24 October 2001
642 * I'm tired of the arguing and bug reports. Bush now leaves SSH_CLIENT
643 * and SSH2_CLIENT alone. I'm going to rely on the shell_level check in
644 * isnetconn() to avoid running the startup files more often than wanted.
645 * That will, of course, only work if the user's login shell is bush, so
646 * I've made that behavior conditional on SSH_SOURCE_BUSHRC being defined
647 * in config-top.h.
649 #if 0
650 temp_var = find_variable ("SSH_CLIENT");
651 if (temp_var && imported_p (temp_var))
653 VUNSETATTR (temp_var, att_exported);
654 array_needs_making = 1;
656 temp_var = find_variable ("SSH2_CLIENT");
657 if (temp_var && imported_p (temp_var))
659 VUNSETATTR (temp_var, att_exported);
660 array_needs_making = 1;
662 #endif
664 /* Get the user's real and effective user ids. */
665 uidset ();
667 temp_var = find_variable ("BUSH_XTRACEFD");
668 if (temp_var && imported_p (temp_var))
669 sv_xtracefd (temp_var->name);
671 sv_shcompat ("BUSH_COMPAT");
673 /* Allow FUNCNEST to be inherited from the environment. */
674 sv_funcnest ("FUNCNEST");
676 /* Initialize the dynamic variables, and seed their values. */
677 initialize_dynamic_variables ();
680 /* **************************************************************** */
681 /* */
682 /* Setting values for special shell variables */
683 /* */
684 /* **************************************************************** */
686 static void
687 set_machine_vars ()
689 SHELL_VAR *temp_var;
691 temp_var = set_if_not ("HOSTTYPE", HOSTTYPE);
692 temp_var = set_if_not ("OSTYPE", OSTYPE);
693 temp_var = set_if_not ("MACHTYPE", MACHTYPE);
695 temp_var = set_if_not ("HOSTNAME", current_host_name);
698 /* Set $HOME to the information in the password file if we didn't get
699 it from the environment. */
701 /* This function is not static so the tilde and readline libraries can
702 use it. */
703 char *
704 sh_get_home_dir ()
706 if (current_user.home_dir == 0)
707 get_current_user_info ();
708 return current_user.home_dir;
711 static void
712 set_home_var ()
714 SHELL_VAR *temp_var;
716 temp_var = find_variable ("HOME");
717 if (temp_var == 0)
718 temp_var = bind_variable ("HOME", sh_get_home_dir (), 0);
719 #if 0
720 VSETATTR (temp_var, att_exported);
721 #endif
724 /* Set $SHELL to the user's login shell if it is not already set. Call
725 get_current_user_info if we haven't already fetched the shell. */
726 static void
727 set_shell_var ()
729 SHELL_VAR *temp_var;
731 temp_var = find_variable ("SHELL");
732 if (temp_var == 0)
734 if (current_user.shell == 0)
735 get_current_user_info ();
736 temp_var = bind_variable ("SHELL", current_user.shell, 0);
738 #if 0
739 VSETATTR (temp_var, att_exported);
740 #endif
743 static char *
744 get_bush_name ()
746 char *name;
748 if ((login_shell == 1) && RELPATH(shell_name))
750 if (current_user.shell == 0)
751 get_current_user_info ();
752 name = savestring (current_user.shell);
754 else if (ABSPATH(shell_name))
755 name = savestring (shell_name);
756 else if (shell_name[0] == '.' && shell_name[1] == '/')
758 /* Fast path for common case. */
759 char *cdir;
760 int len;
762 cdir = get_string_value ("PWD");
763 if (cdir)
765 len = strlen (cdir);
766 name = (char *)xmalloc (len + strlen (shell_name) + 1);
767 strcpy (name, cdir);
768 strcpy (name + len, shell_name + 1);
770 else
771 name = savestring (shell_name);
773 else
775 char *tname;
776 int s;
778 tname = find_user_command (shell_name);
780 if (tname == 0)
782 /* Try the current directory. If there is not an executable
783 there, just punt and use the login shell. */
784 s = file_status (shell_name);
785 if (s & FS_EXECABLE)
787 tname = make_absolute (shell_name, get_string_value ("PWD"));
788 if (*shell_name == '.')
790 name = sh_canonpath (tname, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
791 if (name == 0)
792 name = tname;
793 else
794 free (tname);
796 else
797 name = tname;
799 else
801 if (current_user.shell == 0)
802 get_current_user_info ();
803 name = savestring (current_user.shell);
806 else
808 name = full_pathname (tname);
809 free (tname);
813 return (name);
816 void
817 adjust_shell_level (change)
818 int change;
820 char new_level[5], *old_SHLVL;
821 intmax_t old_level;
822 SHELL_VAR *temp_var;
824 old_SHLVL = get_string_value ("SHLVL");
825 if (old_SHLVL == 0 || *old_SHLVL == '\0' || legal_number (old_SHLVL, &old_level) == 0)
826 old_level = 0;
828 shell_level = old_level + change;
829 if (shell_level < 0)
830 shell_level = 0;
831 else if (shell_level >= 1000)
833 internal_warning (_("shell level (%d) too high, resetting to 1"), shell_level);
834 shell_level = 1;
837 /* We don't need the full generality of itos here. */
838 if (shell_level < 10)
840 new_level[0] = shell_level + '0';
841 new_level[1] = '\0';
843 else if (shell_level < 100)
845 new_level[0] = (shell_level / 10) + '0';
846 new_level[1] = (shell_level % 10) + '0';
847 new_level[2] = '\0';
849 else if (shell_level < 1000)
851 new_level[0] = (shell_level / 100) + '0';
852 old_level = shell_level % 100;
853 new_level[1] = (old_level / 10) + '0';
854 new_level[2] = (old_level % 10) + '0';
855 new_level[3] = '\0';
858 temp_var = bind_variable ("SHLVL", new_level, 0);
859 set_auto_export (temp_var);
862 static void
863 initialize_shell_level ()
865 adjust_shell_level (1);
868 /* If we got PWD from the environment, update our idea of the current
869 working directory. In any case, make sure that PWD exists before
870 checking it. It is possible for getcwd () to fail on shell startup,
871 and in that case, PWD would be undefined. If this is an interactive
872 login shell, see if $HOME is the current working directory, and if
873 that's not the same string as $PWD, set PWD=$HOME. */
875 void
876 set_pwd ()
878 SHELL_VAR *temp_var, *home_var;
879 char *temp_string, *home_string, *current_dir;
881 home_var = find_variable ("HOME");
882 home_string = home_var ? value_cell (home_var) : (char *)NULL;
884 temp_var = find_variable ("PWD");
885 /* Follow posix rules for importing PWD */
886 if (temp_var && imported_p (temp_var) &&
887 (temp_string = value_cell (temp_var)) &&
888 temp_string[0] == '/' &&
889 same_file (temp_string, ".", (struct stat *)NULL, (struct stat *)NULL))
891 current_dir = sh_canonpath (temp_string, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
892 if (current_dir == 0)
893 current_dir = get_working_directory ("shell_init");
894 else
895 set_working_directory (current_dir);
896 if (posixly_correct && current_dir)
898 temp_var = bind_variable ("PWD", current_dir, 0);
899 set_auto_export (temp_var);
901 free (current_dir);
903 else if (home_string && interactive_shell && login_shell &&
904 same_file (home_string, ".", (struct stat *)NULL, (struct stat *)NULL))
906 set_working_directory (home_string);
907 temp_var = bind_variable ("PWD", home_string, 0);
908 set_auto_export (temp_var);
910 else
912 temp_string = get_working_directory ("shell-init");
913 if (temp_string)
915 temp_var = bind_variable ("PWD", temp_string, 0);
916 set_auto_export (temp_var);
917 free (temp_string);
921 /* According to the Single Unix Specification, v2, $OLDPWD is an
922 `environment variable' and therefore should be auto-exported. If we
923 don't find OLDPWD in the environment, or it doesn't name a directory,
924 make a dummy invisible variable for OLDPWD, and mark it as exported. */
925 temp_var = find_variable ("OLDPWD");
926 #if defined (OLDPWD_CHECK_DIRECTORY)
927 if (temp_var == 0 || value_cell (temp_var) == 0 || file_isdir (value_cell (temp_var)) == 0)
928 #else
929 if (temp_var == 0 || value_cell (temp_var) == 0)
930 #endif
932 temp_var = bind_variable ("OLDPWD", (char *)NULL, 0);
933 VSETATTR (temp_var, (att_exported | att_invisible));
937 /* Make a variable $PPID, which holds the pid of the shell's parent. */
938 void
939 set_ppid ()
941 char namebuf[INT_STRLEN_BOUND(pid_t) + 1], *name;
942 SHELL_VAR *temp_var;
944 name = inttostr (getppid (), namebuf, sizeof(namebuf));
945 temp_var = find_variable ("PPID");
946 if (temp_var)
947 VUNSETATTR (temp_var, (att_readonly | att_exported));
948 temp_var = bind_variable ("PPID", name, 0);
949 VSETATTR (temp_var, (att_readonly | att_integer));
952 static void
953 uidset ()
955 char buff[INT_STRLEN_BOUND(uid_t) + 1], *b;
956 register SHELL_VAR *v;
958 b = inttostr (current_user.uid, buff, sizeof (buff));
959 v = find_variable ("UID");
960 if (v == 0)
962 v = bind_variable ("UID", b, 0);
963 VSETATTR (v, (att_readonly | att_integer));
966 if (current_user.euid != current_user.uid)
967 b = inttostr (current_user.euid, buff, sizeof (buff));
969 v = find_variable ("EUID");
970 if (v == 0)
972 v = bind_variable ("EUID", b, 0);
973 VSETATTR (v, (att_readonly | att_integer));
977 #if defined (ARRAY_VARS)
978 static void
979 make_vers_array ()
981 SHELL_VAR *vv;
982 ARRAY *av;
983 char *s, d[32], b[INT_STRLEN_BOUND(int) + 1];
985 unbind_variable_noref ("BUSH_VERSINFO");
987 vv = make_new_array_variable ("BUSH_VERSINFO");
988 av = array_cell (vv);
989 strcpy (d, dist_version);
990 s = strchr (d, '.');
991 if (s)
992 *s++ = '\0';
993 array_insert (av, 0, d);
994 array_insert (av, 1, s);
995 s = inttostr (patch_level, b, sizeof (b));
996 array_insert (av, 2, s);
997 s = inttostr (build_version, b, sizeof (b));
998 array_insert (av, 3, s);
999 array_insert (av, 4, release_status);
1000 array_insert (av, 5, MACHTYPE);
1002 VSETATTR (vv, att_readonly);
1004 #endif /* ARRAY_VARS */
1006 /* Set the environment variables $LINES and $COLUMNS in response to
1007 a window size change. */
1008 void
1009 sh_set_lines_and_columns (lines, cols)
1010 int lines, cols;
1012 char val[INT_STRLEN_BOUND(int) + 1], *v;
1014 #if defined (READLINE)
1015 /* If we are currently assigning to LINES or COLUMNS, don't do anything. */
1016 if (winsize_assignment)
1017 return;
1018 #endif
1020 v = inttostr (lines, val, sizeof (val));
1021 bind_variable ("LINES", v, 0);
1023 v = inttostr (cols, val, sizeof (val));
1024 bind_variable ("COLUMNS", v, 0);
1027 /* **************************************************************** */
1028 /* */
1029 /* Printing variables and values */
1030 /* */
1031 /* **************************************************************** */
1033 /* Print LIST (a list of shell variables) to stdout in such a way that
1034 they can be read back in. */
1035 void
1036 print_var_list (list)
1037 register SHELL_VAR **list;
1039 register int i;
1040 register SHELL_VAR *var;
1042 for (i = 0; list && (var = list[i]); i++)
1043 if (invisible_p (var) == 0)
1044 print_assignment (var);
1047 /* Print LIST (a list of shell functions) to stdout in such a way that
1048 they can be read back in. */
1049 void
1050 print_func_list (list)
1051 register SHELL_VAR **list;
1053 register int i;
1054 register SHELL_VAR *var;
1056 for (i = 0; list && (var = list[i]); i++)
1058 printf ("%s ", var->name);
1059 print_var_function (var);
1060 printf ("\n");
1064 /* Print the value of a single SHELL_VAR. No newline is
1065 output, but the variable is printed in such a way that
1066 it can be read back in. */
1067 void
1068 print_assignment (var)
1069 SHELL_VAR *var;
1071 if (var_isset (var) == 0)
1072 return;
1074 if (function_p (var))
1076 printf ("%s", var->name);
1077 print_var_function (var);
1078 printf ("\n");
1080 #if defined (ARRAY_VARS)
1081 else if (array_p (var))
1082 print_array_assignment (var, 0);
1083 else if (assoc_p (var))
1084 print_assoc_assignment (var, 0);
1085 #endif /* ARRAY_VARS */
1086 else
1088 printf ("%s=", var->name);
1089 print_var_value (var, 1);
1090 printf ("\n");
1094 /* Print the value cell of VAR, a shell variable. Do not print
1095 the name, nor leading/trailing newline. If QUOTE is non-zero,
1096 and the value contains shell metacharacters, quote the value
1097 in such a way that it can be read back in. */
1098 void
1099 print_var_value (var, quote)
1100 SHELL_VAR *var;
1101 int quote;
1103 char *t;
1105 if (var_isset (var) == 0)
1106 return;
1108 if (quote && posixly_correct == 0 && ansic_shouldquote (value_cell (var)))
1110 t = ansic_quote (value_cell (var), 0, (int *)0);
1111 printf ("%s", t);
1112 free (t);
1114 else if (quote && sh_contains_shell_metas (value_cell (var)))
1116 t = sh_single_quote (value_cell (var));
1117 printf ("%s", t);
1118 free (t);
1120 else
1121 printf ("%s", value_cell (var));
1124 /* Print the function cell of VAR, a shell variable. Do not
1125 print the name, nor leading/trailing newline. */
1126 void
1127 print_var_function (var)
1128 SHELL_VAR *var;
1130 char *x;
1132 if (function_p (var) && var_isset (var))
1134 x = named_function_string ((char *)NULL, function_cell(var), FUNC_MULTILINE|FUNC_EXTERNAL);
1135 printf ("%s", x);
1139 /* **************************************************************** */
1140 /* */
1141 /* Dynamic Variables */
1142 /* */
1143 /* **************************************************************** */
1145 /* DYNAMIC VARIABLES
1147 These are variables whose values are generated anew each time they are
1148 referenced. These are implemented using a pair of function pointers
1149 in the struct variable: assign_func, which is called from bind_variable
1150 and, if arrays are compiled into the shell, some of the functions in
1151 arrayfunc.c, and dynamic_value, which is called from find_variable.
1153 assign_func is called from bind_variable_internal, if
1154 bind_variable_internal discovers that the variable being assigned to
1155 has such a function. The function is called as
1156 SHELL_VAR *temp = (*(entry->assign_func)) (entry, value, ind)
1157 and the (SHELL_VAR *)temp is returned as the value of bind_variable. It
1158 is usually ENTRY (self). IND is an index for an array variable, and
1159 unused otherwise.
1161 dynamic_value is called from find_variable_internal to return a `new'
1162 value for the specified dynamic variable. If this function is NULL,
1163 the variable is treated as a `normal' shell variable. If it is not,
1164 however, then this function is called like this:
1165 tempvar = (*(var->dynamic_value)) (var);
1167 Sometimes `tempvar' will replace the value of `var'. Other times, the
1168 shell will simply use the string value. Pretty object-oriented, huh?
1170 Be warned, though: if you `unset' a special variable, it loses its
1171 special meaning, even if you subsequently set it.
1173 The special assignment code would probably have been better put in
1174 subst.c: do_assignment_internal, in the same style as
1175 stupidly_hack_special_variables, but I wanted the changes as
1176 localized as possible. */
1178 #define INIT_DYNAMIC_VAR(var, val, gfunc, afunc) \
1179 do \
1181 v = bind_variable (var, (val), 0); \
1182 v->dynamic_value = gfunc; \
1183 v->assign_func = afunc; \
1185 while (0)
1187 #define INIT_DYNAMIC_ARRAY_VAR(var, gfunc, afunc) \
1188 do \
1190 v = make_new_array_variable (var); \
1191 v->dynamic_value = gfunc; \
1192 v->assign_func = afunc; \
1194 while (0)
1196 #define INIT_DYNAMIC_ASSOC_VAR(var, gfunc, afunc) \
1197 do \
1199 v = make_new_assoc_variable (var); \
1200 v->dynamic_value = gfunc; \
1201 v->assign_func = afunc; \
1203 while (0)
1205 static SHELL_VAR *
1206 null_assign (self, value, unused, key)
1207 SHELL_VAR *self;
1208 char *value;
1209 arrayind_t unused;
1210 char *key;
1212 return (self);
1215 #if defined (ARRAY_VARS)
1216 static SHELL_VAR *
1217 null_array_assign (self, value, ind, key)
1218 SHELL_VAR *self;
1219 char *value;
1220 arrayind_t ind;
1221 char *key;
1223 return (self);
1225 #endif
1227 /* Degenerate `dynamic_value' function; just returns what's passed without
1228 manipulation. */
1229 static SHELL_VAR *
1230 get_self (self)
1231 SHELL_VAR *self;
1233 return (self);
1236 #if defined (ARRAY_VARS)
1237 /* A generic dynamic array variable initializer. Initialize array variable
1238 NAME with dynamic value function GETFUNC and assignment function SETFUNC. */
1239 static SHELL_VAR *
1240 init_dynamic_array_var (name, getfunc, setfunc, attrs)
1241 char *name;
1242 sh_var_value_func_t *getfunc;
1243 sh_var_assign_func_t *setfunc;
1244 int attrs;
1246 SHELL_VAR *v;
1248 v = find_variable (name);
1249 if (v)
1250 return (v);
1251 INIT_DYNAMIC_ARRAY_VAR (name, getfunc, setfunc);
1252 if (attrs)
1253 VSETATTR (v, attrs);
1254 return v;
1257 static SHELL_VAR *
1258 init_dynamic_assoc_var (name, getfunc, setfunc, attrs)
1259 char *name;
1260 sh_var_value_func_t *getfunc;
1261 sh_var_assign_func_t *setfunc;
1262 int attrs;
1264 SHELL_VAR *v;
1266 v = find_variable (name);
1267 if (v)
1268 return (v);
1269 INIT_DYNAMIC_ASSOC_VAR (name, getfunc, setfunc);
1270 if (attrs)
1271 VSETATTR (v, attrs);
1272 return v;
1274 #endif
1276 /* The value of $SECONDS. This is the number of seconds since shell
1277 invocation, or, the number of seconds since the last assignment + the
1278 value of the last assignment. */
1279 static intmax_t seconds_value_assigned;
1281 static SHELL_VAR *
1282 assign_seconds (self, value, unused, key)
1283 SHELL_VAR *self;
1284 char *value;
1285 arrayind_t unused;
1286 char *key;
1288 intmax_t nval;
1289 int expok;
1291 if (integer_p (self))
1292 nval = evalexp (value, 0, &expok);
1293 else
1294 expok = legal_number (value, &nval);
1295 seconds_value_assigned = expok ? nval : 0;
1296 gettimeofday (&shellstart, NULL);
1297 shell_start_time = shellstart.tv_sec;
1298 return (self);
1301 static SHELL_VAR *
1302 get_seconds (var)
1303 SHELL_VAR *var;
1305 time_t time_since_start;
1306 char *p;
1307 struct timeval tv;
1309 gettimeofday(&tv, NULL);
1310 time_since_start = tv.tv_sec - shell_start_time;
1311 p = itos(seconds_value_assigned + time_since_start);
1313 FREE (value_cell (var));
1315 VSETATTR (var, att_integer);
1316 var_setvalue (var, p);
1317 return (var);
1320 static SHELL_VAR *
1321 init_seconds_var ()
1323 SHELL_VAR *v;
1325 v = find_variable ("SECONDS");
1326 if (v)
1328 if (legal_number (value_cell(v), &seconds_value_assigned) == 0)
1329 seconds_value_assigned = 0;
1331 INIT_DYNAMIC_VAR ("SECONDS", (v ? value_cell (v) : (char *)NULL), get_seconds, assign_seconds);
1332 return v;
1335 /* Functions for $RANDOM and $SRANDOM */
1337 int last_random_value;
1338 static int seeded_subshell = 0;
1340 static SHELL_VAR *
1341 assign_random (self, value, unused, key)
1342 SHELL_VAR *self;
1343 char *value;
1344 arrayind_t unused;
1345 char *key;
1347 intmax_t seedval;
1348 int expok;
1350 if (integer_p (self))
1351 seedval = evalexp (value, 0, &expok);
1352 else
1353 expok = legal_number (value, &seedval);
1354 if (expok == 0)
1355 return (self);
1356 sbrand (seedval);
1357 if (subshell_environment)
1358 seeded_subshell = getpid ();
1359 return (self);
1363 get_random_number ()
1365 int rv, pid;
1367 /* Reset for command and process substitution. */
1368 pid = getpid ();
1369 if (subshell_environment && seeded_subshell != pid)
1371 seedrand ();
1372 seeded_subshell = pid;
1376 rv = brand ();
1377 while (rv == last_random_value);
1379 return (last_random_value = rv);
1382 static SHELL_VAR *
1383 get_random (var)
1384 SHELL_VAR *var;
1386 int rv;
1387 char *p;
1389 rv = get_random_number ();
1390 p = itos (rv);
1392 FREE (value_cell (var));
1394 VSETATTR (var, att_integer);
1395 var_setvalue (var, p);
1396 return (var);
1399 static SHELL_VAR *
1400 get_urandom (var)
1401 SHELL_VAR *var;
1403 u_bits32_t rv;
1404 char *p;
1406 rv = get_urandom32 ();
1407 p = itos (rv);
1409 FREE (value_cell (var));
1411 VSETATTR (var, att_integer);
1412 var_setvalue (var, p);
1413 return (var);
1416 static SHELL_VAR *
1417 assign_lineno (var, value, unused, key)
1418 SHELL_VAR *var;
1419 char *value;
1420 arrayind_t unused;
1421 char *key;
1423 intmax_t new_value;
1425 if (value == 0 || *value == '\0' || legal_number (value, &new_value) == 0)
1426 new_value = 0;
1427 line_number = line_number_base = new_value;
1428 return var;
1431 /* Function which returns the current line number. */
1432 static SHELL_VAR *
1433 get_lineno (var)
1434 SHELL_VAR *var;
1436 char *p;
1437 int ln;
1439 ln = executing_line_number ();
1440 p = itos (ln);
1441 FREE (value_cell (var));
1442 var_setvalue (var, p);
1443 return (var);
1446 static SHELL_VAR *
1447 assign_subshell (var, value, unused, key)
1448 SHELL_VAR *var;
1449 char *value;
1450 arrayind_t unused;
1451 char *key;
1453 intmax_t new_value;
1455 if (value == 0 || *value == '\0' || legal_number (value, &new_value) == 0)
1456 new_value = 0;
1457 subshell_level = new_value;
1458 return var;
1461 static SHELL_VAR *
1462 get_subshell (var)
1463 SHELL_VAR *var;
1465 char *p;
1467 p = itos (subshell_level);
1468 FREE (value_cell (var));
1469 var_setvalue (var, p);
1470 return (var);
1473 static SHELL_VAR *
1474 get_epochseconds (var)
1475 SHELL_VAR *var;
1477 intmax_t now;
1478 char *p;
1480 now = NOW;
1481 p = itos (now);
1483 FREE (value_cell (var));
1484 var_setvalue (var, p);
1485 return (var);
1488 static SHELL_VAR *
1489 get_epochrealtime (var)
1490 SHELL_VAR *var;
1492 char buf[32];
1493 char *p;
1494 struct timeval tv;
1496 gettimeofday (&tv, NULL);
1497 snprintf (buf, sizeof (buf), "%u%c%06u", (unsigned)tv.tv_sec,
1498 locale_decpoint (),
1499 (unsigned)tv.tv_usec);
1501 p = savestring (buf);
1502 FREE (value_cell (var));
1503 var_setvalue (var, p);
1504 return (var);
1507 static SHELL_VAR *
1508 get_bushpid (var)
1509 SHELL_VAR *var;
1511 int pid;
1512 char *p;
1514 pid = getpid ();
1515 p = itos (pid);
1517 FREE (value_cell (var));
1518 VSETATTR (var, att_integer); /* XXX - was also att_readonly */
1519 var_setvalue (var, p);
1520 return (var);
1523 static SHELL_VAR *
1524 get_bush_argv0 (var)
1525 SHELL_VAR *var;
1527 char *p;
1529 p = savestring (dollar_vars[0]);
1530 FREE (value_cell (var));
1531 var_setvalue (var, p);
1532 return var;
1535 static char *static_shell_name = 0;
1537 static SHELL_VAR *
1538 assign_bush_argv0 (var, value, unused, key)
1539 SHELL_VAR *var;
1540 char *value;
1541 arrayind_t unused;
1542 char *key;
1544 size_t vlen;
1546 if (value == 0)
1547 return var;
1549 FREE (dollar_vars[0]);
1550 dollar_vars[0] = savestring (value);
1552 /* Need these gyrations because shell_name isn't dynamically allocated */
1553 vlen = STRLEN (value);
1554 static_shell_name = xrealloc (static_shell_name, vlen + 1);
1555 strcpy (static_shell_name, value);
1557 shell_name = static_shell_name;
1558 return var;
1561 static void
1562 set_argv0 ()
1564 SHELL_VAR *v;
1566 v = find_variable ("BUSH_ARGV0");
1567 if (v && imported_p (v))
1568 assign_bush_argv0 (v, value_cell (v), 0, 0);
1571 static SHELL_VAR *
1572 get_bush_command (var)
1573 SHELL_VAR *var;
1575 char *p;
1577 if (the_printed_command_except_trap)
1578 p = savestring (the_printed_command_except_trap);
1579 else
1581 p = (char *)xmalloc (1);
1582 p[0] = '\0';
1584 FREE (value_cell (var));
1585 var_setvalue (var, p);
1586 return (var);
1589 #if defined (HISTORY)
1590 static SHELL_VAR *
1591 get_histcmd (var)
1592 SHELL_VAR *var;
1594 char *p;
1595 int n;
1597 /* Do the same adjustment here we do in parse.y:prompt_history_number,
1598 assuming that we are in one of two states: decoding this as part of
1599 the prompt string, in which case we do not want to assume that the
1600 command has been saved to the history and the history number incremented,
1601 or the expansion is part of the current command being executed and has
1602 already been saved to history and the history number incremented.
1603 Right now we use EXECUTING as the determinant. */
1604 n = history_number () - executing;
1605 p = itos (n);
1606 FREE (value_cell (var));
1607 var_setvalue (var, p);
1608 return (var);
1610 #endif
1612 #if defined (READLINE)
1613 /* When this function returns, VAR->value points to malloced memory. */
1614 static SHELL_VAR *
1615 get_comp_wordbreaks (var)
1616 SHELL_VAR *var;
1618 /* If we don't have anything yet, assign a default value. */
1619 if (rl_completer_word_break_characters == 0 && bush_readline_initialized == 0)
1620 enable_hostname_completion (perform_hostname_completion);
1622 FREE (value_cell (var));
1623 var_setvalue (var, savestring (rl_completer_word_break_characters));
1625 return (var);
1628 /* When this function returns, rl_completer_word_break_characters points to
1629 malloced memory. */
1630 static SHELL_VAR *
1631 assign_comp_wordbreaks (self, value, unused, key)
1632 SHELL_VAR *self;
1633 char *value;
1634 arrayind_t unused;
1635 char *key;
1637 if (rl_completer_word_break_characters &&
1638 rl_completer_word_break_characters != rl_basic_word_break_characters)
1639 free (rl_completer_word_break_characters);
1641 rl_completer_word_break_characters = savestring (value);
1642 return self;
1644 #endif /* READLINE */
1646 #if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
1647 static SHELL_VAR *
1648 assign_dirstack (self, value, ind, key)
1649 SHELL_VAR *self;
1650 char *value;
1651 arrayind_t ind;
1652 char *key;
1654 set_dirstack_element (ind, 1, value);
1655 return self;
1658 static SHELL_VAR *
1659 get_dirstack (self)
1660 SHELL_VAR *self;
1662 ARRAY *a;
1663 WORD_LIST *l;
1665 l = get_directory_stack (0);
1666 a = array_from_word_list (l);
1667 array_dispose (array_cell (self));
1668 dispose_words (l);
1669 var_setarray (self, a);
1670 return self;
1672 #endif /* PUSHD AND POPD && ARRAY_VARS */
1674 #if defined (ARRAY_VARS)
1675 /* We don't want to initialize the group set with a call to getgroups()
1676 unless we're asked to, but we only want to do it once. */
1677 static SHELL_VAR *
1678 get_groupset (self)
1679 SHELL_VAR *self;
1681 register int i;
1682 int ng;
1683 ARRAY *a;
1684 static char **group_set = (char **)NULL;
1686 if (group_set == 0)
1688 group_set = get_group_list (&ng);
1689 a = array_cell (self);
1690 for (i = 0; i < ng; i++)
1691 array_insert (a, i, group_set[i]);
1693 return (self);
1696 # if defined (DEBUGGER)
1697 static SHELL_VAR *
1698 get_bushargcv (self)
1699 SHELL_VAR *self;
1701 static int self_semaphore = 0;
1703 /* Backwards compatibility: if we refer to BUSH_ARGV or BUSH_ARGC at the
1704 top level without enabling debug mode, and we don't have an instance
1705 of the variable set, initialize the arg arrays.
1706 This will already have been done if debugging_mode != 0. */
1707 if (self_semaphore == 0 && variable_context == 0 && debugging_mode == 0) /* don't do it for shell functions */
1709 self_semaphore = 1;
1710 init_bush_argv ();
1711 self_semaphore = 0;
1713 return self;
1715 # endif
1717 static SHELL_VAR *
1718 build_hashcmd (self)
1719 SHELL_VAR *self;
1721 HASH_TABLE *h;
1722 int i;
1723 char *k, *v;
1724 BUCKET_CONTENTS *item;
1726 h = assoc_cell (self);
1727 if (h)
1728 assoc_dispose (h);
1730 if (hashed_filenames == 0 || HASH_ENTRIES (hashed_filenames) == 0)
1732 var_setvalue (self, (char *)NULL);
1733 return self;
1736 h = assoc_create (hashed_filenames->nbuckets);
1737 for (i = 0; i < hashed_filenames->nbuckets; i++)
1739 for (item = hash_items (i, hashed_filenames); item; item = item->next)
1741 k = savestring (item->key);
1742 v = pathdata(item)->path;
1743 assoc_insert (h, k, v);
1747 var_setvalue (self, (char *)h);
1748 return self;
1751 static SHELL_VAR *
1752 get_hashcmd (self)
1753 SHELL_VAR *self;
1755 build_hashcmd (self);
1756 return (self);
1759 static SHELL_VAR *
1760 assign_hashcmd (self, value, ind, key)
1761 SHELL_VAR *self;
1762 char *value;
1763 arrayind_t ind;
1764 char *key;
1766 #if defined (RESTRICTED_SHELL)
1767 char *full_path;
1769 if (restricted)
1771 if (strchr (value, '/'))
1773 sh_restricted (value);
1774 return (SHELL_VAR *)NULL;
1776 /* If we are changing the hash table in a restricted shell, make sure the
1777 target pathname can be found using a $PATH search. */
1778 full_path = find_user_command (value);
1779 if (full_path == 0 || *full_path == 0 || executable_file (full_path) == 0)
1781 sh_notfound (value);
1782 free (full_path);
1783 return ((SHELL_VAR *)NULL);
1785 free (full_path);
1787 #endif
1788 phash_insert (key, value, 0, 0);
1789 return (build_hashcmd (self));
1792 #if defined (ALIAS)
1793 static SHELL_VAR *
1794 build_aliasvar (self)
1795 SHELL_VAR *self;
1797 HASH_TABLE *h;
1798 int i;
1799 char *k, *v;
1800 BUCKET_CONTENTS *item;
1802 h = assoc_cell (self);
1803 if (h)
1804 assoc_dispose (h);
1806 if (aliases == 0 || HASH_ENTRIES (aliases) == 0)
1808 var_setvalue (self, (char *)NULL);
1809 return self;
1812 h = assoc_create (aliases->nbuckets);
1813 for (i = 0; i < aliases->nbuckets; i++)
1815 for (item = hash_items (i, aliases); item; item = item->next)
1817 k = savestring (item->key);
1818 v = ((alias_t *)(item->data))->value;
1819 assoc_insert (h, k, v);
1823 var_setvalue (self, (char *)h);
1824 return self;
1827 static SHELL_VAR *
1828 get_aliasvar (self)
1829 SHELL_VAR *self;
1831 build_aliasvar (self);
1832 return (self);
1835 static SHELL_VAR *
1836 assign_aliasvar (self, value, ind, key)
1837 SHELL_VAR *self;
1838 char *value;
1839 arrayind_t ind;
1840 char *key;
1842 if (legal_alias_name (key, 0) == 0)
1844 report_error (_("`%s': invalid alias name"), key);
1845 return (self);
1847 add_alias (key, value);
1848 return (build_aliasvar (self));
1850 #endif /* ALIAS */
1852 #endif /* ARRAY_VARS */
1854 /* If ARRAY_VARS is not defined, this just returns the name of any
1855 currently-executing function. If we have arrays, it's a call stack. */
1856 static SHELL_VAR *
1857 get_funcname (self)
1858 SHELL_VAR *self;
1860 #if ! defined (ARRAY_VARS)
1861 char *t;
1862 if (variable_context && this_shell_function)
1864 FREE (value_cell (self));
1865 t = savestring (this_shell_function->name);
1866 var_setvalue (self, t);
1868 #endif
1869 return (self);
1872 void
1873 make_funcname_visible (on_or_off)
1874 int on_or_off;
1876 SHELL_VAR *v;
1878 v = find_variable ("FUNCNAME");
1879 if (v == 0 || v->dynamic_value == 0)
1880 return;
1882 if (on_or_off)
1883 VUNSETATTR (v, att_invisible);
1884 else
1885 VSETATTR (v, att_invisible);
1888 static SHELL_VAR *
1889 init_funcname_var ()
1891 SHELL_VAR *v;
1893 v = find_variable ("FUNCNAME");
1894 if (v)
1895 return v;
1896 #if defined (ARRAY_VARS)
1897 INIT_DYNAMIC_ARRAY_VAR ("FUNCNAME", get_funcname, null_array_assign);
1898 #else
1899 INIT_DYNAMIC_VAR ("FUNCNAME", (char *)NULL, get_funcname, null_assign);
1900 #endif
1901 VSETATTR (v, att_invisible|att_noassign);
1902 return v;
1905 static void
1906 initialize_dynamic_variables ()
1908 SHELL_VAR *v;
1910 v = init_seconds_var ();
1912 INIT_DYNAMIC_VAR ("BUSH_ARGV0", (char *)NULL, get_bush_argv0, assign_bush_argv0);
1914 INIT_DYNAMIC_VAR ("BUSH_COMMAND", (char *)NULL, get_bush_command, (sh_var_assign_func_t *)NULL);
1915 INIT_DYNAMIC_VAR ("BUSH_SUBSHELL", (char *)NULL, get_subshell, assign_subshell);
1917 INIT_DYNAMIC_VAR ("RANDOM", (char *)NULL, get_random, assign_random);
1918 VSETATTR (v, att_integer);
1919 INIT_DYNAMIC_VAR ("SRANDOM", (char *)NULL, get_urandom, (sh_var_assign_func_t *)NULL);
1920 VSETATTR (v, att_integer);
1921 INIT_DYNAMIC_VAR ("LINENO", (char *)NULL, get_lineno, assign_lineno);
1922 VSETATTR (v, att_regenerate);
1924 INIT_DYNAMIC_VAR ("BUSHPID", (char *)NULL, get_bushpid, null_assign);
1925 VSETATTR (v, att_integer);
1927 INIT_DYNAMIC_VAR ("EPOCHSECONDS", (char *)NULL, get_epochseconds, null_assign);
1928 VSETATTR (v, att_regenerate);
1929 INIT_DYNAMIC_VAR ("EPOCHREALTIME", (char *)NULL, get_epochrealtime, null_assign);
1930 VSETATTR (v, att_regenerate);
1932 #if defined (HISTORY)
1933 INIT_DYNAMIC_VAR ("HISTCMD", (char *)NULL, get_histcmd, (sh_var_assign_func_t *)NULL);
1934 VSETATTR (v, att_integer);
1935 #endif
1937 #if defined (READLINE)
1938 INIT_DYNAMIC_VAR ("COMP_WORDBREAKS", (char *)NULL, get_comp_wordbreaks, assign_comp_wordbreaks);
1939 #endif
1941 #if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
1942 v = init_dynamic_array_var ("DIRSTACK", get_dirstack, assign_dirstack, 0);
1943 #endif /* PUSHD_AND_POPD && ARRAY_VARS */
1945 #if defined (ARRAY_VARS)
1946 v = init_dynamic_array_var ("GROUPS", get_groupset, null_array_assign, att_noassign);
1948 # if defined (DEBUGGER)
1949 v = init_dynamic_array_var ("BUSH_ARGC", get_bushargcv, null_array_assign, att_noassign|att_nounset);
1950 v = init_dynamic_array_var ("BUSH_ARGV", get_bushargcv, null_array_assign, att_noassign|att_nounset);
1951 # endif /* DEBUGGER */
1952 v = init_dynamic_array_var ("BUSH_SOURCE", get_self, null_array_assign, att_noassign|att_nounset);
1953 v = init_dynamic_array_var ("BUSH_LINENO", get_self, null_array_assign, att_noassign|att_nounset);
1955 v = init_dynamic_assoc_var ("BUSH_CMDS", get_hashcmd, assign_hashcmd, att_nofree);
1956 # if defined (ALIAS)
1957 v = init_dynamic_assoc_var ("BUSH_ALIASES", get_aliasvar, assign_aliasvar, att_nofree);
1958 # endif
1959 #endif
1961 v = init_funcname_var ();
1964 /* **************************************************************** */
1965 /* */
1966 /* Retrieving variables and values */
1967 /* */
1968 /* **************************************************************** */
1970 #if 0 /* not yet */
1972 var_isset (var)
1973 SHELL_VAR *var;
1975 return (var->value != 0);
1979 var_isunset (var)
1980 SHELL_VAR *var;
1982 return (var->value == 0);
1984 #endif
1986 /* How to get a pointer to the shell variable or function named NAME.
1987 HASHED_VARS is a pointer to the hash table containing the list
1988 of interest (either variables or functions). */
1990 static SHELL_VAR *
1991 hash_lookup (name, hashed_vars)
1992 const char *name;
1993 HASH_TABLE *hashed_vars;
1995 BUCKET_CONTENTS *bucket;
1997 bucket = hash_search (name, hashed_vars, 0);
1998 /* If we find the name in HASHED_VARS, set LAST_TABLE_SEARCHED to that
1999 table. */
2000 if (bucket)
2001 last_table_searched = hashed_vars;
2002 return (bucket ? (SHELL_VAR *)bucket->data : (SHELL_VAR *)NULL);
2005 SHELL_VAR *
2006 var_lookup (name, vcontext)
2007 const char *name;
2008 VAR_CONTEXT *vcontext;
2010 VAR_CONTEXT *vc;
2011 SHELL_VAR *v;
2013 v = (SHELL_VAR *)NULL;
2014 for (vc = vcontext; vc; vc = vc->down)
2015 if (v = hash_lookup (name, vc->table))
2016 break;
2018 return v;
2021 /* Look up the variable entry named NAME. If SEARCH_TEMPENV is non-zero,
2022 then also search the temporarily built list of exported variables.
2023 The lookup order is:
2024 temporary_env
2025 shell_variables list
2028 SHELL_VAR *
2029 find_variable_internal (name, flags)
2030 const char *name;
2031 int flags;
2033 SHELL_VAR *var;
2034 int search_tempenv, force_tempenv;
2035 VAR_CONTEXT *vc;
2037 var = (SHELL_VAR *)NULL;
2039 force_tempenv = (flags & FV_FORCETEMPENV);
2041 /* If explicitly requested, first look in the temporary environment for
2042 the variable. This allows constructs such as "foo=x eval 'echo $foo'"
2043 to get the `exported' value of $foo. This happens if we are executing
2044 a function or builtin, or if we are looking up a variable in a
2045 "subshell environment". */
2046 search_tempenv = force_tempenv || (expanding_redir == 0 && subshell_environment);
2048 if (search_tempenv && temporary_env)
2049 var = hash_lookup (name, temporary_env);
2051 if (var == 0)
2053 if ((flags & FV_SKIPINVISIBLE) == 0)
2054 var = var_lookup (name, shell_variables);
2055 else
2057 /* essentially var_lookup expanded inline so we can check for
2058 att_invisible */
2059 for (vc = shell_variables; vc; vc = vc->down)
2061 var = hash_lookup (name, vc->table);
2062 if (var && invisible_p (var))
2063 var = 0;
2064 if (var)
2065 break;
2070 if (var == 0)
2071 return ((SHELL_VAR *)NULL);
2073 return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var);
2076 /* Look up and resolve the chain of nameref variables starting at V all the
2077 way to NULL or non-nameref. */
2078 SHELL_VAR *
2079 find_variable_nameref (v)
2080 SHELL_VAR *v;
2082 int level, flags;
2083 char *newname;
2084 SHELL_VAR *orig, *oldv;
2086 level = 0;
2087 orig = v;
2088 while (v && nameref_p (v))
2090 level++;
2091 if (level > NAMEREF_MAX)
2092 return ((SHELL_VAR *)0); /* error message here? */
2093 newname = nameref_cell (v);
2094 if (newname == 0 || *newname == '\0')
2095 return ((SHELL_VAR *)0);
2096 oldv = v;
2097 flags = 0;
2098 if (expanding_redir == 0 && (assigning_in_environment || executing_builtin))
2099 flags |= FV_FORCETEMPENV;
2100 /* We don't handle array subscripts here. */
2101 v = find_variable_internal (newname, flags);
2102 if (v == orig || v == oldv)
2104 internal_warning (_("%s: circular name reference"), orig->name);
2105 #if 1
2106 /* XXX - provisional change - circular refs go to
2107 global scope for resolution, without namerefs. */
2108 if (variable_context && v->context)
2109 return (find_global_variable_noref (v->name));
2110 else
2111 #endif
2112 return ((SHELL_VAR *)0);
2115 return v;
2118 /* Resolve the chain of nameref variables for NAME. XXX - could change later */
2119 SHELL_VAR *
2120 find_variable_last_nameref (name, vflags)
2121 const char *name;
2122 int vflags;
2124 SHELL_VAR *v, *nv;
2125 char *newname;
2126 int level, flags;
2128 nv = v = find_variable_noref (name);
2129 level = 0;
2130 while (v && nameref_p (v))
2132 level++;
2133 if (level > NAMEREF_MAX)
2134 return ((SHELL_VAR *)0); /* error message here? */
2135 newname = nameref_cell (v);
2136 if (newname == 0 || *newname == '\0')
2137 return ((vflags && invisible_p (v)) ? v : (SHELL_VAR *)0);
2138 nv = v;
2139 flags = 0;
2140 if (expanding_redir == 0 && (assigning_in_environment || executing_builtin))
2141 flags |= FV_FORCETEMPENV;
2142 /* We don't accommodate array subscripts here. */
2143 v = find_variable_internal (newname, flags);
2145 return nv;
2148 /* Resolve the chain of nameref variables for NAME. XXX - could change later */
2149 SHELL_VAR *
2150 find_global_variable_last_nameref (name, vflags)
2151 const char *name;
2152 int vflags;
2154 SHELL_VAR *v, *nv;
2155 char *newname;
2156 int level;
2158 nv = v = find_global_variable_noref (name);
2159 level = 0;
2160 while (v && nameref_p (v))
2162 level++;
2163 if (level > NAMEREF_MAX)
2164 return ((SHELL_VAR *)0); /* error message here? */
2165 newname = nameref_cell (v);
2166 if (newname == 0 || *newname == '\0')
2167 return ((vflags && invisible_p (v)) ? v : (SHELL_VAR *)0);
2168 nv = v;
2169 /* We don't accommodate array subscripts here. */
2170 v = find_global_variable_noref (newname);
2172 return nv;
2175 static SHELL_VAR *
2176 find_nameref_at_context (v, vc)
2177 SHELL_VAR *v;
2178 VAR_CONTEXT *vc;
2180 SHELL_VAR *nv, *nv2;
2181 char *newname;
2182 int level;
2184 nv = v;
2185 level = 1;
2186 while (nv && nameref_p (nv))
2188 level++;
2189 if (level > NAMEREF_MAX)
2190 return (&nameref_maxloop_value);
2191 newname = nameref_cell (nv);
2192 if (newname == 0 || *newname == '\0')
2193 return ((SHELL_VAR *)NULL);
2194 nv2 = hash_lookup (newname, vc->table);
2195 if (nv2 == 0)
2196 break;
2197 nv = nv2;
2199 return nv;
2202 /* Do nameref resolution from the VC, which is the local context for some
2203 function or builtin, `up' the chain to the global variables context. If
2204 NVCP is not NULL, return the variable context where we finally ended the
2205 nameref resolution (so the bind_variable_internal can use the correct
2206 variable context and hash table). */
2207 static SHELL_VAR *
2208 find_variable_nameref_context (v, vc, nvcp)
2209 SHELL_VAR *v;
2210 VAR_CONTEXT *vc;
2211 VAR_CONTEXT **nvcp;
2213 SHELL_VAR *nv, *nv2;
2214 VAR_CONTEXT *nvc;
2216 /* Look starting at the current context all the way `up' */
2217 for (nv = v, nvc = vc; nvc; nvc = nvc->down)
2219 nv2 = find_nameref_at_context (nv, nvc);
2220 if (nv2 == &nameref_maxloop_value)
2221 return (nv2); /* XXX */
2222 if (nv2 == 0)
2223 continue;
2224 nv = nv2;
2225 if (*nvcp)
2226 *nvcp = nvc;
2227 if (nameref_p (nv) == 0)
2228 break;
2230 return (nameref_p (nv) ? (SHELL_VAR *)NULL : nv);
2233 /* Do nameref resolution from the VC, which is the local context for some
2234 function or builtin, `up' the chain to the global variables context. If
2235 NVCP is not NULL, return the variable context where we finally ended the
2236 nameref resolution (so the bind_variable_internal can use the correct
2237 variable context and hash table). */
2238 static SHELL_VAR *
2239 find_variable_last_nameref_context (v, vc, nvcp)
2240 SHELL_VAR *v;
2241 VAR_CONTEXT *vc;
2242 VAR_CONTEXT **nvcp;
2244 SHELL_VAR *nv, *nv2;
2245 VAR_CONTEXT *nvc;
2247 /* Look starting at the current context all the way `up' */
2248 for (nv = v, nvc = vc; nvc; nvc = nvc->down)
2250 nv2 = find_nameref_at_context (nv, nvc);
2251 if (nv2 == &nameref_maxloop_value)
2252 return (nv2); /* XXX */
2253 if (nv2 == 0)
2254 continue;
2255 nv = nv2;
2256 if (*nvcp)
2257 *nvcp = nvc;
2259 return (nameref_p (nv) ? nv : (SHELL_VAR *)NULL);
2262 SHELL_VAR *
2263 find_variable_nameref_for_create (name, flags)
2264 const char *name;
2265 int flags;
2267 SHELL_VAR *var;
2269 /* See if we have a nameref pointing to a variable that hasn't been
2270 created yet. */
2271 var = find_variable_last_nameref (name, 1);
2272 if ((flags&1) && var && nameref_p (var) && invisible_p (var))
2274 internal_warning (_("%s: removing nameref attribute"), name);
2275 VUNSETATTR (var, att_nameref);
2277 if (var && nameref_p (var))
2279 if (legal_identifier (nameref_cell (var)) == 0)
2281 sh_invalidid (nameref_cell (var) ? nameref_cell (var) : "");
2282 return ((SHELL_VAR *)INVALID_NAMEREF_VALUE);
2285 return (var);
2288 SHELL_VAR *
2289 find_variable_nameref_for_assignment (name, flags)
2290 const char *name;
2291 int flags;
2293 SHELL_VAR *var;
2295 /* See if we have a nameref pointing to a variable that hasn't been
2296 created yet. */
2297 var = find_variable_last_nameref (name, 1);
2298 if (var && nameref_p (var) && invisible_p (var)) /* XXX - flags */
2300 internal_warning (_("%s: removing nameref attribute"), name);
2301 VUNSETATTR (var, att_nameref);
2303 if (var && nameref_p (var))
2305 if (valid_nameref_value (nameref_cell (var), 1) == 0)
2307 sh_invalidid (nameref_cell (var) ? nameref_cell (var) : "");
2308 return ((SHELL_VAR *)INVALID_NAMEREF_VALUE);
2311 return (var);
2314 /* If find_variable (name) returns NULL, check that it's not a nameref
2315 referencing a variable that doesn't exist. If it is, return the new
2316 name. If not, return the original name. Kind of like the previous
2317 function, but dealing strictly with names. This takes assignment flags
2318 so it can deal with the various assignment modes used by `declare'. */
2319 char *
2320 nameref_transform_name (name, flags)
2321 char *name;
2322 int flags;
2324 SHELL_VAR *v;
2325 char *newname;
2327 v = 0;
2328 if (flags & ASS_MKLOCAL)
2330 v = find_variable_last_nameref (name, 1);
2331 /* If we're making local variables, only follow namerefs that point to
2332 non-existent variables at the same variable context. */
2333 if (v && v->context != variable_context)
2334 v = 0;
2336 else if (flags & ASS_MKGLOBAL)
2337 v = (flags & ASS_CHKLOCAL) ? find_variable_last_nameref (name, 1)
2338 : find_global_variable_last_nameref (name, 1);
2339 if (v && nameref_p (v) && valid_nameref_value (nameref_cell (v), 1))
2340 return nameref_cell (v);
2341 return name;
2344 /* Find a variable, forcing a search of the temporary environment first */
2345 SHELL_VAR *
2346 find_variable_tempenv (name)
2347 const char *name;
2349 SHELL_VAR *var;
2351 var = find_variable_internal (name, FV_FORCETEMPENV);
2352 if (var && nameref_p (var))
2353 var = find_variable_nameref (var);
2354 return (var);
2357 /* Find a variable, not forcing a search of the temporary environment first */
2358 SHELL_VAR *
2359 find_variable_notempenv (name)
2360 const char *name;
2362 SHELL_VAR *var;
2364 var = find_variable_internal (name, 0);
2365 if (var && nameref_p (var))
2366 var = find_variable_nameref (var);
2367 return (var);
2370 SHELL_VAR *
2371 find_global_variable (name)
2372 const char *name;
2374 SHELL_VAR *var;
2376 var = var_lookup (name, global_variables);
2377 if (var && nameref_p (var))
2378 var = find_variable_nameref (var);
2380 if (var == 0)
2381 return ((SHELL_VAR *)NULL);
2383 return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var);
2386 SHELL_VAR *
2387 find_global_variable_noref (name)
2388 const char *name;
2390 SHELL_VAR *var;
2392 var = var_lookup (name, global_variables);
2394 if (var == 0)
2395 return ((SHELL_VAR *)NULL);
2397 return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var);
2400 SHELL_VAR *
2401 find_shell_variable (name)
2402 const char *name;
2404 SHELL_VAR *var;
2406 var = var_lookup (name, shell_variables);
2407 if (var && nameref_p (var))
2408 var = find_variable_nameref (var);
2410 if (var == 0)
2411 return ((SHELL_VAR *)NULL);
2413 return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var);
2416 /* Look up the variable entry named NAME. Returns the entry or NULL. */
2417 SHELL_VAR *
2418 find_variable (name)
2419 const char *name;
2421 SHELL_VAR *v;
2422 int flags;
2424 last_table_searched = 0;
2425 flags = 0;
2426 if (expanding_redir == 0 && (assigning_in_environment || executing_builtin))
2427 flags |= FV_FORCETEMPENV;
2428 v = find_variable_internal (name, flags);
2429 if (v && nameref_p (v))
2430 v = find_variable_nameref (v);
2431 return v;
2434 /* Find the first instance of NAME in the variable context chain; return first
2435 one found without att_invisible set; return 0 if no non-invisible instances
2436 found. */
2437 SHELL_VAR *
2438 find_variable_no_invisible (name)
2439 const char *name;
2441 SHELL_VAR *v;
2442 int flags;
2444 last_table_searched = 0;
2445 flags = FV_SKIPINVISIBLE;
2446 if (expanding_redir == 0 && (assigning_in_environment || executing_builtin))
2447 flags |= FV_FORCETEMPENV;
2448 v = find_variable_internal (name, flags);
2449 if (v && nameref_p (v))
2450 v = find_variable_nameref (v);
2451 return v;
2454 /* Find the first instance of NAME in the variable context chain; return first
2455 one found even if att_invisible set. */
2456 SHELL_VAR *
2457 find_variable_for_assignment (name)
2458 const char *name;
2460 SHELL_VAR *v;
2461 int flags;
2463 last_table_searched = 0;
2464 flags = 0;
2465 if (expanding_redir == 0 && (assigning_in_environment || executing_builtin))
2466 flags |= FV_FORCETEMPENV;
2467 v = find_variable_internal (name, flags);
2468 if (v && nameref_p (v))
2469 v = find_variable_nameref (v);
2470 return v;
2473 SHELL_VAR *
2474 find_variable_noref (name)
2475 const char *name;
2477 SHELL_VAR *v;
2478 int flags;
2480 flags = 0;
2481 if (expanding_redir == 0 && (assigning_in_environment || executing_builtin))
2482 flags |= FV_FORCETEMPENV;
2483 v = find_variable_internal (name, flags);
2484 return v;
2487 /* Look up the function entry whose name matches STRING.
2488 Returns the entry or NULL. */
2489 SHELL_VAR *
2490 find_function (name)
2491 const char *name;
2493 return (hash_lookup (name, shell_functions));
2496 /* Find the function definition for the shell function named NAME. Returns
2497 the entry or NULL. */
2498 FUNCTION_DEF *
2499 find_function_def (name)
2500 const char *name;
2502 #if defined (DEBUGGER)
2503 return ((FUNCTION_DEF *)hash_lookup (name, shell_function_defs));
2504 #else
2505 return ((FUNCTION_DEF *)0);
2506 #endif
2509 /* Return the value of VAR. VAR is assumed to have been the result of a
2510 lookup without any subscript, if arrays are compiled into the shell. */
2511 char *
2512 get_variable_value (var)
2513 SHELL_VAR *var;
2515 if (var == 0)
2516 return ((char *)NULL);
2517 #if defined (ARRAY_VARS)
2518 else if (array_p (var))
2519 return (array_reference (array_cell (var), 0));
2520 else if (assoc_p (var))
2521 return (assoc_reference (assoc_cell (var), "0"));
2522 #endif
2523 else
2524 return (value_cell (var));
2527 /* Return the string value of a variable. Return NULL if the variable
2528 doesn't exist. Don't cons a new string. This is a potential memory
2529 leak if the variable is found in the temporary environment, but doesn't
2530 leak in practice. Since functions and variables have separate name
2531 spaces, returns NULL if var_name is a shell function only. */
2532 char *
2533 get_string_value (var_name)
2534 const char *var_name;
2536 SHELL_VAR *var;
2538 var = find_variable (var_name);
2539 return ((var) ? get_variable_value (var) : (char *)NULL);
2542 /* This is present for use by the tilde and readline libraries. */
2543 char *
2544 sh_get_env_value (v)
2545 const char *v;
2547 return get_string_value (v);
2550 /* **************************************************************** */
2551 /* */
2552 /* Creating and setting variables */
2553 /* */
2554 /* **************************************************************** */
2556 static int
2557 var_sametype (v1, v2)
2558 SHELL_VAR *v1;
2559 SHELL_VAR *v2;
2561 if (v1 == 0 || v2 == 0)
2562 return 0;
2563 #if defined (ARRAY_VARS)
2564 else if (assoc_p (v1) && assoc_p (v2))
2565 return 1;
2566 else if (array_p (v1) && array_p (v2))
2567 return 1;
2568 else if (array_p (v1) || array_p (v2))
2569 return 0;
2570 else if (assoc_p (v1) || assoc_p (v2))
2571 return 0;
2572 #endif
2573 else
2574 return 1;
2578 validate_inherited_value (var, type)
2579 SHELL_VAR *var;
2580 int type;
2582 #if defined (ARRAY_VARS)
2583 if (type == att_array && assoc_p (var))
2584 return 0;
2585 else if (type == att_assoc && array_p (var))
2586 return 0;
2587 else
2588 #endif
2589 return 1; /* should we run convert_var_to_array here or let the caller? */
2592 /* Set NAME to VALUE if NAME has no value. */
2593 SHELL_VAR *
2594 set_if_not (name, value)
2595 char *name, *value;
2597 SHELL_VAR *v;
2599 if (shell_variables == 0)
2600 create_variable_tables ();
2602 v = find_variable (name);
2603 if (v == 0)
2604 v = bind_variable_internal (name, value, global_variables->table, HASH_NOSRCH, 0);
2605 return (v);
2608 /* Create a local variable referenced by NAME. */
2609 SHELL_VAR *
2610 make_local_variable (name, flags)
2611 const char *name;
2612 int flags;
2614 SHELL_VAR *new_var, *old_var, *old_ref;
2615 VAR_CONTEXT *vc;
2616 int was_tmpvar;
2617 char *old_value;
2619 /* We don't want to follow the nameref chain when making local variables; we
2620 just want to create them. */
2621 old_ref = find_variable_noref (name);
2622 if (old_ref && nameref_p (old_ref) == 0)
2623 old_ref = 0;
2624 /* local foo; local foo; is a no-op. */
2625 old_var = find_variable (name);
2626 if (old_ref == 0 && old_var && local_p (old_var) && old_var->context == variable_context)
2627 return (old_var);
2629 /* local -n foo; local -n foo; is a no-op. */
2630 if (old_ref && local_p (old_ref) && old_ref->context == variable_context)
2631 return (old_ref);
2633 /* From here on, we want to use the refvar, not the variable it references */
2634 if (old_ref)
2635 old_var = old_ref;
2637 was_tmpvar = old_var && tempvar_p (old_var);
2638 /* If we're making a local variable in a shell function, the temporary env
2639 has already been merged into the function's variable context stack. We
2640 can assume that a temporary var in the same context appears in the same
2641 VAR_CONTEXT and can safely be returned without creating a new variable
2642 (which results in duplicate names in the same VAR_CONTEXT->table */
2643 /* We can't just test tmpvar_p because variables in the temporary env given
2644 to a shell function appear in the function's local variable VAR_CONTEXT
2645 but retain their tempvar attribute. We want temporary variables that are
2646 found in temporary_env, hence the test for last_table_searched, which is
2647 set in hash_lookup and only (so far) checked here. */
2648 if (was_tmpvar && old_var->context == variable_context && last_table_searched != temporary_env)
2650 VUNSETATTR (old_var, att_invisible); /* XXX */
2651 /* We still want to flag this variable as local, though, and set things
2652 up so that it gets treated as a local variable. */
2653 new_var = old_var;
2654 /* Since we found the variable in a temporary environment, this will
2655 succeed. */
2656 for (vc = shell_variables; vc; vc = vc->down)
2657 if (vc_isfuncenv (vc) && vc->scope == variable_context)
2658 break;
2659 goto set_local_var_flags;
2661 return (old_var);
2664 /* If we want to change to "inherit the old variable's value" semantics,
2665 here is where to save the old value. */
2666 old_value = was_tmpvar ? value_cell (old_var) : (char *)NULL;
2668 for (vc = shell_variables; vc; vc = vc->down)
2669 if (vc_isfuncenv (vc) && vc->scope == variable_context)
2670 break;
2672 if (vc == 0)
2674 internal_error (_("make_local_variable: no function context at current scope"));
2675 return ((SHELL_VAR *)NULL);
2677 else if (vc->table == 0)
2678 vc->table = hash_create (TEMPENV_HASH_BUCKETS);
2680 /* Since this is called only from the local/declare/typeset code, we can
2681 call builtin_error here without worry (of course, it will also work
2682 for anything that sets this_command_name). Variables with the `noassign'
2683 attribute may not be made local. The test against old_var's context
2684 level is to disallow local copies of readonly global variables (since I
2685 believe that this could be a security hole). Readonly copies of calling
2686 function local variables are OK. */
2687 if (old_var && (noassign_p (old_var) ||
2688 (readonly_p (old_var) && old_var->context == 0)))
2690 if (readonly_p (old_var))
2691 sh_readonly (name);
2692 else if (noassign_p (old_var))
2693 builtin_error (_("%s: variable may not be assigned value"), name);
2694 #if 0
2695 /* Let noassign variables through with a warning */
2696 if (readonly_p (old_var))
2697 #endif
2698 return ((SHELL_VAR *)NULL);
2701 if (old_var == 0)
2702 new_var = make_new_variable (name, vc->table);
2703 else
2705 new_var = make_new_variable (name, vc->table);
2707 /* If we found this variable in one of the temporary environments,
2708 inherit its value. Watch to see if this causes problems with
2709 things like `x=4 local x'. XXX - see above for temporary env
2710 variables with the same context level as variable_context */
2711 /* XXX - we should only do this if the variable is not an array. */
2712 /* If we want to change the local variable semantics to "inherit
2713 the old variable's value" here is where to set it. And we would
2714 need to use copy_variable (currently unused) to do it for all
2715 possible variable values. */
2716 if (was_tmpvar)
2717 var_setvalue (new_var, savestring (old_value));
2718 else if (localvar_inherit || (flags & MKLOC_INHERIT))
2720 /* This may not make sense for nameref variables that are shadowing
2721 variables with the same name, but we don't know that yet. */
2722 #if defined (ARRAY_VARS)
2723 if (assoc_p (old_var))
2724 var_setassoc (new_var, assoc_copy (assoc_cell (old_var)));
2725 else if (array_p (old_var))
2726 var_setarray (new_var, array_copy (array_cell (old_var)));
2727 else if (value_cell (old_var))
2728 #else
2729 if (value_cell (old_var))
2730 #endif
2731 var_setvalue (new_var, savestring (value_cell (old_var)));
2732 else
2733 var_setvalue (new_var, (char *)NULL);
2736 if (localvar_inherit || (flags & MKLOC_INHERIT))
2738 /* It doesn't make sense to inherit the nameref attribute */
2739 new_var->attributes = old_var->attributes & ~att_nameref;
2740 new_var->dynamic_value = old_var->dynamic_value;
2741 new_var->assign_func = old_var->assign_func;
2743 else
2744 /* We inherit the export attribute, but no others. */
2745 new_var->attributes = exported_p (old_var) ? att_exported : 0;
2748 set_local_var_flags:
2749 vc->flags |= VC_HASLOCAL;
2751 new_var->context = variable_context;
2752 VSETATTR (new_var, att_local);
2754 if (ifsname (name))
2755 setifs (new_var);
2757 /* value_cell will be 0 if localvar_inherit == 0 or there was no old variable
2758 with the same name or the old variable was invisible */
2759 if (was_tmpvar == 0 && value_cell (new_var) == 0)
2760 VSETATTR (new_var, att_invisible); /* XXX */
2761 return (new_var);
2764 /* Create a new shell variable with name NAME. */
2765 static SHELL_VAR *
2766 new_shell_variable (name)
2767 const char *name;
2769 SHELL_VAR *entry;
2771 entry = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
2773 entry->name = savestring (name);
2774 var_setvalue (entry, (char *)NULL);
2775 CLEAR_EXPORTSTR (entry);
2777 entry->dynamic_value = (sh_var_value_func_t *)NULL;
2778 entry->assign_func = (sh_var_assign_func_t *)NULL;
2780 entry->attributes = 0;
2782 /* Always assume variables are to be made at toplevel!
2783 make_local_variable has the responsibility of changing the
2784 variable context. */
2785 entry->context = 0;
2787 return (entry);
2790 /* Create a new shell variable with name NAME and add it to the hash table
2791 TABLE. */
2792 static SHELL_VAR *
2793 make_new_variable (name, table)
2794 const char *name;
2795 HASH_TABLE *table;
2797 SHELL_VAR *entry;
2798 BUCKET_CONTENTS *elt;
2800 entry = new_shell_variable (name);
2802 /* Make sure we have a shell_variables hash table to add to. */
2803 if (shell_variables == 0)
2804 create_variable_tables ();
2806 elt = hash_insert (savestring (name), table, HASH_NOSRCH);
2807 elt->data = (PTR_T)entry;
2809 return entry;
2812 #if defined (ARRAY_VARS)
2813 SHELL_VAR *
2814 make_new_array_variable (name)
2815 char *name;
2817 SHELL_VAR *entry;
2818 ARRAY *array;
2820 entry = make_new_variable (name, global_variables->table);
2821 array = array_create ();
2823 var_setarray (entry, array);
2824 VSETATTR (entry, att_array);
2825 return entry;
2828 SHELL_VAR *
2829 make_local_array_variable (name, flags)
2830 char *name;
2831 int flags;
2833 SHELL_VAR *var;
2834 ARRAY *array;
2835 int assoc_ok;
2837 assoc_ok = flags & MKLOC_ASSOCOK;
2839 var = make_local_variable (name, flags & MKLOC_INHERIT); /* XXX for now */
2840 /* If ASSOC_OK is non-zero, assume that we are ok with letting an assoc
2841 variable return to the caller without converting it. The caller will
2842 either flag an error or do the conversion itself. */
2843 if (var == 0 || array_p (var) || (assoc_ok && assoc_p (var)))
2844 return var;
2846 /* Validate any value we inherited from a variable instance at a previous
2847 scope and discard anything that's invalid. */
2848 if (localvar_inherit && assoc_p (var))
2850 internal_warning ("%s: cannot inherit value from incompatible type", name);
2851 VUNSETATTR (var, att_assoc);
2852 dispose_variable_value (var);
2853 array = array_create ();
2854 var_setarray (var, array);
2856 else if (localvar_inherit)
2857 var = convert_var_to_array (var); /* XXX */
2858 else
2860 dispose_variable_value (var);
2861 array = array_create ();
2862 var_setarray (var, array);
2865 VSETATTR (var, att_array);
2866 return var;
2869 SHELL_VAR *
2870 make_new_assoc_variable (name)
2871 char *name;
2873 SHELL_VAR *entry;
2874 HASH_TABLE *hash;
2876 entry = make_new_variable (name, global_variables->table);
2877 hash = assoc_create (ASSOC_HASH_BUCKETS);
2879 var_setassoc (entry, hash);
2880 VSETATTR (entry, att_assoc);
2881 return entry;
2884 SHELL_VAR *
2885 make_local_assoc_variable (name, flags)
2886 char *name;
2887 int flags;
2889 SHELL_VAR *var;
2890 HASH_TABLE *hash;
2891 int array_ok;
2893 array_ok = flags & MKLOC_ARRAYOK;
2895 var = make_local_variable (name, flags & MKLOC_INHERIT); /* XXX for now */
2896 /* If ARRAY_OK is non-zero, assume that we are ok with letting an array
2897 variable return to the caller without converting it. The caller will
2898 either flag an error or do the conversion itself. */
2899 if (var == 0 || assoc_p (var) || (array_ok && array_p (var)))
2900 return var;
2902 /* Validate any value we inherited from a variable instance at a previous
2903 scope and discard anything that's invalid. */
2904 if (localvar_inherit && array_p (var))
2906 internal_warning ("%s: cannot inherit value from incompatible type", name);
2907 VUNSETATTR (var, att_array);
2908 dispose_variable_value (var);
2909 hash = assoc_create (ASSOC_HASH_BUCKETS);
2910 var_setassoc (var, hash);
2912 else if (localvar_inherit)
2913 var = convert_var_to_assoc (var); /* XXX */
2914 else
2916 dispose_variable_value (var);
2917 hash = assoc_create (ASSOC_HASH_BUCKETS);
2918 var_setassoc (var, hash);
2921 VSETATTR (var, att_assoc);
2922 return var;
2924 #endif
2926 char *
2927 make_variable_value (var, value, flags)
2928 SHELL_VAR *var;
2929 char *value;
2930 int flags;
2932 char *retval, *oval;
2933 intmax_t lval, rval;
2934 int expok, olen, op;
2936 /* If this variable has had its type set to integer (via `declare -i'),
2937 then do expression evaluation on it and store the result. The
2938 functions in expr.c (evalexp()) and bind_int_variable() are responsible
2939 for turning off the integer flag if they don't want further
2940 evaluation done. Callers that find it inconvenient to do this can set
2941 the ASS_NOEVAL flag. For the special case of arithmetic expression
2942 evaluation, the caller can set ASS_NOLONGJMP to avoid jumping out to
2943 top_level. */
2944 if ((flags & ASS_NOEVAL) == 0 && integer_p (var))
2946 if (flags & ASS_APPEND)
2948 oval = value_cell (var);
2949 lval = evalexp (oval, 0, &expok); /* ksh93 seems to do this */
2950 if (expok == 0)
2952 if (flags & ASS_NOLONGJMP)
2953 goto make_value;
2954 else
2956 top_level_cleanup ();
2957 jump_to_top_level (DISCARD);
2961 rval = evalexp (value, 0, &expok);
2962 if (expok == 0)
2964 if (flags & ASS_NOLONGJMP)
2965 goto make_value;
2966 else
2968 top_level_cleanup ();
2969 jump_to_top_level (DISCARD);
2972 /* This can be fooled if the variable's value changes while evaluating
2973 `rval'. We can change it if we move the evaluation of lval to here. */
2974 if (flags & ASS_APPEND)
2975 rval += lval;
2976 retval = itos (rval);
2978 #if defined (CASEMOD_ATTRS)
2979 else if ((flags & ASS_NOEVAL) == 0 && (capcase_p (var) || uppercase_p (var) || lowercase_p (var)))
2981 if (flags & ASS_APPEND)
2983 oval = get_variable_value (var);
2984 if (oval == 0) /* paranoia */
2985 oval = "";
2986 olen = STRLEN (oval);
2987 retval = (char *)xmalloc (olen + (value ? STRLEN (value) : 0) + 1);
2988 strcpy (retval, oval);
2989 if (value)
2990 strcpy (retval+olen, value);
2992 else if (*value)
2993 retval = savestring (value);
2994 else
2996 retval = (char *)xmalloc (1);
2997 retval[0] = '\0';
2999 op = capcase_p (var) ? CASE_CAPITALIZE
3000 : (uppercase_p (var) ? CASE_UPPER : CASE_LOWER);
3001 oval = sh_modcase (retval, (char *)0, op);
3002 free (retval);
3003 retval = oval;
3005 #endif /* CASEMOD_ATTRS */
3006 else if (value)
3008 make_value:
3009 if (flags & ASS_APPEND)
3011 oval = get_variable_value (var);
3012 if (oval == 0) /* paranoia */
3013 oval = "";
3014 olen = STRLEN (oval);
3015 retval = (char *)xmalloc (olen + (value ? STRLEN (value) : 0) + 1);
3016 strcpy (retval, oval);
3017 if (value)
3018 strcpy (retval+olen, value);
3020 else if (*value)
3021 retval = savestring (value);
3022 else
3024 retval = (char *)xmalloc (1);
3025 retval[0] = '\0';
3028 else
3029 retval = (char *)NULL;
3031 return retval;
3034 /* If we can optimize appending to string variables, say so */
3035 static int
3036 can_optimize_assignment (entry, value, aflags)
3037 SHELL_VAR *entry;
3038 char *value;
3039 int aflags;
3041 if ((aflags & ASS_APPEND) == 0)
3042 return 0;
3043 #if defined (ARRAY_VARS)
3044 if (array_p (entry) || assoc_p (entry))
3045 return 0;
3046 #endif
3047 if (integer_p (entry) || uppercase_p (entry) || lowercase_p (entry) || capcase_p (entry))
3048 return 0;
3049 if (readonly_p (entry) || noassign_p (entry))
3050 return 0;
3051 return 1;
3054 /* right now we optimize appends to string variables */
3055 static SHELL_VAR *
3056 optimized_assignment (entry, value, aflags)
3057 SHELL_VAR *entry;
3058 char *value;
3059 int aflags;
3061 size_t len, vlen;
3062 char *v, *new;
3064 v = value_cell (entry);
3065 len = STRLEN (v);
3066 vlen = STRLEN (value);
3068 new = (char *)xrealloc (v, len + vlen + 8); /* for now */
3069 if (vlen == 1)
3071 new[len] = *value;
3072 new[len+1] = '\0';
3074 else
3075 strcpy (new + len, value);
3076 var_setvalue (entry, new);
3077 return entry;
3080 /* Bind a variable NAME to VALUE in the HASH_TABLE TABLE, which may be the
3081 temporary environment (but usually is not). HFLAGS controls how NAME
3082 is looked up in TABLE; AFLAGS controls how VALUE is assigned */
3083 static SHELL_VAR *
3084 bind_variable_internal (name, value, table, hflags, aflags)
3085 const char *name;
3086 char *value;
3087 HASH_TABLE *table;
3088 int hflags, aflags;
3090 char *newval, *tname;
3091 SHELL_VAR *entry, *tentry;
3093 entry = (hflags & HASH_NOSRCH) ? (SHELL_VAR *)NULL : hash_lookup (name, table);
3094 /* Follow the nameref chain here if this is the global variables table */
3095 if (entry && nameref_p (entry) && (invisible_p (entry) == 0) && table == global_variables->table)
3097 entry = find_global_variable (entry->name);
3098 /* Let's see if we have a nameref referencing a variable that hasn't yet
3099 been created. */
3100 if (entry == 0)
3101 entry = find_variable_last_nameref (name, 0); /* XXX */
3102 if (entry == 0) /* just in case */
3103 return (entry);
3106 /* The first clause handles `declare -n ref; ref=x;' or `declare -n ref;
3107 declare -n ref' */
3108 if (entry && invisible_p (entry) && nameref_p (entry))
3110 if ((aflags & ASS_FORCE) == 0 && value && valid_nameref_value (value, 0) == 0)
3112 sh_invalidid (value);
3113 return ((SHELL_VAR *)NULL);
3115 goto assign_value;
3117 else if (entry && nameref_p (entry))
3119 newval = nameref_cell (entry); /* XXX - newval can't be NULL here */
3120 if (valid_nameref_value (newval, 0) == 0)
3122 sh_invalidid (newval);
3123 return ((SHELL_VAR *)NULL);
3125 #if defined (ARRAY_VARS)
3126 /* declare -n foo=x[2] ; foo=bar */
3127 if (valid_array_reference (newval, 0))
3129 tname = array_variable_name (newval, 0, (char **)0, (int *)0);
3130 if (tname && (tentry = find_variable_noref (tname)) && nameref_p (tentry))
3132 /* nameref variables can't be arrays */
3133 internal_warning (_("%s: removing nameref attribute"), name_cell (tentry));
3134 FREE (value_cell (tentry)); /* XXX - bush-4.3 compat */
3135 var_setvalue (tentry, (char *)NULL);
3136 VUNSETATTR (tentry, att_nameref);
3138 free (tname);
3139 /* XXX - should it be aflags? */
3140 entry = assign_array_element (newval, make_variable_value (entry, value, aflags), aflags|ASS_NAMEREF);
3141 if (entry == 0)
3142 return entry;
3144 else
3145 #endif
3147 entry = make_new_variable (newval, table);
3148 var_setvalue (entry, make_variable_value (entry, value, aflags));
3151 else if (entry == 0)
3153 entry = make_new_variable (name, table);
3154 var_setvalue (entry, make_variable_value (entry, value, aflags)); /* XXX */
3156 else if (entry->assign_func) /* array vars have assign functions now */
3158 if ((readonly_p (entry) && (aflags & ASS_FORCE) == 0) || noassign_p (entry))
3160 if (readonly_p (entry))
3161 err_readonly (name_cell (entry));
3162 return (entry);
3165 INVALIDATE_EXPORTSTR (entry);
3166 newval = (aflags & ASS_APPEND) ? make_variable_value (entry, value, aflags) : value;
3167 if (assoc_p (entry))
3168 entry = (*(entry->assign_func)) (entry, newval, -1, savestring ("0"));
3169 else if (array_p (entry))
3170 entry = (*(entry->assign_func)) (entry, newval, 0, 0);
3171 else
3172 entry = (*(entry->assign_func)) (entry, newval, -1, 0);
3173 if (newval != value)
3174 free (newval);
3175 return (entry);
3177 else
3179 assign_value:
3180 if ((readonly_p (entry) && (aflags & ASS_FORCE) == 0) || noassign_p (entry))
3182 if (readonly_p (entry))
3183 err_readonly (name_cell (entry));
3184 return (entry);
3187 /* Variables which are bound are visible. */
3188 VUNSETATTR (entry, att_invisible);
3190 /* If we can optimize the assignment, do so and return. Right now, we
3191 optimize appends to string variables. */
3192 if (can_optimize_assignment (entry, value, aflags))
3194 INVALIDATE_EXPORTSTR (entry);
3195 optimized_assignment (entry, value, aflags);
3197 if (mark_modified_vars)
3198 VSETATTR (entry, att_exported);
3200 if (exported_p (entry))
3201 array_needs_making = 1;
3203 return (entry);
3206 #if defined (ARRAY_VARS)
3207 if (assoc_p (entry) || array_p (entry))
3208 newval = make_array_variable_value (entry, 0, "0", value, aflags);
3209 else
3210 #endif
3211 newval = make_variable_value (entry, value, aflags); /* XXX */
3213 /* Invalidate any cached export string */
3214 INVALIDATE_EXPORTSTR (entry);
3216 #if defined (ARRAY_VARS)
3217 /* XXX -- this bears looking at again -- XXX */
3218 /* If an existing array variable x is being assigned to with x=b or
3219 `read x' or something of that nature, silently convert it to
3220 x[0]=b or `read x[0]'. */
3221 if (assoc_p (entry))
3223 assoc_insert (assoc_cell (entry), savestring ("0"), newval);
3224 free (newval);
3226 else if (array_p (entry))
3228 array_insert (array_cell (entry), 0, newval);
3229 free (newval);
3231 else
3232 #endif
3234 FREE (value_cell (entry));
3235 var_setvalue (entry, newval);
3239 if (mark_modified_vars)
3240 VSETATTR (entry, att_exported);
3242 if (exported_p (entry))
3243 array_needs_making = 1;
3245 return (entry);
3248 /* Bind a variable NAME to VALUE. This conses up the name
3249 and value strings. If we have a temporary environment, we bind there
3250 first, then we bind into shell_variables. */
3252 SHELL_VAR *
3253 bind_variable (name, value, flags)
3254 const char *name;
3255 char *value;
3256 int flags;
3258 SHELL_VAR *v, *nv;
3259 VAR_CONTEXT *vc, *nvc;
3261 if (shell_variables == 0)
3262 create_variable_tables ();
3264 /* If we have a temporary environment, look there first for the variable,
3265 and, if found, modify the value there before modifying it in the
3266 shell_variables table. This allows sourced scripts to modify values
3267 given to them in a temporary environment while modifying the variable
3268 value that the caller sees. */
3269 if (temporary_env && value) /* XXX - can value be null here? */
3270 bind_tempenv_variable (name, value);
3272 /* XXX -- handle local variables here. */
3273 for (vc = shell_variables; vc; vc = vc->down)
3275 if (vc_isfuncenv (vc) || vc_isbltnenv (vc))
3277 v = hash_lookup (name, vc->table);
3278 nvc = vc;
3279 if (v && nameref_p (v))
3281 /* This starts at the context where we found the nameref. If we
3282 want to start the name resolution over again at the original
3283 context, this is where we need to change it */
3284 nv = find_variable_nameref_context (v, vc, &nvc);
3285 if (nv == 0)
3287 nv = find_variable_last_nameref_context (v, vc, &nvc);
3288 if (nv && nameref_p (nv))
3290 /* If this nameref variable doesn't have a value yet,
3291 set the value. Otherwise, assign using the value as
3292 normal. */
3293 if (nameref_cell (nv) == 0)
3294 return (bind_variable_internal (nv->name, value, nvc->table, 0, flags));
3295 #if defined (ARRAY_VARS)
3296 else if (valid_array_reference (nameref_cell (nv), 0))
3297 return (assign_array_element (nameref_cell (nv), value, flags));
3298 else
3299 #endif
3300 return (bind_variable_internal (nameref_cell (nv), value, nvc->table, 0, flags));
3302 else if (nv == &nameref_maxloop_value)
3304 internal_warning (_("%s: circular name reference"), v->name);
3305 return (bind_global_variable (v->name, value, flags));
3307 else
3308 v = nv;
3310 else if (nv == &nameref_maxloop_value)
3312 internal_warning (_("%s: circular name reference"), v->name);
3313 return (bind_global_variable (v->name, value, flags));
3315 else
3316 v = nv;
3318 if (v)
3319 return (bind_variable_internal (v->name, value, nvc->table, 0, flags));
3322 /* bind_variable_internal will handle nameref resolution in this case */
3323 return (bind_variable_internal (name, value, global_variables->table, 0, flags));
3326 SHELL_VAR *
3327 bind_global_variable (name, value, flags)
3328 const char *name;
3329 char *value;
3330 int flags;
3332 if (shell_variables == 0)
3333 create_variable_tables ();
3335 /* bind_variable_internal will handle nameref resolution in this case */
3336 return (bind_variable_internal (name, value, global_variables->table, 0, flags));
3339 static SHELL_VAR *
3340 bind_invalid_envvar (name, value, flags)
3341 const char *name;
3342 char *value;
3343 int flags;
3345 if (invalid_env == 0)
3346 invalid_env = hash_create (64); /* XXX */
3347 return (bind_variable_internal (name, value, invalid_env, HASH_NOSRCH, flags));
3350 /* Make VAR, a simple shell variable, have value VALUE. Once assigned a
3351 value, variables are no longer invisible. This is a duplicate of part
3352 of the internals of bind_variable. If the variable is exported, or
3353 all modified variables should be exported, mark the variable for export
3354 and note that the export environment needs to be recreated. */
3355 SHELL_VAR *
3356 bind_variable_value (var, value, aflags)
3357 SHELL_VAR *var;
3358 char *value;
3359 int aflags;
3361 char *t;
3362 int invis;
3364 invis = invisible_p (var);
3365 VUNSETATTR (var, att_invisible);
3367 if (var->assign_func)
3369 /* If we're appending, we need the old value, so use
3370 make_variable_value */
3371 t = (aflags & ASS_APPEND) ? make_variable_value (var, value, aflags) : value;
3372 (*(var->assign_func)) (var, t, -1, 0);
3373 if (t != value && t)
3374 free (t);
3376 else
3378 t = make_variable_value (var, value, aflags);
3379 if ((aflags & (ASS_NAMEREF|ASS_FORCE)) == ASS_NAMEREF && check_selfref (name_cell (var), t, 0))
3381 if (variable_context)
3382 internal_warning (_("%s: circular name reference"), name_cell (var));
3383 else
3385 internal_error (_("%s: nameref variable self references not allowed"), name_cell (var));
3386 free (t);
3387 if (invis)
3388 VSETATTR (var, att_invisible); /* XXX */
3389 return ((SHELL_VAR *)NULL);
3392 if ((aflags & ASS_NAMEREF) && (valid_nameref_value (t, 0) == 0))
3394 free (t);
3395 if (invis)
3396 VSETATTR (var, att_invisible); /* XXX */
3397 return ((SHELL_VAR *)NULL);
3399 FREE (value_cell (var));
3400 var_setvalue (var, t);
3403 INVALIDATE_EXPORTSTR (var);
3405 if (mark_modified_vars)
3406 VSETATTR (var, att_exported);
3408 if (exported_p (var))
3409 array_needs_making = 1;
3411 return (var);
3414 /* Bind/create a shell variable with the name LHS to the RHS.
3415 This creates or modifies a variable such that it is an integer.
3417 This used to be in expr.c, but it is here so that all of the
3418 variable binding stuff is localized. Since we don't want any
3419 recursive evaluation from bind_variable() (possible without this code,
3420 since bind_variable() calls the evaluator for variables with the integer
3421 attribute set), we temporarily turn off the integer attribute for each
3422 variable we set here, then turn it back on after binding as necessary. */
3424 SHELL_VAR *
3425 bind_int_variable (lhs, rhs, flags)
3426 char *lhs, *rhs;
3427 int flags;
3429 register SHELL_VAR *v;
3430 int isint, isarr, implicitarray;
3432 isint = isarr = implicitarray = 0;
3433 #if defined (ARRAY_VARS)
3434 if (valid_array_reference (lhs, (flags & ASS_NOEXPAND) != 0))
3436 isarr = 1;
3437 v = array_variable_part (lhs, (flags & ASS_NOEXPAND) != 0, (char **)0, (int *)0);
3439 else if (legal_identifier (lhs) == 0)
3441 sh_invalidid (lhs);
3442 return ((SHELL_VAR *)NULL);
3444 else
3445 #endif
3446 v = find_variable (lhs);
3448 if (v)
3450 isint = integer_p (v);
3451 VUNSETATTR (v, att_integer);
3452 #if defined (ARRAY_VARS)
3453 if (array_p (v) && isarr == 0)
3454 implicitarray = 1;
3455 #endif
3458 #if defined (ARRAY_VARS)
3459 if (isarr)
3460 v = assign_array_element (lhs, rhs, flags);
3461 else if (implicitarray)
3462 v = bind_array_variable (lhs, 0, rhs, 0); /* XXX - check on flags */
3463 else
3464 #endif
3465 v = bind_variable (lhs, rhs, 0); /* why not use bind_variable_value? */
3467 if (v)
3469 if (isint)
3470 VSETATTR (v, att_integer);
3471 VUNSETATTR (v, att_invisible);
3474 if (v && nameref_p (v))
3475 internal_warning (_("%s: assigning integer to name reference"), lhs);
3477 return (v);
3480 SHELL_VAR *
3481 bind_var_to_int (var, val)
3482 char *var;
3483 intmax_t val;
3485 char ibuf[INT_STRLEN_BOUND (intmax_t) + 1], *p;
3487 p = fmtulong (val, 10, ibuf, sizeof (ibuf), 0);
3488 return (bind_int_variable (var, p, 0));
3491 /* Do a function binding to a variable. You pass the name and
3492 the command to bind to. This conses the name and command. */
3493 SHELL_VAR *
3494 bind_function (name, value)
3495 const char *name;
3496 COMMAND *value;
3498 SHELL_VAR *entry;
3500 entry = find_function (name);
3501 if (entry == 0)
3503 BUCKET_CONTENTS *elt;
3505 elt = hash_insert (savestring (name), shell_functions, HASH_NOSRCH);
3506 entry = new_shell_variable (name);
3507 elt->data = (PTR_T)entry;
3509 else
3510 INVALIDATE_EXPORTSTR (entry);
3512 if (var_isset (entry))
3513 dispose_command (function_cell (entry));
3515 if (value)
3516 var_setfunc (entry, copy_command (value));
3517 else
3518 var_setfunc (entry, 0);
3520 VSETATTR (entry, att_function);
3522 if (mark_modified_vars)
3523 VSETATTR (entry, att_exported);
3525 VUNSETATTR (entry, att_invisible); /* Just to be sure */
3527 if (exported_p (entry))
3528 array_needs_making = 1;
3530 #if defined (PROGRAMMABLE_COMPLETION)
3531 set_itemlist_dirty (&it_functions);
3532 #endif
3534 return (entry);
3537 #if defined (DEBUGGER)
3538 /* Bind a function definition, which includes source file and line number
3539 information in addition to the command, into the FUNCTION_DEF hash table.
3540 If (FLAGS & 1), overwrite any existing definition. If FLAGS == 0, leave
3541 any existing definition alone. */
3542 void
3543 bind_function_def (name, value, flags)
3544 const char *name;
3545 FUNCTION_DEF *value;
3546 int flags;
3548 FUNCTION_DEF *entry;
3549 BUCKET_CONTENTS *elt;
3550 COMMAND *cmd;
3552 entry = find_function_def (name);
3553 if (entry && (flags & 1))
3555 dispose_function_def_contents (entry);
3556 entry = copy_function_def_contents (value, entry);
3558 else if (entry)
3559 return;
3560 else
3562 cmd = value->command;
3563 value->command = 0;
3564 entry = copy_function_def (value);
3565 value->command = cmd;
3567 elt = hash_insert (savestring (name), shell_function_defs, HASH_NOSRCH);
3568 elt->data = (PTR_T *)entry;
3571 #endif /* DEBUGGER */
3573 /* Add STRING, which is of the form foo=bar, to the temporary environment
3574 HASH_TABLE (temporary_env). The functions in execute_cmd.c are
3575 responsible for moving the main temporary env to one of the other
3576 temporary environments. The expansion code in subst.c calls this. */
3578 assign_in_env (word, flags)
3579 WORD_DESC *word;
3580 int flags;
3582 int offset, aflags;
3583 char *name, *temp, *value, *newname;
3584 SHELL_VAR *var;
3585 const char *string;
3587 string = word->word;
3589 aflags = 0;
3590 offset = assignment (string, 0);
3591 newname = name = savestring (string);
3592 value = (char *)NULL;
3594 if (name[offset] == '=')
3596 name[offset] = 0;
3598 /* don't ignore the `+' when assigning temporary environment */
3599 if (name[offset - 1] == '+')
3601 name[offset - 1] = '\0';
3602 aflags |= ASS_APPEND;
3605 if (legal_identifier (name) == 0)
3607 sh_invalidid (name);
3608 return (0);
3611 var = find_variable (name);
3612 if (var == 0)
3614 var = find_variable_last_nameref (name, 1);
3615 /* If we're assigning a value to a nameref variable in the temp
3616 environment, and the value of the nameref is valid for assignment,
3617 but the variable does not already exist, assign to the nameref
3618 target and add the target to the temporary environment. This is
3619 what ksh93 does */
3620 /* We use 2 in the call to valid_nameref_value because we don't want
3621 to allow array references here at all (newname will be used to
3622 create a variable directly below) */
3623 if (var && nameref_p (var) && valid_nameref_value (nameref_cell (var), 2))
3625 newname = nameref_cell (var);
3626 var = 0; /* don't use it for append */
3629 else
3630 newname = name_cell (var); /* no-op if not nameref */
3632 if (var && (readonly_p (var) || noassign_p (var)))
3634 if (readonly_p (var))
3635 err_readonly (name);
3636 free (name);
3637 return (0);
3639 temp = name + offset + 1;
3641 value = expand_assignment_string_to_string (temp, 0);
3643 if (var && (aflags & ASS_APPEND))
3645 if (value == 0)
3647 value = (char *)xmalloc (1); /* like do_assignment_internal */
3648 value[0] = '\0';
3650 temp = make_variable_value (var, value, aflags);
3651 FREE (value);
3652 value = temp;
3656 if (temporary_env == 0)
3657 temporary_env = hash_create (TEMPENV_HASH_BUCKETS);
3659 var = hash_lookup (newname, temporary_env);
3660 if (var == 0)
3661 var = make_new_variable (newname, temporary_env);
3662 else
3663 FREE (value_cell (var));
3665 if (value == 0)
3667 value = (char *)xmalloc (1); /* see above */
3668 value[0] = '\0';
3671 var_setvalue (var, value);
3672 var->attributes |= (att_exported|att_tempvar);
3673 var->context = variable_context; /* XXX */
3675 INVALIDATE_EXPORTSTR (var);
3676 var->exportstr = mk_env_string (newname, value, 0);
3678 array_needs_making = 1;
3680 if (flags)
3682 if (STREQ (newname, "POSIXLY_CORRECT") || STREQ (newname, "POSIX_PEDANDTIC"))
3683 save_posix_options (); /* XXX one level of saving right now */
3684 stupidly_hack_special_variables (newname);
3687 if (echo_command_at_execute)
3688 /* The Korn shell prints the `+ ' in front of assignment statements,
3689 so we do too. */
3690 xtrace_print_assignment (name, value, 0, 1);
3692 free (name);
3693 return 1;
3696 /* **************************************************************** */
3697 /* */
3698 /* Copying variables */
3699 /* */
3700 /* **************************************************************** */
3702 #ifdef INCLUDE_UNUSED
3703 /* Copy VAR to a new data structure and return that structure. */
3704 SHELL_VAR *
3705 copy_variable (var)
3706 SHELL_VAR *var;
3708 SHELL_VAR *copy = (SHELL_VAR *)NULL;
3710 if (var)
3712 copy = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
3714 copy->attributes = var->attributes;
3715 copy->name = savestring (var->name);
3717 if (function_p (var))
3718 var_setfunc (copy, copy_command (function_cell (var)));
3719 #if defined (ARRAY_VARS)
3720 else if (array_p (var))
3721 var_setarray (copy, array_copy (array_cell (var)));
3722 else if (assoc_p (var))
3723 var_setassoc (copy, assoc_copy (assoc_cell (var)));
3724 #endif
3725 else if (nameref_cell (var)) /* XXX - nameref */
3726 var_setref (copy, savestring (nameref_cell (var)));
3727 else if (value_cell (var)) /* XXX - nameref */
3728 var_setvalue (copy, savestring (value_cell (var)));
3729 else
3730 var_setvalue (copy, (char *)NULL);
3732 copy->dynamic_value = var->dynamic_value;
3733 copy->assign_func = var->assign_func;
3735 copy->exportstr = COPY_EXPORTSTR (var);
3737 copy->context = var->context;
3739 return (copy);
3741 #endif
3743 /* **************************************************************** */
3744 /* */
3745 /* Deleting and unsetting variables */
3746 /* */
3747 /* **************************************************************** */
3749 /* Dispose of the information attached to VAR. */
3750 static void
3751 dispose_variable_value (var)
3752 SHELL_VAR *var;
3754 if (function_p (var))
3755 dispose_command (function_cell (var));
3756 #if defined (ARRAY_VARS)
3757 else if (array_p (var))
3758 array_dispose (array_cell (var));
3759 else if (assoc_p (var))
3760 assoc_dispose (assoc_cell (var));
3761 #endif
3762 else if (nameref_p (var))
3763 FREE (nameref_cell (var));
3764 else
3765 FREE (value_cell (var));
3768 void
3769 dispose_variable (var)
3770 SHELL_VAR *var;
3772 if (var == 0)
3773 return;
3775 if (nofree_p (var) == 0)
3776 dispose_variable_value (var);
3778 FREE_EXPORTSTR (var);
3780 free (var->name);
3782 if (exported_p (var))
3783 array_needs_making = 1;
3785 free (var);
3788 /* Unset the shell variable referenced by NAME. Unsetting a nameref variable
3789 unsets the variable it resolves to but leaves the nameref alone. */
3791 unbind_variable (name)
3792 const char *name;
3794 SHELL_VAR *v, *nv;
3795 int r;
3797 v = var_lookup (name, shell_variables);
3798 nv = (v && nameref_p (v)) ? find_variable_nameref (v) : (SHELL_VAR *)NULL;
3800 r = nv ? makunbound (nv->name, shell_variables) : makunbound (name, shell_variables);
3801 return r;
3804 /* Unbind NAME, where NAME is assumed to be a nameref variable */
3806 unbind_nameref (name)
3807 const char *name;
3809 SHELL_VAR *v;
3811 v = var_lookup (name, shell_variables);
3812 if (v && nameref_p (v))
3813 return makunbound (name, shell_variables);
3814 return 0;
3817 /* Unbind the first instance of NAME, whether it's a nameref or not */
3819 unbind_variable_noref (name)
3820 const char *name;
3822 SHELL_VAR *v;
3824 v = var_lookup (name, shell_variables);
3825 if (v)
3826 return makunbound (name, shell_variables);
3827 return 0;
3831 check_unbind_variable (name)
3832 const char *name;
3834 SHELL_VAR *v;
3836 v = find_variable (name);
3837 if (v && readonly_p (v))
3839 internal_error (_("%s: cannot unset: readonly %s"), name, "variable");
3840 return -2;
3842 else if (v && non_unsettable_p (v))
3844 internal_error (_("%s: cannot unset"), name);
3845 return -2;
3847 return (unbind_variable (name));
3850 /* Unset the shell function named NAME. */
3852 unbind_func (name)
3853 const char *name;
3855 BUCKET_CONTENTS *elt;
3856 SHELL_VAR *func;
3858 elt = hash_remove (name, shell_functions, 0);
3860 if (elt == 0)
3861 return -1;
3863 #if defined (PROGRAMMABLE_COMPLETION)
3864 set_itemlist_dirty (&it_functions);
3865 #endif
3867 func = (SHELL_VAR *)elt->data;
3868 if (func)
3870 if (exported_p (func))
3871 array_needs_making++;
3872 dispose_variable (func);
3875 free (elt->key);
3876 free (elt);
3878 return 0;
3881 #if defined (DEBUGGER)
3883 unbind_function_def (name)
3884 const char *name;
3886 BUCKET_CONTENTS *elt;
3887 FUNCTION_DEF *funcdef;
3889 elt = hash_remove (name, shell_function_defs, 0);
3891 if (elt == 0)
3892 return -1;
3894 funcdef = (FUNCTION_DEF *)elt->data;
3895 if (funcdef)
3896 dispose_function_def (funcdef);
3898 free (elt->key);
3899 free (elt);
3901 return 0;
3903 #endif /* DEBUGGER */
3906 delete_var (name, vc)
3907 const char *name;
3908 VAR_CONTEXT *vc;
3910 BUCKET_CONTENTS *elt;
3911 SHELL_VAR *old_var;
3912 VAR_CONTEXT *v;
3914 for (elt = (BUCKET_CONTENTS *)NULL, v = vc; v; v = v->down)
3915 if (elt = hash_remove (name, v->table, 0))
3916 break;
3918 if (elt == 0)
3919 return (-1);
3921 old_var = (SHELL_VAR *)elt->data;
3922 free (elt->key);
3923 free (elt);
3925 dispose_variable (old_var);
3926 return (0);
3929 /* Make the variable associated with NAME go away. HASH_LIST is the
3930 hash table from which this variable should be deleted (either
3931 shell_variables or shell_functions).
3932 Returns non-zero if the variable couldn't be found. */
3934 makunbound (name, vc)
3935 const char *name;
3936 VAR_CONTEXT *vc;
3938 BUCKET_CONTENTS *elt, *new_elt;
3939 SHELL_VAR *old_var;
3940 VAR_CONTEXT *v;
3941 char *t;
3943 for (elt = (BUCKET_CONTENTS *)NULL, v = vc; v; v = v->down)
3944 if (elt = hash_remove (name, v->table, 0))
3945 break;
3947 if (elt == 0)
3948 return (-1);
3950 old_var = (SHELL_VAR *)elt->data;
3952 if (old_var && exported_p (old_var))
3953 array_needs_making++;
3955 /* If we're unsetting a local variable and we're still executing inside
3956 the function, just mark the variable as invisible. The function
3957 eventually called by pop_var_context() will clean it up later. This
3958 must be done so that if the variable is subsequently assigned a new
3959 value inside the function, the `local' attribute is still present.
3960 We also need to add it back into the correct hash table. */
3961 if (old_var && local_p (old_var) &&
3962 (old_var->context == variable_context || (localvar_unset && old_var->context < variable_context)))
3964 if (nofree_p (old_var))
3965 var_setvalue (old_var, (char *)NULL);
3966 #if defined (ARRAY_VARS)
3967 else if (array_p (old_var))
3968 array_dispose (array_cell (old_var));
3969 else if (assoc_p (old_var))
3970 assoc_dispose (assoc_cell (old_var));
3971 #endif
3972 else if (nameref_p (old_var))
3973 FREE (nameref_cell (old_var));
3974 else
3975 FREE (value_cell (old_var));
3976 /* Reset the attributes. Preserve the export attribute if the variable
3977 came from a temporary environment. Make sure it stays local, and
3978 make it invisible. */
3979 old_var->attributes = (exported_p (old_var) && tempvar_p (old_var)) ? att_exported : 0;
3980 VSETATTR (old_var, att_local);
3981 VSETATTR (old_var, att_invisible);
3982 var_setvalue (old_var, (char *)NULL);
3983 INVALIDATE_EXPORTSTR (old_var);
3985 new_elt = hash_insert (savestring (old_var->name), v->table, 0);
3986 new_elt->data = (PTR_T)old_var;
3987 stupidly_hack_special_variables (old_var->name);
3989 free (elt->key);
3990 free (elt);
3991 return (0);
3994 /* Have to save a copy of name here, because it might refer to
3995 old_var->name. If so, stupidly_hack_special_variables will
3996 reference freed memory. */
3997 t = savestring (name);
3999 free (elt->key);
4000 free (elt);
4002 dispose_variable (old_var);
4003 stupidly_hack_special_variables (t);
4004 free (t);
4006 return (0);
4009 /* Get rid of all of the variables in the current context. */
4010 void
4011 kill_all_local_variables ()
4013 VAR_CONTEXT *vc;
4015 for (vc = shell_variables; vc; vc = vc->down)
4016 if (vc_isfuncenv (vc) && vc->scope == variable_context)
4017 break;
4018 if (vc == 0)
4019 return; /* XXX */
4021 if (vc->table && vc_haslocals (vc))
4023 delete_all_variables (vc->table);
4024 hash_dispose (vc->table);
4026 vc->table = (HASH_TABLE *)NULL;
4029 static void
4030 free_variable_hash_data (data)
4031 PTR_T data;
4033 SHELL_VAR *var;
4035 var = (SHELL_VAR *)data;
4036 dispose_variable (var);
4039 /* Delete the entire contents of the hash table. */
4040 void
4041 delete_all_variables (hashed_vars)
4042 HASH_TABLE *hashed_vars;
4044 hash_flush (hashed_vars, free_variable_hash_data);
4047 /* **************************************************************** */
4048 /* */
4049 /* Setting variable attributes */
4050 /* */
4051 /* **************************************************************** */
4053 #define FIND_OR_MAKE_VARIABLE(name, entry) \
4054 do \
4056 entry = find_variable (name); \
4057 if (!entry) \
4059 entry = bind_variable (name, "", 0); \
4060 if (entry) entry->attributes |= att_invisible; \
4063 while (0)
4065 /* Make the variable associated with NAME be readonly.
4066 If NAME does not exist yet, create it. */
4067 void
4068 set_var_read_only (name)
4069 char *name;
4071 SHELL_VAR *entry;
4073 FIND_OR_MAKE_VARIABLE (name, entry);
4074 VSETATTR (entry, att_readonly);
4077 #ifdef INCLUDE_UNUSED
4078 /* Make the function associated with NAME be readonly.
4079 If NAME does not exist, we just punt, like auto_export code below. */
4080 void
4081 set_func_read_only (name)
4082 const char *name;
4084 SHELL_VAR *entry;
4086 entry = find_function (name);
4087 if (entry)
4088 VSETATTR (entry, att_readonly);
4091 /* Make the variable associated with NAME be auto-exported.
4092 If NAME does not exist yet, create it. */
4093 void
4094 set_var_auto_export (name)
4095 char *name;
4097 SHELL_VAR *entry;
4099 FIND_OR_MAKE_VARIABLE (name, entry);
4100 set_auto_export (entry);
4103 /* Make the function associated with NAME be auto-exported. */
4104 void
4105 set_func_auto_export (name)
4106 const char *name;
4108 SHELL_VAR *entry;
4110 entry = find_function (name);
4111 if (entry)
4112 set_auto_export (entry);
4114 #endif
4116 /* **************************************************************** */
4117 /* */
4118 /* Creating lists of variables */
4119 /* */
4120 /* **************************************************************** */
4122 static VARLIST *
4123 vlist_alloc (nentries)
4124 int nentries;
4126 VARLIST *vlist;
4128 vlist = (VARLIST *)xmalloc (sizeof (VARLIST));
4129 vlist->list = (SHELL_VAR **)xmalloc ((nentries + 1) * sizeof (SHELL_VAR *));
4130 vlist->list_size = nentries;
4131 vlist->list_len = 0;
4132 vlist->list[0] = (SHELL_VAR *)NULL;
4134 return vlist;
4137 static VARLIST *
4138 vlist_realloc (vlist, n)
4139 VARLIST *vlist;
4140 int n;
4142 if (vlist == 0)
4143 return (vlist = vlist_alloc (n));
4144 if (n > vlist->list_size)
4146 vlist->list_size = n;
4147 vlist->list = (SHELL_VAR **)xrealloc (vlist->list, (vlist->list_size + 1) * sizeof (SHELL_VAR *));
4149 return vlist;
4152 static void
4153 vlist_add (vlist, var, flags)
4154 VARLIST *vlist;
4155 SHELL_VAR *var;
4156 int flags;
4158 register int i;
4160 for (i = 0; i < vlist->list_len; i++)
4161 if (STREQ (var->name, vlist->list[i]->name))
4162 break;
4163 if (i < vlist->list_len)
4164 return;
4166 if (i >= vlist->list_size)
4167 vlist = vlist_realloc (vlist, vlist->list_size + 16);
4169 vlist->list[vlist->list_len++] = var;
4170 vlist->list[vlist->list_len] = (SHELL_VAR *)NULL;
4173 /* Map FUNCTION over the variables in VAR_HASH_TABLE. Return an array of the
4174 variables for which FUNCTION returns a non-zero value. A NULL value
4175 for FUNCTION means to use all variables. */
4176 SHELL_VAR **
4177 map_over (function, vc)
4178 sh_var_map_func_t *function;
4179 VAR_CONTEXT *vc;
4181 VAR_CONTEXT *v;
4182 VARLIST *vlist;
4183 SHELL_VAR **ret;
4184 int nentries;
4186 for (nentries = 0, v = vc; v; v = v->down)
4187 nentries += HASH_ENTRIES (v->table);
4189 if (nentries == 0)
4190 return (SHELL_VAR **)NULL;
4192 vlist = vlist_alloc (nentries);
4194 for (v = vc; v; v = v->down)
4195 flatten (v->table, function, vlist, 0);
4197 ret = vlist->list;
4198 free (vlist);
4199 return ret;
4202 SHELL_VAR **
4203 map_over_funcs (function)
4204 sh_var_map_func_t *function;
4206 VARLIST *vlist;
4207 SHELL_VAR **ret;
4209 if (shell_functions == 0 || HASH_ENTRIES (shell_functions) == 0)
4210 return ((SHELL_VAR **)NULL);
4212 vlist = vlist_alloc (HASH_ENTRIES (shell_functions));
4214 flatten (shell_functions, function, vlist, 0);
4216 ret = vlist->list;
4217 free (vlist);
4218 return ret;
4221 /* Flatten VAR_HASH_TABLE, applying FUNC to each member and adding those
4222 elements for which FUNC succeeds to VLIST->list. FLAGS is reserved
4223 for future use. Only unique names are added to VLIST. If FUNC is
4224 NULL, each variable in VAR_HASH_TABLE is added to VLIST. If VLIST is
4225 NULL, FUNC is applied to each SHELL_VAR in VAR_HASH_TABLE. If VLIST
4226 and FUNC are both NULL, nothing happens. */
4227 static void
4228 flatten (var_hash_table, func, vlist, flags)
4229 HASH_TABLE *var_hash_table;
4230 sh_var_map_func_t *func;
4231 VARLIST *vlist;
4232 int flags;
4234 register int i;
4235 register BUCKET_CONTENTS *tlist;
4236 int r;
4237 SHELL_VAR *var;
4239 if (var_hash_table == 0 || (HASH_ENTRIES (var_hash_table) == 0) || (vlist == 0 && func == 0))
4240 return;
4242 for (i = 0; i < var_hash_table->nbuckets; i++)
4244 for (tlist = hash_items (i, var_hash_table); tlist; tlist = tlist->next)
4246 var = (SHELL_VAR *)tlist->data;
4248 r = func ? (*func) (var) : 1;
4249 if (r && vlist)
4250 vlist_add (vlist, var, flags);
4255 void
4256 sort_variables (array)
4257 SHELL_VAR **array;
4259 qsort (array, strvec_len ((char **)array), sizeof (SHELL_VAR *), (QSFUNC *)qsort_var_comp);
4262 static int
4263 qsort_var_comp (var1, var2)
4264 SHELL_VAR **var1, **var2;
4266 int result;
4268 if ((result = (*var1)->name[0] - (*var2)->name[0]) == 0)
4269 result = strcmp ((*var1)->name, (*var2)->name);
4271 return (result);
4274 /* Apply FUNC to each variable in SHELL_VARIABLES, adding each one for
4275 which FUNC succeeds to an array of SHELL_VAR *s. Returns the array. */
4276 static SHELL_VAR **
4277 vapply (func)
4278 sh_var_map_func_t *func;
4280 SHELL_VAR **list;
4282 list = map_over (func, shell_variables);
4283 if (list /* && posixly_correct */)
4284 sort_variables (list);
4285 return (list);
4288 /* Apply FUNC to each variable in SHELL_FUNCTIONS, adding each one for
4289 which FUNC succeeds to an array of SHELL_VAR *s. Returns the array. */
4290 static SHELL_VAR **
4291 fapply (func)
4292 sh_var_map_func_t *func;
4294 SHELL_VAR **list;
4296 list = map_over_funcs (func);
4297 if (list /* && posixly_correct */)
4298 sort_variables (list);
4299 return (list);
4302 /* Create a NULL terminated array of all the shell variables. */
4303 SHELL_VAR **
4304 all_shell_variables ()
4306 return (vapply ((sh_var_map_func_t *)NULL));
4309 /* Create a NULL terminated array of all the shell functions. */
4310 SHELL_VAR **
4311 all_shell_functions ()
4313 return (fapply ((sh_var_map_func_t *)NULL));
4316 static int
4317 visible_var (var)
4318 SHELL_VAR *var;
4320 return (invisible_p (var) == 0);
4323 SHELL_VAR **
4324 all_visible_functions ()
4326 return (fapply (visible_var));
4329 SHELL_VAR **
4330 all_visible_variables ()
4332 return (vapply (visible_var));
4335 /* Return non-zero if the variable VAR is visible and exported. Array
4336 variables cannot be exported. */
4337 static int
4338 visible_and_exported (var)
4339 SHELL_VAR *var;
4341 return (invisible_p (var) == 0 && exported_p (var));
4344 /* Candidate variables for the export environment are either valid variables
4345 with the export attribute or invalid variables inherited from the initial
4346 environment and simply passed through. */
4347 static int
4348 export_environment_candidate (var)
4349 SHELL_VAR *var;
4351 return (exported_p (var) && (invisible_p (var) == 0 || imported_p (var)));
4354 /* Return non-zero if VAR is a local variable in the current context and
4355 is exported. */
4356 static int
4357 local_and_exported (var)
4358 SHELL_VAR *var;
4360 return (invisible_p (var) == 0 && local_p (var) && var->context == variable_context && exported_p (var));
4363 SHELL_VAR **
4364 all_exported_variables ()
4366 return (vapply (visible_and_exported));
4369 SHELL_VAR **
4370 local_exported_variables ()
4372 return (vapply (local_and_exported));
4375 static int
4376 variable_in_context (var)
4377 SHELL_VAR *var;
4379 return (local_p (var) && var->context == variable_context);
4382 static int
4383 visible_variable_in_context (var)
4384 SHELL_VAR *var;
4386 return (invisible_p (var) == 0 && local_p (var) && var->context == variable_context);
4389 SHELL_VAR **
4390 all_local_variables (visible_only)
4391 int visible_only;
4393 VARLIST *vlist;
4394 SHELL_VAR **ret;
4395 VAR_CONTEXT *vc;
4397 vc = shell_variables;
4398 for (vc = shell_variables; vc; vc = vc->down)
4399 if (vc_isfuncenv (vc) && vc->scope == variable_context)
4400 break;
4402 if (vc == 0)
4404 internal_error (_("all_local_variables: no function context at current scope"));
4405 return (SHELL_VAR **)NULL;
4407 if (vc->table == 0 || HASH_ENTRIES (vc->table) == 0 || vc_haslocals (vc) == 0)
4408 return (SHELL_VAR **)NULL;
4410 vlist = vlist_alloc (HASH_ENTRIES (vc->table));
4412 if (visible_only)
4413 flatten (vc->table, visible_variable_in_context, vlist, 0);
4414 else
4415 flatten (vc->table, variable_in_context, vlist, 0);
4417 ret = vlist->list;
4418 free (vlist);
4419 if (ret)
4420 sort_variables (ret);
4421 return ret;
4424 #if defined (ARRAY_VARS)
4425 /* Return non-zero if the variable VAR is visible and an array. */
4426 static int
4427 visible_array_vars (var)
4428 SHELL_VAR *var;
4430 return (invisible_p (var) == 0 && (array_p (var) || assoc_p (var)));
4433 SHELL_VAR **
4434 all_array_variables ()
4436 return (vapply (visible_array_vars));
4438 #endif /* ARRAY_VARS */
4440 char **
4441 all_variables_matching_prefix (prefix)
4442 const char *prefix;
4444 SHELL_VAR **varlist;
4445 char **rlist;
4446 int vind, rind, plen;
4448 plen = STRLEN (prefix);
4449 varlist = all_visible_variables ();
4450 for (vind = 0; varlist && varlist[vind]; vind++)
4452 if (varlist == 0 || vind == 0)
4453 return ((char **)NULL);
4454 rlist = strvec_create (vind + 1);
4455 for (vind = rind = 0; varlist[vind]; vind++)
4457 if (plen == 0 || STREQN (prefix, varlist[vind]->name, plen))
4458 rlist[rind++] = savestring (varlist[vind]->name);
4460 rlist[rind] = (char *)0;
4461 free (varlist);
4463 return rlist;
4466 /* **************************************************************** */
4467 /* */
4468 /* Managing temporary variable scopes */
4469 /* */
4470 /* **************************************************************** */
4472 /* Make variable NAME have VALUE in the temporary environment. */
4473 static SHELL_VAR *
4474 bind_tempenv_variable (name, value)
4475 const char *name;
4476 char *value;
4478 SHELL_VAR *var;
4480 var = temporary_env ? hash_lookup (name, temporary_env) : (SHELL_VAR *)NULL;
4482 if (var)
4484 FREE (value_cell (var));
4485 var_setvalue (var, savestring (value));
4486 INVALIDATE_EXPORTSTR (var);
4489 return (var);
4492 /* Find a variable in the temporary environment that is named NAME.
4493 Return the SHELL_VAR *, or NULL if not found. */
4494 SHELL_VAR *
4495 find_tempenv_variable (name)
4496 const char *name;
4498 return (temporary_env ? hash_lookup (name, temporary_env) : (SHELL_VAR *)NULL);
4501 char **tempvar_list;
4502 int tvlist_ind;
4504 /* Take a variable from an assignment statement preceding a posix special
4505 builtin (including `return') and create a global variable from it. This
4506 is called from merge_temporary_env, which is only called when in posix
4507 mode. */
4508 static void
4509 push_posix_temp_var (data)
4510 PTR_T data;
4512 SHELL_VAR *var, *v;
4513 HASH_TABLE *binding_table;
4515 var = (SHELL_VAR *)data;
4517 /* Just like do_assignment_internal(). This makes assignments preceding
4518 special builtins act like standalone assignment statements when in
4519 posix mode, satisfying the posix requirement that this affect the
4520 "current execution environment." */
4521 v = bind_variable (var->name, value_cell (var), ASS_FORCE|ASS_NOLONGJMP);
4523 /* XXX - do we need to worry about array variables here? */
4525 /* If this modifies an existing local variable, v->context will be non-zero.
4526 If it comes back with v->context == 0, we bound at the global context.
4527 Set binding_table appropriately. It doesn't matter whether it's correct
4528 if the variable is local, only that it's not global_variables->table */
4529 binding_table = v->context ? shell_variables->table : global_variables->table;
4531 /* global variables are no longer temporary and don't need propagating. */
4532 if (v->context == 0)
4533 var->attributes &= ~(att_tempvar|att_propagate);
4535 if (v)
4537 v->attributes |= var->attributes; /* preserve tempvar attribute if appropriate */
4538 /* If we don't bind a local variable, propagate the value. If we bind a
4539 local variable (the "current execution environment"), keep it as local
4540 and don't propagate it to the calling environment. */
4541 if (v->context > 0 && local_p (v) == 0)
4542 v->attributes |= att_propagate;
4543 else
4544 v->attributes &= ~att_propagate;
4547 if (find_special_var (var->name) >= 0)
4548 tempvar_list[tvlist_ind++] = savestring (var->name);
4550 dispose_variable (var);
4553 /* Push the variable described by (SHELL_VAR *)DATA down to the next
4554 variable context from the temporary environment. This can be called
4555 from one context:
4556 1. propagate_temp_var: which is called to propagate variables in
4557 assignments like `var=value declare -x var' to the surrounding
4558 scope.
4560 In this case, the variable should have the att_propagate flag set and
4561 we can create variables in the current scope.
4563 static void
4564 push_temp_var (data)
4565 PTR_T data;
4567 SHELL_VAR *var, *v;
4568 HASH_TABLE *binding_table;
4570 var = (SHELL_VAR *)data;
4572 binding_table = shell_variables->table;
4573 if (binding_table == 0)
4575 if (shell_variables == global_variables)
4576 /* shouldn't happen */
4577 binding_table = shell_variables->table = global_variables->table = hash_create (VARIABLES_HASH_BUCKETS);
4578 else
4579 binding_table = shell_variables->table = hash_create (TEMPENV_HASH_BUCKETS);
4582 v = bind_variable_internal (var->name, value_cell (var), binding_table, 0, ASS_FORCE|ASS_NOLONGJMP);
4584 /* XXX - should we set the context here? It shouldn't matter because of how
4585 assign_in_env works, but we do it anyway. */
4586 if (v)
4587 v->context = shell_variables->scope;
4589 if (binding_table == global_variables->table) /* XXX */
4590 var->attributes &= ~(att_tempvar|att_propagate);
4591 else
4593 var->attributes |= att_propagate; /* XXX - propagate more than once? */
4594 if (binding_table == shell_variables->table)
4595 shell_variables->flags |= VC_HASTMPVAR;
4597 if (v)
4598 v->attributes |= var->attributes;
4600 if (find_special_var (var->name) >= 0)
4601 tempvar_list[tvlist_ind++] = savestring (var->name);
4603 dispose_variable (var);
4606 /* Take a variable described by DATA and push it to the surrounding scope if
4607 the PROPAGATE attribute is set. That gets set by push_temp_var if we are
4608 taking a variable like `var=value declare -x var' and propagating it to
4609 the enclosing scope. */
4610 static void
4611 propagate_temp_var (data)
4612 PTR_T data;
4614 SHELL_VAR *var;
4616 var = (SHELL_VAR *)data;
4617 if (tempvar_p (var) && (var->attributes & att_propagate))
4618 push_temp_var (data);
4619 else
4621 if (find_special_var (var->name) >= 0)
4622 tempvar_list[tvlist_ind++] = savestring (var->name);
4623 dispose_variable (var);
4627 /* Free the storage used in the hash table for temporary
4628 environment variables. PUSHF is a function to be called
4629 to free each hash table entry. It takes care of pushing variables
4630 to previous scopes if appropriate. PUSHF stores names of variables
4631 that require special handling (e.g., IFS) on tempvar_list, so this
4632 function can call stupidly_hack_special_variables on all the
4633 variables in the list when the temporary hash table is destroyed. */
4634 static void
4635 dispose_temporary_env (pushf)
4636 sh_free_func_t *pushf;
4638 int i;
4639 HASH_TABLE *disposer;
4641 tempvar_list = strvec_create (HASH_ENTRIES (temporary_env) + 1);
4642 tempvar_list[tvlist_ind = 0] = 0;
4644 disposer = temporary_env;
4645 temporary_env = (HASH_TABLE *)NULL;
4647 hash_flush (disposer, pushf);
4648 hash_dispose (disposer);
4650 tempvar_list[tvlist_ind] = 0;
4652 array_needs_making = 1;
4654 for (i = 0; i < tvlist_ind; i++)
4655 stupidly_hack_special_variables (tempvar_list[i]);
4657 strvec_dispose (tempvar_list);
4658 tempvar_list = 0;
4659 tvlist_ind = 0;
4662 void
4663 dispose_used_env_vars ()
4665 if (temporary_env)
4667 dispose_temporary_env (propagate_temp_var);
4668 maybe_make_export_env ();
4672 /* Take all of the shell variables in the temporary environment HASH_TABLE
4673 and make shell variables from them at the current variable context.
4674 Right now, this is only called in Posix mode to implement the historical
4675 accident of creating global variables from assignment statements preceding
4676 special builtins, but we check in case this acquires another caller later. */
4677 void
4678 merge_temporary_env ()
4680 if (temporary_env)
4681 dispose_temporary_env (posixly_correct ? push_posix_temp_var : push_temp_var);
4684 /* Temporary function to use if we want to separate function and special
4685 builtin behavior. */
4686 void
4687 merge_function_temporary_env ()
4689 if (temporary_env)
4690 dispose_temporary_env (push_temp_var);
4693 void
4694 flush_temporary_env ()
4696 if (temporary_env)
4698 hash_flush (temporary_env, free_variable_hash_data);
4699 hash_dispose (temporary_env);
4700 temporary_env = (HASH_TABLE *)NULL;
4704 /* **************************************************************** */
4705 /* */
4706 /* Creating and manipulating the environment */
4707 /* */
4708 /* **************************************************************** */
4710 static inline char *
4711 mk_env_string (name, value, isfunc)
4712 const char *name, *value;
4713 int isfunc;
4715 size_t name_len, value_len;
4716 char *p, *q, *t;
4718 name_len = strlen (name);
4719 value_len = STRLEN (value);
4721 /* If we are exporting a shell function, construct the encoded function
4722 name. */
4723 if (isfunc && value)
4725 p = (char *)xmalloc (BUSHFUNC_PREFLEN + name_len + BUSHFUNC_SUFFLEN + value_len + 2);
4726 q = p;
4727 memcpy (q, BUSHFUNC_PREFIX, BUSHFUNC_PREFLEN);
4728 q += BUSHFUNC_PREFLEN;
4729 memcpy (q, name, name_len);
4730 q += name_len;
4731 memcpy (q, BUSHFUNC_SUFFIX, BUSHFUNC_SUFFLEN);
4732 q += BUSHFUNC_SUFFLEN;
4734 else
4736 p = (char *)xmalloc (2 + name_len + value_len);
4737 memcpy (p, name, name_len);
4738 q = p + name_len;
4741 q[0] = '=';
4742 if (value && *value)
4744 if (isfunc)
4746 t = dequote_escapes (value);
4747 value_len = STRLEN (t);
4748 memcpy (q + 1, t, value_len + 1);
4749 free (t);
4751 else
4752 memcpy (q + 1, value, value_len + 1);
4754 else
4755 q[1] = '\0';
4757 return (p);
4760 #ifdef DEBUG
4761 /* Debugging */
4762 static int
4763 valid_exportstr (v)
4764 SHELL_VAR *v;
4766 char *s;
4768 s = v->exportstr;
4769 if (s == 0)
4771 internal_error (_("%s has null exportstr"), v->name);
4772 return (0);
4774 if (legal_variable_starter ((unsigned char)*s) == 0)
4776 internal_error (_("invalid character %d in exportstr for %s"), *s, v->name);
4777 return (0);
4779 for (s = v->exportstr + 1; s && *s; s++)
4781 if (*s == '=')
4782 break;
4783 if (legal_variable_char ((unsigned char)*s) == 0)
4785 internal_error (_("invalid character %d in exportstr for %s"), *s, v->name);
4786 return (0);
4789 if (*s != '=')
4791 internal_error (_("no `=' in exportstr for %s"), v->name);
4792 return (0);
4794 return (1);
4796 #endif
4798 static char **
4799 make_env_array_from_var_list (vars)
4800 SHELL_VAR **vars;
4802 register int i, list_index;
4803 register SHELL_VAR *var;
4804 char **list, *value;
4806 list = strvec_create ((1 + strvec_len ((char **)vars)));
4808 #define USE_EXPORTSTR (value == var->exportstr)
4810 for (i = 0, list_index = 0; var = vars[i]; i++)
4812 #if defined (__CYGWIN__)
4813 /* We don't use the exportstr stuff on Cygwin at all. */
4814 INVALIDATE_EXPORTSTR (var);
4815 #endif
4817 /* If the value is generated dynamically, generate it here. */
4818 if (regen_p (var) && var->dynamic_value)
4820 var = (*(var->dynamic_value)) (var);
4821 INVALIDATE_EXPORTSTR (var);
4824 if (var->exportstr)
4825 value = var->exportstr;
4826 else if (function_p (var))
4827 value = named_function_string ((char *)NULL, function_cell (var), 0);
4828 #if defined (ARRAY_VARS)
4829 else if (array_p (var))
4830 # if ARRAY_EXPORT
4831 value = array_to_assign (array_cell (var), 0);
4832 # else
4833 continue; /* XXX array vars cannot yet be exported */
4834 # endif /* ARRAY_EXPORT */
4835 else if (assoc_p (var))
4836 # if 0
4837 value = assoc_to_assign (assoc_cell (var), 0);
4838 # else
4839 continue; /* XXX associative array vars cannot yet be exported */
4840 # endif
4841 #endif
4842 else
4843 value = value_cell (var);
4845 if (value)
4847 /* Gee, I'd like to get away with not using savestring() if we're
4848 using the cached exportstr... */
4849 list[list_index] = USE_EXPORTSTR ? savestring (value)
4850 : mk_env_string (var->name, value, function_p (var));
4851 if (USE_EXPORTSTR == 0)
4852 SAVE_EXPORTSTR (var, list[list_index]);
4854 list_index++;
4855 #undef USE_EXPORTSTR
4857 #if 0 /* not yet */
4858 #if defined (ARRAY_VARS)
4859 if (array_p (var) || assoc_p (var))
4860 free (value);
4861 #endif
4862 #endif
4866 list[list_index] = (char *)NULL;
4867 return (list);
4870 /* Make an array of assignment statements from the hash table
4871 HASHED_VARS which contains SHELL_VARs. Only visible, exported
4872 variables are eligible. */
4873 static char **
4874 make_var_export_array (vcxt)
4875 VAR_CONTEXT *vcxt;
4877 char **list;
4878 SHELL_VAR **vars;
4880 #if 0
4881 vars = map_over (visible_and_exported, vcxt);
4882 #else
4883 vars = map_over (export_environment_candidate, vcxt);
4884 #endif
4886 if (vars == 0)
4887 return (char **)NULL;
4889 list = make_env_array_from_var_list (vars);
4891 free (vars);
4892 return (list);
4895 static char **
4896 make_func_export_array ()
4898 char **list;
4899 SHELL_VAR **vars;
4901 vars = map_over_funcs (visible_and_exported);
4902 if (vars == 0)
4903 return (char **)NULL;
4905 list = make_env_array_from_var_list (vars);
4907 free (vars);
4908 return (list);
4911 /* Add ENVSTR to the end of the exported environment, EXPORT_ENV. */
4912 #define add_to_export_env(envstr,do_alloc) \
4913 do \
4915 if (export_env_index >= (export_env_size - 1)) \
4917 export_env_size += 16; \
4918 export_env = strvec_resize (export_env, export_env_size); \
4919 environ = export_env; \
4921 export_env[export_env_index++] = (do_alloc) ? savestring (envstr) : envstr; \
4922 export_env[export_env_index] = (char *)NULL; \
4923 } while (0)
4925 /* Add ASSIGN to EXPORT_ENV, or supersede a previous assignment in the
4926 array with the same left-hand side. Return the new EXPORT_ENV. */
4927 char **
4928 add_or_supercede_exported_var (assign, do_alloc)
4929 char *assign;
4930 int do_alloc;
4932 register int i;
4933 int equal_offset;
4935 equal_offset = assignment (assign, 0);
4936 if (equal_offset == 0)
4937 return (export_env);
4939 /* If this is a function, then only supersede the function definition.
4940 We do this by including the `=() {' in the comparison, like
4941 initialize_shell_variables does. */
4942 if (assign[equal_offset + 1] == '(' &&
4943 strncmp (assign + equal_offset + 2, ") {", 3) == 0) /* } */
4944 equal_offset += 4;
4946 for (i = 0; i < export_env_index; i++)
4948 if (STREQN (assign, export_env[i], equal_offset + 1))
4950 free (export_env[i]);
4951 export_env[i] = do_alloc ? savestring (assign) : assign;
4952 return (export_env);
4955 add_to_export_env (assign, do_alloc);
4956 return (export_env);
4959 static void
4960 add_temp_array_to_env (temp_array, do_alloc, do_supercede)
4961 char **temp_array;
4962 int do_alloc, do_supercede;
4964 register int i;
4966 if (temp_array == 0)
4967 return;
4969 for (i = 0; temp_array[i]; i++)
4971 if (do_supercede)
4972 export_env = add_or_supercede_exported_var (temp_array[i], do_alloc);
4973 else
4974 add_to_export_env (temp_array[i], do_alloc);
4977 free (temp_array);
4980 /* Make the environment array for the command about to be executed, if the
4981 array needs making. Otherwise, do nothing. If a shell action could
4982 change the array that commands receive for their environment, then the
4983 code should `array_needs_making++'.
4985 The order to add to the array is:
4986 temporary_env
4987 list of var contexts whose head is shell_variables
4988 shell_functions
4990 This is the shell variable lookup order. We add only new variable
4991 names at each step, which allows local variables and variables in
4992 the temporary environments to shadow variables in the global (or
4993 any previous) scope.
4996 static int
4997 n_shell_variables ()
4999 VAR_CONTEXT *vc;
5000 int n;
5002 for (n = 0, vc = shell_variables; vc; vc = vc->down)
5003 n += HASH_ENTRIES (vc->table);
5004 return n;
5008 chkexport (name)
5009 char *name;
5011 SHELL_VAR *v;
5013 v = find_variable (name);
5014 if (v && exported_p (v))
5016 array_needs_making = 1;
5017 maybe_make_export_env ();
5018 return 1;
5020 return 0;
5023 void
5024 maybe_make_export_env ()
5026 register char **temp_array;
5027 int new_size;
5028 VAR_CONTEXT *tcxt, *icxt;
5030 if (array_needs_making)
5032 if (export_env)
5033 strvec_flush (export_env);
5035 /* Make a guess based on how many shell variables and functions we
5036 have. Since there will always be array variables, and array
5037 variables are not (yet) exported, this will always be big enough
5038 for the exported variables and functions. */
5039 new_size = n_shell_variables () + HASH_ENTRIES (shell_functions) + 1 +
5040 HASH_ENTRIES (temporary_env) + HASH_ENTRIES (invalid_env);
5041 if (new_size > export_env_size)
5043 export_env_size = new_size;
5044 export_env = strvec_resize (export_env, export_env_size);
5045 environ = export_env;
5047 export_env[export_env_index = 0] = (char *)NULL;
5049 /* Make a dummy variable context from the temporary_env, stick it on
5050 the front of shell_variables, call make_var_export_array on the
5051 whole thing to flatten it, and convert the list of SHELL_VAR *s
5052 to the form needed by the environment. */
5053 if (temporary_env)
5055 tcxt = new_var_context ((char *)NULL, 0);
5056 tcxt->table = temporary_env;
5057 tcxt->down = shell_variables;
5059 else
5060 tcxt = shell_variables;
5062 if (invalid_env)
5064 icxt = new_var_context ((char *)NULL, 0);
5065 icxt->table = invalid_env;
5066 icxt->down = tcxt;
5068 else
5069 icxt = tcxt;
5071 temp_array = make_var_export_array (icxt);
5072 if (temp_array)
5073 add_temp_array_to_env (temp_array, 0, 0);
5075 if (icxt != tcxt)
5076 free (icxt);
5078 if (tcxt != shell_variables)
5079 free (tcxt);
5081 #if defined (RESTRICTED_SHELL)
5082 /* Restricted shells may not export shell functions. */
5083 temp_array = restricted ? (char **)0 : make_func_export_array ();
5084 #else
5085 temp_array = make_func_export_array ();
5086 #endif
5087 if (temp_array)
5088 add_temp_array_to_env (temp_array, 0, 0);
5090 array_needs_making = 0;
5094 /* This is an efficiency hack. PWD and OLDPWD are auto-exported, so
5095 we will need to remake the exported environment every time we
5096 change directories. `_' is always put into the environment for
5097 every external command, so without special treatment it will always
5098 cause the environment to be remade.
5100 If there is no other reason to make the exported environment, we can
5101 just update the variables in place and mark the exported environment
5102 as no longer needing a remake. */
5103 void
5104 update_export_env_inplace (env_prefix, preflen, value)
5105 char *env_prefix;
5106 int preflen;
5107 char *value;
5109 char *evar;
5111 evar = (char *)xmalloc (STRLEN (value) + preflen + 1);
5112 strcpy (evar, env_prefix);
5113 if (value)
5114 strcpy (evar + preflen, value);
5115 export_env = add_or_supercede_exported_var (evar, 0);
5118 /* We always put _ in the environment as the name of this command. */
5119 void
5120 put_command_name_into_env (command_name)
5121 char *command_name;
5123 update_export_env_inplace ("_=", 2, command_name);
5126 /* **************************************************************** */
5127 /* */
5128 /* Managing variable contexts */
5129 /* */
5130 /* **************************************************************** */
5132 /* Allocate and return a new variable context with NAME and FLAGS.
5133 NAME can be NULL. */
5135 VAR_CONTEXT *
5136 new_var_context (name, flags)
5137 char *name;
5138 int flags;
5140 VAR_CONTEXT *vc;
5142 vc = (VAR_CONTEXT *)xmalloc (sizeof (VAR_CONTEXT));
5143 vc->name = name ? savestring (name) : (char *)NULL;
5144 vc->scope = variable_context;
5145 vc->flags = flags;
5147 vc->up = vc->down = (VAR_CONTEXT *)NULL;
5148 vc->table = (HASH_TABLE *)NULL;
5150 return vc;
5153 /* Free a variable context and its data, including the hash table. Dispose
5154 all of the variables. */
5155 void
5156 dispose_var_context (vc)
5157 VAR_CONTEXT *vc;
5159 FREE (vc->name);
5161 if (vc->table)
5163 delete_all_variables (vc->table);
5164 hash_dispose (vc->table);
5167 free (vc);
5170 /* Set VAR's scope level to the current variable context. */
5171 static int
5172 set_context (var)
5173 SHELL_VAR *var;
5175 return (var->context = variable_context);
5178 /* Make a new variable context with NAME and FLAGS and a HASH_TABLE of
5179 temporary variables, and push it onto shell_variables. This is
5180 for shell functions. */
5181 VAR_CONTEXT *
5182 push_var_context (name, flags, tempvars)
5183 char *name;
5184 int flags;
5185 HASH_TABLE *tempvars;
5187 VAR_CONTEXT *vc;
5188 int posix_func_behavior;
5190 /* As of IEEE Std 1003.1-2017, assignment statements preceding shell
5191 functions no longer behave like assignment statements preceding
5192 special builtins, and do not persist in the current shell environment.
5193 This is austin group interp #654, though nobody implements it yet. */
5194 posix_func_behavior = 0;
5196 vc = new_var_context (name, flags);
5197 /* Posix interp 1009, temporary assignments preceding function calls modify
5198 the current environment *before* the command is executed. */
5199 if (posix_func_behavior && (flags & VC_FUNCENV) && tempvars == temporary_env)
5200 merge_temporary_env ();
5201 else if (tempvars)
5203 vc->table = tempvars;
5204 /* Have to do this because the temp environment was created before
5205 variable_context was incremented. */
5206 /* XXX - only need to do it if flags&VC_FUNCENV */
5207 flatten (tempvars, set_context, (VARLIST *)NULL, 0);
5208 vc->flags |= VC_HASTMPVAR;
5210 vc->down = shell_variables;
5211 shell_variables->up = vc;
5213 return (shell_variables = vc);
5216 /* This can be called from one of two code paths:
5217 1. pop_scope, which implements the posix rules for propagating variable
5218 assignments preceding special builtins to the surrounding scope
5219 (push_builtin_var -- isbltin == 1);
5220 2. pop_var_context, which is called from pop_context and implements the
5221 posix rules for propagating variable assignments preceding function
5222 calls to the surrounding scope (push_func_var -- isbltin == 0)
5224 It takes variables out of a temporary environment hash table. We take the
5225 variable in data.
5228 static inline void
5229 push_posix_tempvar_internal (var, isbltin)
5230 SHELL_VAR *var;
5231 int isbltin;
5233 SHELL_VAR *v;
5234 int posix_var_behavior;
5236 /* As of IEEE Std 1003.1-2017, assignment statements preceding shell
5237 functions no longer behave like assignment statements preceding
5238 special builtins, and do not persist in the current shell environment.
5239 This is austin group interp #654, though nobody implements it yet. */
5240 posix_var_behavior = posixly_correct && isbltin;
5241 v = 0;
5243 if (local_p (var) && STREQ (var->name, "-"))
5245 set_current_options (value_cell (var));
5246 set_shellopts ();
5248 /* This takes variable assignments preceding special builtins that can execute
5249 multiple commands (source, eval, etc.) and performs the equivalent of
5250 an assignment statement to modify the closest enclosing variable (the
5251 posix "current execution environment"). This makes the behavior the same
5252 as push_posix_temp_var; but the circumstances of calling are slightly
5253 different. */
5254 else if (tempvar_p (var) && posix_var_behavior)
5256 /* similar to push_posix_temp_var */
5257 v = bind_variable (var->name, value_cell (var), ASS_FORCE|ASS_NOLONGJMP);
5258 if (v)
5260 v->attributes |= var->attributes;
5261 if (v->context == 0)
5262 v->attributes &= ~(att_tempvar|att_propagate);
5263 /* XXX - set att_propagate here if v->context > 0? */
5266 else if (tempvar_p (var) && propagate_p (var))
5268 /* Make sure we have a hash table to store the variable in while it is
5269 being propagated down to the global variables table. Create one if
5270 we have to */
5271 if ((vc_isfuncenv (shell_variables) || vc_istempenv (shell_variables)) && shell_variables->table == 0)
5272 shell_variables->table = hash_create (VARIABLES_HASH_BUCKETS);
5273 v = bind_variable_internal (var->name, value_cell (var), shell_variables->table, 0, 0);
5274 /* XXX - should we set v->context here? */
5275 if (v)
5276 v->context = shell_variables->scope;
5277 if (shell_variables == global_variables)
5278 var->attributes &= ~(att_tempvar|att_propagate);
5279 else
5280 shell_variables->flags |= VC_HASTMPVAR;
5281 if (v)
5282 v->attributes |= var->attributes;
5284 else
5285 stupidly_hack_special_variables (var->name); /* XXX */
5287 #if defined (ARRAY_VARS)
5288 if (v && (array_p (var) || assoc_p (var)))
5290 FREE (value_cell (v));
5291 if (array_p (var))
5292 var_setarray (v, array_copy (array_cell (var)));
5293 else
5294 var_setassoc (v, assoc_copy (assoc_cell (var)));
5296 #endif
5298 dispose_variable (var);
5301 static void
5302 push_func_var (data)
5303 PTR_T data;
5305 SHELL_VAR *var;
5307 var = (SHELL_VAR *)data;
5308 push_posix_tempvar_internal (var, 0);
5311 static void
5312 push_builtin_var (data)
5313 PTR_T data;
5315 SHELL_VAR *var;
5317 var = (SHELL_VAR *)data;
5318 push_posix_tempvar_internal (var, 1);
5321 /* Pop the top context off of VCXT and dispose of it, returning the rest of
5322 the stack. */
5323 void
5324 pop_var_context ()
5326 VAR_CONTEXT *ret, *vcxt;
5328 vcxt = shell_variables;
5329 if (vc_isfuncenv (vcxt) == 0)
5331 internal_error (_("pop_var_context: head of shell_variables not a function context"));
5332 return;
5335 if (ret = vcxt->down)
5337 ret->up = (VAR_CONTEXT *)NULL;
5338 shell_variables = ret;
5339 if (vcxt->table)
5340 hash_flush (vcxt->table, push_func_var);
5341 dispose_var_context (vcxt);
5343 else
5344 internal_error (_("pop_var_context: no global_variables context"));
5347 /* Delete the HASH_TABLEs for all variable contexts beginning at VCXT, and
5348 all of the VAR_CONTEXTs except GLOBAL_VARIABLES. */
5349 void
5350 delete_all_contexts (vcxt)
5351 VAR_CONTEXT *vcxt;
5353 VAR_CONTEXT *v, *t;
5355 for (v = vcxt; v != global_variables; v = t)
5357 t = v->down;
5358 dispose_var_context (v);
5361 delete_all_variables (global_variables->table);
5362 shell_variables = global_variables;
5365 /* **************************************************************** */
5366 /* */
5367 /* Pushing and Popping temporary variable scopes */
5368 /* */
5369 /* **************************************************************** */
5371 VAR_CONTEXT *
5372 push_scope (flags, tmpvars)
5373 int flags;
5374 HASH_TABLE *tmpvars;
5376 return (push_var_context ((char *)NULL, flags, tmpvars));
5379 static void
5380 push_exported_var (data)
5381 PTR_T data;
5383 SHELL_VAR *var, *v;
5385 var = (SHELL_VAR *)data;
5387 /* If a temp var had its export attribute set, or it's marked to be
5388 propagated, bind it in the previous scope before disposing it. */
5389 /* XXX - This isn't exactly right, because all tempenv variables have the
5390 export attribute set. */
5391 if (tempvar_p (var) && exported_p (var) && (var->attributes & att_propagate))
5393 var->attributes &= ~att_tempvar; /* XXX */
5394 v = bind_variable_internal (var->name, value_cell (var), shell_variables->table, 0, 0);
5395 if (shell_variables == global_variables)
5396 var->attributes &= ~att_propagate;
5397 if (v)
5399 v->attributes |= var->attributes;
5400 v->context = shell_variables->scope;
5403 else
5404 stupidly_hack_special_variables (var->name); /* XXX */
5406 dispose_variable (var);
5409 /* This is called to propagate variables in the temporary environment of a
5410 special builtin (if IS_SPECIAL != 0) or exported variables that are the
5411 result of a builtin like `source' or `command' that can operate on the
5412 variables in its temporary environment. In the first case, we call
5413 push_builtin_var, which does the right thing. */
5414 void
5415 pop_scope (is_special)
5416 int is_special;
5418 VAR_CONTEXT *vcxt, *ret;
5419 int is_bltinenv;
5421 vcxt = shell_variables;
5422 if (vc_istempscope (vcxt) == 0)
5424 internal_error (_("pop_scope: head of shell_variables not a temporary environment scope"));
5425 return;
5427 is_bltinenv = vc_isbltnenv (vcxt); /* XXX - for later */
5429 ret = vcxt->down;
5430 if (ret)
5431 ret->up = (VAR_CONTEXT *)NULL;
5433 shell_variables = ret;
5435 /* Now we can take care of merging variables in VCXT into set of scopes
5436 whose head is RET (shell_variables). */
5437 FREE (vcxt->name);
5438 if (vcxt->table)
5440 if (is_special)
5441 hash_flush (vcxt->table, push_builtin_var);
5442 else
5443 hash_flush (vcxt->table, push_exported_var);
5444 hash_dispose (vcxt->table);
5446 free (vcxt);
5448 sv_ifs ("IFS"); /* XXX here for now */
5451 /* **************************************************************** */
5452 /* */
5453 /* Pushing and Popping function contexts */
5454 /* */
5455 /* **************************************************************** */
5457 struct saved_dollar_vars {
5458 char **first_ten;
5459 WORD_LIST *rest;
5460 int count;
5463 static struct saved_dollar_vars *dollar_arg_stack = (struct saved_dollar_vars *)NULL;
5464 static int dollar_arg_stack_slots;
5465 static int dollar_arg_stack_index;
5467 /* Functions to manipulate dollar_vars array. Need to keep these in sync with
5468 whatever remember_args() does. */
5469 static char **
5470 save_dollar_vars ()
5472 char **ret;
5473 int i;
5475 ret = strvec_create (10);
5476 for (i = 1; i < 10; i++)
5478 ret[i] = dollar_vars[i];
5479 dollar_vars[i] = (char *)NULL;
5481 return ret;
5484 static void
5485 restore_dollar_vars (args)
5486 char **args;
5488 int i;
5490 for (i = 1; i < 10; i++)
5491 dollar_vars[i] = args[i];
5494 static void
5495 free_dollar_vars ()
5497 int i;
5499 for (i = 1; i < 10; i++)
5501 FREE (dollar_vars[i]);
5502 dollar_vars[i] = (char *)NULL;
5506 static void
5507 free_saved_dollar_vars (args)
5508 char **args;
5510 int i;
5512 for (i = 1; i < 10; i++)
5513 FREE (args[i]);
5516 /* Do what remember_args (xxx, 1) would have done. */
5517 void
5518 clear_dollar_vars ()
5520 free_dollar_vars ();
5521 dispose_words (rest_of_args);
5523 rest_of_args = (WORD_LIST *)NULL;
5524 posparam_count = 0;
5527 /* XXX - should always be followed by remember_args () */
5528 void
5529 push_context (name, is_subshell, tempvars)
5530 char *name; /* function name */
5531 int is_subshell;
5532 HASH_TABLE *tempvars;
5534 if (is_subshell == 0)
5535 push_dollar_vars ();
5536 variable_context++;
5537 push_var_context (name, VC_FUNCENV, tempvars);
5540 /* Only called when subshell == 0, so we don't need to check, and can
5541 unconditionally pop the dollar vars off the stack. */
5542 void
5543 pop_context ()
5545 pop_dollar_vars ();
5546 variable_context--;
5547 pop_var_context ();
5549 sv_ifs ("IFS"); /* XXX here for now */
5552 /* Save the existing positional parameters on a stack. */
5553 void
5554 push_dollar_vars ()
5556 if (dollar_arg_stack_index + 2 > dollar_arg_stack_slots)
5558 dollar_arg_stack = (struct saved_dollar_vars *)
5559 xrealloc (dollar_arg_stack, (dollar_arg_stack_slots += 10)
5560 * sizeof (struct saved_dollar_vars));
5563 dollar_arg_stack[dollar_arg_stack_index].count = posparam_count;
5564 dollar_arg_stack[dollar_arg_stack_index].first_ten = save_dollar_vars ();
5565 dollar_arg_stack[dollar_arg_stack_index++].rest = rest_of_args;
5566 rest_of_args = (WORD_LIST *)NULL;
5567 posparam_count = 0;
5569 dollar_arg_stack[dollar_arg_stack_index].first_ten = (char **)NULL;
5570 dollar_arg_stack[dollar_arg_stack_index].rest = (WORD_LIST *)NULL;
5573 /* Restore the positional parameters from our stack. */
5574 void
5575 pop_dollar_vars ()
5577 if (dollar_arg_stack == 0 || dollar_arg_stack_index == 0)
5578 return;
5580 /* Wipe out current values */
5581 clear_dollar_vars ();
5583 rest_of_args = dollar_arg_stack[--dollar_arg_stack_index].rest;
5584 restore_dollar_vars (dollar_arg_stack[dollar_arg_stack_index].first_ten);
5585 free (dollar_arg_stack[dollar_arg_stack_index].first_ten);
5586 posparam_count = dollar_arg_stack[dollar_arg_stack_index].count;
5588 dollar_arg_stack[dollar_arg_stack_index].first_ten = (char **)NULL;
5589 dollar_arg_stack[dollar_arg_stack_index].rest = (WORD_LIST *)NULL;
5590 dollar_arg_stack[dollar_arg_stack_index].count = 0;
5592 set_dollar_vars_unchanged ();
5593 invalidate_cached_quoted_dollar_at ();
5596 void
5597 dispose_saved_dollar_vars ()
5599 if (dollar_arg_stack == 0 || dollar_arg_stack_index == 0)
5600 return;
5602 dispose_words (dollar_arg_stack[--dollar_arg_stack_index].rest);
5603 free_saved_dollar_vars (dollar_arg_stack[dollar_arg_stack_index].first_ten);
5604 free (dollar_arg_stack[dollar_arg_stack_index].first_ten);
5606 dollar_arg_stack[dollar_arg_stack_index].first_ten = (char **)NULL;
5607 dollar_arg_stack[dollar_arg_stack_index].rest = (WORD_LIST *)NULL;
5608 dollar_arg_stack[dollar_arg_stack_index].count = 0;
5611 /* Initialize BUSH_ARGV and BUSH_ARGC after turning on extdebug after the
5612 shell is initialized */
5613 void
5614 init_bush_argv ()
5616 if (bush_argv_initialized == 0)
5618 save_bush_argv ();
5619 bush_argv_initialized = 1;
5623 void
5624 save_bush_argv ()
5626 WORD_LIST *list;
5628 list = list_rest_of_args ();
5629 push_args (list);
5630 dispose_words (list);
5633 /* Manipulate the special BUSH_ARGV and BUSH_ARGC variables. */
5635 void
5636 push_args (list)
5637 WORD_LIST *list;
5639 #if defined (ARRAY_VARS) && defined (DEBUGGER)
5640 SHELL_VAR *bush_argv_v, *bush_argc_v;
5641 ARRAY *bush_argv_a, *bush_argc_a;
5642 WORD_LIST *l;
5643 arrayind_t i;
5644 char *t;
5646 GET_ARRAY_FROM_VAR ("BUSH_ARGV", bush_argv_v, bush_argv_a);
5647 GET_ARRAY_FROM_VAR ("BUSH_ARGC", bush_argc_v, bush_argc_a);
5649 for (l = list, i = 0; l; l = l->next, i++)
5650 array_push (bush_argv_a, l->word->word);
5652 t = itos (i);
5653 array_push (bush_argc_a, t);
5654 free (t);
5655 #endif /* ARRAY_VARS && DEBUGGER */
5658 /* Remove arguments from BUSH_ARGV array. Pop top element off BUSH_ARGC
5659 array and use that value as the count of elements to remove from
5660 BUSH_ARGV. */
5661 void
5662 pop_args ()
5664 #if defined (ARRAY_VARS) && defined (DEBUGGER)
5665 SHELL_VAR *bush_argv_v, *bush_argc_v;
5666 ARRAY *bush_argv_a, *bush_argc_a;
5667 ARRAY_ELEMENT *ce;
5668 intmax_t i;
5670 GET_ARRAY_FROM_VAR ("BUSH_ARGV", bush_argv_v, bush_argv_a);
5671 GET_ARRAY_FROM_VAR ("BUSH_ARGC", bush_argc_v, bush_argc_a);
5673 ce = array_shift (bush_argc_a, 1, 0);
5674 if (ce == 0 || legal_number (element_value (ce), &i) == 0)
5675 i = 0;
5677 for ( ; i > 0; i--)
5678 array_pop (bush_argv_a);
5679 array_dispose_element (ce);
5680 #endif /* ARRAY_VARS && DEBUGGER */
5683 /*************************************************
5685 * Functions to manage special variables *
5687 *************************************************/
5689 /* Extern declarations for variables this code has to manage. */
5691 /* An alist of name.function for each special variable. Most of the
5692 functions don't do much, and in fact, this would be faster with a
5693 switch statement, but by the end of this file, I am sick of switch
5694 statements. */
5696 #define SET_INT_VAR(name, intvar) intvar = find_variable (name) != 0
5698 /* This table will be sorted with qsort() the first time it's accessed. */
5699 struct name_and_function {
5700 char *name;
5701 sh_sv_func_t *function;
5704 static struct name_and_function special_vars[] = {
5705 { "BUSH_COMPAT", sv_shcompat },
5706 { "BUSH_XTRACEFD", sv_xtracefd },
5708 #if defined (JOB_CONTROL)
5709 { "CHILD_MAX", sv_childmax },
5710 #endif
5712 #if defined (READLINE)
5713 # if defined (STRICT_POSIX)
5714 { "COLUMNS", sv_winsize },
5715 # endif
5716 { "COMP_WORDBREAKS", sv_comp_wordbreaks },
5717 #endif
5719 { "EXECIGNORE", sv_execignore },
5721 { "FUNCNEST", sv_funcnest },
5723 { "GLOBIGNORE", sv_globignore },
5725 #if defined (HISTORY)
5726 { "HISTCONTROL", sv_history_control },
5727 { "HISTFILESIZE", sv_histsize },
5728 { "HISTIGNORE", sv_histignore },
5729 { "HISTSIZE", sv_histsize },
5730 { "HISTTIMEFORMAT", sv_histtimefmt },
5731 #endif
5733 #if defined (__CYGWIN__)
5734 { "HOME", sv_home },
5735 #endif
5737 #if defined (READLINE)
5738 { "HOSTFILE", sv_hostfile },
5739 #endif
5741 { "IFS", sv_ifs },
5742 { "IGNOREEOF", sv_ignoreeof },
5744 { "LANG", sv_locale },
5745 { "LC_ALL", sv_locale },
5746 { "LC_COLLATE", sv_locale },
5747 { "LC_CTYPE", sv_locale },
5748 { "LC_MESSAGES", sv_locale },
5749 { "LC_NUMERIC", sv_locale },
5750 { "LC_TIME", sv_locale },
5752 #if defined (READLINE) && defined (STRICT_POSIX)
5753 { "LINES", sv_winsize },
5754 #endif
5756 { "MAIL", sv_mail },
5757 { "MAILCHECK", sv_mail },
5758 { "MAILPATH", sv_mail },
5760 { "OPTERR", sv_opterr },
5761 { "OPTIND", sv_optind },
5763 { "PATH", sv_path },
5764 { "POSIXLY_CORRECT", sv_strict_posix },
5766 #if defined (READLINE)
5767 { "TERM", sv_terminal },
5768 { "TERMCAP", sv_terminal },
5769 { "TERMINFO", sv_terminal },
5770 #endif /* READLINE */
5772 { "TEXTDOMAIN", sv_locale },
5773 { "TEXTDOMAINDIR", sv_locale },
5775 #if defined (HAVE_TZSET)
5776 { "TZ", sv_tz },
5777 #endif
5779 #if defined (HISTORY) && defined (BANG_HISTORY)
5780 { "histchars", sv_histchars },
5781 #endif /* HISTORY && BANG_HISTORY */
5783 { "ignoreeof", sv_ignoreeof },
5785 { (char *)0, (sh_sv_func_t *)0 }
5788 #define N_SPECIAL_VARS (sizeof (special_vars) / sizeof (special_vars[0]) - 1)
5790 static int
5791 sv_compare (sv1, sv2)
5792 struct name_and_function *sv1, *sv2;
5794 int r;
5796 if ((r = sv1->name[0] - sv2->name[0]) == 0)
5797 r = strcmp (sv1->name, sv2->name);
5798 return r;
5801 static inline int
5802 find_special_var (name)
5803 const char *name;
5805 register int i, r;
5807 for (i = 0; special_vars[i].name; i++)
5809 r = special_vars[i].name[0] - name[0];
5810 if (r == 0)
5811 r = strcmp (special_vars[i].name, name);
5812 if (r == 0)
5813 return i;
5814 else if (r > 0)
5815 /* Can't match any of rest of elements in sorted list. Take this out
5816 if it causes problems in certain environments. */
5817 break;
5819 return -1;
5822 /* The variable in NAME has just had its state changed. Check to see if it
5823 is one of the special ones where something special happens. */
5824 void
5825 stupidly_hack_special_variables (name)
5826 char *name;
5828 static int sv_sorted = 0;
5829 int i;
5831 if (sv_sorted == 0) /* shouldn't need, but it's fairly cheap. */
5833 qsort (special_vars, N_SPECIAL_VARS, sizeof (special_vars[0]),
5834 (QSFUNC *)sv_compare);
5835 sv_sorted = 1;
5838 i = find_special_var (name);
5839 if (i != -1)
5840 (*(special_vars[i].function)) (name);
5843 /* Special variables that need hooks to be run when they are unset as part
5844 of shell reinitialization should have their sv_ functions run here. */
5845 void
5846 reinit_special_variables ()
5848 #if defined (READLINE)
5849 sv_comp_wordbreaks ("COMP_WORDBREAKS");
5850 #endif
5851 sv_globignore ("GLOBIGNORE");
5852 sv_opterr ("OPTERR");
5855 void
5856 sv_ifs (name)
5857 char *name;
5859 SHELL_VAR *v;
5861 v = find_variable ("IFS");
5862 setifs (v);
5865 /* What to do just after the PATH variable has changed. */
5866 void
5867 sv_path (name)
5868 char *name;
5870 /* hash -r */
5871 phash_flush ();
5874 /* What to do just after one of the MAILxxxx variables has changed. NAME
5875 is the name of the variable. This is called with NAME set to one of
5876 MAIL, MAILCHECK, or MAILPATH. */
5877 void
5878 sv_mail (name)
5879 char *name;
5881 /* If the time interval for checking the files has changed, then
5882 reset the mail timer. Otherwise, one of the pathname vars
5883 to the users mailbox has changed, so rebuild the array of
5884 filenames. */
5885 if (name[4] == 'C') /* if (strcmp (name, "MAILCHECK") == 0) */
5886 reset_mail_timer ();
5887 else
5889 free_mail_files ();
5890 remember_mail_dates ();
5894 void
5895 sv_funcnest (name)
5896 char *name;
5898 SHELL_VAR *v;
5899 intmax_t num;
5901 v = find_variable (name);
5902 if (v == 0)
5903 funcnest_max = 0;
5904 else if (legal_number (value_cell (v), &num) == 0)
5905 funcnest_max = 0;
5906 else
5907 funcnest_max = num;
5910 /* What to do when EXECIGNORE changes. */
5911 void
5912 sv_execignore (name)
5913 char *name;
5915 setup_exec_ignore (name);
5918 /* What to do when GLOBIGNORE changes. */
5919 void
5920 sv_globignore (name)
5921 char *name;
5923 if (privileged_mode == 0)
5924 setup_glob_ignore (name);
5927 #if defined (READLINE)
5928 void
5929 sv_comp_wordbreaks (name)
5930 char *name;
5932 SHELL_VAR *sv;
5934 sv = find_variable (name);
5935 if (sv == 0)
5936 reset_completer_word_break_chars ();
5939 /* What to do just after one of the TERMxxx variables has changed.
5940 If we are an interactive shell, then try to reset the terminal
5941 information in readline. */
5942 void
5943 sv_terminal (name)
5944 char *name;
5946 if (interactive_shell && no_line_editing == 0)
5947 rl_reset_terminal (get_string_value ("TERM"));
5950 void
5951 sv_hostfile (name)
5952 char *name;
5954 SHELL_VAR *v;
5956 v = find_variable (name);
5957 if (v == 0)
5958 clear_hostname_list ();
5959 else
5960 hostname_list_initialized = 0;
5963 #if defined (STRICT_POSIX)
5964 /* In strict posix mode, we allow assignments to LINES and COLUMNS (and values
5965 found in the initial environment) to override the terminal size reported by
5966 the kernel. */
5967 void
5968 sv_winsize (name)
5969 char *name;
5971 SHELL_VAR *v;
5972 intmax_t xd;
5973 int d;
5975 if (posixly_correct == 0 || interactive_shell == 0 || no_line_editing)
5976 return;
5978 v = find_variable (name);
5979 if (v == 0 || var_isset (v) == 0)
5980 rl_reset_screen_size ();
5981 else
5983 if (legal_number (value_cell (v), &xd) == 0)
5984 return;
5985 winsize_assignment = 1;
5986 d = xd; /* truncate */
5987 if (name[0] == 'L') /* LINES */
5988 rl_set_screen_size (d, -1);
5989 else /* COLUMNS */
5990 rl_set_screen_size (-1, d);
5991 winsize_assignment = 0;
5994 #endif /* STRICT_POSIX */
5995 #endif /* READLINE */
5997 /* Update the value of HOME in the export environment so tilde expansion will
5998 work on cygwin. */
5999 #if defined (__CYGWIN__)
6000 sv_home (name)
6001 char *name;
6003 array_needs_making = 1;
6004 maybe_make_export_env ();
6006 #endif
6008 #if defined (HISTORY)
6009 /* What to do after the HISTSIZE or HISTFILESIZE variables change.
6010 If there is a value for this HISTSIZE (and it is numeric), then stifle
6011 the history. Otherwise, if there is NO value for this variable,
6012 unstifle the history. If name is HISTFILESIZE, and its value is
6013 numeric, truncate the history file to hold no more than that many
6014 lines. */
6015 void
6016 sv_histsize (name)
6017 char *name;
6019 char *temp;
6020 intmax_t num;
6021 int hmax;
6023 temp = get_string_value (name);
6025 if (temp && *temp)
6027 if (legal_number (temp, &num))
6029 hmax = num;
6030 if (hmax < 0 && name[4] == 'S')
6031 unstifle_history (); /* unstifle history if HISTSIZE < 0 */
6032 else if (name[4] == 'S')
6034 stifle_history (hmax);
6035 hmax = where_history ();
6036 if (history_lines_this_session > hmax)
6037 history_lines_this_session = hmax;
6039 else if (hmax >= 0) /* truncate HISTFILE if HISTFILESIZE >= 0 */
6041 history_truncate_file (get_string_value ("HISTFILE"), hmax);
6042 /* If we just shrank the history file to fewer lines than we've
6043 already read, make sure we adjust our idea of how many lines
6044 we have read from the file. */
6045 if (hmax < history_lines_in_file)
6046 history_lines_in_file = hmax;
6050 else if (name[4] == 'S')
6051 unstifle_history ();
6054 /* What to do after the HISTIGNORE variable changes. */
6055 void
6056 sv_histignore (name)
6057 char *name;
6059 setup_history_ignore (name);
6062 /* What to do after the HISTCONTROL variable changes. */
6063 void
6064 sv_history_control (name)
6065 char *name;
6067 char *temp;
6068 char *val;
6069 int tptr;
6071 history_control = 0;
6072 temp = get_string_value (name);
6074 if (temp == 0 || *temp == 0)
6075 return;
6077 tptr = 0;
6078 while (val = extract_colon_unit (temp, &tptr))
6080 if (STREQ (val, "ignorespace"))
6081 history_control |= HC_IGNSPACE;
6082 else if (STREQ (val, "ignoredups"))
6083 history_control |= HC_IGNDUPS;
6084 else if (STREQ (val, "ignoreboth"))
6085 history_control |= HC_IGNBOTH;
6086 else if (STREQ (val, "erasedups"))
6087 history_control |= HC_ERASEDUPS;
6089 free (val);
6093 #if defined (BANG_HISTORY)
6094 /* Setting/unsetting of the history expansion character. */
6095 void
6096 sv_histchars (name)
6097 char *name;
6099 char *temp;
6101 temp = get_string_value (name);
6102 if (temp)
6104 history_expansion_char = *temp;
6105 if (temp[0] && temp[1])
6107 history_subst_char = temp[1];
6108 if (temp[2])
6109 history_comment_char = temp[2];
6112 else
6114 history_expansion_char = '!';
6115 history_subst_char = '^';
6116 history_comment_char = '#';
6119 #endif /* BANG_HISTORY */
6121 void
6122 sv_histtimefmt (name)
6123 char *name;
6125 SHELL_VAR *v;
6127 if (v = find_variable (name))
6129 if (history_comment_char == 0)
6130 history_comment_char = '#';
6132 history_write_timestamps = (v != 0);
6134 #endif /* HISTORY */
6136 #if defined (HAVE_TZSET)
6137 void
6138 sv_tz (name)
6139 char *name;
6141 SHELL_VAR *v;
6143 v = find_variable (name);
6144 if (v && exported_p (v))
6145 array_needs_making = 1;
6146 else if (v == 0)
6147 array_needs_making = 1;
6149 if (array_needs_making)
6151 maybe_make_export_env ();
6152 tzset ();
6155 #endif
6157 /* If the variable exists, then the value of it can be the number
6158 of times we actually ignore the EOF. The default is small,
6159 (smaller than csh, anyway). */
6160 void
6161 sv_ignoreeof (name)
6162 char *name;
6164 SHELL_VAR *tmp_var;
6165 char *temp;
6167 eof_encountered = 0;
6169 tmp_var = find_variable (name);
6170 ignoreeof = tmp_var && var_isset (tmp_var);
6171 temp = tmp_var ? value_cell (tmp_var) : (char *)NULL;
6172 if (temp)
6173 eof_encountered_limit = (*temp && all_digits (temp)) ? atoi (temp) : 10;
6174 set_shellopts (); /* make sure `ignoreeof' is/is not in $SHELLOPTS */
6177 void
6178 sv_optind (name)
6179 char *name;
6181 SHELL_VAR *var;
6182 char *tt;
6183 int s;
6185 var = find_variable ("OPTIND");
6186 tt = var ? get_variable_value (var) : (char *)NULL;
6188 /* Assume that if var->context < variable_context and variable_context > 0
6189 then we are restoring the variables's previous state while returning
6190 from a function. */
6191 if (tt && *tt)
6193 s = atoi (tt);
6195 /* According to POSIX, setting OPTIND=1 resets the internal state
6196 of getopt (). */
6197 if (s < 0 || s == 1)
6198 s = 0;
6200 else
6201 s = 0;
6202 getopts_reset (s);
6205 void
6206 sv_opterr (name)
6207 char *name;
6209 char *tt;
6211 tt = get_string_value ("OPTERR");
6212 sh_opterr = (tt && *tt) ? atoi (tt) : 1;
6215 void
6216 sv_strict_posix (name)
6217 char *name;
6219 SHELL_VAR *var;
6221 var = find_variable (name);
6222 posixly_correct = var && var_isset (var);
6223 posix_initialize (posixly_correct);
6224 #if defined (READLINE)
6225 if (interactive_shell)
6226 posix_readline_initialize (posixly_correct);
6227 #endif /* READLINE */
6228 set_shellopts (); /* make sure `posix' is/is not in $SHELLOPTS */
6231 void
6232 sv_locale (name)
6233 char *name;
6235 char *v;
6236 int r;
6238 v = get_string_value (name);
6239 if (name[0] == 'L' && name[1] == 'A') /* LANG */
6240 r = set_lang (name, v);
6241 else
6242 r = set_locale_var (name, v); /* LC_*, TEXTDOMAIN* */
6244 #if 1
6245 if (r == 0 && posixly_correct)
6246 set_exit_status (EXECUTION_FAILURE);
6247 #endif
6250 #if defined (ARRAY_VARS)
6251 void
6252 set_pipestatus_array (ps, nproc)
6253 int *ps;
6254 int nproc;
6256 SHELL_VAR *v;
6257 ARRAY *a;
6258 ARRAY_ELEMENT *ae;
6259 register int i;
6260 char *t, tbuf[INT_STRLEN_BOUND(int) + 1];
6262 v = find_variable ("PIPESTATUS");
6263 if (v == 0)
6264 v = make_new_array_variable ("PIPESTATUS");
6265 if (array_p (v) == 0)
6266 return; /* Do nothing if not an array variable. */
6267 a = array_cell (v);
6269 if (a == 0 || array_num_elements (a) == 0)
6271 for (i = 0; i < nproc; i++) /* was ps[i] != -1, not i < nproc */
6273 t = inttostr (ps[i], tbuf, sizeof (tbuf));
6274 array_insert (a, i, t);
6276 return;
6279 /* Fast case */
6280 if (array_num_elements (a) == nproc && nproc == 1)
6282 ae = element_forw (a->head);
6283 free (element_value (ae));
6284 set_element_value (ae, itos (ps[0]));
6286 else if (array_num_elements (a) <= nproc)
6288 /* modify in array_num_elements members in place, then add */
6289 ae = a->head;
6290 for (i = 0; i < array_num_elements (a); i++)
6292 ae = element_forw (ae);
6293 free (element_value (ae));
6294 set_element_value (ae, itos (ps[i]));
6296 /* add any more */
6297 for ( ; i < nproc; i++)
6299 t = inttostr (ps[i], tbuf, sizeof (tbuf));
6300 array_insert (a, i, t);
6303 else
6305 /* deleting elements. it's faster to rebuild the array. */
6306 array_flush (a);
6307 for (i = 0; ps[i] != -1; i++)
6309 t = inttostr (ps[i], tbuf, sizeof (tbuf));
6310 array_insert (a, i, t);
6315 ARRAY *
6316 save_pipestatus_array ()
6318 SHELL_VAR *v;
6319 ARRAY *a;
6321 v = find_variable ("PIPESTATUS");
6322 if (v == 0 || array_p (v) == 0 || array_cell (v) == 0)
6323 return ((ARRAY *)NULL);
6325 a = array_copy (array_cell (v));
6327 return a;
6330 void
6331 restore_pipestatus_array (a)
6332 ARRAY *a;
6334 SHELL_VAR *v;
6335 ARRAY *a2;
6337 v = find_variable ("PIPESTATUS");
6338 /* XXX - should we still assign even if existing value is NULL? */
6339 if (v == 0 || array_p (v) == 0 || array_cell (v) == 0)
6340 return;
6342 a2 = array_cell (v);
6343 var_setarray (v, a);
6345 array_dispose (a2);
6347 #endif
6349 void
6350 set_pipestatus_from_exit (s)
6351 int s;
6353 #if defined (ARRAY_VARS)
6354 static int v[2] = { 0, -1 };
6356 v[0] = s;
6357 set_pipestatus_array (v, 1);
6358 #endif
6361 void
6362 sv_xtracefd (name)
6363 char *name;
6365 SHELL_VAR *v;
6366 char *t, *e;
6367 int fd;
6368 FILE *fp;
6370 v = find_variable (name);
6371 if (v == 0)
6373 xtrace_reset ();
6374 return;
6377 t = value_cell (v);
6378 if (t == 0 || *t == 0)
6379 xtrace_reset ();
6380 else
6382 fd = (int)strtol (t, &e, 10);
6383 if (e != t && *e == '\0' && sh_validfd (fd))
6385 fp = fdopen (fd, "w");
6386 if (fp == 0)
6387 internal_error (_("%s: %s: cannot open as FILE"), name, value_cell (v));
6388 else
6389 xtrace_set (fd, fp);
6391 else
6392 internal_error (_("%s: %s: invalid value for trace file descriptor"), name, value_cell (v));
6396 #define MIN_COMPAT_LEVEL 31
6398 void
6399 sv_shcompat (name)
6400 char *name;
6402 SHELL_VAR *v;
6403 char *val;
6404 int tens, ones, compatval;
6406 v = find_variable (name);
6407 if (v == 0)
6409 shell_compatibility_level = DEFAULT_COMPAT_LEVEL;
6410 set_compatibility_opts ();
6411 return;
6413 val = value_cell (v);
6414 if (val == 0 || *val == '\0')
6416 shell_compatibility_level = DEFAULT_COMPAT_LEVEL;
6417 set_compatibility_opts ();
6418 return;
6420 /* Handle decimal-like compatibility version specifications: 4.2 */
6421 if (ISDIGIT (val[0]) && val[1] == '.' && ISDIGIT (val[2]) && val[3] == 0)
6423 tens = val[0] - '0';
6424 ones = val[2] - '0';
6425 compatval = tens*10 + ones;
6427 /* Handle integer-like compatibility version specifications: 42 */
6428 else if (ISDIGIT (val[0]) && ISDIGIT (val[1]) && val[2] == 0)
6430 tens = val[0] - '0';
6431 ones = val[1] - '0';
6432 compatval = tens*10 + ones;
6434 else
6436 compat_error:
6437 internal_error (_("%s: %s: compatibility value out of range"), name, val);
6438 shell_compatibility_level = DEFAULT_COMPAT_LEVEL;
6439 set_compatibility_opts ();
6440 return;
6443 if (compatval < MIN_COMPAT_LEVEL || compatval > DEFAULT_COMPAT_LEVEL)
6444 goto compat_error;
6446 shell_compatibility_level = compatval;
6447 set_compatibility_opts ();
6450 #if defined (JOB_CONTROL)
6451 void
6452 sv_childmax (name)
6453 char *name;
6455 char *tt;
6456 int s;
6458 tt = get_string_value (name);
6459 s = (tt && *tt) ? atoi (tt) : 0;
6460 set_maxchild (s);
6462 #endif