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