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