]> git.ipfire.org Git - thirdparty/bash.git/blob - variables.c
Bash-4.3 patch 25
[thirdparty/bash.git] / variables.c
1 /* variables.c -- Functions for hacking shell variables. */
2
3 /* Copyright (C) 1987-2013 Free Software Foundation, Inc.
4
5 This file is part of GNU Bash, the Bourne Again SHell.
6
7 Bash is free software: you can redistribute it and/or modify
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.
11
12 Bash is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Bash. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "config.h"
22
23 #include "bashtypes.h"
24 #include "posixstat.h"
25 #include "posixtime.h"
26
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__ */
34
35 #if defined (HAVE_UNISTD_H)
36 # include <unistd.h>
37 #endif
38
39 #include <stdio.h>
40 #include "chartypes.h"
41 #if defined (HAVE_PWD_H)
42 # include <pwd.h>
43 #endif
44 #include "bashansi.h"
45 #include "bashintl.h"
46
47 #define NEED_XTRACE_SET_DECL
48
49 #include "shell.h"
50 #include "flags.h"
51 #include "execute_cmd.h"
52 #include "findcmd.h"
53 #include "mailcheck.h"
54 #include "input.h"
55 #include "hashcmd.h"
56 #include "pathexp.h"
57 #include "alias.h"
58 #include "jobs.h"
59
60 #include "version.h"
61
62 #include "builtins/getopt.h"
63 #include "builtins/common.h"
64 #include "builtins/builtext.h"
65
66 #if defined (READLINE)
67 # include "bashline.h"
68 # include <readline/readline.h>
69 #else
70 # include <tilde/tilde.h>
71 #endif
72
73 #if defined (HISTORY)
74 # include "bashhist.h"
75 # include <readline/history.h>
76 #endif /* HISTORY */
77
78 #if defined (PROGRAMMABLE_COMPLETION)
79 # include "pcomplete.h"
80 #endif
81
82 #define TEMPENV_HASH_BUCKETS 4 /* must be power of two */
83
84 #define ifsname(s) ((s)[0] == 'I' && (s)[1] == 'F' && (s)[2] == 'S' && (s)[3] == '\0')
85
86 extern char **environ;
87
88 /* Variables used here and defined in other files. */
89 extern int posixly_correct;
90 extern int line_number, line_number_base;
91 extern int subshell_environment, indirection_level, subshell_level;
92 extern int build_version, patch_level;
93 extern int expanding_redir;
94 extern int last_command_exit_value;
95 extern char *dist_version, *release_status;
96 extern char *shell_name;
97 extern char *primary_prompt, *secondary_prompt;
98 extern char *current_host_name;
99 extern sh_builtin_func_t *this_shell_builtin;
100 extern SHELL_VAR *this_shell_function;
101 extern char *the_printed_command_except_trap;
102 extern char *this_command_name;
103 extern char *command_execution_string;
104 extern time_t shell_start_time;
105 extern int assigning_in_environment;
106 extern int executing_builtin;
107 extern int funcnest_max;
108
109 #if defined (READLINE)
110 extern int no_line_editing;
111 extern int perform_hostname_completion;
112 #endif
113
114 /* The list of shell variables that the user has created at the global
115 scope, or that came from the environment. */
116 VAR_CONTEXT *global_variables = (VAR_CONTEXT *)NULL;
117
118 /* The current list of shell variables, including function scopes */
119 VAR_CONTEXT *shell_variables = (VAR_CONTEXT *)NULL;
120
121 /* The list of shell functions that the user has created, or that came from
122 the environment. */
123 HASH_TABLE *shell_functions = (HASH_TABLE *)NULL;
124
125 #if defined (DEBUGGER)
126 /* The table of shell function definitions that the user defined or that
127 came from the environment. */
128 HASH_TABLE *shell_function_defs = (HASH_TABLE *)NULL;
129 #endif
130
131 /* The current variable context. This is really a count of how deep into
132 executing functions we are. */
133 int variable_context = 0;
134
135 /* The set of shell assignments which are made only in the environment
136 for a single command. */
137 HASH_TABLE *temporary_env = (HASH_TABLE *)NULL;
138
139 /* Set to non-zero if an assignment error occurs while putting variables
140 into the temporary environment. */
141 int tempenv_assign_error;
142
143 /* Some funky variables which are known about specially. Here is where
144 "$*", "$1", and all the cruft is kept. */
145 char *dollar_vars[10];
146 WORD_LIST *rest_of_args = (WORD_LIST *)NULL;
147
148 /* The value of $$. */
149 pid_t dollar_dollar_pid;
150
151 /* Non-zero means that we have to remake EXPORT_ENV. */
152 int array_needs_making = 1;
153
154 /* The number of times BASH has been executed. This is set
155 by initialize_variables (). */
156 int shell_level = 0;
157
158 /* An array which is passed to commands as their environment. It is
159 manufactured from the union of the initial environment and the
160 shell variables that are marked for export. */
161 char **export_env = (char **)NULL;
162 static int export_env_index;
163 static int export_env_size;
164
165 #if defined (READLINE)
166 static int winsize_assignment; /* currently assigning to LINES or COLUMNS */
167 #endif
168
169 static HASH_TABLE *last_table_searched; /* hash_lookup sets this */
170
171 /* Some forward declarations. */
172 static void create_variable_tables __P((void));
173
174 static void set_machine_vars __P((void));
175 static void set_home_var __P((void));
176 static void set_shell_var __P((void));
177 static char *get_bash_name __P((void));
178 static void initialize_shell_level __P((void));
179 static void uidset __P((void));
180 #if defined (ARRAY_VARS)
181 static void make_vers_array __P((void));
182 #endif
183
184 static SHELL_VAR *null_assign __P((SHELL_VAR *, char *, arrayind_t, char *));
185 #if defined (ARRAY_VARS)
186 static SHELL_VAR *null_array_assign __P((SHELL_VAR *, char *, arrayind_t, char *));
187 #endif
188 static SHELL_VAR *get_self __P((SHELL_VAR *));
189
190 #if defined (ARRAY_VARS)
191 static SHELL_VAR *init_dynamic_array_var __P((char *, sh_var_value_func_t *, sh_var_assign_func_t *, int));
192 static SHELL_VAR *init_dynamic_assoc_var __P((char *, sh_var_value_func_t *, sh_var_assign_func_t *, int));
193 #endif
194
195 static SHELL_VAR *assign_seconds __P((SHELL_VAR *, char *, arrayind_t, char *));
196 static SHELL_VAR *get_seconds __P((SHELL_VAR *));
197 static SHELL_VAR *init_seconds_var __P((void));
198
199 static int brand __P((void));
200 static void sbrand __P((unsigned long)); /* set bash random number generator. */
201 static void seedrand __P((void)); /* seed generator randomly */
202 static SHELL_VAR *assign_random __P((SHELL_VAR *, char *, arrayind_t, char *));
203 static SHELL_VAR *get_random __P((SHELL_VAR *));
204
205 static SHELL_VAR *assign_lineno __P((SHELL_VAR *, char *, arrayind_t, char *));
206 static SHELL_VAR *get_lineno __P((SHELL_VAR *));
207
208 static SHELL_VAR *assign_subshell __P((SHELL_VAR *, char *, arrayind_t, char *));
209 static SHELL_VAR *get_subshell __P((SHELL_VAR *));
210
211 static SHELL_VAR *get_bashpid __P((SHELL_VAR *));
212
213 #if defined (HISTORY)
214 static SHELL_VAR *get_histcmd __P((SHELL_VAR *));
215 #endif
216
217 #if defined (READLINE)
218 static SHELL_VAR *get_comp_wordbreaks __P((SHELL_VAR *));
219 static SHELL_VAR *assign_comp_wordbreaks __P((SHELL_VAR *, char *, arrayind_t, char *));
220 #endif
221
222 #if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
223 static SHELL_VAR *assign_dirstack __P((SHELL_VAR *, char *, arrayind_t, char *));
224 static SHELL_VAR *get_dirstack __P((SHELL_VAR *));
225 #endif
226
227 #if defined (ARRAY_VARS)
228 static SHELL_VAR *get_groupset __P((SHELL_VAR *));
229
230 static SHELL_VAR *build_hashcmd __P((SHELL_VAR *));
231 static SHELL_VAR *get_hashcmd __P((SHELL_VAR *));
232 static SHELL_VAR *assign_hashcmd __P((SHELL_VAR *, char *, arrayind_t, char *));
233 # if defined (ALIAS)
234 static SHELL_VAR *build_aliasvar __P((SHELL_VAR *));
235 static SHELL_VAR *get_aliasvar __P((SHELL_VAR *));
236 static SHELL_VAR *assign_aliasvar __P((SHELL_VAR *, char *, arrayind_t, char *));
237 # endif
238 #endif
239
240 static SHELL_VAR *get_funcname __P((SHELL_VAR *));
241 static SHELL_VAR *init_funcname_var __P((void));
242
243 static void initialize_dynamic_variables __P((void));
244
245 static SHELL_VAR *hash_lookup __P((const char *, HASH_TABLE *));
246 static SHELL_VAR *new_shell_variable __P((const char *));
247 static SHELL_VAR *make_new_variable __P((const char *, HASH_TABLE *));
248 static SHELL_VAR *bind_variable_internal __P((const char *, char *, HASH_TABLE *, int, int));
249
250 static void dispose_variable_value __P((SHELL_VAR *));
251 static void free_variable_hash_data __P((PTR_T));
252
253 static VARLIST *vlist_alloc __P((int));
254 static VARLIST *vlist_realloc __P((VARLIST *, int));
255 static void vlist_add __P((VARLIST *, SHELL_VAR *, int));
256
257 static void flatten __P((HASH_TABLE *, sh_var_map_func_t *, VARLIST *, int));
258
259 static int qsort_var_comp __P((SHELL_VAR **, SHELL_VAR **));
260
261 static SHELL_VAR **vapply __P((sh_var_map_func_t *));
262 static SHELL_VAR **fapply __P((sh_var_map_func_t *));
263
264 static int visible_var __P((SHELL_VAR *));
265 static int visible_and_exported __P((SHELL_VAR *));
266 static int export_environment_candidate __P((SHELL_VAR *));
267 static int local_and_exported __P((SHELL_VAR *));
268 static int variable_in_context __P((SHELL_VAR *));
269 #if defined (ARRAY_VARS)
270 static int visible_array_vars __P((SHELL_VAR *));
271 #endif
272
273 static SHELL_VAR *find_nameref_at_context __P((SHELL_VAR *, VAR_CONTEXT *));
274 static SHELL_VAR *find_variable_nameref_context __P((SHELL_VAR *, VAR_CONTEXT *, VAR_CONTEXT **));
275 static SHELL_VAR *find_variable_last_nameref_context __P((SHELL_VAR *, VAR_CONTEXT *, VAR_CONTEXT **));
276
277 static SHELL_VAR *bind_tempenv_variable __P((const char *, char *));
278 static void push_temp_var __P((PTR_T));
279 static void propagate_temp_var __P((PTR_T));
280 static void dispose_temporary_env __P((sh_free_func_t *));
281
282 static inline char *mk_env_string __P((const char *, const char *));
283 static char **make_env_array_from_var_list __P((SHELL_VAR **));
284 static char **make_var_export_array __P((VAR_CONTEXT *));
285 static char **make_func_export_array __P((void));
286 static void add_temp_array_to_env __P((char **, int, int));
287
288 static int n_shell_variables __P((void));
289 static int set_context __P((SHELL_VAR *));
290
291 static void push_func_var __P((PTR_T));
292 static void push_exported_var __P((PTR_T));
293
294 static inline int find_special_var __P((const char *));
295
296 static void
297 create_variable_tables ()
298 {
299 if (shell_variables == 0)
300 {
301 shell_variables = global_variables = new_var_context ((char *)NULL, 0);
302 shell_variables->scope = 0;
303 shell_variables->table = hash_create (0);
304 }
305
306 if (shell_functions == 0)
307 shell_functions = hash_create (0);
308
309 #if defined (DEBUGGER)
310 if (shell_function_defs == 0)
311 shell_function_defs = hash_create (0);
312 #endif
313 }
314
315 /* Initialize the shell variables from the current environment.
316 If PRIVMODE is nonzero, don't import functions from ENV or
317 parse $SHELLOPTS. */
318 void
319 initialize_shell_variables (env, privmode)
320 char **env;
321 int privmode;
322 {
323 char *name, *string, *temp_string;
324 int c, char_index, string_index, string_length, ro;
325 SHELL_VAR *temp_var;
326
327 create_variable_tables ();
328
329 for (string_index = 0; string = env[string_index++]; )
330 {
331 char_index = 0;
332 name = string;
333 while ((c = *string++) && c != '=')
334 ;
335 if (string[-1] == '=')
336 char_index = string - name - 1;
337
338 /* If there are weird things in the environment, like `=xxx' or a
339 string without an `=', just skip them. */
340 if (char_index == 0)
341 continue;
342
343 /* ASSERT(name[char_index] == '=') */
344 name[char_index] = '\0';
345 /* Now, name = env variable name, string = env variable value, and
346 char_index == strlen (name) */
347
348 temp_var = (SHELL_VAR *)NULL;
349
350 /* If exported function, define it now. Don't import functions from
351 the environment in privileged mode. */
352 if (privmode == 0 && read_but_dont_execute == 0 && STREQN ("() {", string, 4))
353 {
354 string_length = strlen (string);
355 temp_string = (char *)xmalloc (3 + string_length + char_index);
356
357 strcpy (temp_string, name);
358 temp_string[char_index] = ' ';
359 strcpy (temp_string + char_index + 1, string);
360
361 /* Don't import function names that are invalid identifiers from the
362 environment, though we still allow them to be defined as shell
363 variables. */
364 if (legal_identifier (name))
365 parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD);
366
367 if (temp_var = find_function (name))
368 {
369 VSETATTR (temp_var, (att_exported|att_imported));
370 array_needs_making = 1;
371 }
372 else
373 {
374 if (temp_var = bind_variable (name, string, 0))
375 {
376 VSETATTR (temp_var, (att_exported | att_imported | att_invisible));
377 array_needs_making = 1;
378 }
379 last_command_exit_value = 1;
380 report_error (_("error importing function definition for `%s'"), name);
381 }
382 }
383 #if defined (ARRAY_VARS)
384 # if ARRAY_EXPORT
385 /* Array variables may not yet be exported. */
386 else if (*string == '(' && string[1] == '[' && string[strlen (string) - 1] == ')')
387 {
388 string_length = 1;
389 temp_string = extract_array_assignment_list (string, &string_length);
390 temp_var = assign_array_from_string (name, temp_string);
391 FREE (temp_string);
392 VSETATTR (temp_var, (att_exported | att_imported));
393 array_needs_making = 1;
394 }
395 # endif /* ARRAY_EXPORT */
396 #endif
397 #if 0
398 else if (legal_identifier (name))
399 #else
400 else
401 #endif
402 {
403 ro = 0;
404 if (posixly_correct && STREQ (name, "SHELLOPTS"))
405 {
406 temp_var = find_variable ("SHELLOPTS");
407 ro = temp_var && readonly_p (temp_var);
408 if (temp_var)
409 VUNSETATTR (temp_var, att_readonly);
410 }
411 temp_var = bind_variable (name, string, 0);
412 if (temp_var)
413 {
414 if (legal_identifier (name))
415 VSETATTR (temp_var, (att_exported | att_imported));
416 else
417 VSETATTR (temp_var, (att_exported | att_imported | att_invisible));
418 if (ro)
419 VSETATTR (temp_var, att_readonly);
420 array_needs_making = 1;
421 }
422 }
423
424 name[char_index] = '=';
425 /* temp_var can be NULL if it was an exported function with a syntax
426 error (a different bug, but it still shouldn't dump core). */
427 if (temp_var && function_p (temp_var) == 0) /* XXX not yet */
428 {
429 CACHE_IMPORTSTR (temp_var, name);
430 }
431 }
432
433 set_pwd ();
434
435 /* Set up initial value of $_ */
436 temp_var = set_if_not ("_", dollar_vars[0]);
437
438 /* Remember this pid. */
439 dollar_dollar_pid = getpid ();
440
441 /* Now make our own defaults in case the vars that we think are
442 important are missing. */
443 temp_var = set_if_not ("PATH", DEFAULT_PATH_VALUE);
444 #if 0
445 set_auto_export (temp_var); /* XXX */
446 #endif
447
448 temp_var = set_if_not ("TERM", "dumb");
449 #if 0
450 set_auto_export (temp_var); /* XXX */
451 #endif
452
453 #if defined (__QNX__)
454 /* set node id -- don't import it from the environment */
455 {
456 char node_name[22];
457 # if defined (__QNXNTO__)
458 netmgr_ndtostr(ND2S_LOCAL_STR, ND_LOCAL_NODE, node_name, sizeof(node_name));
459 # else
460 qnx_nidtostr (getnid (), node_name, sizeof (node_name));
461 # endif
462 temp_var = bind_variable ("NODE", node_name, 0);
463 set_auto_export (temp_var);
464 }
465 #endif
466
467 /* set up the prompts. */
468 if (interactive_shell)
469 {
470 #if defined (PROMPT_STRING_DECODE)
471 set_if_not ("PS1", primary_prompt);
472 #else
473 if (current_user.uid == -1)
474 get_current_user_info ();
475 set_if_not ("PS1", current_user.euid == 0 ? "# " : primary_prompt);
476 #endif
477 set_if_not ("PS2", secondary_prompt);
478 }
479 set_if_not ("PS4", "+ ");
480
481 /* Don't allow IFS to be imported from the environment. */
482 temp_var = bind_variable ("IFS", " \t\n", 0);
483 setifs (temp_var);
484
485 /* Magic machine types. Pretty convenient. */
486 set_machine_vars ();
487
488 /* Default MAILCHECK for interactive shells. Defer the creation of a
489 default MAILPATH until the startup files are read, because MAIL
490 names a mail file if MAILPATH is not set, and we should provide a
491 default only if neither is set. */
492 if (interactive_shell)
493 {
494 temp_var = set_if_not ("MAILCHECK", posixly_correct ? "600" : "60");
495 VSETATTR (temp_var, att_integer);
496 }
497
498 /* Do some things with shell level. */
499 initialize_shell_level ();
500
501 set_ppid ();
502
503 /* Initialize the `getopts' stuff. */
504 temp_var = bind_variable ("OPTIND", "1", 0);
505 VSETATTR (temp_var, att_integer);
506 getopts_reset (0);
507 bind_variable ("OPTERR", "1", 0);
508 sh_opterr = 1;
509
510 if (login_shell == 1 && posixly_correct == 0)
511 set_home_var ();
512
513 /* Get the full pathname to THIS shell, and set the BASH variable
514 to it. */
515 name = get_bash_name ();
516 temp_var = bind_variable ("BASH", name, 0);
517 free (name);
518
519 /* Make the exported environment variable SHELL be the user's login
520 shell. Note that the `tset' command looks at this variable
521 to determine what style of commands to output; if it ends in "csh",
522 then C-shell commands are output, else Bourne shell commands. */
523 set_shell_var ();
524
525 /* Make a variable called BASH_VERSION which contains the version info. */
526 bind_variable ("BASH_VERSION", shell_version_string (), 0);
527 #if defined (ARRAY_VARS)
528 make_vers_array ();
529 #endif
530
531 if (command_execution_string)
532 bind_variable ("BASH_EXECUTION_STRING", command_execution_string, 0);
533
534 /* Find out if we're supposed to be in Posix.2 mode via an
535 environment variable. */
536 temp_var = find_variable ("POSIXLY_CORRECT");
537 if (!temp_var)
538 temp_var = find_variable ("POSIX_PEDANTIC");
539 if (temp_var && imported_p (temp_var))
540 sv_strict_posix (temp_var->name);
541
542 #if defined (HISTORY)
543 /* Set history variables to defaults, and then do whatever we would
544 do if the variable had just been set. Do this only in the case
545 that we are remembering commands on the history list. */
546 if (remember_on_history)
547 {
548 name = bash_tilde_expand (posixly_correct ? "~/.sh_history" : "~/.bash_history", 0);
549
550 set_if_not ("HISTFILE", name);
551 free (name);
552 }
553 #endif /* HISTORY */
554
555 /* Seed the random number generator. */
556 seedrand ();
557
558 /* Handle some "special" variables that we may have inherited from a
559 parent shell. */
560 if (interactive_shell)
561 {
562 temp_var = find_variable ("IGNOREEOF");
563 if (!temp_var)
564 temp_var = find_variable ("ignoreeof");
565 if (temp_var && imported_p (temp_var))
566 sv_ignoreeof (temp_var->name);
567 }
568
569 #if defined (HISTORY)
570 if (interactive_shell && remember_on_history)
571 {
572 sv_history_control ("HISTCONTROL");
573 sv_histignore ("HISTIGNORE");
574 sv_histtimefmt ("HISTTIMEFORMAT");
575 }
576 #endif /* HISTORY */
577
578 #if defined (READLINE) && defined (STRICT_POSIX)
579 /* POSIXLY_CORRECT will only be 1 here if the shell was compiled
580 -DSTRICT_POSIX */
581 if (interactive_shell && posixly_correct && no_line_editing == 0)
582 rl_prefer_env_winsize = 1;
583 #endif /* READLINE && STRICT_POSIX */
584
585 /*
586 * 24 October 2001
587 *
588 * I'm tired of the arguing and bug reports. Bash now leaves SSH_CLIENT
589 * and SSH2_CLIENT alone. I'm going to rely on the shell_level check in
590 * isnetconn() to avoid running the startup files more often than wanted.
591 * That will, of course, only work if the user's login shell is bash, so
592 * I've made that behavior conditional on SSH_SOURCE_BASHRC being defined
593 * in config-top.h.
594 */
595 #if 0
596 temp_var = find_variable ("SSH_CLIENT");
597 if (temp_var && imported_p (temp_var))
598 {
599 VUNSETATTR (temp_var, att_exported);
600 array_needs_making = 1;
601 }
602 temp_var = find_variable ("SSH2_CLIENT");
603 if (temp_var && imported_p (temp_var))
604 {
605 VUNSETATTR (temp_var, att_exported);
606 array_needs_making = 1;
607 }
608 #endif
609
610 /* Get the user's real and effective user ids. */
611 uidset ();
612
613 temp_var = find_variable ("BASH_XTRACEFD");
614 if (temp_var && imported_p (temp_var))
615 sv_xtracefd (temp_var->name);
616
617 /* Initialize the dynamic variables, and seed their values. */
618 initialize_dynamic_variables ();
619 }
620
621 /* **************************************************************** */
622 /* */
623 /* Setting values for special shell variables */
624 /* */
625 /* **************************************************************** */
626
627 static void
628 set_machine_vars ()
629 {
630 SHELL_VAR *temp_var;
631
632 temp_var = set_if_not ("HOSTTYPE", HOSTTYPE);
633 temp_var = set_if_not ("OSTYPE", OSTYPE);
634 temp_var = set_if_not ("MACHTYPE", MACHTYPE);
635
636 temp_var = set_if_not ("HOSTNAME", current_host_name);
637 }
638
639 /* Set $HOME to the information in the password file if we didn't get
640 it from the environment. */
641
642 /* This function is not static so the tilde and readline libraries can
643 use it. */
644 char *
645 sh_get_home_dir ()
646 {
647 if (current_user.home_dir == 0)
648 get_current_user_info ();
649 return current_user.home_dir;
650 }
651
652 static void
653 set_home_var ()
654 {
655 SHELL_VAR *temp_var;
656
657 temp_var = find_variable ("HOME");
658 if (temp_var == 0)
659 temp_var = bind_variable ("HOME", sh_get_home_dir (), 0);
660 #if 0
661 VSETATTR (temp_var, att_exported);
662 #endif
663 }
664
665 /* Set $SHELL to the user's login shell if it is not already set. Call
666 get_current_user_info if we haven't already fetched the shell. */
667 static void
668 set_shell_var ()
669 {
670 SHELL_VAR *temp_var;
671
672 temp_var = find_variable ("SHELL");
673 if (temp_var == 0)
674 {
675 if (current_user.shell == 0)
676 get_current_user_info ();
677 temp_var = bind_variable ("SHELL", current_user.shell, 0);
678 }
679 #if 0
680 VSETATTR (temp_var, att_exported);
681 #endif
682 }
683
684 static char *
685 get_bash_name ()
686 {
687 char *name;
688
689 if ((login_shell == 1) && RELPATH(shell_name))
690 {
691 if (current_user.shell == 0)
692 get_current_user_info ();
693 name = savestring (current_user.shell);
694 }
695 else if (ABSPATH(shell_name))
696 name = savestring (shell_name);
697 else if (shell_name[0] == '.' && shell_name[1] == '/')
698 {
699 /* Fast path for common case. */
700 char *cdir;
701 int len;
702
703 cdir = get_string_value ("PWD");
704 if (cdir)
705 {
706 len = strlen (cdir);
707 name = (char *)xmalloc (len + strlen (shell_name) + 1);
708 strcpy (name, cdir);
709 strcpy (name + len, shell_name + 1);
710 }
711 else
712 name = savestring (shell_name);
713 }
714 else
715 {
716 char *tname;
717 int s;
718
719 tname = find_user_command (shell_name);
720
721 if (tname == 0)
722 {
723 /* Try the current directory. If there is not an executable
724 there, just punt and use the login shell. */
725 s = file_status (shell_name);
726 if (s & FS_EXECABLE)
727 {
728 tname = make_absolute (shell_name, get_string_value ("PWD"));
729 if (*shell_name == '.')
730 {
731 name = sh_canonpath (tname, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
732 if (name == 0)
733 name = tname;
734 else
735 free (tname);
736 }
737 else
738 name = tname;
739 }
740 else
741 {
742 if (current_user.shell == 0)
743 get_current_user_info ();
744 name = savestring (current_user.shell);
745 }
746 }
747 else
748 {
749 name = full_pathname (tname);
750 free (tname);
751 }
752 }
753
754 return (name);
755 }
756
757 void
758 adjust_shell_level (change)
759 int change;
760 {
761 char new_level[5], *old_SHLVL;
762 intmax_t old_level;
763 SHELL_VAR *temp_var;
764
765 old_SHLVL = get_string_value ("SHLVL");
766 if (old_SHLVL == 0 || *old_SHLVL == '\0' || legal_number (old_SHLVL, &old_level) == 0)
767 old_level = 0;
768
769 shell_level = old_level + change;
770 if (shell_level < 0)
771 shell_level = 0;
772 else if (shell_level > 1000)
773 {
774 internal_warning (_("shell level (%d) too high, resetting to 1"), shell_level);
775 shell_level = 1;
776 }
777
778 /* We don't need the full generality of itos here. */
779 if (shell_level < 10)
780 {
781 new_level[0] = shell_level + '0';
782 new_level[1] = '\0';
783 }
784 else if (shell_level < 100)
785 {
786 new_level[0] = (shell_level / 10) + '0';
787 new_level[1] = (shell_level % 10) + '0';
788 new_level[2] = '\0';
789 }
790 else if (shell_level < 1000)
791 {
792 new_level[0] = (shell_level / 100) + '0';
793 old_level = shell_level % 100;
794 new_level[1] = (old_level / 10) + '0';
795 new_level[2] = (old_level % 10) + '0';
796 new_level[3] = '\0';
797 }
798
799 temp_var = bind_variable ("SHLVL", new_level, 0);
800 set_auto_export (temp_var);
801 }
802
803 static void
804 initialize_shell_level ()
805 {
806 adjust_shell_level (1);
807 }
808
809 /* If we got PWD from the environment, update our idea of the current
810 working directory. In any case, make sure that PWD exists before
811 checking it. It is possible for getcwd () to fail on shell startup,
812 and in that case, PWD would be undefined. If this is an interactive
813 login shell, see if $HOME is the current working directory, and if
814 that's not the same string as $PWD, set PWD=$HOME. */
815
816 void
817 set_pwd ()
818 {
819 SHELL_VAR *temp_var, *home_var;
820 char *temp_string, *home_string;
821
822 home_var = find_variable ("HOME");
823 home_string = home_var ? value_cell (home_var) : (char *)NULL;
824
825 temp_var = find_variable ("PWD");
826 if (temp_var && imported_p (temp_var) &&
827 (temp_string = value_cell (temp_var)) &&
828 same_file (temp_string, ".", (struct stat *)NULL, (struct stat *)NULL))
829 set_working_directory (temp_string);
830 else if (home_string && interactive_shell && login_shell &&
831 same_file (home_string, ".", (struct stat *)NULL, (struct stat *)NULL))
832 {
833 set_working_directory (home_string);
834 temp_var = bind_variable ("PWD", home_string, 0);
835 set_auto_export (temp_var);
836 }
837 else
838 {
839 temp_string = get_working_directory ("shell-init");
840 if (temp_string)
841 {
842 temp_var = bind_variable ("PWD", temp_string, 0);
843 set_auto_export (temp_var);
844 free (temp_string);
845 }
846 }
847
848 /* According to the Single Unix Specification, v2, $OLDPWD is an
849 `environment variable' and therefore should be auto-exported.
850 Make a dummy invisible variable for OLDPWD, and mark it as exported. */
851 temp_var = bind_variable ("OLDPWD", (char *)NULL, 0);
852 VSETATTR (temp_var, (att_exported | att_invisible));
853 }
854
855 /* Make a variable $PPID, which holds the pid of the shell's parent. */
856 void
857 set_ppid ()
858 {
859 char namebuf[INT_STRLEN_BOUND(pid_t) + 1], *name;
860 SHELL_VAR *temp_var;
861
862 name = inttostr (getppid (), namebuf, sizeof(namebuf));
863 temp_var = find_variable ("PPID");
864 if (temp_var)
865 VUNSETATTR (temp_var, (att_readonly | att_exported));
866 temp_var = bind_variable ("PPID", name, 0);
867 VSETATTR (temp_var, (att_readonly | att_integer));
868 }
869
870 static void
871 uidset ()
872 {
873 char buff[INT_STRLEN_BOUND(uid_t) + 1], *b;
874 register SHELL_VAR *v;
875
876 b = inttostr (current_user.uid, buff, sizeof (buff));
877 v = find_variable ("UID");
878 if (v == 0)
879 {
880 v = bind_variable ("UID", b, 0);
881 VSETATTR (v, (att_readonly | att_integer));
882 }
883
884 if (current_user.euid != current_user.uid)
885 b = inttostr (current_user.euid, buff, sizeof (buff));
886
887 v = find_variable ("EUID");
888 if (v == 0)
889 {
890 v = bind_variable ("EUID", b, 0);
891 VSETATTR (v, (att_readonly | att_integer));
892 }
893 }
894
895 #if defined (ARRAY_VARS)
896 static void
897 make_vers_array ()
898 {
899 SHELL_VAR *vv;
900 ARRAY *av;
901 char *s, d[32], b[INT_STRLEN_BOUND(int) + 1];
902
903 unbind_variable ("BASH_VERSINFO");
904
905 vv = make_new_array_variable ("BASH_VERSINFO");
906 av = array_cell (vv);
907 strcpy (d, dist_version);
908 s = strchr (d, '.');
909 if (s)
910 *s++ = '\0';
911 array_insert (av, 0, d);
912 array_insert (av, 1, s);
913 s = inttostr (patch_level, b, sizeof (b));
914 array_insert (av, 2, s);
915 s = inttostr (build_version, b, sizeof (b));
916 array_insert (av, 3, s);
917 array_insert (av, 4, release_status);
918 array_insert (av, 5, MACHTYPE);
919
920 VSETATTR (vv, att_readonly);
921 }
922 #endif /* ARRAY_VARS */
923
924 /* Set the environment variables $LINES and $COLUMNS in response to
925 a window size change. */
926 void
927 sh_set_lines_and_columns (lines, cols)
928 int lines, cols;
929 {
930 char val[INT_STRLEN_BOUND(int) + 1], *v;
931
932 #if defined (READLINE)
933 /* If we are currently assigning to LINES or COLUMNS, don't do anything. */
934 if (winsize_assignment)
935 return;
936 #endif
937
938 v = inttostr (lines, val, sizeof (val));
939 bind_variable ("LINES", v, 0);
940
941 v = inttostr (cols, val, sizeof (val));
942 bind_variable ("COLUMNS", v, 0);
943 }
944
945 /* **************************************************************** */
946 /* */
947 /* Printing variables and values */
948 /* */
949 /* **************************************************************** */
950
951 /* Print LIST (a list of shell variables) to stdout in such a way that
952 they can be read back in. */
953 void
954 print_var_list (list)
955 register SHELL_VAR **list;
956 {
957 register int i;
958 register SHELL_VAR *var;
959
960 for (i = 0; list && (var = list[i]); i++)
961 if (invisible_p (var) == 0)
962 print_assignment (var);
963 }
964
965 /* Print LIST (a list of shell functions) to stdout in such a way that
966 they can be read back in. */
967 void
968 print_func_list (list)
969 register SHELL_VAR **list;
970 {
971 register int i;
972 register SHELL_VAR *var;
973
974 for (i = 0; list && (var = list[i]); i++)
975 {
976 printf ("%s ", var->name);
977 print_var_function (var);
978 printf ("\n");
979 }
980 }
981
982 /* Print the value of a single SHELL_VAR. No newline is
983 output, but the variable is printed in such a way that
984 it can be read back in. */
985 void
986 print_assignment (var)
987 SHELL_VAR *var;
988 {
989 if (var_isset (var) == 0)
990 return;
991
992 if (function_p (var))
993 {
994 printf ("%s", var->name);
995 print_var_function (var);
996 printf ("\n");
997 }
998 #if defined (ARRAY_VARS)
999 else if (array_p (var))
1000 print_array_assignment (var, 0);
1001 else if (assoc_p (var))
1002 print_assoc_assignment (var, 0);
1003 #endif /* ARRAY_VARS */
1004 else
1005 {
1006 printf ("%s=", var->name);
1007 print_var_value (var, 1);
1008 printf ("\n");
1009 }
1010 }
1011
1012 /* Print the value cell of VAR, a shell variable. Do not print
1013 the name, nor leading/trailing newline. If QUOTE is non-zero,
1014 and the value contains shell metacharacters, quote the value
1015 in such a way that it can be read back in. */
1016 void
1017 print_var_value (var, quote)
1018 SHELL_VAR *var;
1019 int quote;
1020 {
1021 char *t;
1022
1023 if (var_isset (var) == 0)
1024 return;
1025
1026 if (quote && posixly_correct == 0 && ansic_shouldquote (value_cell (var)))
1027 {
1028 t = ansic_quote (value_cell (var), 0, (int *)0);
1029 printf ("%s", t);
1030 free (t);
1031 }
1032 else if (quote && sh_contains_shell_metas (value_cell (var)))
1033 {
1034 t = sh_single_quote (value_cell (var));
1035 printf ("%s", t);
1036 free (t);
1037 }
1038 else
1039 printf ("%s", value_cell (var));
1040 }
1041
1042 /* Print the function cell of VAR, a shell variable. Do not
1043 print the name, nor leading/trailing newline. */
1044 void
1045 print_var_function (var)
1046 SHELL_VAR *var;
1047 {
1048 char *x;
1049
1050 if (function_p (var) && var_isset (var))
1051 {
1052 x = named_function_string ((char *)NULL, function_cell(var), FUNC_MULTILINE|FUNC_EXTERNAL);
1053 printf ("%s", x);
1054 }
1055 }
1056
1057 /* **************************************************************** */
1058 /* */
1059 /* Dynamic Variables */
1060 /* */
1061 /* **************************************************************** */
1062
1063 /* DYNAMIC VARIABLES
1064
1065 These are variables whose values are generated anew each time they are
1066 referenced. These are implemented using a pair of function pointers
1067 in the struct variable: assign_func, which is called from bind_variable
1068 and, if arrays are compiled into the shell, some of the functions in
1069 arrayfunc.c, and dynamic_value, which is called from find_variable.
1070
1071 assign_func is called from bind_variable_internal, if
1072 bind_variable_internal discovers that the variable being assigned to
1073 has such a function. The function is called as
1074 SHELL_VAR *temp = (*(entry->assign_func)) (entry, value, ind)
1075 and the (SHELL_VAR *)temp is returned as the value of bind_variable. It
1076 is usually ENTRY (self). IND is an index for an array variable, and
1077 unused otherwise.
1078
1079 dynamic_value is called from find_variable_internal to return a `new'
1080 value for the specified dynamic varible. If this function is NULL,
1081 the variable is treated as a `normal' shell variable. If it is not,
1082 however, then this function is called like this:
1083 tempvar = (*(var->dynamic_value)) (var);
1084
1085 Sometimes `tempvar' will replace the value of `var'. Other times, the
1086 shell will simply use the string value. Pretty object-oriented, huh?
1087
1088 Be warned, though: if you `unset' a special variable, it loses its
1089 special meaning, even if you subsequently set it.
1090
1091 The special assignment code would probably have been better put in
1092 subst.c: do_assignment_internal, in the same style as
1093 stupidly_hack_special_variables, but I wanted the changes as
1094 localized as possible. */
1095
1096 #define INIT_DYNAMIC_VAR(var, val, gfunc, afunc) \
1097 do \
1098 { \
1099 v = bind_variable (var, (val), 0); \
1100 v->dynamic_value = gfunc; \
1101 v->assign_func = afunc; \
1102 } \
1103 while (0)
1104
1105 #define INIT_DYNAMIC_ARRAY_VAR(var, gfunc, afunc) \
1106 do \
1107 { \
1108 v = make_new_array_variable (var); \
1109 v->dynamic_value = gfunc; \
1110 v->assign_func = afunc; \
1111 } \
1112 while (0)
1113
1114 #define INIT_DYNAMIC_ASSOC_VAR(var, gfunc, afunc) \
1115 do \
1116 { \
1117 v = make_new_assoc_variable (var); \
1118 v->dynamic_value = gfunc; \
1119 v->assign_func = afunc; \
1120 } \
1121 while (0)
1122
1123 static SHELL_VAR *
1124 null_assign (self, value, unused, key)
1125 SHELL_VAR *self;
1126 char *value;
1127 arrayind_t unused;
1128 char *key;
1129 {
1130 return (self);
1131 }
1132
1133 #if defined (ARRAY_VARS)
1134 static SHELL_VAR *
1135 null_array_assign (self, value, ind, key)
1136 SHELL_VAR *self;
1137 char *value;
1138 arrayind_t ind;
1139 char *key;
1140 {
1141 return (self);
1142 }
1143 #endif
1144
1145 /* Degenerate `dynamic_value' function; just returns what's passed without
1146 manipulation. */
1147 static SHELL_VAR *
1148 get_self (self)
1149 SHELL_VAR *self;
1150 {
1151 return (self);
1152 }
1153
1154 #if defined (ARRAY_VARS)
1155 /* A generic dynamic array variable initializer. Initialize array variable
1156 NAME with dynamic value function GETFUNC and assignment function SETFUNC. */
1157 static SHELL_VAR *
1158 init_dynamic_array_var (name, getfunc, setfunc, attrs)
1159 char *name;
1160 sh_var_value_func_t *getfunc;
1161 sh_var_assign_func_t *setfunc;
1162 int attrs;
1163 {
1164 SHELL_VAR *v;
1165
1166 v = find_variable (name);
1167 if (v)
1168 return (v);
1169 INIT_DYNAMIC_ARRAY_VAR (name, getfunc, setfunc);
1170 if (attrs)
1171 VSETATTR (v, attrs);
1172 return v;
1173 }
1174
1175 static SHELL_VAR *
1176 init_dynamic_assoc_var (name, getfunc, setfunc, attrs)
1177 char *name;
1178 sh_var_value_func_t *getfunc;
1179 sh_var_assign_func_t *setfunc;
1180 int attrs;
1181 {
1182 SHELL_VAR *v;
1183
1184 v = find_variable (name);
1185 if (v)
1186 return (v);
1187 INIT_DYNAMIC_ASSOC_VAR (name, getfunc, setfunc);
1188 if (attrs)
1189 VSETATTR (v, attrs);
1190 return v;
1191 }
1192 #endif
1193
1194 /* The value of $SECONDS. This is the number of seconds since shell
1195 invocation, or, the number of seconds since the last assignment + the
1196 value of the last assignment. */
1197 static intmax_t seconds_value_assigned;
1198
1199 static SHELL_VAR *
1200 assign_seconds (self, value, unused, key)
1201 SHELL_VAR *self;
1202 char *value;
1203 arrayind_t unused;
1204 char *key;
1205 {
1206 if (legal_number (value, &seconds_value_assigned) == 0)
1207 seconds_value_assigned = 0;
1208 shell_start_time = NOW;
1209 return (self);
1210 }
1211
1212 static SHELL_VAR *
1213 get_seconds (var)
1214 SHELL_VAR *var;
1215 {
1216 time_t time_since_start;
1217 char *p;
1218
1219 time_since_start = NOW - shell_start_time;
1220 p = itos(seconds_value_assigned + time_since_start);
1221
1222 FREE (value_cell (var));
1223
1224 VSETATTR (var, att_integer);
1225 var_setvalue (var, p);
1226 return (var);
1227 }
1228
1229 static SHELL_VAR *
1230 init_seconds_var ()
1231 {
1232 SHELL_VAR *v;
1233
1234 v = find_variable ("SECONDS");
1235 if (v)
1236 {
1237 if (legal_number (value_cell(v), &seconds_value_assigned) == 0)
1238 seconds_value_assigned = 0;
1239 }
1240 INIT_DYNAMIC_VAR ("SECONDS", (v ? value_cell (v) : (char *)NULL), get_seconds, assign_seconds);
1241 return v;
1242 }
1243
1244 /* The random number seed. You can change this by setting RANDOM. */
1245 static unsigned long rseed = 1;
1246 static int last_random_value;
1247 static int seeded_subshell = 0;
1248
1249 /* A linear congruential random number generator based on the example
1250 one in the ANSI C standard. This one isn't very good, but a more
1251 complicated one is overkill. */
1252
1253 /* Returns a pseudo-random number between 0 and 32767. */
1254 static int
1255 brand ()
1256 {
1257 /* From "Random number generators: good ones are hard to find",
1258 Park and Miller, Communications of the ACM, vol. 31, no. 10,
1259 October 1988, p. 1195. filtered through FreeBSD */
1260 long h, l;
1261
1262 /* Can't seed with 0. */
1263 if (rseed == 0)
1264 rseed = 123459876;
1265 h = rseed / 127773;
1266 l = rseed % 127773;
1267 rseed = 16807 * l - 2836 * h;
1268 #if 0
1269 if (rseed < 0)
1270 rseed += 0x7fffffff;
1271 #endif
1272 return ((unsigned int)(rseed & 32767)); /* was % 32768 */
1273 }
1274
1275 /* Set the random number generator seed to SEED. */
1276 static void
1277 sbrand (seed)
1278 unsigned long seed;
1279 {
1280 rseed = seed;
1281 last_random_value = 0;
1282 }
1283
1284 static void
1285 seedrand ()
1286 {
1287 struct timeval tv;
1288
1289 gettimeofday (&tv, NULL);
1290 sbrand (tv.tv_sec ^ tv.tv_usec ^ getpid ());
1291 }
1292
1293 static SHELL_VAR *
1294 assign_random (self, value, unused, key)
1295 SHELL_VAR *self;
1296 char *value;
1297 arrayind_t unused;
1298 char *key;
1299 {
1300 sbrand (strtoul (value, (char **)NULL, 10));
1301 if (subshell_environment)
1302 seeded_subshell = getpid ();
1303 return (self);
1304 }
1305
1306 int
1307 get_random_number ()
1308 {
1309 int rv, pid;
1310
1311 /* Reset for command and process substitution. */
1312 pid = getpid ();
1313 if (subshell_environment && seeded_subshell != pid)
1314 {
1315 seedrand ();
1316 seeded_subshell = pid;
1317 }
1318
1319 do
1320 rv = brand ();
1321 while (rv == last_random_value);
1322 return rv;
1323 }
1324
1325 static SHELL_VAR *
1326 get_random (var)
1327 SHELL_VAR *var;
1328 {
1329 int rv;
1330 char *p;
1331
1332 rv = get_random_number ();
1333 last_random_value = rv;
1334 p = itos (rv);
1335
1336 FREE (value_cell (var));
1337
1338 VSETATTR (var, att_integer);
1339 var_setvalue (var, p);
1340 return (var);
1341 }
1342
1343 static SHELL_VAR *
1344 assign_lineno (var, value, unused, key)
1345 SHELL_VAR *var;
1346 char *value;
1347 arrayind_t unused;
1348 char *key;
1349 {
1350 intmax_t new_value;
1351
1352 if (value == 0 || *value == '\0' || legal_number (value, &new_value) == 0)
1353 new_value = 0;
1354 line_number = line_number_base = new_value;
1355 return var;
1356 }
1357
1358 /* Function which returns the current line number. */
1359 static SHELL_VAR *
1360 get_lineno (var)
1361 SHELL_VAR *var;
1362 {
1363 char *p;
1364 int ln;
1365
1366 ln = executing_line_number ();
1367 p = itos (ln);
1368 FREE (value_cell (var));
1369 var_setvalue (var, p);
1370 return (var);
1371 }
1372
1373 static SHELL_VAR *
1374 assign_subshell (var, value, unused, key)
1375 SHELL_VAR *var;
1376 char *value;
1377 arrayind_t unused;
1378 char *key;
1379 {
1380 intmax_t new_value;
1381
1382 if (value == 0 || *value == '\0' || legal_number (value, &new_value) == 0)
1383 new_value = 0;
1384 subshell_level = new_value;
1385 return var;
1386 }
1387
1388 static SHELL_VAR *
1389 get_subshell (var)
1390 SHELL_VAR *var;
1391 {
1392 char *p;
1393
1394 p = itos (subshell_level);
1395 FREE (value_cell (var));
1396 var_setvalue (var, p);
1397 return (var);
1398 }
1399
1400 static SHELL_VAR *
1401 get_bashpid (var)
1402 SHELL_VAR *var;
1403 {
1404 int pid;
1405 char *p;
1406
1407 pid = getpid ();
1408 p = itos (pid);
1409
1410 FREE (value_cell (var));
1411 VSETATTR (var, att_integer|att_readonly);
1412 var_setvalue (var, p);
1413 return (var);
1414 }
1415
1416 static SHELL_VAR *
1417 get_bash_command (var)
1418 SHELL_VAR *var;
1419 {
1420 char *p;
1421
1422 if (the_printed_command_except_trap)
1423 p = savestring (the_printed_command_except_trap);
1424 else
1425 {
1426 p = (char *)xmalloc (1);
1427 p[0] = '\0';
1428 }
1429 FREE (value_cell (var));
1430 var_setvalue (var, p);
1431 return (var);
1432 }
1433
1434 #if defined (HISTORY)
1435 static SHELL_VAR *
1436 get_histcmd (var)
1437 SHELL_VAR *var;
1438 {
1439 char *p;
1440
1441 p = itos (history_number ());
1442 FREE (value_cell (var));
1443 var_setvalue (var, p);
1444 return (var);
1445 }
1446 #endif
1447
1448 #if defined (READLINE)
1449 /* When this function returns, VAR->value points to malloced memory. */
1450 static SHELL_VAR *
1451 get_comp_wordbreaks (var)
1452 SHELL_VAR *var;
1453 {
1454 /* If we don't have anything yet, assign a default value. */
1455 if (rl_completer_word_break_characters == 0 && bash_readline_initialized == 0)
1456 enable_hostname_completion (perform_hostname_completion);
1457
1458 FREE (value_cell (var));
1459 var_setvalue (var, savestring (rl_completer_word_break_characters));
1460
1461 return (var);
1462 }
1463
1464 /* When this function returns, rl_completer_word_break_characters points to
1465 malloced memory. */
1466 static SHELL_VAR *
1467 assign_comp_wordbreaks (self, value, unused, key)
1468 SHELL_VAR *self;
1469 char *value;
1470 arrayind_t unused;
1471 char *key;
1472 {
1473 if (rl_completer_word_break_characters &&
1474 rl_completer_word_break_characters != rl_basic_word_break_characters)
1475 free (rl_completer_word_break_characters);
1476
1477 rl_completer_word_break_characters = savestring (value);
1478 return self;
1479 }
1480 #endif /* READLINE */
1481
1482 #if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
1483 static SHELL_VAR *
1484 assign_dirstack (self, value, ind, key)
1485 SHELL_VAR *self;
1486 char *value;
1487 arrayind_t ind;
1488 char *key;
1489 {
1490 set_dirstack_element (ind, 1, value);
1491 return self;
1492 }
1493
1494 static SHELL_VAR *
1495 get_dirstack (self)
1496 SHELL_VAR *self;
1497 {
1498 ARRAY *a;
1499 WORD_LIST *l;
1500
1501 l = get_directory_stack (0);
1502 a = array_from_word_list (l);
1503 array_dispose (array_cell (self));
1504 dispose_words (l);
1505 var_setarray (self, a);
1506 return self;
1507 }
1508 #endif /* PUSHD AND POPD && ARRAY_VARS */
1509
1510 #if defined (ARRAY_VARS)
1511 /* We don't want to initialize the group set with a call to getgroups()
1512 unless we're asked to, but we only want to do it once. */
1513 static SHELL_VAR *
1514 get_groupset (self)
1515 SHELL_VAR *self;
1516 {
1517 register int i;
1518 int ng;
1519 ARRAY *a;
1520 static char **group_set = (char **)NULL;
1521
1522 if (group_set == 0)
1523 {
1524 group_set = get_group_list (&ng);
1525 a = array_cell (self);
1526 for (i = 0; i < ng; i++)
1527 array_insert (a, i, group_set[i]);
1528 }
1529 return (self);
1530 }
1531
1532 static SHELL_VAR *
1533 build_hashcmd (self)
1534 SHELL_VAR *self;
1535 {
1536 HASH_TABLE *h;
1537 int i;
1538 char *k, *v;
1539 BUCKET_CONTENTS *item;
1540
1541 h = assoc_cell (self);
1542 if (h)
1543 assoc_dispose (h);
1544
1545 if (hashed_filenames == 0 || HASH_ENTRIES (hashed_filenames) == 0)
1546 {
1547 var_setvalue (self, (char *)NULL);
1548 return self;
1549 }
1550
1551 h = assoc_create (hashed_filenames->nbuckets);
1552 for (i = 0; i < hashed_filenames->nbuckets; i++)
1553 {
1554 for (item = hash_items (i, hashed_filenames); item; item = item->next)
1555 {
1556 k = savestring (item->key);
1557 v = pathdata(item)->path;
1558 assoc_insert (h, k, v);
1559 }
1560 }
1561
1562 var_setvalue (self, (char *)h);
1563 return self;
1564 }
1565
1566 static SHELL_VAR *
1567 get_hashcmd (self)
1568 SHELL_VAR *self;
1569 {
1570 build_hashcmd (self);
1571 return (self);
1572 }
1573
1574 static SHELL_VAR *
1575 assign_hashcmd (self, value, ind, key)
1576 SHELL_VAR *self;
1577 char *value;
1578 arrayind_t ind;
1579 char *key;
1580 {
1581 phash_insert (key, value, 0, 0);
1582 return (build_hashcmd (self));
1583 }
1584
1585 #if defined (ALIAS)
1586 static SHELL_VAR *
1587 build_aliasvar (self)
1588 SHELL_VAR *self;
1589 {
1590 HASH_TABLE *h;
1591 int i;
1592 char *k, *v;
1593 BUCKET_CONTENTS *item;
1594
1595 h = assoc_cell (self);
1596 if (h)
1597 assoc_dispose (h);
1598
1599 if (aliases == 0 || HASH_ENTRIES (aliases) == 0)
1600 {
1601 var_setvalue (self, (char *)NULL);
1602 return self;
1603 }
1604
1605 h = assoc_create (aliases->nbuckets);
1606 for (i = 0; i < aliases->nbuckets; i++)
1607 {
1608 for (item = hash_items (i, aliases); item; item = item->next)
1609 {
1610 k = savestring (item->key);
1611 v = ((alias_t *)(item->data))->value;
1612 assoc_insert (h, k, v);
1613 }
1614 }
1615
1616 var_setvalue (self, (char *)h);
1617 return self;
1618 }
1619
1620 static SHELL_VAR *
1621 get_aliasvar (self)
1622 SHELL_VAR *self;
1623 {
1624 build_aliasvar (self);
1625 return (self);
1626 }
1627
1628 static SHELL_VAR *
1629 assign_aliasvar (self, value, ind, key)
1630 SHELL_VAR *self;
1631 char *value;
1632 arrayind_t ind;
1633 char *key;
1634 {
1635 add_alias (key, value);
1636 return (build_aliasvar (self));
1637 }
1638 #endif /* ALIAS */
1639
1640 #endif /* ARRAY_VARS */
1641
1642 /* If ARRAY_VARS is not defined, this just returns the name of any
1643 currently-executing function. If we have arrays, it's a call stack. */
1644 static SHELL_VAR *
1645 get_funcname (self)
1646 SHELL_VAR *self;
1647 {
1648 #if ! defined (ARRAY_VARS)
1649 char *t;
1650 if (variable_context && this_shell_function)
1651 {
1652 FREE (value_cell (self));
1653 t = savestring (this_shell_function->name);
1654 var_setvalue (self, t);
1655 }
1656 #endif
1657 return (self);
1658 }
1659
1660 void
1661 make_funcname_visible (on_or_off)
1662 int on_or_off;
1663 {
1664 SHELL_VAR *v;
1665
1666 v = find_variable ("FUNCNAME");
1667 if (v == 0 || v->dynamic_value == 0)
1668 return;
1669
1670 if (on_or_off)
1671 VUNSETATTR (v, att_invisible);
1672 else
1673 VSETATTR (v, att_invisible);
1674 }
1675
1676 static SHELL_VAR *
1677 init_funcname_var ()
1678 {
1679 SHELL_VAR *v;
1680
1681 v = find_variable ("FUNCNAME");
1682 if (v)
1683 return v;
1684 #if defined (ARRAY_VARS)
1685 INIT_DYNAMIC_ARRAY_VAR ("FUNCNAME", get_funcname, null_array_assign);
1686 #else
1687 INIT_DYNAMIC_VAR ("FUNCNAME", (char *)NULL, get_funcname, null_assign);
1688 #endif
1689 VSETATTR (v, att_invisible|att_noassign);
1690 return v;
1691 }
1692
1693 static void
1694 initialize_dynamic_variables ()
1695 {
1696 SHELL_VAR *v;
1697
1698 v = init_seconds_var ();
1699
1700 INIT_DYNAMIC_VAR ("BASH_COMMAND", (char *)NULL, get_bash_command, (sh_var_assign_func_t *)NULL);
1701 INIT_DYNAMIC_VAR ("BASH_SUBSHELL", (char *)NULL, get_subshell, assign_subshell);
1702
1703 INIT_DYNAMIC_VAR ("RANDOM", (char *)NULL, get_random, assign_random);
1704 VSETATTR (v, att_integer);
1705 INIT_DYNAMIC_VAR ("LINENO", (char *)NULL, get_lineno, assign_lineno);
1706 VSETATTR (v, att_integer);
1707
1708 INIT_DYNAMIC_VAR ("BASHPID", (char *)NULL, get_bashpid, null_assign);
1709 VSETATTR (v, att_integer|att_readonly);
1710
1711 #if defined (HISTORY)
1712 INIT_DYNAMIC_VAR ("HISTCMD", (char *)NULL, get_histcmd, (sh_var_assign_func_t *)NULL);
1713 VSETATTR (v, att_integer);
1714 #endif
1715
1716 #if defined (READLINE)
1717 INIT_DYNAMIC_VAR ("COMP_WORDBREAKS", (char *)NULL, get_comp_wordbreaks, assign_comp_wordbreaks);
1718 #endif
1719
1720 #if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
1721 v = init_dynamic_array_var ("DIRSTACK", get_dirstack, assign_dirstack, 0);
1722 #endif /* PUSHD_AND_POPD && ARRAY_VARS */
1723
1724 #if defined (ARRAY_VARS)
1725 v = init_dynamic_array_var ("GROUPS", get_groupset, null_array_assign, att_noassign);
1726
1727 # if defined (DEBUGGER)
1728 v = init_dynamic_array_var ("BASH_ARGC", get_self, null_array_assign, att_noassign|att_nounset);
1729 v = init_dynamic_array_var ("BASH_ARGV", get_self, null_array_assign, att_noassign|att_nounset);
1730 # endif /* DEBUGGER */
1731 v = init_dynamic_array_var ("BASH_SOURCE", get_self, null_array_assign, att_noassign|att_nounset);
1732 v = init_dynamic_array_var ("BASH_LINENO", get_self, null_array_assign, att_noassign|att_nounset);
1733
1734 v = init_dynamic_assoc_var ("BASH_CMDS", get_hashcmd, assign_hashcmd, att_nofree);
1735 # if defined (ALIAS)
1736 v = init_dynamic_assoc_var ("BASH_ALIASES", get_aliasvar, assign_aliasvar, att_nofree);
1737 # endif
1738 #endif
1739
1740 v = init_funcname_var ();
1741 }
1742
1743 /* **************************************************************** */
1744 /* */
1745 /* Retrieving variables and values */
1746 /* */
1747 /* **************************************************************** */
1748
1749 /* How to get a pointer to the shell variable or function named NAME.
1750 HASHED_VARS is a pointer to the hash table containing the list
1751 of interest (either variables or functions). */
1752
1753 static SHELL_VAR *
1754 hash_lookup (name, hashed_vars)
1755 const char *name;
1756 HASH_TABLE *hashed_vars;
1757 {
1758 BUCKET_CONTENTS *bucket;
1759
1760 bucket = hash_search (name, hashed_vars, 0);
1761 /* If we find the name in HASHED_VARS, set LAST_TABLE_SEARCHED to that
1762 table. */
1763 if (bucket)
1764 last_table_searched = hashed_vars;
1765 return (bucket ? (SHELL_VAR *)bucket->data : (SHELL_VAR *)NULL);
1766 }
1767
1768 SHELL_VAR *
1769 var_lookup (name, vcontext)
1770 const char *name;
1771 VAR_CONTEXT *vcontext;
1772 {
1773 VAR_CONTEXT *vc;
1774 SHELL_VAR *v;
1775
1776 v = (SHELL_VAR *)NULL;
1777 for (vc = vcontext; vc; vc = vc->down)
1778 if (v = hash_lookup (name, vc->table))
1779 break;
1780
1781 return v;
1782 }
1783
1784 /* Look up the variable entry named NAME. If SEARCH_TEMPENV is non-zero,
1785 then also search the temporarily built list of exported variables.
1786 The lookup order is:
1787 temporary_env
1788 shell_variables list
1789 */
1790
1791 SHELL_VAR *
1792 find_variable_internal (name, force_tempenv)
1793 const char *name;
1794 int force_tempenv;
1795 {
1796 SHELL_VAR *var;
1797 int search_tempenv;
1798 VAR_CONTEXT *vc;
1799
1800 var = (SHELL_VAR *)NULL;
1801
1802 /* If explicitly requested, first look in the temporary environment for
1803 the variable. This allows constructs such as "foo=x eval 'echo $foo'"
1804 to get the `exported' value of $foo. This happens if we are executing
1805 a function or builtin, or if we are looking up a variable in a
1806 "subshell environment". */
1807 search_tempenv = force_tempenv || (expanding_redir == 0 && subshell_environment);
1808
1809 if (search_tempenv && temporary_env)
1810 var = hash_lookup (name, temporary_env);
1811
1812 vc = shell_variables;
1813 #if 0
1814 if (search_tempenv == 0 && /* (subshell_environment & SUBSHELL_COMSUB) && */
1815 expanding_redir &&
1816 (this_shell_builtin == eval_builtin || this_shell_builtin == command_builtin))
1817 {
1818 itrace("find_variable_internal: search_tempenv == 0: skipping VC_BLTNENV");
1819 while (vc && (vc->flags & VC_BLTNENV))
1820 vc = vc->down;
1821 if (vc == 0)
1822 vc = shell_variables;
1823 }
1824 #endif
1825
1826 if (var == 0)
1827 var = var_lookup (name, vc);
1828
1829 if (var == 0)
1830 return ((SHELL_VAR *)NULL);
1831
1832 return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var);
1833 }
1834
1835 /* Look up and resolve the chain of nameref variables starting at V all the
1836 way to NULL or non-nameref. */
1837 SHELL_VAR *
1838 find_variable_nameref (v)
1839 SHELL_VAR *v;
1840 {
1841 int level;
1842 char *newname;
1843 SHELL_VAR *orig, *oldv;
1844
1845 level = 0;
1846 orig = v;
1847 while (v && nameref_p (v))
1848 {
1849 level++;
1850 if (level > NAMEREF_MAX)
1851 return ((SHELL_VAR *)0); /* error message here? */
1852 newname = nameref_cell (v);
1853 if (newname == 0 || *newname == '\0')
1854 return ((SHELL_VAR *)0);
1855 oldv = v;
1856 v = find_variable_internal (newname, (expanding_redir == 0 && (assigning_in_environment || executing_builtin)));
1857 if (v == orig || v == oldv)
1858 {
1859 internal_warning (_("%s: circular name reference"), orig->name);
1860 return ((SHELL_VAR *)0);
1861 }
1862 }
1863 return v;
1864 }
1865
1866 /* Resolve the chain of nameref variables for NAME. XXX - could change later */
1867 SHELL_VAR *
1868 find_variable_last_nameref (name)
1869 const char *name;
1870 {
1871 SHELL_VAR *v, *nv;
1872 char *newname;
1873 int level;
1874
1875 nv = v = find_variable_noref (name);
1876 level = 0;
1877 while (v && nameref_p (v))
1878 {
1879 level++;
1880 if (level > NAMEREF_MAX)
1881 return ((SHELL_VAR *)0); /* error message here? */
1882 newname = nameref_cell (v);
1883 if (newname == 0 || *newname == '\0')
1884 return ((SHELL_VAR *)0);
1885 nv = v;
1886 v = find_variable_internal (newname, (expanding_redir == 0 && (assigning_in_environment || executing_builtin)));
1887 }
1888 return nv;
1889 }
1890
1891 /* Resolve the chain of nameref variables for NAME. XXX - could change later */
1892 SHELL_VAR *
1893 find_global_variable_last_nameref (name)
1894 const char *name;
1895 {
1896 SHELL_VAR *v, *nv;
1897 char *newname;
1898 int level;
1899
1900 nv = v = find_global_variable_noref (name);
1901 level = 0;
1902 while (v && nameref_p (v))
1903 {
1904 level++;
1905 if (level > NAMEREF_MAX)
1906 return ((SHELL_VAR *)0); /* error message here? */
1907 newname = nameref_cell (v);
1908 if (newname == 0 || *newname == '\0')
1909 return ((SHELL_VAR *)0);
1910 nv = v;
1911 v = find_global_variable_noref (newname);
1912 }
1913 return nv;
1914 }
1915
1916 static SHELL_VAR *
1917 find_nameref_at_context (v, vc)
1918 SHELL_VAR *v;
1919 VAR_CONTEXT *vc;
1920 {
1921 SHELL_VAR *nv, *nv2;
1922 VAR_CONTEXT *nvc;
1923 char *newname;
1924 int level;
1925
1926 nv = v;
1927 level = 1;
1928 while (nv && nameref_p (nv))
1929 {
1930 level++;
1931 if (level > NAMEREF_MAX)
1932 return ((SHELL_VAR *)NULL);
1933 newname = nameref_cell (nv);
1934 if (newname == 0 || *newname == '\0')
1935 return ((SHELL_VAR *)NULL);
1936 nv2 = hash_lookup (newname, vc->table);
1937 if (nv2 == 0)
1938 break;
1939 nv = nv2;
1940 }
1941 return nv;
1942 }
1943
1944 /* Do nameref resolution from the VC, which is the local context for some
1945 function or builtin, `up' the chain to the global variables context. If
1946 NVCP is not NULL, return the variable context where we finally ended the
1947 nameref resolution (so the bind_variable_internal can use the correct
1948 variable context and hash table). */
1949 static SHELL_VAR *
1950 find_variable_nameref_context (v, vc, nvcp)
1951 SHELL_VAR *v;
1952 VAR_CONTEXT *vc;
1953 VAR_CONTEXT **nvcp;
1954 {
1955 SHELL_VAR *nv, *nv2;
1956 VAR_CONTEXT *nvc;
1957
1958 /* Look starting at the current context all the way `up' */
1959 for (nv = v, nvc = vc; nvc; nvc = nvc->down)
1960 {
1961 nv2 = find_nameref_at_context (nv, nvc);
1962 if (nv2 == 0)
1963 continue;
1964 nv = nv2;
1965 if (*nvcp)
1966 *nvcp = nvc;
1967 if (nameref_p (nv) == 0)
1968 break;
1969 }
1970 return (nameref_p (nv) ? (SHELL_VAR *)NULL : nv);
1971 }
1972
1973 /* Do nameref resolution from the VC, which is the local context for some
1974 function or builtin, `up' the chain to the global variables context. If
1975 NVCP is not NULL, return the variable context where we finally ended the
1976 nameref resolution (so the bind_variable_internal can use the correct
1977 variable context and hash table). */
1978 static SHELL_VAR *
1979 find_variable_last_nameref_context (v, vc, nvcp)
1980 SHELL_VAR *v;
1981 VAR_CONTEXT *vc;
1982 VAR_CONTEXT **nvcp;
1983 {
1984 SHELL_VAR *nv, *nv2;
1985 VAR_CONTEXT *nvc;
1986
1987 /* Look starting at the current context all the way `up' */
1988 for (nv = v, nvc = vc; nvc; nvc = nvc->down)
1989 {
1990 nv2 = find_nameref_at_context (nv, nvc);
1991 if (nv2 == 0)
1992 continue;
1993 nv = nv2;
1994 if (*nvcp)
1995 *nvcp = nvc;
1996 }
1997 return (nameref_p (nv) ? nv : (SHELL_VAR *)NULL);
1998 }
1999
2000 /* Find a variable, forcing a search of the temporary environment first */
2001 SHELL_VAR *
2002 find_variable_tempenv (name)
2003 const char *name;
2004 {
2005 SHELL_VAR *var;
2006
2007 var = find_variable_internal (name, 1);
2008 if (var && nameref_p (var))
2009 var = find_variable_nameref (var);
2010 return (var);
2011 }
2012
2013 /* Find a variable, not forcing a search of the temporary environment first */
2014 SHELL_VAR *
2015 find_variable_notempenv (name)
2016 const char *name;
2017 {
2018 SHELL_VAR *var;
2019
2020 var = find_variable_internal (name, 0);
2021 if (var && nameref_p (var))
2022 var = find_variable_nameref (var);
2023 return (var);
2024 }
2025
2026 SHELL_VAR *
2027 find_global_variable (name)
2028 const char *name;
2029 {
2030 SHELL_VAR *var;
2031
2032 var = var_lookup (name, global_variables);
2033 if (var && nameref_p (var))
2034 var = find_variable_nameref (var);
2035
2036 if (var == 0)
2037 return ((SHELL_VAR *)NULL);
2038
2039 return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var);
2040 }
2041
2042 SHELL_VAR *
2043 find_global_variable_noref (name)
2044 const char *name;
2045 {
2046 SHELL_VAR *var;
2047
2048 var = var_lookup (name, global_variables);
2049
2050 if (var == 0)
2051 return ((SHELL_VAR *)NULL);
2052
2053 return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var);
2054 }
2055
2056 SHELL_VAR *
2057 find_shell_variable (name)
2058 const char *name;
2059 {
2060 SHELL_VAR *var;
2061
2062 var = var_lookup (name, shell_variables);
2063 if (var && nameref_p (var))
2064 var = find_variable_nameref (var);
2065
2066 if (var == 0)
2067 return ((SHELL_VAR *)NULL);
2068
2069 return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var);
2070 }
2071
2072 /* Look up the variable entry named NAME. Returns the entry or NULL. */
2073 SHELL_VAR *
2074 find_variable (name)
2075 const char *name;
2076 {
2077 SHELL_VAR *v;
2078
2079 last_table_searched = 0;
2080 v = find_variable_internal (name, (expanding_redir == 0 && (assigning_in_environment || executing_builtin)));
2081 if (v && nameref_p (v))
2082 v = find_variable_nameref (v);
2083 return v;
2084 }
2085
2086 SHELL_VAR *
2087 find_variable_noref (name)
2088 const char *name;
2089 {
2090 SHELL_VAR *v;
2091
2092 v = find_variable_internal (name, (expanding_redir == 0 && (assigning_in_environment || executing_builtin)));
2093 return v;
2094 }
2095
2096 /* Look up the function entry whose name matches STRING.
2097 Returns the entry or NULL. */
2098 SHELL_VAR *
2099 find_function (name)
2100 const char *name;
2101 {
2102 return (hash_lookup (name, shell_functions));
2103 }
2104
2105 /* Find the function definition for the shell function named NAME. Returns
2106 the entry or NULL. */
2107 FUNCTION_DEF *
2108 find_function_def (name)
2109 const char *name;
2110 {
2111 #if defined (DEBUGGER)
2112 return ((FUNCTION_DEF *)hash_lookup (name, shell_function_defs));
2113 #else
2114 return ((FUNCTION_DEF *)0);
2115 #endif
2116 }
2117
2118 /* Return the value of VAR. VAR is assumed to have been the result of a
2119 lookup without any subscript, if arrays are compiled into the shell. */
2120 char *
2121 get_variable_value (var)
2122 SHELL_VAR *var;
2123 {
2124 if (var == 0)
2125 return ((char *)NULL);
2126 #if defined (ARRAY_VARS)
2127 else if (array_p (var))
2128 return (array_reference (array_cell (var), 0));
2129 else if (assoc_p (var))
2130 return (assoc_reference (assoc_cell (var), "0"));
2131 #endif
2132 else
2133 return (value_cell (var));
2134 }
2135
2136 /* Return the string value of a variable. Return NULL if the variable
2137 doesn't exist. Don't cons a new string. This is a potential memory
2138 leak if the variable is found in the temporary environment. Since
2139 functions and variables have separate name spaces, returns NULL if
2140 var_name is a shell function only. */
2141 char *
2142 get_string_value (var_name)
2143 const char *var_name;
2144 {
2145 SHELL_VAR *var;
2146
2147 var = find_variable (var_name);
2148 return ((var) ? get_variable_value (var) : (char *)NULL);
2149 }
2150
2151 /* This is present for use by the tilde and readline libraries. */
2152 char *
2153 sh_get_env_value (v)
2154 const char *v;
2155 {
2156 return get_string_value (v);
2157 }
2158
2159 /* **************************************************************** */
2160 /* */
2161 /* Creating and setting variables */
2162 /* */
2163 /* **************************************************************** */
2164
2165 /* Set NAME to VALUE if NAME has no value. */
2166 SHELL_VAR *
2167 set_if_not (name, value)
2168 char *name, *value;
2169 {
2170 SHELL_VAR *v;
2171
2172 if (shell_variables == 0)
2173 create_variable_tables ();
2174
2175 v = find_variable (name);
2176 if (v == 0)
2177 v = bind_variable_internal (name, value, global_variables->table, HASH_NOSRCH, 0);
2178 return (v);
2179 }
2180
2181 /* Create a local variable referenced by NAME. */
2182 SHELL_VAR *
2183 make_local_variable (name)
2184 const char *name;
2185 {
2186 SHELL_VAR *new_var, *old_var;
2187 VAR_CONTEXT *vc;
2188 int was_tmpvar;
2189 char *tmp_value;
2190
2191 /* local foo; local foo; is a no-op. */
2192 old_var = find_variable (name);
2193 if (old_var && local_p (old_var) && old_var->context == variable_context)
2194 return (old_var);
2195
2196 was_tmpvar = old_var && tempvar_p (old_var);
2197 /* If we're making a local variable in a shell function, the temporary env
2198 has already been merged into the function's variable context stack. We
2199 can assume that a temporary var in the same context appears in the same
2200 VAR_CONTEXT and can safely be returned without creating a new variable
2201 (which results in duplicate names in the same VAR_CONTEXT->table */
2202 /* We can't just test tmpvar_p because variables in the temporary env given
2203 to a shell function appear in the function's local variable VAR_CONTEXT
2204 but retain their tempvar attribute. We want temporary variables that are
2205 found in temporary_env, hence the test for last_table_searched, which is
2206 set in hash_lookup and only (so far) checked here. */
2207 if (was_tmpvar && old_var->context == variable_context && last_table_searched != temporary_env)
2208 {
2209 VUNSETATTR (old_var, att_invisible);
2210 return (old_var);
2211 }
2212 if (was_tmpvar)
2213 tmp_value = value_cell (old_var);
2214
2215 for (vc = shell_variables; vc; vc = vc->down)
2216 if (vc_isfuncenv (vc) && vc->scope == variable_context)
2217 break;
2218
2219 if (vc == 0)
2220 {
2221 internal_error (_("make_local_variable: no function context at current scope"));
2222 return ((SHELL_VAR *)NULL);
2223 }
2224 else if (vc->table == 0)
2225 vc->table = hash_create (TEMPENV_HASH_BUCKETS);
2226
2227 /* Since this is called only from the local/declare/typeset code, we can
2228 call builtin_error here without worry (of course, it will also work
2229 for anything that sets this_command_name). Variables with the `noassign'
2230 attribute may not be made local. The test against old_var's context
2231 level is to disallow local copies of readonly global variables (since I
2232 believe that this could be a security hole). Readonly copies of calling
2233 function local variables are OK. */
2234 if (old_var && (noassign_p (old_var) ||
2235 (readonly_p (old_var) && old_var->context == 0)))
2236 {
2237 if (readonly_p (old_var))
2238 sh_readonly (name);
2239 else if (noassign_p (old_var))
2240 builtin_error (_("%s: variable may not be assigned value"), name);
2241 #if 0
2242 /* Let noassign variables through with a warning */
2243 if (readonly_p (old_var))
2244 #endif
2245 return ((SHELL_VAR *)NULL);
2246 }
2247
2248 if (old_var == 0)
2249 new_var = make_new_variable (name, vc->table);
2250 else
2251 {
2252 new_var = make_new_variable (name, vc->table);
2253
2254 /* If we found this variable in one of the temporary environments,
2255 inherit its value. Watch to see if this causes problems with
2256 things like `x=4 local x'. XXX - see above for temporary env
2257 variables with the same context level as variable_context */
2258 /* XXX - we should only do this if the variable is not an array. */
2259 if (was_tmpvar)
2260 var_setvalue (new_var, savestring (tmp_value));
2261
2262 new_var->attributes = exported_p (old_var) ? att_exported : 0;
2263 }
2264
2265 vc->flags |= VC_HASLOCAL;
2266
2267 new_var->context = variable_context;
2268 VSETATTR (new_var, att_local);
2269
2270 if (ifsname (name))
2271 setifs (new_var);
2272
2273 if (was_tmpvar == 0)
2274 VSETATTR (new_var, att_invisible); /* XXX */
2275 return (new_var);
2276 }
2277
2278 /* Create a new shell variable with name NAME. */
2279 static SHELL_VAR *
2280 new_shell_variable (name)
2281 const char *name;
2282 {
2283 SHELL_VAR *entry;
2284
2285 entry = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
2286
2287 entry->name = savestring (name);
2288 var_setvalue (entry, (char *)NULL);
2289 CLEAR_EXPORTSTR (entry);
2290
2291 entry->dynamic_value = (sh_var_value_func_t *)NULL;
2292 entry->assign_func = (sh_var_assign_func_t *)NULL;
2293
2294 entry->attributes = 0;
2295
2296 /* Always assume variables are to be made at toplevel!
2297 make_local_variable has the responsibility of changing the
2298 variable context. */
2299 entry->context = 0;
2300
2301 return (entry);
2302 }
2303
2304 /* Create a new shell variable with name NAME and add it to the hash table
2305 TABLE. */
2306 static SHELL_VAR *
2307 make_new_variable (name, table)
2308 const char *name;
2309 HASH_TABLE *table;
2310 {
2311 SHELL_VAR *entry;
2312 BUCKET_CONTENTS *elt;
2313
2314 entry = new_shell_variable (name);
2315
2316 /* Make sure we have a shell_variables hash table to add to. */
2317 if (shell_variables == 0)
2318 create_variable_tables ();
2319
2320 elt = hash_insert (savestring (name), table, HASH_NOSRCH);
2321 elt->data = (PTR_T)entry;
2322
2323 return entry;
2324 }
2325
2326 #if defined (ARRAY_VARS)
2327 SHELL_VAR *
2328 make_new_array_variable (name)
2329 char *name;
2330 {
2331 SHELL_VAR *entry;
2332 ARRAY *array;
2333
2334 entry = make_new_variable (name, global_variables->table);
2335 array = array_create ();
2336
2337 var_setarray (entry, array);
2338 VSETATTR (entry, att_array);
2339 return entry;
2340 }
2341
2342 SHELL_VAR *
2343 make_local_array_variable (name, assoc_ok)
2344 char *name;
2345 int assoc_ok;
2346 {
2347 SHELL_VAR *var;
2348 ARRAY *array;
2349
2350 var = make_local_variable (name);
2351 if (var == 0 || array_p (var) || (assoc_ok && assoc_p (var)))
2352 return var;
2353
2354 array = array_create ();
2355
2356 dispose_variable_value (var);
2357 var_setarray (var, array);
2358 VSETATTR (var, att_array);
2359 return var;
2360 }
2361
2362 SHELL_VAR *
2363 make_new_assoc_variable (name)
2364 char *name;
2365 {
2366 SHELL_VAR *entry;
2367 HASH_TABLE *hash;
2368
2369 entry = make_new_variable (name, global_variables->table);
2370 hash = assoc_create (0);
2371
2372 var_setassoc (entry, hash);
2373 VSETATTR (entry, att_assoc);
2374 return entry;
2375 }
2376
2377 SHELL_VAR *
2378 make_local_assoc_variable (name)
2379 char *name;
2380 {
2381 SHELL_VAR *var;
2382 HASH_TABLE *hash;
2383
2384 var = make_local_variable (name);
2385 if (var == 0 || assoc_p (var))
2386 return var;
2387
2388 dispose_variable_value (var);
2389 hash = assoc_create (0);
2390
2391 var_setassoc (var, hash);
2392 VSETATTR (var, att_assoc);
2393 return var;
2394 }
2395 #endif
2396
2397 char *
2398 make_variable_value (var, value, flags)
2399 SHELL_VAR *var;
2400 char *value;
2401 int flags;
2402 {
2403 char *retval, *oval;
2404 intmax_t lval, rval;
2405 int expok, olen, op;
2406
2407 /* If this variable has had its type set to integer (via `declare -i'),
2408 then do expression evaluation on it and store the result. The
2409 functions in expr.c (evalexp()) and bind_int_variable() are responsible
2410 for turning off the integer flag if they don't want further
2411 evaluation done. */
2412 if (integer_p (var))
2413 {
2414 if (flags & ASS_APPEND)
2415 {
2416 oval = value_cell (var);
2417 lval = evalexp (oval, &expok); /* ksh93 seems to do this */
2418 if (expok == 0)
2419 {
2420 top_level_cleanup ();
2421 jump_to_top_level (DISCARD);
2422 }
2423 }
2424 rval = evalexp (value, &expok);
2425 if (expok == 0)
2426 {
2427 top_level_cleanup ();
2428 jump_to_top_level (DISCARD);
2429 }
2430 /* This can be fooled if the variable's value changes while evaluating
2431 `rval'. We can change it if we move the evaluation of lval to here. */
2432 if (flags & ASS_APPEND)
2433 rval += lval;
2434 retval = itos (rval);
2435 }
2436 #if defined (CASEMOD_ATTRS)
2437 else if (capcase_p (var) || uppercase_p (var) || lowercase_p (var))
2438 {
2439 if (flags & ASS_APPEND)
2440 {
2441 oval = get_variable_value (var);
2442 if (oval == 0) /* paranoia */
2443 oval = "";
2444 olen = STRLEN (oval);
2445 retval = (char *)xmalloc (olen + (value ? STRLEN (value) : 0) + 1);
2446 strcpy (retval, oval);
2447 if (value)
2448 strcpy (retval+olen, value);
2449 }
2450 else if (*value)
2451 retval = savestring (value);
2452 else
2453 {
2454 retval = (char *)xmalloc (1);
2455 retval[0] = '\0';
2456 }
2457 op = capcase_p (var) ? CASE_CAPITALIZE
2458 : (uppercase_p (var) ? CASE_UPPER : CASE_LOWER);
2459 oval = sh_modcase (retval, (char *)0, op);
2460 free (retval);
2461 retval = oval;
2462 }
2463 #endif /* CASEMOD_ATTRS */
2464 else if (value)
2465 {
2466 if (flags & ASS_APPEND)
2467 {
2468 oval = get_variable_value (var);
2469 if (oval == 0) /* paranoia */
2470 oval = "";
2471 olen = STRLEN (oval);
2472 retval = (char *)xmalloc (olen + (value ? STRLEN (value) : 0) + 1);
2473 strcpy (retval, oval);
2474 if (value)
2475 strcpy (retval+olen, value);
2476 }
2477 else if (*value)
2478 retval = savestring (value);
2479 else
2480 {
2481 retval = (char *)xmalloc (1);
2482 retval[0] = '\0';
2483 }
2484 }
2485 else
2486 retval = (char *)NULL;
2487
2488 return retval;
2489 }
2490
2491 /* Bind a variable NAME to VALUE in the HASH_TABLE TABLE, which may be the
2492 temporary environment (but usually is not). */
2493 static SHELL_VAR *
2494 bind_variable_internal (name, value, table, hflags, aflags)
2495 const char *name;
2496 char *value;
2497 HASH_TABLE *table;
2498 int hflags, aflags;
2499 {
2500 char *newval;
2501 SHELL_VAR *entry;
2502
2503 entry = (hflags & HASH_NOSRCH) ? (SHELL_VAR *)NULL : hash_lookup (name, table);
2504 /* Follow the nameref chain here if this is the global variables table */
2505 if (entry && nameref_p (entry) && (invisible_p (entry) == 0) && table == global_variables->table)
2506 {
2507 entry = find_global_variable (entry->name);
2508 /* Let's see if we have a nameref referencing a variable that hasn't yet
2509 been created. */
2510 if (entry == 0)
2511 entry = find_variable_last_nameref (name); /* XXX */
2512 if (entry == 0) /* just in case */
2513 return (entry);
2514 }
2515
2516 /* The first clause handles `declare -n ref; ref=x;' */
2517 if (entry && invisible_p (entry) && nameref_p (entry))
2518 goto assign_value;
2519 else if (entry && nameref_p (entry))
2520 {
2521 newval = nameref_cell (entry);
2522 #if defined (ARRAY_VARS)
2523 /* declare -n foo=x[2] */
2524 if (valid_array_reference (newval))
2525 /* XXX - should it be aflags? */
2526 entry = assign_array_element (newval, make_variable_value (entry, value, 0), aflags);
2527 else
2528 #endif
2529 {
2530 entry = make_new_variable (newval, table);
2531 var_setvalue (entry, make_variable_value (entry, value, 0));
2532 }
2533 }
2534 else if (entry == 0)
2535 {
2536 entry = make_new_variable (name, table);
2537 var_setvalue (entry, make_variable_value (entry, value, 0)); /* XXX */
2538 }
2539 else if (entry->assign_func) /* array vars have assign functions now */
2540 {
2541 INVALIDATE_EXPORTSTR (entry);
2542 newval = (aflags & ASS_APPEND) ? make_variable_value (entry, value, aflags) : value;
2543 if (assoc_p (entry))
2544 entry = (*(entry->assign_func)) (entry, newval, -1, savestring ("0"));
2545 else if (array_p (entry))
2546 entry = (*(entry->assign_func)) (entry, newval, 0, 0);
2547 else
2548 entry = (*(entry->assign_func)) (entry, newval, -1, 0);
2549 if (newval != value)
2550 free (newval);
2551 return (entry);
2552 }
2553 else
2554 {
2555 assign_value:
2556 if (readonly_p (entry) || noassign_p (entry))
2557 {
2558 if (readonly_p (entry))
2559 err_readonly (name);
2560 return (entry);
2561 }
2562
2563 /* Variables which are bound are visible. */
2564 VUNSETATTR (entry, att_invisible);
2565
2566 #if defined (ARRAY_VARS)
2567 if (assoc_p (entry) || array_p (entry))
2568 newval = make_array_variable_value (entry, 0, "0", value, aflags);
2569 else
2570 #endif
2571
2572 newval = make_variable_value (entry, value, aflags); /* XXX */
2573
2574 /* Invalidate any cached export string */
2575 INVALIDATE_EXPORTSTR (entry);
2576
2577 #if defined (ARRAY_VARS)
2578 /* XXX -- this bears looking at again -- XXX */
2579 /* If an existing array variable x is being assigned to with x=b or
2580 `read x' or something of that nature, silently convert it to
2581 x[0]=b or `read x[0]'. */
2582 if (assoc_p (entry))
2583 {
2584 assoc_insert (assoc_cell (entry), savestring ("0"), newval);
2585 free (newval);
2586 }
2587 else if (array_p (entry))
2588 {
2589 array_insert (array_cell (entry), 0, newval);
2590 free (newval);
2591 }
2592 else
2593 #endif
2594 {
2595 FREE (value_cell (entry));
2596 var_setvalue (entry, newval);
2597 }
2598 }
2599
2600 if (mark_modified_vars)
2601 VSETATTR (entry, att_exported);
2602
2603 if (exported_p (entry))
2604 array_needs_making = 1;
2605
2606 return (entry);
2607 }
2608
2609 /* Bind a variable NAME to VALUE. This conses up the name
2610 and value strings. If we have a temporary environment, we bind there
2611 first, then we bind into shell_variables. */
2612
2613 SHELL_VAR *
2614 bind_variable (name, value, flags)
2615 const char *name;
2616 char *value;
2617 int flags;
2618 {
2619 SHELL_VAR *v, *nv;
2620 VAR_CONTEXT *vc, *nvc;
2621 int level;
2622
2623 if (shell_variables == 0)
2624 create_variable_tables ();
2625
2626 /* If we have a temporary environment, look there first for the variable,
2627 and, if found, modify the value there before modifying it in the
2628 shell_variables table. This allows sourced scripts to modify values
2629 given to them in a temporary environment while modifying the variable
2630 value that the caller sees. */
2631 if (temporary_env)
2632 bind_tempenv_variable (name, value);
2633
2634 /* XXX -- handle local variables here. */
2635 for (vc = shell_variables; vc; vc = vc->down)
2636 {
2637 if (vc_isfuncenv (vc) || vc_isbltnenv (vc))
2638 {
2639 v = hash_lookup (name, vc->table);
2640 nvc = vc;
2641 if (v && nameref_p (v))
2642 {
2643 nv = find_variable_nameref_context (v, vc, &nvc);
2644 if (nv == 0)
2645 {
2646 nv = find_variable_last_nameref_context (v, vc, &nvc);
2647 if (nv && nameref_p (nv))
2648 {
2649 /* If this nameref variable doesn't have a value yet,
2650 set the value. Otherwise, assign using the value as
2651 normal. */
2652 if (nameref_cell (nv) == 0)
2653 return (bind_variable_internal (nv->name, value, nvc->table, 0, flags));
2654 return (bind_variable_internal (nameref_cell (nv), value, nvc->table, 0, flags));
2655 }
2656 else
2657 v = nv;
2658 }
2659 else
2660 v = nv;
2661 }
2662 if (v)
2663 return (bind_variable_internal (v->name, value, nvc->table, 0, flags));
2664 }
2665 }
2666 /* bind_variable_internal will handle nameref resolution in this case */
2667 return (bind_variable_internal (name, value, global_variables->table, 0, flags));
2668 }
2669
2670 SHELL_VAR *
2671 bind_global_variable (name, value, flags)
2672 const char *name;
2673 char *value;
2674 int flags;
2675 {
2676 SHELL_VAR *v, *nv;
2677 VAR_CONTEXT *vc, *nvc;
2678 int level;
2679
2680 if (shell_variables == 0)
2681 create_variable_tables ();
2682
2683 /* bind_variable_internal will handle nameref resolution in this case */
2684 return (bind_variable_internal (name, value, global_variables->table, 0, flags));
2685 }
2686
2687 /* Make VAR, a simple shell variable, have value VALUE. Once assigned a
2688 value, variables are no longer invisible. This is a duplicate of part
2689 of the internals of bind_variable. If the variable is exported, or
2690 all modified variables should be exported, mark the variable for export
2691 and note that the export environment needs to be recreated. */
2692 SHELL_VAR *
2693 bind_variable_value (var, value, aflags)
2694 SHELL_VAR *var;
2695 char *value;
2696 int aflags;
2697 {
2698 char *t;
2699 int invis;
2700
2701 invis = invisible_p (var);
2702 VUNSETATTR (var, att_invisible);
2703
2704 if (var->assign_func)
2705 {
2706 /* If we're appending, we need the old value, so use
2707 make_variable_value */
2708 t = (aflags & ASS_APPEND) ? make_variable_value (var, value, aflags) : value;
2709 (*(var->assign_func)) (var, t, -1, 0);
2710 if (t != value && t)
2711 free (t);
2712 }
2713 else
2714 {
2715 t = make_variable_value (var, value, aflags);
2716 #if defined (ARRAY_VARS)
2717 if ((aflags & ASS_NAMEREF) && (t == 0 || *t == 0 || (legal_identifier (t) == 0 && valid_array_reference (t) == 0)))
2718 #else
2719 if ((aflags & ASS_NAMEREF) && (t == 0 || *t == 0 || legal_identifier (t) == 0))
2720 #endif
2721 {
2722 free (t);
2723 if (invis)
2724 VSETATTR (var, att_invisible); /* XXX */
2725 return ((SHELL_VAR *)NULL);
2726 }
2727 FREE (value_cell (var));
2728 var_setvalue (var, t);
2729 }
2730
2731 INVALIDATE_EXPORTSTR (var);
2732
2733 if (mark_modified_vars)
2734 VSETATTR (var, att_exported);
2735
2736 if (exported_p (var))
2737 array_needs_making = 1;
2738
2739 return (var);
2740 }
2741
2742 /* Bind/create a shell variable with the name LHS to the RHS.
2743 This creates or modifies a variable such that it is an integer.
2744
2745 This used to be in expr.c, but it is here so that all of the
2746 variable binding stuff is localized. Since we don't want any
2747 recursive evaluation from bind_variable() (possible without this code,
2748 since bind_variable() calls the evaluator for variables with the integer
2749 attribute set), we temporarily turn off the integer attribute for each
2750 variable we set here, then turn it back on after binding as necessary. */
2751
2752 SHELL_VAR *
2753 bind_int_variable (lhs, rhs)
2754 char *lhs, *rhs;
2755 {
2756 register SHELL_VAR *v;
2757 int isint, isarr, implicitarray;
2758
2759 isint = isarr = implicitarray = 0;
2760 #if defined (ARRAY_VARS)
2761 if (valid_array_reference (lhs))
2762 {
2763 isarr = 1;
2764 v = array_variable_part (lhs, (char **)0, (int *)0);
2765 }
2766 else
2767 #endif
2768 v = find_variable (lhs);
2769
2770 if (v)
2771 {
2772 isint = integer_p (v);
2773 VUNSETATTR (v, att_integer);
2774 #if defined (ARRAY_VARS)
2775 if (array_p (v) && isarr == 0)
2776 implicitarray = 1;
2777 #endif
2778 }
2779
2780 #if defined (ARRAY_VARS)
2781 if (isarr)
2782 v = assign_array_element (lhs, rhs, 0);
2783 else if (implicitarray)
2784 v = bind_array_variable (lhs, 0, rhs, 0);
2785 else
2786 #endif
2787 v = bind_variable (lhs, rhs, 0);
2788
2789 if (v && isint)
2790 VSETATTR (v, att_integer);
2791
2792 VUNSETATTR (v, att_invisible);
2793
2794 return (v);
2795 }
2796
2797 SHELL_VAR *
2798 bind_var_to_int (var, val)
2799 char *var;
2800 intmax_t val;
2801 {
2802 char ibuf[INT_STRLEN_BOUND (intmax_t) + 1], *p;
2803
2804 p = fmtulong (val, 10, ibuf, sizeof (ibuf), 0);
2805 return (bind_int_variable (var, p));
2806 }
2807
2808 /* Do a function binding to a variable. You pass the name and
2809 the command to bind to. This conses the name and command. */
2810 SHELL_VAR *
2811 bind_function (name, value)
2812 const char *name;
2813 COMMAND *value;
2814 {
2815 SHELL_VAR *entry;
2816
2817 entry = find_function (name);
2818 if (entry == 0)
2819 {
2820 BUCKET_CONTENTS *elt;
2821
2822 elt = hash_insert (savestring (name), shell_functions, HASH_NOSRCH);
2823 entry = new_shell_variable (name);
2824 elt->data = (PTR_T)entry;
2825 }
2826 else
2827 INVALIDATE_EXPORTSTR (entry);
2828
2829 if (var_isset (entry))
2830 dispose_command (function_cell (entry));
2831
2832 if (value)
2833 var_setfunc (entry, copy_command (value));
2834 else
2835 var_setfunc (entry, 0);
2836
2837 VSETATTR (entry, att_function);
2838
2839 if (mark_modified_vars)
2840 VSETATTR (entry, att_exported);
2841
2842 VUNSETATTR (entry, att_invisible); /* Just to be sure */
2843
2844 if (exported_p (entry))
2845 array_needs_making = 1;
2846
2847 #if defined (PROGRAMMABLE_COMPLETION)
2848 set_itemlist_dirty (&it_functions);
2849 #endif
2850
2851 return (entry);
2852 }
2853
2854 #if defined (DEBUGGER)
2855 /* Bind a function definition, which includes source file and line number
2856 information in addition to the command, into the FUNCTION_DEF hash table.*/
2857 void
2858 bind_function_def (name, value)
2859 const char *name;
2860 FUNCTION_DEF *value;
2861 {
2862 FUNCTION_DEF *entry;
2863 BUCKET_CONTENTS *elt;
2864 COMMAND *cmd;
2865
2866 entry = find_function_def (name);
2867 if (entry)
2868 {
2869 dispose_function_def_contents (entry);
2870 entry = copy_function_def_contents (value, entry);
2871 }
2872 else
2873 {
2874 cmd = value->command;
2875 value->command = 0;
2876 entry = copy_function_def (value);
2877 value->command = cmd;
2878
2879 elt = hash_insert (savestring (name), shell_function_defs, HASH_NOSRCH);
2880 elt->data = (PTR_T *)entry;
2881 }
2882 }
2883 #endif /* DEBUGGER */
2884
2885 /* Add STRING, which is of the form foo=bar, to the temporary environment
2886 HASH_TABLE (temporary_env). The functions in execute_cmd.c are
2887 responsible for moving the main temporary env to one of the other
2888 temporary environments. The expansion code in subst.c calls this. */
2889 int
2890 assign_in_env (word, flags)
2891 WORD_DESC *word;
2892 int flags;
2893 {
2894 int offset, aflags;
2895 char *name, *temp, *value;
2896 SHELL_VAR *var;
2897 const char *string;
2898
2899 string = word->word;
2900
2901 aflags = 0;
2902 offset = assignment (string, 0);
2903 name = savestring (string);
2904 value = (char *)NULL;
2905
2906 if (name[offset] == '=')
2907 {
2908 name[offset] = 0;
2909
2910 /* don't ignore the `+' when assigning temporary environment */
2911 if (name[offset - 1] == '+')
2912 {
2913 name[offset - 1] = '\0';
2914 aflags |= ASS_APPEND;
2915 }
2916
2917 var = find_variable (name);
2918 if (var && (readonly_p (var) || noassign_p (var)))
2919 {
2920 if (readonly_p (var))
2921 err_readonly (name);
2922 free (name);
2923 return (0);
2924 }
2925
2926 temp = name + offset + 1;
2927 value = expand_assignment_string_to_string (temp, 0);
2928
2929 if (var && (aflags & ASS_APPEND))
2930 {
2931 temp = make_variable_value (var, value, aflags);
2932 FREE (value);
2933 value = temp;
2934 }
2935 }
2936
2937 if (temporary_env == 0)
2938 temporary_env = hash_create (TEMPENV_HASH_BUCKETS);
2939
2940 var = hash_lookup (name, temporary_env);
2941 if (var == 0)
2942 var = make_new_variable (name, temporary_env);
2943 else
2944 FREE (value_cell (var));
2945
2946 if (value == 0)
2947 {
2948 value = (char *)xmalloc (1); /* like do_assignment_internal */
2949 value[0] = '\0';
2950 }
2951
2952 var_setvalue (var, value);
2953 var->attributes |= (att_exported|att_tempvar);
2954 var->context = variable_context; /* XXX */
2955
2956 INVALIDATE_EXPORTSTR (var);
2957 var->exportstr = mk_env_string (name, value);
2958
2959 array_needs_making = 1;
2960
2961 if (flags)
2962 stupidly_hack_special_variables (name);
2963
2964 if (echo_command_at_execute)
2965 /* The Korn shell prints the `+ ' in front of assignment statements,
2966 so we do too. */
2967 xtrace_print_assignment (name, value, 0, 1);
2968
2969 free (name);
2970 return 1;
2971 }
2972
2973 /* **************************************************************** */
2974 /* */
2975 /* Copying variables */
2976 /* */
2977 /* **************************************************************** */
2978
2979 #ifdef INCLUDE_UNUSED
2980 /* Copy VAR to a new data structure and return that structure. */
2981 SHELL_VAR *
2982 copy_variable (var)
2983 SHELL_VAR *var;
2984 {
2985 SHELL_VAR *copy = (SHELL_VAR *)NULL;
2986
2987 if (var)
2988 {
2989 copy = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
2990
2991 copy->attributes = var->attributes;
2992 copy->name = savestring (var->name);
2993
2994 if (function_p (var))
2995 var_setfunc (copy, copy_command (function_cell (var)));
2996 #if defined (ARRAY_VARS)
2997 else if (array_p (var))
2998 var_setarray (copy, array_copy (array_cell (var)));
2999 else if (assoc_p (var))
3000 var_setassoc (copy, assoc_copy (assoc_cell (var)));
3001 #endif
3002 else if (nameref_cell (var)) /* XXX - nameref */
3003 var_setref (copy, savestring (nameref_cell (var)));
3004 else if (value_cell (var)) /* XXX - nameref */
3005 var_setvalue (copy, savestring (value_cell (var)));
3006 else
3007 var_setvalue (copy, (char *)NULL);
3008
3009 copy->dynamic_value = var->dynamic_value;
3010 copy->assign_func = var->assign_func;
3011
3012 copy->exportstr = COPY_EXPORTSTR (var);
3013
3014 copy->context = var->context;
3015 }
3016 return (copy);
3017 }
3018 #endif
3019
3020 /* **************************************************************** */
3021 /* */
3022 /* Deleting and unsetting variables */
3023 /* */
3024 /* **************************************************************** */
3025
3026 /* Dispose of the information attached to VAR. */
3027 static void
3028 dispose_variable_value (var)
3029 SHELL_VAR *var;
3030 {
3031 if (function_p (var))
3032 dispose_command (function_cell (var));
3033 #if defined (ARRAY_VARS)
3034 else if (array_p (var))
3035 array_dispose (array_cell (var));
3036 else if (assoc_p (var))
3037 assoc_dispose (assoc_cell (var));
3038 #endif
3039 else if (nameref_p (var))
3040 FREE (nameref_cell (var));
3041 else
3042 FREE (value_cell (var));
3043 }
3044
3045 void
3046 dispose_variable (var)
3047 SHELL_VAR *var;
3048 {
3049 if (var == 0)
3050 return;
3051
3052 if (nofree_p (var) == 0)
3053 dispose_variable_value (var);
3054
3055 FREE_EXPORTSTR (var);
3056
3057 free (var->name);
3058
3059 if (exported_p (var))
3060 array_needs_making = 1;
3061
3062 free (var);
3063 }
3064
3065 /* Unset the shell variable referenced by NAME. Unsetting a nameref variable
3066 unsets the variable it resolves to but leaves the nameref alone. */
3067 int
3068 unbind_variable (name)
3069 const char *name;
3070 {
3071 SHELL_VAR *v, *nv;
3072 int r;
3073
3074 v = var_lookup (name, shell_variables);
3075 nv = (v && nameref_p (v)) ? find_variable_nameref (v) : (SHELL_VAR *)NULL;
3076
3077 r = nv ? makunbound (nv->name, shell_variables) : makunbound (name, shell_variables);
3078 return r;
3079 }
3080
3081 /* Unbind NAME, where NAME is assumed to be a nameref variable */
3082 int
3083 unbind_nameref (name)
3084 const char *name;
3085 {
3086 SHELL_VAR *v;
3087
3088 v = var_lookup (name, shell_variables);
3089 if (v && nameref_p (v))
3090 return makunbound (name, shell_variables);
3091 return 0;
3092 }
3093
3094 /* Unset the shell function named NAME. */
3095 int
3096 unbind_func (name)
3097 const char *name;
3098 {
3099 BUCKET_CONTENTS *elt;
3100 SHELL_VAR *func;
3101
3102 elt = hash_remove (name, shell_functions, 0);
3103
3104 if (elt == 0)
3105 return -1;
3106
3107 #if defined (PROGRAMMABLE_COMPLETION)
3108 set_itemlist_dirty (&it_functions);
3109 #endif
3110
3111 func = (SHELL_VAR *)elt->data;
3112 if (func)
3113 {
3114 if (exported_p (func))
3115 array_needs_making++;
3116 dispose_variable (func);
3117 }
3118
3119 free (elt->key);
3120 free (elt);
3121
3122 return 0;
3123 }
3124
3125 #if defined (DEBUGGER)
3126 int
3127 unbind_function_def (name)
3128 const char *name;
3129 {
3130 BUCKET_CONTENTS *elt;
3131 FUNCTION_DEF *funcdef;
3132
3133 elt = hash_remove (name, shell_function_defs, 0);
3134
3135 if (elt == 0)
3136 return -1;
3137
3138 funcdef = (FUNCTION_DEF *)elt->data;
3139 if (funcdef)
3140 dispose_function_def (funcdef);
3141
3142 free (elt->key);
3143 free (elt);
3144
3145 return 0;
3146 }
3147 #endif /* DEBUGGER */
3148
3149 int
3150 delete_var (name, vc)
3151 const char *name;
3152 VAR_CONTEXT *vc;
3153 {
3154 BUCKET_CONTENTS *elt;
3155 SHELL_VAR *old_var;
3156 VAR_CONTEXT *v;
3157
3158 for (elt = (BUCKET_CONTENTS *)NULL, v = vc; v; v = v->down)
3159 if (elt = hash_remove (name, v->table, 0))
3160 break;
3161
3162 if (elt == 0)
3163 return (-1);
3164
3165 old_var = (SHELL_VAR *)elt->data;
3166 free (elt->key);
3167 free (elt);
3168
3169 dispose_variable (old_var);
3170 return (0);
3171 }
3172
3173 /* Make the variable associated with NAME go away. HASH_LIST is the
3174 hash table from which this variable should be deleted (either
3175 shell_variables or shell_functions).
3176 Returns non-zero if the variable couldn't be found. */
3177 int
3178 makunbound (name, vc)
3179 const char *name;
3180 VAR_CONTEXT *vc;
3181 {
3182 BUCKET_CONTENTS *elt, *new_elt;
3183 SHELL_VAR *old_var;
3184 VAR_CONTEXT *v;
3185 char *t;
3186
3187 for (elt = (BUCKET_CONTENTS *)NULL, v = vc; v; v = v->down)
3188 if (elt = hash_remove (name, v->table, 0))
3189 break;
3190
3191 if (elt == 0)
3192 return (-1);
3193
3194 old_var = (SHELL_VAR *)elt->data;
3195
3196 if (old_var && exported_p (old_var))
3197 array_needs_making++;
3198
3199 /* If we're unsetting a local variable and we're still executing inside
3200 the function, just mark the variable as invisible. The function
3201 eventually called by pop_var_context() will clean it up later. This
3202 must be done so that if the variable is subsequently assigned a new
3203 value inside the function, the `local' attribute is still present.
3204 We also need to add it back into the correct hash table. */
3205 if (old_var && local_p (old_var) && variable_context == old_var->context)
3206 {
3207 if (nofree_p (old_var))
3208 var_setvalue (old_var, (char *)NULL);
3209 #if defined (ARRAY_VARS)
3210 else if (array_p (old_var))
3211 array_dispose (array_cell (old_var));
3212 else if (assoc_p (old_var))
3213 assoc_dispose (assoc_cell (old_var));
3214 #endif
3215 else if (nameref_p (old_var))
3216 FREE (nameref_cell (old_var));
3217 else
3218 FREE (value_cell (old_var));
3219 /* Reset the attributes. Preserve the export attribute if the variable
3220 came from a temporary environment. Make sure it stays local, and
3221 make it invisible. */
3222 old_var->attributes = (exported_p (old_var) && tempvar_p (old_var)) ? att_exported : 0;
3223 VSETATTR (old_var, att_local);
3224 VSETATTR (old_var, att_invisible);
3225 var_setvalue (old_var, (char *)NULL);
3226 INVALIDATE_EXPORTSTR (old_var);
3227
3228 new_elt = hash_insert (savestring (old_var->name), v->table, 0);
3229 new_elt->data = (PTR_T)old_var;
3230 stupidly_hack_special_variables (old_var->name);
3231
3232 free (elt->key);
3233 free (elt);
3234 return (0);
3235 }
3236
3237 /* Have to save a copy of name here, because it might refer to
3238 old_var->name. If so, stupidly_hack_special_variables will
3239 reference freed memory. */
3240 t = savestring (name);
3241
3242 free (elt->key);
3243 free (elt);
3244
3245 dispose_variable (old_var);
3246 stupidly_hack_special_variables (t);
3247 free (t);
3248
3249 return (0);
3250 }
3251
3252 /* Get rid of all of the variables in the current context. */
3253 void
3254 kill_all_local_variables ()
3255 {
3256 VAR_CONTEXT *vc;
3257
3258 for (vc = shell_variables; vc; vc = vc->down)
3259 if (vc_isfuncenv (vc) && vc->scope == variable_context)
3260 break;
3261 if (vc == 0)
3262 return; /* XXX */
3263
3264 if (vc->table && vc_haslocals (vc))
3265 {
3266 delete_all_variables (vc->table);
3267 hash_dispose (vc->table);
3268 }
3269 vc->table = (HASH_TABLE *)NULL;
3270 }
3271
3272 static void
3273 free_variable_hash_data (data)
3274 PTR_T data;
3275 {
3276 SHELL_VAR *var;
3277
3278 var = (SHELL_VAR *)data;
3279 dispose_variable (var);
3280 }
3281
3282 /* Delete the entire contents of the hash table. */
3283 void
3284 delete_all_variables (hashed_vars)
3285 HASH_TABLE *hashed_vars;
3286 {
3287 hash_flush (hashed_vars, free_variable_hash_data);
3288 }
3289
3290 /* **************************************************************** */
3291 /* */
3292 /* Setting variable attributes */
3293 /* */
3294 /* **************************************************************** */
3295
3296 #define FIND_OR_MAKE_VARIABLE(name, entry) \
3297 do \
3298 { \
3299 entry = find_variable (name); \
3300 if (!entry) \
3301 { \
3302 entry = bind_variable (name, "", 0); \
3303 if (!no_invisible_vars && entry) entry->attributes |= att_invisible; \
3304 } \
3305 } \
3306 while (0)
3307
3308 /* Make the variable associated with NAME be readonly.
3309 If NAME does not exist yet, create it. */
3310 void
3311 set_var_read_only (name)
3312 char *name;
3313 {
3314 SHELL_VAR *entry;
3315
3316 FIND_OR_MAKE_VARIABLE (name, entry);
3317 VSETATTR (entry, att_readonly);
3318 }
3319
3320 #ifdef INCLUDE_UNUSED
3321 /* Make the function associated with NAME be readonly.
3322 If NAME does not exist, we just punt, like auto_export code below. */
3323 void
3324 set_func_read_only (name)
3325 const char *name;
3326 {
3327 SHELL_VAR *entry;
3328
3329 entry = find_function (name);
3330 if (entry)
3331 VSETATTR (entry, att_readonly);
3332 }
3333
3334 /* Make the variable associated with NAME be auto-exported.
3335 If NAME does not exist yet, create it. */
3336 void
3337 set_var_auto_export (name)
3338 char *name;
3339 {
3340 SHELL_VAR *entry;
3341
3342 FIND_OR_MAKE_VARIABLE (name, entry);
3343 set_auto_export (entry);
3344 }
3345
3346 /* Make the function associated with NAME be auto-exported. */
3347 void
3348 set_func_auto_export (name)
3349 const char *name;
3350 {
3351 SHELL_VAR *entry;
3352
3353 entry = find_function (name);
3354 if (entry)
3355 set_auto_export (entry);
3356 }
3357 #endif
3358
3359 /* **************************************************************** */
3360 /* */
3361 /* Creating lists of variables */
3362 /* */
3363 /* **************************************************************** */
3364
3365 static VARLIST *
3366 vlist_alloc (nentries)
3367 int nentries;
3368 {
3369 VARLIST *vlist;
3370
3371 vlist = (VARLIST *)xmalloc (sizeof (VARLIST));
3372 vlist->list = (SHELL_VAR **)xmalloc ((nentries + 1) * sizeof (SHELL_VAR *));
3373 vlist->list_size = nentries;
3374 vlist->list_len = 0;
3375 vlist->list[0] = (SHELL_VAR *)NULL;
3376
3377 return vlist;
3378 }
3379
3380 static VARLIST *
3381 vlist_realloc (vlist, n)
3382 VARLIST *vlist;
3383 int n;
3384 {
3385 if (vlist == 0)
3386 return (vlist = vlist_alloc (n));
3387 if (n > vlist->list_size)
3388 {
3389 vlist->list_size = n;
3390 vlist->list = (SHELL_VAR **)xrealloc (vlist->list, (vlist->list_size + 1) * sizeof (SHELL_VAR *));
3391 }
3392 return vlist;
3393 }
3394
3395 static void
3396 vlist_add (vlist, var, flags)
3397 VARLIST *vlist;
3398 SHELL_VAR *var;
3399 int flags;
3400 {
3401 register int i;
3402
3403 for (i = 0; i < vlist->list_len; i++)
3404 if (STREQ (var->name, vlist->list[i]->name))
3405 break;
3406 if (i < vlist->list_len)
3407 return;
3408
3409 if (i >= vlist->list_size)
3410 vlist = vlist_realloc (vlist, vlist->list_size + 16);
3411
3412 vlist->list[vlist->list_len++] = var;
3413 vlist->list[vlist->list_len] = (SHELL_VAR *)NULL;
3414 }
3415
3416 /* Map FUNCTION over the variables in VAR_HASH_TABLE. Return an array of the
3417 variables for which FUNCTION returns a non-zero value. A NULL value
3418 for FUNCTION means to use all variables. */
3419 SHELL_VAR **
3420 map_over (function, vc)
3421 sh_var_map_func_t *function;
3422 VAR_CONTEXT *vc;
3423 {
3424 VAR_CONTEXT *v;
3425 VARLIST *vlist;
3426 SHELL_VAR **ret;
3427 int nentries;
3428
3429 for (nentries = 0, v = vc; v; v = v->down)
3430 nentries += HASH_ENTRIES (v->table);
3431
3432 if (nentries == 0)
3433 return (SHELL_VAR **)NULL;
3434
3435 vlist = vlist_alloc (nentries);
3436
3437 for (v = vc; v; v = v->down)
3438 flatten (v->table, function, vlist, 0);
3439
3440 ret = vlist->list;
3441 free (vlist);
3442 return ret;
3443 }
3444
3445 SHELL_VAR **
3446 map_over_funcs (function)
3447 sh_var_map_func_t *function;
3448 {
3449 VARLIST *vlist;
3450 SHELL_VAR **ret;
3451
3452 if (shell_functions == 0 || HASH_ENTRIES (shell_functions) == 0)
3453 return ((SHELL_VAR **)NULL);
3454
3455 vlist = vlist_alloc (HASH_ENTRIES (shell_functions));
3456
3457 flatten (shell_functions, function, vlist, 0);
3458
3459 ret = vlist->list;
3460 free (vlist);
3461 return ret;
3462 }
3463
3464 /* Flatten VAR_HASH_TABLE, applying FUNC to each member and adding those
3465 elements for which FUNC succeeds to VLIST->list. FLAGS is reserved
3466 for future use. Only unique names are added to VLIST. If FUNC is
3467 NULL, each variable in VAR_HASH_TABLE is added to VLIST. If VLIST is
3468 NULL, FUNC is applied to each SHELL_VAR in VAR_HASH_TABLE. If VLIST
3469 and FUNC are both NULL, nothing happens. */
3470 static void
3471 flatten (var_hash_table, func, vlist, flags)
3472 HASH_TABLE *var_hash_table;
3473 sh_var_map_func_t *func;
3474 VARLIST *vlist;
3475 int flags;
3476 {
3477 register int i;
3478 register BUCKET_CONTENTS *tlist;
3479 int r;
3480 SHELL_VAR *var;
3481
3482 if (var_hash_table == 0 || (HASH_ENTRIES (var_hash_table) == 0) || (vlist == 0 && func == 0))
3483 return;
3484
3485 for (i = 0; i < var_hash_table->nbuckets; i++)
3486 {
3487 for (tlist = hash_items (i, var_hash_table); tlist; tlist = tlist->next)
3488 {
3489 var = (SHELL_VAR *)tlist->data;
3490
3491 r = func ? (*func) (var) : 1;
3492 if (r && vlist)
3493 vlist_add (vlist, var, flags);
3494 }
3495 }
3496 }
3497
3498 void
3499 sort_variables (array)
3500 SHELL_VAR **array;
3501 {
3502 qsort (array, strvec_len ((char **)array), sizeof (SHELL_VAR *), (QSFUNC *)qsort_var_comp);
3503 }
3504
3505 static int
3506 qsort_var_comp (var1, var2)
3507 SHELL_VAR **var1, **var2;
3508 {
3509 int result;
3510
3511 if ((result = (*var1)->name[0] - (*var2)->name[0]) == 0)
3512 result = strcmp ((*var1)->name, (*var2)->name);
3513
3514 return (result);
3515 }
3516
3517 /* Apply FUNC to each variable in SHELL_VARIABLES, adding each one for
3518 which FUNC succeeds to an array of SHELL_VAR *s. Returns the array. */
3519 static SHELL_VAR **
3520 vapply (func)
3521 sh_var_map_func_t *func;
3522 {
3523 SHELL_VAR **list;
3524
3525 list = map_over (func, shell_variables);
3526 if (list /* && posixly_correct */)
3527 sort_variables (list);
3528 return (list);
3529 }
3530
3531 /* Apply FUNC to each variable in SHELL_FUNCTIONS, adding each one for
3532 which FUNC succeeds to an array of SHELL_VAR *s. Returns the array. */
3533 static SHELL_VAR **
3534 fapply (func)
3535 sh_var_map_func_t *func;
3536 {
3537 SHELL_VAR **list;
3538
3539 list = map_over_funcs (func);
3540 if (list /* && posixly_correct */)
3541 sort_variables (list);
3542 return (list);
3543 }
3544
3545 /* Create a NULL terminated array of all the shell variables. */
3546 SHELL_VAR **
3547 all_shell_variables ()
3548 {
3549 return (vapply ((sh_var_map_func_t *)NULL));
3550 }
3551
3552 /* Create a NULL terminated array of all the shell functions. */
3553 SHELL_VAR **
3554 all_shell_functions ()
3555 {
3556 return (fapply ((sh_var_map_func_t *)NULL));
3557 }
3558
3559 static int
3560 visible_var (var)
3561 SHELL_VAR *var;
3562 {
3563 return (invisible_p (var) == 0);
3564 }
3565
3566 SHELL_VAR **
3567 all_visible_functions ()
3568 {
3569 return (fapply (visible_var));
3570 }
3571
3572 SHELL_VAR **
3573 all_visible_variables ()
3574 {
3575 return (vapply (visible_var));
3576 }
3577
3578 /* Return non-zero if the variable VAR is visible and exported. Array
3579 variables cannot be exported. */
3580 static int
3581 visible_and_exported (var)
3582 SHELL_VAR *var;
3583 {
3584 return (invisible_p (var) == 0 && exported_p (var));
3585 }
3586
3587 /* Candidate variables for the export environment are either valid variables
3588 with the export attribute or invalid variables inherited from the initial
3589 environment and simply passed through. */
3590 static int
3591 export_environment_candidate (var)
3592 SHELL_VAR *var;
3593 {
3594 return (exported_p (var) && (invisible_p (var) == 0 || imported_p (var)));
3595 }
3596
3597 /* Return non-zero if VAR is a local variable in the current context and
3598 is exported. */
3599 static int
3600 local_and_exported (var)
3601 SHELL_VAR *var;
3602 {
3603 return (invisible_p (var) == 0 && local_p (var) && var->context == variable_context && exported_p (var));
3604 }
3605
3606 SHELL_VAR **
3607 all_exported_variables ()
3608 {
3609 return (vapply (visible_and_exported));
3610 }
3611
3612 SHELL_VAR **
3613 local_exported_variables ()
3614 {
3615 return (vapply (local_and_exported));
3616 }
3617
3618 static int
3619 variable_in_context (var)
3620 SHELL_VAR *var;
3621 {
3622 return (invisible_p (var) == 0 && local_p (var) && var->context == variable_context);
3623 }
3624
3625 SHELL_VAR **
3626 all_local_variables ()
3627 {
3628 VARLIST *vlist;
3629 SHELL_VAR **ret;
3630 VAR_CONTEXT *vc;
3631
3632 vc = shell_variables;
3633 for (vc = shell_variables; vc; vc = vc->down)
3634 if (vc_isfuncenv (vc) && vc->scope == variable_context)
3635 break;
3636
3637 if (vc == 0)
3638 {
3639 internal_error (_("all_local_variables: no function context at current scope"));
3640 return (SHELL_VAR **)NULL;
3641 }
3642 if (vc->table == 0 || HASH_ENTRIES (vc->table) == 0 || vc_haslocals (vc) == 0)
3643 return (SHELL_VAR **)NULL;
3644
3645 vlist = vlist_alloc (HASH_ENTRIES (vc->table));
3646
3647 flatten (vc->table, variable_in_context, vlist, 0);
3648
3649 ret = vlist->list;
3650 free (vlist);
3651 if (ret)
3652 sort_variables (ret);
3653 return ret;
3654 }
3655
3656 #if defined (ARRAY_VARS)
3657 /* Return non-zero if the variable VAR is visible and an array. */
3658 static int
3659 visible_array_vars (var)
3660 SHELL_VAR *var;
3661 {
3662 return (invisible_p (var) == 0 && array_p (var));
3663 }
3664
3665 SHELL_VAR **
3666 all_array_variables ()
3667 {
3668 return (vapply (visible_array_vars));
3669 }
3670 #endif /* ARRAY_VARS */
3671
3672 char **
3673 all_variables_matching_prefix (prefix)
3674 const char *prefix;
3675 {
3676 SHELL_VAR **varlist;
3677 char **rlist;
3678 int vind, rind, plen;
3679
3680 plen = STRLEN (prefix);
3681 varlist = all_visible_variables ();
3682 for (vind = 0; varlist && varlist[vind]; vind++)
3683 ;
3684 if (varlist == 0 || vind == 0)
3685 return ((char **)NULL);
3686 rlist = strvec_create (vind + 1);
3687 for (vind = rind = 0; varlist[vind]; vind++)
3688 {
3689 if (plen == 0 || STREQN (prefix, varlist[vind]->name, plen))
3690 rlist[rind++] = savestring (varlist[vind]->name);
3691 }
3692 rlist[rind] = (char *)0;
3693 free (varlist);
3694
3695 return rlist;
3696 }
3697
3698 /* **************************************************************** */
3699 /* */
3700 /* Managing temporary variable scopes */
3701 /* */
3702 /* **************************************************************** */
3703
3704 /* Make variable NAME have VALUE in the temporary environment. */
3705 static SHELL_VAR *
3706 bind_tempenv_variable (name, value)
3707 const char *name;
3708 char *value;
3709 {
3710 SHELL_VAR *var;
3711
3712 var = temporary_env ? hash_lookup (name, temporary_env) : (SHELL_VAR *)NULL;
3713
3714 if (var)
3715 {
3716 FREE (value_cell (var));
3717 var_setvalue (var, savestring (value));
3718 INVALIDATE_EXPORTSTR (var);
3719 }
3720
3721 return (var);
3722 }
3723
3724 /* Find a variable in the temporary environment that is named NAME.
3725 Return the SHELL_VAR *, or NULL if not found. */
3726 SHELL_VAR *
3727 find_tempenv_variable (name)
3728 const char *name;
3729 {
3730 return (temporary_env ? hash_lookup (name, temporary_env) : (SHELL_VAR *)NULL);
3731 }
3732
3733 char **tempvar_list;
3734 int tvlist_ind;
3735
3736 /* Push the variable described by (SHELL_VAR *)DATA down to the next
3737 variable context from the temporary environment. */
3738 static void
3739 push_temp_var (data)
3740 PTR_T data;
3741 {
3742 SHELL_VAR *var, *v;
3743 HASH_TABLE *binding_table;
3744
3745 var = (SHELL_VAR *)data;
3746
3747 binding_table = shell_variables->table;
3748 if (binding_table == 0)
3749 {
3750 if (shell_variables == global_variables)
3751 /* shouldn't happen */
3752 binding_table = shell_variables->table = global_variables->table = hash_create (0);
3753 else
3754 binding_table = shell_variables->table = hash_create (TEMPENV_HASH_BUCKETS);
3755 }
3756
3757 v = bind_variable_internal (var->name, value_cell (var), binding_table, 0, 0);
3758
3759 /* XXX - should we set the context here? It shouldn't matter because of how
3760 assign_in_env works, but might want to check. */
3761 if (binding_table == global_variables->table) /* XXX */
3762 var->attributes &= ~(att_tempvar|att_propagate);
3763 else
3764 {
3765 var->attributes |= att_propagate;
3766 if (binding_table == shell_variables->table)
3767 shell_variables->flags |= VC_HASTMPVAR;
3768 }
3769 v->attributes |= var->attributes;
3770
3771 if (find_special_var (var->name) >= 0)
3772 tempvar_list[tvlist_ind++] = savestring (var->name);
3773
3774 dispose_variable (var);
3775 }
3776
3777 static void
3778 propagate_temp_var (data)
3779 PTR_T data;
3780 {
3781 SHELL_VAR *var;
3782
3783 var = (SHELL_VAR *)data;
3784 if (tempvar_p (var) && (var->attributes & att_propagate))
3785 push_temp_var (data);
3786 else
3787 {
3788 if (find_special_var (var->name) >= 0)
3789 tempvar_list[tvlist_ind++] = savestring (var->name);
3790 dispose_variable (var);
3791 }
3792 }
3793
3794 /* Free the storage used in the hash table for temporary
3795 environment variables. PUSHF is a function to be called
3796 to free each hash table entry. It takes care of pushing variables
3797 to previous scopes if appropriate. PUSHF stores names of variables
3798 that require special handling (e.g., IFS) on tempvar_list, so this
3799 function can call stupidly_hack_special_variables on all the
3800 variables in the list when the temporary hash table is destroyed. */
3801 static void
3802 dispose_temporary_env (pushf)
3803 sh_free_func_t *pushf;
3804 {
3805 int i;
3806
3807 tempvar_list = strvec_create (HASH_ENTRIES (temporary_env) + 1);
3808 tempvar_list[tvlist_ind = 0] = 0;
3809
3810 hash_flush (temporary_env, pushf);
3811 hash_dispose (temporary_env);
3812 temporary_env = (HASH_TABLE *)NULL;
3813
3814 tempvar_list[tvlist_ind] = 0;
3815
3816 array_needs_making = 1;
3817
3818 #if 0
3819 sv_ifs ("IFS"); /* XXX here for now -- check setifs in assign_in_env */
3820 #endif
3821 for (i = 0; i < tvlist_ind; i++)
3822 stupidly_hack_special_variables (tempvar_list[i]);
3823
3824 strvec_dispose (tempvar_list);
3825 tempvar_list = 0;
3826 tvlist_ind = 0;
3827 }
3828
3829 void
3830 dispose_used_env_vars ()
3831 {
3832 if (temporary_env)
3833 {
3834 dispose_temporary_env (propagate_temp_var);
3835 maybe_make_export_env ();
3836 }
3837 }
3838
3839 /* Take all of the shell variables in the temporary environment HASH_TABLE
3840 and make shell variables from them at the current variable context. */
3841 void
3842 merge_temporary_env ()
3843 {
3844 if (temporary_env)
3845 dispose_temporary_env (push_temp_var);
3846 }
3847
3848 /* **************************************************************** */
3849 /* */
3850 /* Creating and manipulating the environment */
3851 /* */
3852 /* **************************************************************** */
3853
3854 static inline char *
3855 mk_env_string (name, value)
3856 const char *name, *value;
3857 {
3858 int name_len, value_len;
3859 char *p;
3860
3861 name_len = strlen (name);
3862 value_len = STRLEN (value);
3863 p = (char *)xmalloc (2 + name_len + value_len);
3864 strcpy (p, name);
3865 p[name_len] = '=';
3866 if (value && *value)
3867 strcpy (p + name_len + 1, value);
3868 else
3869 p[name_len + 1] = '\0';
3870 return (p);
3871 }
3872
3873 #ifdef DEBUG
3874 /* Debugging */
3875 static int
3876 valid_exportstr (v)
3877 SHELL_VAR *v;
3878 {
3879 char *s;
3880
3881 s = v->exportstr;
3882 if (s == 0)
3883 {
3884 internal_error (_("%s has null exportstr"), v->name);
3885 return (0);
3886 }
3887 if (legal_variable_starter ((unsigned char)*s) == 0)
3888 {
3889 internal_error (_("invalid character %d in exportstr for %s"), *s, v->name);
3890 return (0);
3891 }
3892 for (s = v->exportstr + 1; s && *s; s++)
3893 {
3894 if (*s == '=')
3895 break;
3896 if (legal_variable_char ((unsigned char)*s) == 0)
3897 {
3898 internal_error (_("invalid character %d in exportstr for %s"), *s, v->name);
3899 return (0);
3900 }
3901 }
3902 if (*s != '=')
3903 {
3904 internal_error (_("no `=' in exportstr for %s"), v->name);
3905 return (0);
3906 }
3907 return (1);
3908 }
3909 #endif
3910
3911 static char **
3912 make_env_array_from_var_list (vars)
3913 SHELL_VAR **vars;
3914 {
3915 register int i, list_index;
3916 register SHELL_VAR *var;
3917 char **list, *value;
3918
3919 list = strvec_create ((1 + strvec_len ((char **)vars)));
3920
3921 #define USE_EXPORTSTR (value == var->exportstr)
3922
3923 for (i = 0, list_index = 0; var = vars[i]; i++)
3924 {
3925 #if defined (__CYGWIN__)
3926 /* We don't use the exportstr stuff on Cygwin at all. */
3927 INVALIDATE_EXPORTSTR (var);
3928 #endif
3929 if (var->exportstr)
3930 value = var->exportstr;
3931 else if (function_p (var))
3932 value = named_function_string ((char *)NULL, function_cell (var), 0);
3933 #if defined (ARRAY_VARS)
3934 else if (array_p (var))
3935 # if ARRAY_EXPORT
3936 value = array_to_assignment_string (array_cell (var));
3937 # else
3938 continue; /* XXX array vars cannot yet be exported */
3939 # endif /* ARRAY_EXPORT */
3940 else if (assoc_p (var))
3941 # if 0
3942 value = assoc_to_assignment_string (assoc_cell (var));
3943 # else
3944 continue; /* XXX associative array vars cannot yet be exported */
3945 # endif
3946 #endif
3947 else
3948 value = value_cell (var);
3949
3950 if (value)
3951 {
3952 /* Gee, I'd like to get away with not using savestring() if we're
3953 using the cached exportstr... */
3954 list[list_index] = USE_EXPORTSTR ? savestring (value)
3955 : mk_env_string (var->name, value);
3956
3957 if (USE_EXPORTSTR == 0)
3958 SAVE_EXPORTSTR (var, list[list_index]);
3959
3960 list_index++;
3961 #undef USE_EXPORTSTR
3962
3963 #if 0 /* not yet */
3964 #if defined (ARRAY_VARS)
3965 if (array_p (var) || assoc_p (var))
3966 free (value);
3967 #endif
3968 #endif
3969 }
3970 }
3971
3972 list[list_index] = (char *)NULL;
3973 return (list);
3974 }
3975
3976 /* Make an array of assignment statements from the hash table
3977 HASHED_VARS which contains SHELL_VARs. Only visible, exported
3978 variables are eligible. */
3979 static char **
3980 make_var_export_array (vcxt)
3981 VAR_CONTEXT *vcxt;
3982 {
3983 char **list;
3984 SHELL_VAR **vars;
3985
3986 #if 0
3987 vars = map_over (visible_and_exported, vcxt);
3988 #else
3989 vars = map_over (export_environment_candidate, vcxt);
3990 #endif
3991
3992 if (vars == 0)
3993 return (char **)NULL;
3994
3995 list = make_env_array_from_var_list (vars);
3996
3997 free (vars);
3998 return (list);
3999 }
4000
4001 static char **
4002 make_func_export_array ()
4003 {
4004 char **list;
4005 SHELL_VAR **vars;
4006
4007 vars = map_over_funcs (visible_and_exported);
4008 if (vars == 0)
4009 return (char **)NULL;
4010
4011 list = make_env_array_from_var_list (vars);
4012
4013 free (vars);
4014 return (list);
4015 }
4016
4017 /* Add ENVSTR to the end of the exported environment, EXPORT_ENV. */
4018 #define add_to_export_env(envstr,do_alloc) \
4019 do \
4020 { \
4021 if (export_env_index >= (export_env_size - 1)) \
4022 { \
4023 export_env_size += 16; \
4024 export_env = strvec_resize (export_env, export_env_size); \
4025 environ = export_env; \
4026 } \
4027 export_env[export_env_index++] = (do_alloc) ? savestring (envstr) : envstr; \
4028 export_env[export_env_index] = (char *)NULL; \
4029 } while (0)
4030
4031 /* Add ASSIGN to EXPORT_ENV, or supercede a previous assignment in the
4032 array with the same left-hand side. Return the new EXPORT_ENV. */
4033 char **
4034 add_or_supercede_exported_var (assign, do_alloc)
4035 char *assign;
4036 int do_alloc;
4037 {
4038 register int i;
4039 int equal_offset;
4040
4041 equal_offset = assignment (assign, 0);
4042 if (equal_offset == 0)
4043 return (export_env);
4044
4045 /* If this is a function, then only supersede the function definition.
4046 We do this by including the `=() {' in the comparison, like
4047 initialize_shell_variables does. */
4048 if (assign[equal_offset + 1] == '(' &&
4049 strncmp (assign + equal_offset + 2, ") {", 3) == 0) /* } */
4050 equal_offset += 4;
4051
4052 for (i = 0; i < export_env_index; i++)
4053 {
4054 if (STREQN (assign, export_env[i], equal_offset + 1))
4055 {
4056 free (export_env[i]);
4057 export_env[i] = do_alloc ? savestring (assign) : assign;
4058 return (export_env);
4059 }
4060 }
4061 add_to_export_env (assign, do_alloc);
4062 return (export_env);
4063 }
4064
4065 static void
4066 add_temp_array_to_env (temp_array, do_alloc, do_supercede)
4067 char **temp_array;
4068 int do_alloc, do_supercede;
4069 {
4070 register int i;
4071
4072 if (temp_array == 0)
4073 return;
4074
4075 for (i = 0; temp_array[i]; i++)
4076 {
4077 if (do_supercede)
4078 export_env = add_or_supercede_exported_var (temp_array[i], do_alloc);
4079 else
4080 add_to_export_env (temp_array[i], do_alloc);
4081 }
4082
4083 free (temp_array);
4084 }
4085
4086 /* Make the environment array for the command about to be executed, if the
4087 array needs making. Otherwise, do nothing. If a shell action could
4088 change the array that commands receive for their environment, then the
4089 code should `array_needs_making++'.
4090
4091 The order to add to the array is:
4092 temporary_env
4093 list of var contexts whose head is shell_variables
4094 shell_functions
4095
4096 This is the shell variable lookup order. We add only new variable
4097 names at each step, which allows local variables and variables in
4098 the temporary environments to shadow variables in the global (or
4099 any previous) scope.
4100 */
4101
4102 static int
4103 n_shell_variables ()
4104 {
4105 VAR_CONTEXT *vc;
4106 int n;
4107
4108 for (n = 0, vc = shell_variables; vc; vc = vc->down)
4109 n += HASH_ENTRIES (vc->table);
4110 return n;
4111 }
4112
4113 int
4114 chkexport (name)
4115 char *name;
4116 {
4117 SHELL_VAR *v;
4118
4119 v = find_variable (name);
4120 if (v && exported_p (v))
4121 {
4122 array_needs_making = 1;
4123 maybe_make_export_env ();
4124 return 1;
4125 }
4126 return 0;
4127 }
4128
4129 void
4130 maybe_make_export_env ()
4131 {
4132 register char **temp_array;
4133 int new_size;
4134 VAR_CONTEXT *tcxt;
4135
4136 if (array_needs_making)
4137 {
4138 if (export_env)
4139 strvec_flush (export_env);
4140
4141 /* Make a guess based on how many shell variables and functions we
4142 have. Since there will always be array variables, and array
4143 variables are not (yet) exported, this will always be big enough
4144 for the exported variables and functions. */
4145 new_size = n_shell_variables () + HASH_ENTRIES (shell_functions) + 1 +
4146 HASH_ENTRIES (temporary_env);
4147 if (new_size > export_env_size)
4148 {
4149 export_env_size = new_size;
4150 export_env = strvec_resize (export_env, export_env_size);
4151 environ = export_env;
4152 }
4153 export_env[export_env_index = 0] = (char *)NULL;
4154
4155 /* Make a dummy variable context from the temporary_env, stick it on
4156 the front of shell_variables, call make_var_export_array on the
4157 whole thing to flatten it, and convert the list of SHELL_VAR *s
4158 to the form needed by the environment. */
4159 if (temporary_env)
4160 {
4161 tcxt = new_var_context ((char *)NULL, 0);
4162 tcxt->table = temporary_env;
4163 tcxt->down = shell_variables;
4164 }
4165 else
4166 tcxt = shell_variables;
4167
4168 temp_array = make_var_export_array (tcxt);
4169 if (temp_array)
4170 add_temp_array_to_env (temp_array, 0, 0);
4171
4172 if (tcxt != shell_variables)
4173 free (tcxt);
4174
4175 #if defined (RESTRICTED_SHELL)
4176 /* Restricted shells may not export shell functions. */
4177 temp_array = restricted ? (char **)0 : make_func_export_array ();
4178 #else
4179 temp_array = make_func_export_array ();
4180 #endif
4181 if (temp_array)
4182 add_temp_array_to_env (temp_array, 0, 0);
4183
4184 array_needs_making = 0;
4185 }
4186 }
4187
4188 /* This is an efficiency hack. PWD and OLDPWD are auto-exported, so
4189 we will need to remake the exported environment every time we
4190 change directories. `_' is always put into the environment for
4191 every external command, so without special treatment it will always
4192 cause the environment to be remade.
4193
4194 If there is no other reason to make the exported environment, we can
4195 just update the variables in place and mark the exported environment
4196 as no longer needing a remake. */
4197 void
4198 update_export_env_inplace (env_prefix, preflen, value)
4199 char *env_prefix;
4200 int preflen;
4201 char *value;
4202 {
4203 char *evar;
4204
4205 evar = (char *)xmalloc (STRLEN (value) + preflen + 1);
4206 strcpy (evar, env_prefix);
4207 if (value)
4208 strcpy (evar + preflen, value);
4209 export_env = add_or_supercede_exported_var (evar, 0);
4210 }
4211
4212 /* We always put _ in the environment as the name of this command. */
4213 void
4214 put_command_name_into_env (command_name)
4215 char *command_name;
4216 {
4217 update_export_env_inplace ("_=", 2, command_name);
4218 }
4219
4220 /* **************************************************************** */
4221 /* */
4222 /* Managing variable contexts */
4223 /* */
4224 /* **************************************************************** */
4225
4226 /* Allocate and return a new variable context with NAME and FLAGS.
4227 NAME can be NULL. */
4228
4229 VAR_CONTEXT *
4230 new_var_context (name, flags)
4231 char *name;
4232 int flags;
4233 {
4234 VAR_CONTEXT *vc;
4235
4236 vc = (VAR_CONTEXT *)xmalloc (sizeof (VAR_CONTEXT));
4237 vc->name = name ? savestring (name) : (char *)NULL;
4238 vc->scope = variable_context;
4239 vc->flags = flags;
4240
4241 vc->up = vc->down = (VAR_CONTEXT *)NULL;
4242 vc->table = (HASH_TABLE *)NULL;
4243
4244 return vc;
4245 }
4246
4247 /* Free a variable context and its data, including the hash table. Dispose
4248 all of the variables. */
4249 void
4250 dispose_var_context (vc)
4251 VAR_CONTEXT *vc;
4252 {
4253 FREE (vc->name);
4254
4255 if (vc->table)
4256 {
4257 delete_all_variables (vc->table);
4258 hash_dispose (vc->table);
4259 }
4260
4261 free (vc);
4262 }
4263
4264 /* Set VAR's scope level to the current variable context. */
4265 static int
4266 set_context (var)
4267 SHELL_VAR *var;
4268 {
4269 return (var->context = variable_context);
4270 }
4271
4272 /* Make a new variable context with NAME and FLAGS and a HASH_TABLE of
4273 temporary variables, and push it onto shell_variables. This is
4274 for shell functions. */
4275 VAR_CONTEXT *
4276 push_var_context (name, flags, tempvars)
4277 char *name;
4278 int flags;
4279 HASH_TABLE *tempvars;
4280 {
4281 VAR_CONTEXT *vc;
4282
4283 vc = new_var_context (name, flags);
4284 vc->table = tempvars;
4285 if (tempvars)
4286 {
4287 /* Have to do this because the temp environment was created before
4288 variable_context was incremented. */
4289 flatten (tempvars, set_context, (VARLIST *)NULL, 0);
4290 vc->flags |= VC_HASTMPVAR;
4291 }
4292 vc->down = shell_variables;
4293 shell_variables->up = vc;
4294
4295 return (shell_variables = vc);
4296 }
4297
4298 static void
4299 push_func_var (data)
4300 PTR_T data;
4301 {
4302 SHELL_VAR *var, *v;
4303
4304 var = (SHELL_VAR *)data;
4305
4306 if (tempvar_p (var) && (posixly_correct || (var->attributes & att_propagate)))
4307 {
4308 /* Make sure we have a hash table to store the variable in while it is
4309 being propagated down to the global variables table. Create one if
4310 we have to */
4311 if ((vc_isfuncenv (shell_variables) || vc_istempenv (shell_variables)) && shell_variables->table == 0)
4312 shell_variables->table = hash_create (0);
4313 /* XXX - should we set v->context here? */
4314 v = bind_variable_internal (var->name, value_cell (var), shell_variables->table, 0, 0);
4315 if (shell_variables == global_variables)
4316 var->attributes &= ~(att_tempvar|att_propagate);
4317 else
4318 shell_variables->flags |= VC_HASTMPVAR;
4319 v->attributes |= var->attributes;
4320 }
4321 else
4322 stupidly_hack_special_variables (var->name); /* XXX */
4323
4324 dispose_variable (var);
4325 }
4326
4327 /* Pop the top context off of VCXT and dispose of it, returning the rest of
4328 the stack. */
4329 void
4330 pop_var_context ()
4331 {
4332 VAR_CONTEXT *ret, *vcxt;
4333
4334 vcxt = shell_variables;
4335 if (vc_isfuncenv (vcxt) == 0)
4336 {
4337 internal_error (_("pop_var_context: head of shell_variables not a function context"));
4338 return;
4339 }
4340
4341 if (ret = vcxt->down)
4342 {
4343 ret->up = (VAR_CONTEXT *)NULL;
4344 shell_variables = ret;
4345 if (vcxt->table)
4346 hash_flush (vcxt->table, push_func_var);
4347 dispose_var_context (vcxt);
4348 }
4349 else
4350 internal_error (_("pop_var_context: no global_variables context"));
4351 }
4352
4353 /* Delete the HASH_TABLEs for all variable contexts beginning at VCXT, and
4354 all of the VAR_CONTEXTs except GLOBAL_VARIABLES. */
4355 void
4356 delete_all_contexts (vcxt)
4357 VAR_CONTEXT *vcxt;
4358 {
4359 VAR_CONTEXT *v, *t;
4360
4361 for (v = vcxt; v != global_variables; v = t)
4362 {
4363 t = v->down;
4364 dispose_var_context (v);
4365 }
4366
4367 delete_all_variables (global_variables->table);
4368 shell_variables = global_variables;
4369 }
4370
4371 /* **************************************************************** */
4372 /* */
4373 /* Pushing and Popping temporary variable scopes */
4374 /* */
4375 /* **************************************************************** */
4376
4377 VAR_CONTEXT *
4378 push_scope (flags, tmpvars)
4379 int flags;
4380 HASH_TABLE *tmpvars;
4381 {
4382 return (push_var_context ((char *)NULL, flags, tmpvars));
4383 }
4384
4385 static void
4386 push_exported_var (data)
4387 PTR_T data;
4388 {
4389 SHELL_VAR *var, *v;
4390
4391 var = (SHELL_VAR *)data;
4392
4393 /* If a temp var had its export attribute set, or it's marked to be
4394 propagated, bind it in the previous scope before disposing it. */
4395 /* XXX - This isn't exactly right, because all tempenv variables have the
4396 export attribute set. */
4397 #if 0
4398 if (exported_p (var) || (var->attributes & att_propagate))
4399 #else
4400 if (tempvar_p (var) && exported_p (var) && (var->attributes & att_propagate))
4401 #endif
4402 {
4403 var->attributes &= ~att_tempvar; /* XXX */
4404 v = bind_variable_internal (var->name, value_cell (var), shell_variables->table, 0, 0);
4405 if (shell_variables == global_variables)
4406 var->attributes &= ~att_propagate;
4407 v->attributes |= var->attributes;
4408 }
4409 else
4410 stupidly_hack_special_variables (var->name); /* XXX */
4411
4412 dispose_variable (var);
4413 }
4414
4415 void
4416 pop_scope (is_special)
4417 int is_special;
4418 {
4419 VAR_CONTEXT *vcxt, *ret;
4420
4421 vcxt = shell_variables;
4422 if (vc_istempscope (vcxt) == 0)
4423 {
4424 internal_error (_("pop_scope: head of shell_variables not a temporary environment scope"));
4425 return;
4426 }
4427
4428 ret = vcxt->down;
4429 if (ret)
4430 ret->up = (VAR_CONTEXT *)NULL;
4431
4432 shell_variables = ret;
4433
4434 /* Now we can take care of merging variables in VCXT into set of scopes
4435 whose head is RET (shell_variables). */
4436 FREE (vcxt->name);
4437 if (vcxt->table)
4438 {
4439 if (is_special)
4440 hash_flush (vcxt->table, push_func_var);
4441 else
4442 hash_flush (vcxt->table, push_exported_var);
4443 hash_dispose (vcxt->table);
4444 }
4445 free (vcxt);
4446
4447 sv_ifs ("IFS"); /* XXX here for now */
4448 }
4449
4450 /* **************************************************************** */
4451 /* */
4452 /* Pushing and Popping function contexts */
4453 /* */
4454 /* **************************************************************** */
4455
4456 static WORD_LIST **dollar_arg_stack = (WORD_LIST **)NULL;
4457 static int dollar_arg_stack_slots;
4458 static int dollar_arg_stack_index;
4459
4460 /* XXX - we might want to consider pushing and popping the `getopts' state
4461 when we modify the positional parameters. */
4462 void
4463 push_context (name, is_subshell, tempvars)
4464 char *name; /* function name */
4465 int is_subshell;
4466 HASH_TABLE *tempvars;
4467 {
4468 if (is_subshell == 0)
4469 push_dollar_vars ();
4470 variable_context++;
4471 push_var_context (name, VC_FUNCENV, tempvars);
4472 }
4473
4474 /* Only called when subshell == 0, so we don't need to check, and can
4475 unconditionally pop the dollar vars off the stack. */
4476 void
4477 pop_context ()
4478 {
4479 pop_dollar_vars ();
4480 variable_context--;
4481 pop_var_context ();
4482
4483 sv_ifs ("IFS"); /* XXX here for now */
4484 }
4485
4486 /* Save the existing positional parameters on a stack. */
4487 void
4488 push_dollar_vars ()
4489 {
4490 if (dollar_arg_stack_index + 2 > dollar_arg_stack_slots)
4491 {
4492 dollar_arg_stack = (WORD_LIST **)
4493 xrealloc (dollar_arg_stack, (dollar_arg_stack_slots += 10)
4494 * sizeof (WORD_LIST *));
4495 }
4496 dollar_arg_stack[dollar_arg_stack_index++] = list_rest_of_args ();
4497 dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
4498 }
4499
4500 /* Restore the positional parameters from our stack. */
4501 void
4502 pop_dollar_vars ()
4503 {
4504 if (!dollar_arg_stack || dollar_arg_stack_index == 0)
4505 return;
4506
4507 remember_args (dollar_arg_stack[--dollar_arg_stack_index], 1);
4508 dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
4509 dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
4510 set_dollar_vars_unchanged ();
4511 }
4512
4513 void
4514 dispose_saved_dollar_vars ()
4515 {
4516 if (!dollar_arg_stack || dollar_arg_stack_index == 0)
4517 return;
4518
4519 dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
4520 dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
4521 }
4522
4523 /* Manipulate the special BASH_ARGV and BASH_ARGC variables. */
4524
4525 void
4526 push_args (list)
4527 WORD_LIST *list;
4528 {
4529 #if defined (ARRAY_VARS) && defined (DEBUGGER)
4530 SHELL_VAR *bash_argv_v, *bash_argc_v;
4531 ARRAY *bash_argv_a, *bash_argc_a;
4532 WORD_LIST *l;
4533 arrayind_t i;
4534 char *t;
4535
4536 GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a);
4537 GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
4538
4539 for (l = list, i = 0; l; l = l->next, i++)
4540 array_push (bash_argv_a, l->word->word);
4541
4542 t = itos (i);
4543 array_push (bash_argc_a, t);
4544 free (t);
4545 #endif /* ARRAY_VARS && DEBUGGER */
4546 }
4547
4548 /* Remove arguments from BASH_ARGV array. Pop top element off BASH_ARGC
4549 array and use that value as the count of elements to remove from
4550 BASH_ARGV. */
4551 void
4552 pop_args ()
4553 {
4554 #if defined (ARRAY_VARS) && defined (DEBUGGER)
4555 SHELL_VAR *bash_argv_v, *bash_argc_v;
4556 ARRAY *bash_argv_a, *bash_argc_a;
4557 ARRAY_ELEMENT *ce;
4558 intmax_t i;
4559
4560 GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a);
4561 GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
4562
4563 ce = array_shift (bash_argc_a, 1, 0);
4564 if (ce == 0 || legal_number (element_value (ce), &i) == 0)
4565 i = 0;
4566
4567 for ( ; i > 0; i--)
4568 array_pop (bash_argv_a);
4569 array_dispose_element (ce);
4570 #endif /* ARRAY_VARS && DEBUGGER */
4571 }
4572
4573 /*************************************************
4574 * *
4575 * Functions to manage special variables *
4576 * *
4577 *************************************************/
4578
4579 /* Extern declarations for variables this code has to manage. */
4580 extern int eof_encountered, eof_encountered_limit, ignoreeof;
4581
4582 #if defined (READLINE)
4583 extern int hostname_list_initialized;
4584 #endif
4585
4586 /* An alist of name.function for each special variable. Most of the
4587 functions don't do much, and in fact, this would be faster with a
4588 switch statement, but by the end of this file, I am sick of switch
4589 statements. */
4590
4591 #define SET_INT_VAR(name, intvar) intvar = find_variable (name) != 0
4592
4593 /* This table will be sorted with qsort() the first time it's accessed. */
4594 struct name_and_function {
4595 char *name;
4596 sh_sv_func_t *function;
4597 };
4598
4599 static struct name_and_function special_vars[] = {
4600 { "BASH_COMPAT", sv_shcompat },
4601 { "BASH_XTRACEFD", sv_xtracefd },
4602
4603 #if defined (JOB_CONTROL)
4604 { "CHILD_MAX", sv_childmax },
4605 #endif
4606
4607 #if defined (READLINE)
4608 # if defined (STRICT_POSIX)
4609 { "COLUMNS", sv_winsize },
4610 # endif
4611 { "COMP_WORDBREAKS", sv_comp_wordbreaks },
4612 #endif
4613
4614 { "FUNCNEST", sv_funcnest },
4615
4616 { "GLOBIGNORE", sv_globignore },
4617
4618 #if defined (HISTORY)
4619 { "HISTCONTROL", sv_history_control },
4620 { "HISTFILESIZE", sv_histsize },
4621 { "HISTIGNORE", sv_histignore },
4622 { "HISTSIZE", sv_histsize },
4623 { "HISTTIMEFORMAT", sv_histtimefmt },
4624 #endif
4625
4626 #if defined (__CYGWIN__)
4627 { "HOME", sv_home },
4628 #endif
4629
4630 #if defined (READLINE)
4631 { "HOSTFILE", sv_hostfile },
4632 #endif
4633
4634 { "IFS", sv_ifs },
4635 { "IGNOREEOF", sv_ignoreeof },
4636
4637 { "LANG", sv_locale },
4638 { "LC_ALL", sv_locale },
4639 { "LC_COLLATE", sv_locale },
4640 { "LC_CTYPE", sv_locale },
4641 { "LC_MESSAGES", sv_locale },
4642 { "LC_NUMERIC", sv_locale },
4643 { "LC_TIME", sv_locale },
4644
4645 #if defined (READLINE) && defined (STRICT_POSIX)
4646 { "LINES", sv_winsize },
4647 #endif
4648
4649 { "MAIL", sv_mail },
4650 { "MAILCHECK", sv_mail },
4651 { "MAILPATH", sv_mail },
4652
4653 { "OPTERR", sv_opterr },
4654 { "OPTIND", sv_optind },
4655
4656 { "PATH", sv_path },
4657 { "POSIXLY_CORRECT", sv_strict_posix },
4658
4659 #if defined (READLINE)
4660 { "TERM", sv_terminal },
4661 { "TERMCAP", sv_terminal },
4662 { "TERMINFO", sv_terminal },
4663 #endif /* READLINE */
4664
4665 { "TEXTDOMAIN", sv_locale },
4666 { "TEXTDOMAINDIR", sv_locale },
4667
4668 #if defined (HAVE_TZSET)
4669 { "TZ", sv_tz },
4670 #endif
4671
4672 #if defined (HISTORY) && defined (BANG_HISTORY)
4673 { "histchars", sv_histchars },
4674 #endif /* HISTORY && BANG_HISTORY */
4675
4676 { "ignoreeof", sv_ignoreeof },
4677
4678 { (char *)0, (sh_sv_func_t *)0 }
4679 };
4680
4681 #define N_SPECIAL_VARS (sizeof (special_vars) / sizeof (special_vars[0]) - 1)
4682
4683 static int
4684 sv_compare (sv1, sv2)
4685 struct name_and_function *sv1, *sv2;
4686 {
4687 int r;
4688
4689 if ((r = sv1->name[0] - sv2->name[0]) == 0)
4690 r = strcmp (sv1->name, sv2->name);
4691 return r;
4692 }
4693
4694 static inline int
4695 find_special_var (name)
4696 const char *name;
4697 {
4698 register int i, r;
4699
4700 for (i = 0; special_vars[i].name; i++)
4701 {
4702 r = special_vars[i].name[0] - name[0];
4703 if (r == 0)
4704 r = strcmp (special_vars[i].name, name);
4705 if (r == 0)
4706 return i;
4707 else if (r > 0)
4708 /* Can't match any of rest of elements in sorted list. Take this out
4709 if it causes problems in certain environments. */
4710 break;
4711 }
4712 return -1;
4713 }
4714
4715 /* The variable in NAME has just had its state changed. Check to see if it
4716 is one of the special ones where something special happens. */
4717 void
4718 stupidly_hack_special_variables (name)
4719 char *name;
4720 {
4721 static int sv_sorted = 0;
4722 int i;
4723
4724 if (sv_sorted == 0) /* shouldn't need, but it's fairly cheap. */
4725 {
4726 qsort (special_vars, N_SPECIAL_VARS, sizeof (special_vars[0]),
4727 (QSFUNC *)sv_compare);
4728 sv_sorted = 1;
4729 }
4730
4731 i = find_special_var (name);
4732 if (i != -1)
4733 (*(special_vars[i].function)) (name);
4734 }
4735
4736 /* Special variables that need hooks to be run when they are unset as part
4737 of shell reinitialization should have their sv_ functions run here. */
4738 void
4739 reinit_special_variables ()
4740 {
4741 #if defined (READLINE)
4742 sv_comp_wordbreaks ("COMP_WORDBREAKS");
4743 #endif
4744 sv_globignore ("GLOBIGNORE");
4745 sv_opterr ("OPTERR");
4746 }
4747
4748 void
4749 sv_ifs (name)
4750 char *name;
4751 {
4752 SHELL_VAR *v;
4753
4754 v = find_variable ("IFS");
4755 setifs (v);
4756 }
4757
4758 /* What to do just after the PATH variable has changed. */
4759 void
4760 sv_path (name)
4761 char *name;
4762 {
4763 /* hash -r */
4764 phash_flush ();
4765 }
4766
4767 /* What to do just after one of the MAILxxxx variables has changed. NAME
4768 is the name of the variable. This is called with NAME set to one of
4769 MAIL, MAILCHECK, or MAILPATH. */
4770 void
4771 sv_mail (name)
4772 char *name;
4773 {
4774 /* If the time interval for checking the files has changed, then
4775 reset the mail timer. Otherwise, one of the pathname vars
4776 to the users mailbox has changed, so rebuild the array of
4777 filenames. */
4778 if (name[4] == 'C') /* if (strcmp (name, "MAILCHECK") == 0) */
4779 reset_mail_timer ();
4780 else
4781 {
4782 free_mail_files ();
4783 remember_mail_dates ();
4784 }
4785 }
4786
4787 void
4788 sv_funcnest (name)
4789 char *name;
4790 {
4791 SHELL_VAR *v;
4792 intmax_t num;
4793
4794 v = find_variable (name);
4795 if (v == 0)
4796 funcnest_max = 0;
4797 else if (legal_number (value_cell (v), &num) == 0)
4798 funcnest_max = 0;
4799 else
4800 funcnest_max = num;
4801 }
4802
4803 /* What to do when GLOBIGNORE changes. */
4804 void
4805 sv_globignore (name)
4806 char *name;
4807 {
4808 if (privileged_mode == 0)
4809 setup_glob_ignore (name);
4810 }
4811
4812 #if defined (READLINE)
4813 void
4814 sv_comp_wordbreaks (name)
4815 char *name;
4816 {
4817 SHELL_VAR *sv;
4818
4819 sv = find_variable (name);
4820 if (sv == 0)
4821 reset_completer_word_break_chars ();
4822 }
4823
4824 /* What to do just after one of the TERMxxx variables has changed.
4825 If we are an interactive shell, then try to reset the terminal
4826 information in readline. */
4827 void
4828 sv_terminal (name)
4829 char *name;
4830 {
4831 if (interactive_shell && no_line_editing == 0)
4832 rl_reset_terminal (get_string_value ("TERM"));
4833 }
4834
4835 void
4836 sv_hostfile (name)
4837 char *name;
4838 {
4839 SHELL_VAR *v;
4840
4841 v = find_variable (name);
4842 if (v == 0)
4843 clear_hostname_list ();
4844 else
4845 hostname_list_initialized = 0;
4846 }
4847
4848 #if defined (STRICT_POSIX)
4849 /* In strict posix mode, we allow assignments to LINES and COLUMNS (and values
4850 found in the initial environment) to override the terminal size reported by
4851 the kernel. */
4852 void
4853 sv_winsize (name)
4854 char *name;
4855 {
4856 SHELL_VAR *v;
4857 intmax_t xd;
4858 int d;
4859
4860 if (posixly_correct == 0 || interactive_shell == 0 || no_line_editing)
4861 return;
4862
4863 v = find_variable (name);
4864 if (v == 0 || var_isnull (v))
4865 rl_reset_screen_size ();
4866 else
4867 {
4868 if (legal_number (value_cell (v), &xd) == 0)
4869 return;
4870 winsize_assignment = 1;
4871 d = xd; /* truncate */
4872 if (name[0] == 'L') /* LINES */
4873 rl_set_screen_size (d, -1);
4874 else /* COLUMNS */
4875 rl_set_screen_size (-1, d);
4876 winsize_assignment = 0;
4877 }
4878 }
4879 #endif /* STRICT_POSIX */
4880 #endif /* READLINE */
4881
4882 /* Update the value of HOME in the export environment so tilde expansion will
4883 work on cygwin. */
4884 #if defined (__CYGWIN__)
4885 sv_home (name)
4886 char *name;
4887 {
4888 array_needs_making = 1;
4889 maybe_make_export_env ();
4890 }
4891 #endif
4892
4893 #if defined (HISTORY)
4894 /* What to do after the HISTSIZE or HISTFILESIZE variables change.
4895 If there is a value for this HISTSIZE (and it is numeric), then stifle
4896 the history. Otherwise, if there is NO value for this variable,
4897 unstifle the history. If name is HISTFILESIZE, and its value is
4898 numeric, truncate the history file to hold no more than that many
4899 lines. */
4900 void
4901 sv_histsize (name)
4902 char *name;
4903 {
4904 char *temp;
4905 intmax_t num;
4906 int hmax;
4907
4908 temp = get_string_value (name);
4909
4910 if (temp && *temp)
4911 {
4912 if (legal_number (temp, &num))
4913 {
4914 hmax = num;
4915 if (hmax < 0 && name[4] == 'S')
4916 unstifle_history (); /* unstifle history if HISTSIZE < 0 */
4917 else if (name[4] == 'S')
4918 {
4919 stifle_history (hmax);
4920 hmax = where_history ();
4921 if (history_lines_this_session > hmax)
4922 history_lines_this_session = hmax;
4923 }
4924 else if (hmax >= 0) /* truncate HISTFILE if HISTFILESIZE >= 0 */
4925 {
4926 history_truncate_file (get_string_value ("HISTFILE"), hmax);
4927 if (hmax <= history_lines_in_file)
4928 history_lines_in_file = hmax;
4929 }
4930 }
4931 }
4932 else if (name[4] == 'S')
4933 unstifle_history ();
4934 }
4935
4936 /* What to do after the HISTIGNORE variable changes. */
4937 void
4938 sv_histignore (name)
4939 char *name;
4940 {
4941 setup_history_ignore (name);
4942 }
4943
4944 /* What to do after the HISTCONTROL variable changes. */
4945 void
4946 sv_history_control (name)
4947 char *name;
4948 {
4949 char *temp;
4950 char *val;
4951 int tptr;
4952
4953 history_control = 0;
4954 temp = get_string_value (name);
4955
4956 if (temp == 0 || *temp == 0)
4957 return;
4958
4959 tptr = 0;
4960 while (val = extract_colon_unit (temp, &tptr))
4961 {
4962 if (STREQ (val, "ignorespace"))
4963 history_control |= HC_IGNSPACE;
4964 else if (STREQ (val, "ignoredups"))
4965 history_control |= HC_IGNDUPS;
4966 else if (STREQ (val, "ignoreboth"))
4967 history_control |= HC_IGNBOTH;
4968 else if (STREQ (val, "erasedups"))
4969 history_control |= HC_ERASEDUPS;
4970
4971 free (val);
4972 }
4973 }
4974
4975 #if defined (BANG_HISTORY)
4976 /* Setting/unsetting of the history expansion character. */
4977 void
4978 sv_histchars (name)
4979 char *name;
4980 {
4981 char *temp;
4982
4983 temp = get_string_value (name);
4984 if (temp)
4985 {
4986 history_expansion_char = *temp;
4987 if (temp[0] && temp[1])
4988 {
4989 history_subst_char = temp[1];
4990 if (temp[2])
4991 history_comment_char = temp[2];
4992 }
4993 }
4994 else
4995 {
4996 history_expansion_char = '!';
4997 history_subst_char = '^';
4998 history_comment_char = '#';
4999 }
5000 }
5001 #endif /* BANG_HISTORY */
5002
5003 void
5004 sv_histtimefmt (name)
5005 char *name;
5006 {
5007 SHELL_VAR *v;
5008
5009 if (v = find_variable (name))
5010 {
5011 if (history_comment_char == 0)
5012 history_comment_char = '#';
5013 }
5014 history_write_timestamps = (v != 0);
5015 }
5016 #endif /* HISTORY */
5017
5018 #if defined (HAVE_TZSET)
5019 void
5020 sv_tz (name)
5021 char *name;
5022 {
5023 if (chkexport (name))
5024 tzset ();
5025 }
5026 #endif
5027
5028 /* If the variable exists, then the value of it can be the number
5029 of times we actually ignore the EOF. The default is small,
5030 (smaller than csh, anyway). */
5031 void
5032 sv_ignoreeof (name)
5033 char *name;
5034 {
5035 SHELL_VAR *tmp_var;
5036 char *temp;
5037
5038 eof_encountered = 0;
5039
5040 tmp_var = find_variable (name);
5041 ignoreeof = tmp_var != 0;
5042 temp = tmp_var ? value_cell (tmp_var) : (char *)NULL;
5043 if (temp)
5044 eof_encountered_limit = (*temp && all_digits (temp)) ? atoi (temp) : 10;
5045 set_shellopts (); /* make sure `ignoreeof' is/is not in $SHELLOPTS */
5046 }
5047
5048 void
5049 sv_optind (name)
5050 char *name;
5051 {
5052 char *tt;
5053 int s;
5054
5055 tt = get_string_value ("OPTIND");
5056 if (tt && *tt)
5057 {
5058 s = atoi (tt);
5059
5060 /* According to POSIX, setting OPTIND=1 resets the internal state
5061 of getopt (). */
5062 if (s < 0 || s == 1)
5063 s = 0;
5064 }
5065 else
5066 s = 0;
5067 getopts_reset (s);
5068 }
5069
5070 void
5071 sv_opterr (name)
5072 char *name;
5073 {
5074 char *tt;
5075
5076 tt = get_string_value ("OPTERR");
5077 sh_opterr = (tt && *tt) ? atoi (tt) : 1;
5078 }
5079
5080 void
5081 sv_strict_posix (name)
5082 char *name;
5083 {
5084 SET_INT_VAR (name, posixly_correct);
5085 posix_initialize (posixly_correct);
5086 #if defined (READLINE)
5087 if (interactive_shell)
5088 posix_readline_initialize (posixly_correct);
5089 #endif /* READLINE */
5090 set_shellopts (); /* make sure `posix' is/is not in $SHELLOPTS */
5091 }
5092
5093 void
5094 sv_locale (name)
5095 char *name;
5096 {
5097 char *v;
5098 int r;
5099
5100 v = get_string_value (name);
5101 if (name[0] == 'L' && name[1] == 'A') /* LANG */
5102 r = set_lang (name, v);
5103 else
5104 r = set_locale_var (name, v); /* LC_*, TEXTDOMAIN* */
5105
5106 #if 1
5107 if (r == 0 && posixly_correct)
5108 last_command_exit_value = 1;
5109 #endif
5110 }
5111
5112 #if defined (ARRAY_VARS)
5113 void
5114 set_pipestatus_array (ps, nproc)
5115 int *ps;
5116 int nproc;
5117 {
5118 SHELL_VAR *v;
5119 ARRAY *a;
5120 ARRAY_ELEMENT *ae;
5121 register int i;
5122 char *t, tbuf[INT_STRLEN_BOUND(int) + 1];
5123
5124 v = find_variable ("PIPESTATUS");
5125 if (v == 0)
5126 v = make_new_array_variable ("PIPESTATUS");
5127 if (array_p (v) == 0)
5128 return; /* Do nothing if not an array variable. */
5129 a = array_cell (v);
5130
5131 if (a == 0 || array_num_elements (a) == 0)
5132 {
5133 for (i = 0; i < nproc; i++) /* was ps[i] != -1, not i < nproc */
5134 {
5135 t = inttostr (ps[i], tbuf, sizeof (tbuf));
5136 array_insert (a, i, t);
5137 }
5138 return;
5139 }
5140
5141 /* Fast case */
5142 if (array_num_elements (a) == nproc && nproc == 1)
5143 {
5144 ae = element_forw (a->head);
5145 free (element_value (ae));
5146 ae->value = itos (ps[0]);
5147 }
5148 else if (array_num_elements (a) <= nproc)
5149 {
5150 /* modify in array_num_elements members in place, then add */
5151 ae = a->head;
5152 for (i = 0; i < array_num_elements (a); i++)
5153 {
5154 ae = element_forw (ae);
5155 free (element_value (ae));
5156 ae->value = itos (ps[i]);
5157 }
5158 /* add any more */
5159 for ( ; i < nproc; i++)
5160 {
5161 t = inttostr (ps[i], tbuf, sizeof (tbuf));
5162 array_insert (a, i, t);
5163 }
5164 }
5165 else
5166 {
5167 /* deleting elements. it's faster to rebuild the array. */
5168 array_flush (a);
5169 for (i = 0; ps[i] != -1; i++)
5170 {
5171 t = inttostr (ps[i], tbuf, sizeof (tbuf));
5172 array_insert (a, i, t);
5173 }
5174 }
5175 }
5176
5177 ARRAY *
5178 save_pipestatus_array ()
5179 {
5180 SHELL_VAR *v;
5181 ARRAY *a, *a2;
5182
5183 v = find_variable ("PIPESTATUS");
5184 if (v == 0 || array_p (v) == 0 || array_cell (v) == 0)
5185 return ((ARRAY *)NULL);
5186
5187 a = array_cell (v);
5188 a2 = array_copy (array_cell (v));
5189
5190 return a2;
5191 }
5192
5193 void
5194 restore_pipestatus_array (a)
5195 ARRAY *a;
5196 {
5197 SHELL_VAR *v;
5198 ARRAY *a2;
5199
5200 v = find_variable ("PIPESTATUS");
5201 /* XXX - should we still assign even if existing value is NULL? */
5202 if (v == 0 || array_p (v) == 0 || array_cell (v) == 0)
5203 return;
5204
5205 a2 = array_cell (v);
5206 var_setarray (v, a);
5207
5208 array_dispose (a2);
5209 }
5210 #endif
5211
5212 void
5213 set_pipestatus_from_exit (s)
5214 int s;
5215 {
5216 #if defined (ARRAY_VARS)
5217 static int v[2] = { 0, -1 };
5218
5219 v[0] = s;
5220 set_pipestatus_array (v, 1);
5221 #endif
5222 }
5223
5224 void
5225 sv_xtracefd (name)
5226 char *name;
5227 {
5228 SHELL_VAR *v;
5229 char *t, *e;
5230 int fd;
5231 FILE *fp;
5232
5233 v = find_variable (name);
5234 if (v == 0)
5235 {
5236 xtrace_reset ();
5237 return;
5238 }
5239
5240 t = value_cell (v);
5241 if (t == 0 || *t == 0)
5242 xtrace_reset ();
5243 else
5244 {
5245 fd = (int)strtol (t, &e, 10);
5246 if (e != t && *e == '\0' && sh_validfd (fd))
5247 {
5248 fp = fdopen (fd, "w");
5249 if (fp == 0)
5250 internal_error (_("%s: %s: cannot open as FILE"), name, value_cell (v));
5251 else
5252 xtrace_set (fd, fp);
5253 }
5254 else
5255 internal_error (_("%s: %s: invalid value for trace file descriptor"), name, value_cell (v));
5256 }
5257 }
5258
5259 #define MIN_COMPAT_LEVEL 31
5260
5261 void
5262 sv_shcompat (name)
5263 char *name;
5264 {
5265 SHELL_VAR *v;
5266 char *val;
5267 int tens, ones, compatval;
5268
5269 v = find_variable (name);
5270 if (v == 0)
5271 {
5272 shell_compatibility_level = DEFAULT_COMPAT_LEVEL;
5273 set_compatibility_opts ();
5274 return;
5275 }
5276 val = value_cell (v);
5277 if (val == 0 || *val == '\0')
5278 {
5279 shell_compatibility_level = DEFAULT_COMPAT_LEVEL;
5280 set_compatibility_opts ();
5281 return;
5282 }
5283 /* Handle decimal-like compatibility version specifications: 4.2 */
5284 if (isdigit (val[0]) && val[1] == '.' && isdigit (val[2]) && val[3] == 0)
5285 {
5286 tens = val[0] - '0';
5287 ones = val[2] - '0';
5288 compatval = tens*10 + ones;
5289 }
5290 /* Handle integer-like compatibility version specifications: 42 */
5291 else if (isdigit (val[0]) && isdigit (val[1]) && val[2] == 0)
5292 {
5293 tens = val[0] - '0';
5294 ones = val[1] - '0';
5295 compatval = tens*10 + ones;
5296 }
5297 else
5298 {
5299 compat_error:
5300 internal_error (_("%s: %s: compatibility value out of range"), name, val);
5301 shell_compatibility_level = DEFAULT_COMPAT_LEVEL;
5302 set_compatibility_opts ();
5303 return;
5304 }
5305
5306 if (compatval < MIN_COMPAT_LEVEL || compatval > DEFAULT_COMPAT_LEVEL)
5307 goto compat_error;
5308
5309 shell_compatibility_level = compatval;
5310 set_compatibility_opts ();
5311 }
5312
5313 #if defined (JOB_CONTROL)
5314 void
5315 sv_childmax (name)
5316 char *name;
5317 {
5318 char *tt;
5319 int s;
5320
5321 tt = get_string_value (name);
5322 s = (tt && *tt) ? atoi (tt) : 0;
5323 set_maxchild (s);
5324 }
5325 #endif