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