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