1 /* variables.c -- Functions for hacking shell variables. */
3 /* Copyright (C) 1987-2022 Free Software Foundation, Inc.
5 This file is part of GNU Bash, the Bourne Again SHell.
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.
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.
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/>.
23 #include "bashtypes.h"
24 #include "posixstat.h"
25 #include "posixtime.h"
28 # if defined (__QNXNTO__)
29 # include <sys/netmgr.h>
32 # endif /* !__QNXNTO__ */
35 #if defined (HAVE_UNISTD_H)
40 #include "chartypes.h"
41 #if defined (HAVE_PWD_H)
48 #define NEED_XTRACE_SET_DECL
53 #include "execute_cmd.h"
55 #include "mailcheck.h"
64 #include "builtins/getopt.h"
65 #include "builtins/common.h"
66 #include "builtins/builtext.h"
68 #if defined (READLINE)
69 # include "bashline.h"
70 # include <readline/readline.h>
72 # include <tilde/tilde.h>
76 # include "bashhist.h"
77 # include <readline/history.h>
80 #if defined (PROGRAMMABLE_COMPLETION)
81 # include "pcomplete.h"
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 */
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) */
94 #define BASHARRAY_PREFIX "BASH_ARRAY_"
95 #define BASHARRAY_PREFLEN 11
96 #define BASHARRAY_SUFFIX "%%"
97 #define BASHARRAY_SUFFLEN 2
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
105 /* flags for find_variable_internal */
107 #define FV_FORCETEMPENV 0x01
108 #define FV_SKIPINVISIBLE 0x02
109 #define FV_NODYNAMIC 0x04
111 extern char **environ
;
113 /* Variables used here and defined in other files. */
114 extern time_t shell_start_time
;
115 extern struct timeval shellstart
;
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
;
121 /* The current list of shell variables, including function scopes */
122 VAR_CONTEXT
*shell_variables
= (VAR_CONTEXT
*)NULL
;
124 /* The list of shell functions that the user has created, or that came from
126 HASH_TABLE
*shell_functions
= (HASH_TABLE
*)NULL
;
128 HASH_TABLE
*invalid_env
= (HASH_TABLE
*)NULL
;
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
;
136 /* The current variable context. This is really a count of how deep into
137 executing functions we are. */
138 int variable_context
= 0;
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;
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;
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
;
153 /* Set to non-zero if an assignment error occurs while putting variables
154 into the temporary environment. */
155 int tempenv_assign_error
;
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;
163 /* The value of $$. */
164 pid_t dollar_dollar_pid
;
166 /* Non-zero means that we have to remake EXPORT_ENV. */
167 int array_needs_making
= 1;
169 /* The number of times BASH has been executed. This is set
170 by initialize_variables (). */
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 int export_env_size
;
180 #if defined (READLINE)
181 static int winsize_assignment
; /* currently assigning to LINES or COLUMNS */
184 SHELL_VAR nameref_invalid_value
;
185 static SHELL_VAR nameref_maxloop_value
;
187 static HASH_TABLE
*last_table_searched
; /* hash_lookup sets this */
188 static VAR_CONTEXT
*last_context_searched
;
190 /* Some forward declarations. */
191 static void create_variable_tables
PARAMS((void));
193 static void set_machine_vars
PARAMS((void));
194 static void set_home_var
PARAMS((void));
195 static void set_shell_var
PARAMS((void));
196 static char *get_bash_name
PARAMS((void));
197 static void initialize_shell_level
PARAMS((void));
198 static void uidset
PARAMS((void));
199 #if defined (ARRAY_VARS)
200 static void make_vers_array
PARAMS((void));
203 static SHELL_VAR
*null_assign
PARAMS((SHELL_VAR
*, char *, arrayind_t
, char *));
204 #if defined (ARRAY_VARS)
205 static SHELL_VAR
*null_array_assign
PARAMS((SHELL_VAR
*, char *, arrayind_t
, char *));
207 static SHELL_VAR
*get_self
PARAMS((SHELL_VAR
*));
209 #if defined (ARRAY_VARS)
210 static SHELL_VAR
*init_dynamic_array_var
PARAMS((char *, sh_var_value_func_t
*, sh_var_assign_func_t
*, int));
211 static SHELL_VAR
*init_dynamic_assoc_var
PARAMS((char *, sh_var_value_func_t
*, sh_var_assign_func_t
*, int));
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);
217 static SHELL_VAR
*assign_seconds
PARAMS((SHELL_VAR
*, char *, arrayind_t
, char *));
218 static SHELL_VAR
*get_seconds
PARAMS((SHELL_VAR
*));
219 static SHELL_VAR
*init_seconds_var
PARAMS((void));
221 static SHELL_VAR
*assign_random
PARAMS((SHELL_VAR
*, char *, arrayind_t
, char *));
222 static SHELL_VAR
*get_random
PARAMS((SHELL_VAR
*));
224 static SHELL_VAR
*get_urandom
PARAMS((SHELL_VAR
*));
226 static SHELL_VAR
*assign_lineno
PARAMS((SHELL_VAR
*, char *, arrayind_t
, char *));
227 static SHELL_VAR
*get_lineno
PARAMS((SHELL_VAR
*));
229 static SHELL_VAR
*assign_subshell
PARAMS((SHELL_VAR
*, char *, arrayind_t
, char *));
230 static SHELL_VAR
*get_subshell
PARAMS((SHELL_VAR
*));
232 static SHELL_VAR
*get_epochseconds
PARAMS((SHELL_VAR
*));
233 static SHELL_VAR
*get_epochrealtime
PARAMS((SHELL_VAR
*));
235 static SHELL_VAR
*get_bashpid
PARAMS((SHELL_VAR
*));
237 static SHELL_VAR
*get_bash_argv0
PARAMS((SHELL_VAR
*));
238 static SHELL_VAR
*assign_bash_argv0
PARAMS((SHELL_VAR
*, char *, arrayind_t
, char *));
239 static void set_argv0
PARAMS((void));
241 #if defined (HISTORY)
242 static SHELL_VAR
*get_histcmd
PARAMS((SHELL_VAR
*));
245 #if defined (READLINE)
246 static SHELL_VAR
*get_comp_wordbreaks
PARAMS((SHELL_VAR
*));
247 static SHELL_VAR
*assign_comp_wordbreaks
PARAMS((SHELL_VAR
*, char *, arrayind_t
, char *));
250 #if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
251 static SHELL_VAR
*assign_dirstack
PARAMS((SHELL_VAR
*, char *, arrayind_t
, char *));
252 static SHELL_VAR
*get_dirstack
PARAMS((SHELL_VAR
*));
255 #if defined (ARRAY_VARS)
256 static SHELL_VAR
*get_groupset
PARAMS((SHELL_VAR
*));
257 # if defined (DEBUGGER)
258 static SHELL_VAR
*get_bashargcv
PARAMS((SHELL_VAR
*));
260 static SHELL_VAR
*build_hashcmd
PARAMS((SHELL_VAR
*));
261 static SHELL_VAR
*get_hashcmd
PARAMS((SHELL_VAR
*));
262 static SHELL_VAR
*assign_hashcmd
PARAMS((SHELL_VAR
*, char *, arrayind_t
, char *));
264 static SHELL_VAR
*build_aliasvar
PARAMS((SHELL_VAR
*));
265 static SHELL_VAR
*get_aliasvar
PARAMS((SHELL_VAR
*));
266 static SHELL_VAR
*assign_aliasvar
PARAMS((SHELL_VAR
*, char *, arrayind_t
, char *));
270 static SHELL_VAR
*get_funcname
PARAMS((SHELL_VAR
*));
271 static SHELL_VAR
*init_funcname_var
PARAMS((void));
273 static void initialize_dynamic_variables
PARAMS((void));
275 static SHELL_VAR
*bind_invalid_envvar
PARAMS((const char *, char *, int));
277 static int var_sametype
PARAMS((SHELL_VAR
*, SHELL_VAR
*));
279 static SHELL_VAR
*hash_lookup
PARAMS((const char *, HASH_TABLE
*));
280 static SHELL_VAR
*new_shell_variable
PARAMS((const char *));
281 static SHELL_VAR
*make_new_variable
PARAMS((const char *, HASH_TABLE
*));
282 static SHELL_VAR
*bind_variable_internal
PARAMS((const char *, char *, HASH_TABLE
*, int, int));
284 static void dispose_variable_value
PARAMS((SHELL_VAR
*));
285 static void free_variable_hash_data
PARAMS((PTR_T
));
287 static VARLIST
*vlist_alloc
PARAMS((int));
288 static VARLIST
*vlist_realloc
PARAMS((VARLIST
*, int));
289 static void vlist_add
PARAMS((VARLIST
*, SHELL_VAR
*, int));
291 static void flatten
PARAMS((HASH_TABLE
*, sh_var_map_func_t
*, VARLIST
*, int));
293 static int qsort_var_comp
PARAMS((SHELL_VAR
**, SHELL_VAR
**));
295 static SHELL_VAR
**vapply
PARAMS((sh_var_map_func_t
*));
296 static SHELL_VAR
**fapply
PARAMS((sh_var_map_func_t
*));
298 static int visible_var
PARAMS((SHELL_VAR
*));
299 static int visible_and_exported
PARAMS((SHELL_VAR
*));
300 static int export_environment_candidate
PARAMS((SHELL_VAR
*));
301 static int local_and_exported
PARAMS((SHELL_VAR
*));
302 static int visible_variable_in_context
PARAMS((SHELL_VAR
*));
303 static int variable_in_context
PARAMS((SHELL_VAR
*));
304 #if defined (ARRAY_VARS)
305 static int visible_array_vars
PARAMS((SHELL_VAR
*));
308 static SHELL_VAR
*find_variable_internal
PARAMS((const char *, int));
310 static SHELL_VAR
*find_nameref_at_context
PARAMS((SHELL_VAR
*, VAR_CONTEXT
*));
311 static SHELL_VAR
*find_variable_nameref_context
PARAMS((SHELL_VAR
*, VAR_CONTEXT
*, VAR_CONTEXT
**));
312 static SHELL_VAR
*find_variable_last_nameref_context
PARAMS((SHELL_VAR
*, VAR_CONTEXT
*, VAR_CONTEXT
**));
314 static SHELL_VAR
*bind_tempenv_variable
PARAMS((const char *, char *));
315 static void push_posix_temp_var
PARAMS((PTR_T
));
316 static void push_temp_var
PARAMS((PTR_T
));
317 static void propagate_temp_var
PARAMS((PTR_T
));
318 static void dispose_temporary_env
PARAMS((sh_free_func_t
*));
320 static inline char *mk_env_string
PARAMS((const char *, const char *, int));
321 static char **make_env_array_from_var_list
PARAMS((SHELL_VAR
**));
322 static char **make_var_export_array
PARAMS((VAR_CONTEXT
*));
323 static char **make_func_export_array
PARAMS((void));
324 static void add_temp_array_to_env
PARAMS((char **, int, int));
326 static int n_shell_variables
PARAMS((void));
327 static int set_context
PARAMS((SHELL_VAR
*));
329 static void push_func_var
PARAMS((PTR_T
));
330 static void push_builtin_var
PARAMS((PTR_T
));
331 static void push_exported_var
PARAMS((PTR_T
));
333 static void delete_local_contexts
PARAMS((VAR_CONTEXT
*));
335 /* This needs to be looked at again. */
336 static inline void push_posix_tempvar_internal
PARAMS((SHELL_VAR
*, int));
338 static inline int find_special_var
PARAMS((const char *));
341 create_variable_tables ()
343 if (shell_variables
== 0)
345 shell_variables
= global_variables
= new_var_context ((char *)NULL
, 0);
346 shell_variables
->scope
= 0;
347 shell_variables
->table
= hash_create (VARIABLES_HASH_BUCKETS
);
350 if (shell_functions
== 0)
351 shell_functions
= hash_create (FUNCTIONS_HASH_BUCKETS
);
353 #if defined (DEBUGGER)
354 if (shell_function_defs
== 0)
355 shell_function_defs
= hash_create (FUNCTIONS_HASH_BUCKETS
);
359 /* Initialize the shell variables from the current environment.
360 If PRIVMODE is nonzero, don't import functions from ENV or
363 initialize_shell_variables (env
, privmode
)
367 char *name
, *string
, *temp_string
;
368 int c
, char_index
, string_index
, string_length
, ro
;
371 create_variable_tables ();
373 for (string_index
= 0; env
&& (string
= env
[string_index
++]); )
377 while ((c
= *string
++) && c
!= '=')
379 if (string
[-1] == '=')
380 char_index
= string
- name
- 1;
382 /* If there are weird things in the environment, like `=xxx' or a
383 string without an `=', just skip them. */
387 /* ASSERT(name[char_index] == '=') */
388 name
[char_index
] = '\0';
389 /* Now, name = env variable name, string = env variable value, and
390 char_index == strlen (name) */
392 temp_var
= (SHELL_VAR
*)NULL
;
394 #if defined (FUNCTION_IMPORT)
395 /* If exported function, define it now. Don't import functions from
396 the environment in privileged mode. */
397 if (privmode
== 0 && read_but_dont_execute
== 0 &&
398 STREQN (BASHFUNC_PREFIX
, name
, BASHFUNC_PREFLEN
) &&
399 STREQ (BASHFUNC_SUFFIX
, name
+ char_index
- BASHFUNC_SUFFLEN
) &&
400 STREQN ("() {", string
, 4))
403 char *tname
; /* desired imported function name */
405 namelen
= char_index
- BASHFUNC_PREFLEN
- BASHFUNC_SUFFLEN
;
407 tname
= name
+ BASHFUNC_PREFLEN
; /* start of func name */
408 tname
[namelen
] = '\0'; /* now tname == func name */
410 string_length
= strlen (string
);
411 temp_string
= (char *)xmalloc (namelen
+ string_length
+ 2);
413 memcpy (temp_string
, tname
, namelen
);
414 temp_string
[namelen
] = ' ';
415 memcpy (temp_string
+ namelen
+ 1, string
, string_length
+ 1);
417 /* Don't import function names that are invalid identifiers from the
418 environment in posix mode, though we still allow them to be defined as
420 if (absolute_program (tname
) == 0 && (posixly_correct
== 0 || legal_identifier (tname
)))
421 parse_and_execute (temp_string
, tname
, SEVAL_NONINT
|SEVAL_NOHIST
|SEVAL_FUNCDEF
|SEVAL_ONECMD
);
423 free (temp_string
); /* parse_and_execute does this */
425 if (temp_var
= find_function (tname
))
427 VSETATTR (temp_var
, (att_exported
|att_imported
));
428 array_needs_making
= 1;
432 if (temp_var
= bind_invalid_envvar (name
, string
, 0))
434 VSETATTR (temp_var
, (att_exported
| att_imported
| att_invisible
));
435 array_needs_making
= 1;
437 last_command_exit_value
= EXECUTION_FAILURE
;
438 report_error (_("error importing function definition for `%s'"), tname
);
441 /* Restore original suffix */
442 tname
[namelen
] = BASHFUNC_SUFFIX
[0];
445 #endif /* FUNCTION_IMPORT */
446 #if defined (ARRAY_VARS)
448 /* Array variables may not yet be exported. */
449 if (STREQN (BASHARRAY_PREFIX
, name
, BASHARRAY_PREFLEN
) &&
450 STREQN (BASHARRAY_SUFFIX
, name
+ char_index
- BASHARRAY_SUFFLEN
, BASHARRAY_SUFFLEN
) &&
451 *string
== '(' && string
[1] == '[' && string
[strlen (string
) - 1] == ')')
454 char *tname
; /* desired imported array variable name */
456 namelen
= char_index
- BASHARRAY_PREFLEN
- BASHARRAY_SUFFLEN
;
458 tname
= name
+ BASHARRAY_PREFLEN
; /* start of variable name */
459 tname
[namelen
] = '\0'; /* now tname == varname */
462 temp_string
= extract_array_assignment_list (string
, &string_length
);
463 temp_var
= assign_array_from_string (tname
, temp_string
, 0);
467 VSETATTR (temp_var
, (att_exported
| att_imported
));
468 array_needs_making
= 1;
471 else if (STREQN (BASHASSOC_PREFIX
, name
, BASHASSOC_PREFLEN
) &&
472 STREQN (BASHASSOC_SUFFIX
, name
+ char_index
- BASHASSOC_SUFFLEN
, BASHASSOC_SUFFLEN
) &&
473 *string
== '(' && string
[1] == '[' && string
[strlen (string
) - 1] == ')')
476 char *tname
; /* desired imported assoc variable name */
478 namelen
= char_index
- BASHASSOC_PREFLEN
- BASHASSOC_SUFFLEN
;
480 tname
= name
+ BASHASSOC_PREFLEN
; /* start of variable name */
481 tname
[namelen
] = '\0'; /* now tname == varname */
483 /* need to make sure it exists as an associative array first */
484 temp_var
= find_or_make_array_variable (tname
, 2);
488 temp_string
= extract_array_assignment_list (string
, &string_length
);
489 temp_var
= assign_array_var_from_string (temp_var
, temp_string
, 0);
494 VSETATTR (temp_var
, (att_exported
| att_imported
));
495 array_needs_making
= 1;
499 # endif /* ARRAY_EXPORT */
503 /* If we processed a command-line option that caused SHELLOPTS to be
504 set, it may already be set (and read-only) by the time we process
505 the shell's environment. */
506 if (/* posixly_correct &&*/ STREQ (name
, "SHELLOPTS"))
508 temp_var
= find_variable ("SHELLOPTS");
509 ro
= temp_var
&& readonly_p (temp_var
);
511 VUNSETATTR (temp_var
, att_readonly
);
513 if (legal_identifier (name
))
515 temp_var
= bind_variable (name
, string
, 0);
518 VSETATTR (temp_var
, (att_exported
| att_imported
));
520 VSETATTR (temp_var
, att_readonly
);
525 temp_var
= bind_invalid_envvar (name
, string
, 0);
527 VSETATTR (temp_var
, (att_exported
| att_imported
| att_invisible
));
530 array_needs_making
= 1;
533 name
[char_index
] = '=';
534 /* temp_var can be NULL if it was an exported function with a syntax
535 error (a different bug, but it still shouldn't dump core). */
536 if (temp_var
&& function_p (temp_var
) == 0) /* XXX not yet */
538 CACHE_IMPORTSTR (temp_var
, name
);
544 /* Set up initial value of $_ */
545 temp_var
= set_if_not ("_", dollar_vars
[0]);
547 /* Remember this pid. */
548 dollar_dollar_pid
= getpid ();
550 /* Now make our own defaults in case the vars that we think are
551 important are missing. */
552 temp_var
= set_if_not ("PATH", DEFAULT_PATH_VALUE
);
553 temp_var
= set_if_not ("TERM", "dumb");
555 #if defined (__QNX__)
556 /* set node id -- don't import it from the environment */
559 # if defined (__QNXNTO__)
560 netmgr_ndtostr(ND2S_LOCAL_STR
, ND_LOCAL_NODE
, node_name
, sizeof(node_name
));
562 qnx_nidtostr (getnid (), node_name
, sizeof (node_name
));
564 temp_var
= bind_variable ("NODE", node_name
, 0);
566 set_auto_export (temp_var
);
570 /* set up the prompts. */
571 if (interactive_shell
)
573 #if defined (PROMPT_STRING_DECODE)
574 set_if_not ("PS1", primary_prompt
);
576 if (current_user
.uid
== -1)
577 get_current_user_info ();
578 set_if_not ("PS1", current_user
.euid
== 0 ? "# " : primary_prompt
);
580 set_if_not ("PS2", secondary_prompt
);
583 if (current_user
.euid
== 0)
584 bind_variable ("PS4", "+ ", 0);
586 set_if_not ("PS4", "+ ");
588 /* Don't allow IFS to be imported from the environment. */
589 temp_var
= bind_variable ("IFS", " \t\n", 0);
592 /* Magic machine types. Pretty convenient. */
595 /* Default MAILCHECK for interactive shells. Defer the creation of a
596 default MAILPATH until the startup files are read, because MAIL
597 names a mail file if MAILPATH is not set, and we should provide a
598 default only if neither is set. */
599 if (interactive_shell
)
601 temp_var
= set_if_not ("MAILCHECK", posixly_correct
? "600" : "60");
602 VSETATTR (temp_var
, att_integer
);
605 /* Do some things with shell level. */
606 initialize_shell_level ();
612 /* Initialize the `getopts' stuff. */
613 temp_var
= bind_variable ("OPTIND", "1", 0);
614 VSETATTR (temp_var
, att_integer
);
616 bind_variable ("OPTERR", "1", 0);
619 if (login_shell
== 1 && posixly_correct
== 0)
622 /* Get the full pathname to THIS shell, and set the BASH variable
624 name
= get_bash_name ();
625 temp_var
= bind_variable ("BASH", name
, 0);
628 /* Make the exported environment variable SHELL be the user's login
629 shell. Note that the `tset' command looks at this variable
630 to determine what style of commands to output; if it ends in "csh",
631 then C-shell commands are output, else Bourne shell commands. */
634 /* Make a variable called BASH_VERSION which contains the version info. */
635 bind_variable ("BASH_VERSION", shell_version_string (), 0);
636 #if defined (ARRAY_VARS)
640 if (command_execution_string
)
641 bind_variable ("BASH_EXECUTION_STRING", command_execution_string
, 0);
643 /* Find out if we're supposed to be in Posix.2 mode via an
644 environment variable. */
645 temp_var
= find_variable ("POSIXLY_CORRECT");
647 temp_var
= find_variable ("POSIX_PEDANTIC");
648 if (temp_var
&& imported_p (temp_var
))
649 sv_strict_posix (temp_var
->name
);
651 #if defined (HISTORY)
652 /* Set history variables to defaults, and then do whatever we would
653 do if the variable had just been set. Do this only in the case
654 that we are remembering commands on the history list. */
655 if (remember_on_history
)
657 name
= bash_tilde_expand (posixly_correct
? "~/.sh_history" : "~/.bash_history", 0);
659 set_if_not ("HISTFILE", name
);
664 /* Seed the random number generators. */
668 /* Handle some "special" variables that we may have inherited from a
670 if (interactive_shell
)
672 temp_var
= find_variable ("IGNOREEOF");
674 temp_var
= find_variable ("ignoreeof");
675 if (temp_var
&& imported_p (temp_var
))
676 sv_ignoreeof (temp_var
->name
);
679 #if defined (HISTORY)
680 if (interactive_shell
&& remember_on_history
)
682 sv_history_control ("HISTCONTROL");
683 sv_histignore ("HISTIGNORE");
684 sv_histtimefmt ("HISTTIMEFORMAT");
688 #if defined (READLINE) && defined (STRICT_POSIX)
689 /* POSIXLY_CORRECT will be 1 here if the shell was compiled
690 -DSTRICT_POSIX or if POSIXLY_CORRECT was supplied in the shell's
692 if (interactive_shell
&& posixly_correct
&& no_line_editing
== 0)
693 rl_prefer_env_winsize
= 1;
694 #endif /* READLINE && STRICT_POSIX */
696 /* Get the user's real and effective user ids. */
699 temp_var
= set_if_not ("BASH_LOADABLES_PATH", DEFAULT_LOADABLE_BUILTINS_PATH
);
701 temp_var
= find_variable ("BASH_XTRACEFD");
702 if (temp_var
&& imported_p (temp_var
))
703 sv_xtracefd (temp_var
->name
);
705 sv_shcompat ("BASH_COMPAT");
707 /* Allow FUNCNEST to be inherited from the environment. */
708 sv_funcnest ("FUNCNEST");
710 /* Initialize the dynamic variables, and seed their values. */
711 initialize_dynamic_variables ();
714 /* **************************************************************** */
716 /* Setting values for special shell variables */
718 /* **************************************************************** */
725 temp_var
= set_if_not ("HOSTTYPE", HOSTTYPE
);
726 temp_var
= set_if_not ("OSTYPE", OSTYPE
);
727 temp_var
= set_if_not ("MACHTYPE", MACHTYPE
);
729 temp_var
= set_if_not ("HOSTNAME", current_host_name
);
732 /* Set $HOME to the information in the password file if we didn't get
733 it from the environment. */
735 /* This function is not static so the tilde and readline libraries can
740 if (current_user
.home_dir
== 0)
741 get_current_user_info ();
742 return current_user
.home_dir
;
750 temp_var
= find_variable ("HOME");
752 temp_var
= bind_variable ("HOME", sh_get_home_dir (), 0);
754 VSETATTR (temp_var
, att_exported
);
758 /* Set $SHELL to the user's login shell if it is not already set. Call
759 get_current_user_info if we haven't already fetched the shell. */
765 temp_var
= find_variable ("SHELL");
768 if (current_user
.shell
== 0)
769 get_current_user_info ();
770 temp_var
= bind_variable ("SHELL", current_user
.shell
, 0);
773 VSETATTR (temp_var
, att_exported
);
782 if ((login_shell
== 1) && RELPATH(shell_name
))
784 if (current_user
.shell
== 0)
785 get_current_user_info ();
786 name
= savestring (current_user
.shell
);
788 else if (ABSPATH(shell_name
))
789 name
= savestring (shell_name
);
790 else if (shell_name
[0] == '.' && shell_name
[1] == '/')
792 /* Fast path for common case. */
796 cdir
= get_string_value ("PWD");
800 name
= (char *)xmalloc (len
+ strlen (shell_name
) + 1);
802 strcpy (name
+ len
, shell_name
+ 1);
805 name
= savestring (shell_name
);
812 tname
= find_user_command (shell_name
);
816 /* Try the current directory. If there is not an executable
817 there, just punt and use the login shell. */
818 s
= file_status (shell_name
);
821 tname
= make_absolute (shell_name
, get_string_value ("PWD"));
822 if (*shell_name
== '.')
824 name
= sh_canonpath (tname
, PATH_CHECKDOTDOT
|PATH_CHECKEXISTS
);
835 if (current_user
.shell
== 0)
836 get_current_user_info ();
837 name
= savestring (current_user
.shell
);
842 name
= full_pathname (tname
);
851 adjust_shell_level (change
)
854 char new_level
[5], *old_SHLVL
;
858 old_SHLVL
= get_string_value ("SHLVL");
859 if (old_SHLVL
== 0 || *old_SHLVL
== '\0' || legal_number (old_SHLVL
, &old_level
) == 0)
862 shell_level
= old_level
+ change
;
865 else if (shell_level
>= 1000)
867 internal_warning (_("shell level (%d) too high, resetting to 1"), shell_level
);
871 /* We don't need the full generality of itos here. */
872 if (shell_level
< 10)
874 new_level
[0] = shell_level
+ '0';
877 else if (shell_level
< 100)
879 new_level
[0] = (shell_level
/ 10) + '0';
880 new_level
[1] = (shell_level
% 10) + '0';
883 else if (shell_level
< 1000)
885 new_level
[0] = (shell_level
/ 100) + '0';
886 old_level
= shell_level
% 100;
887 new_level
[1] = (old_level
/ 10) + '0';
888 new_level
[2] = (old_level
% 10) + '0';
892 temp_var
= bind_variable ("SHLVL", new_level
, 0);
893 set_auto_export (temp_var
);
897 initialize_shell_level ()
899 adjust_shell_level (1);
902 /* If we got PWD from the environment, update our idea of the current
903 working directory. In any case, make sure that PWD exists before
904 checking it. It is possible for getcwd () to fail on shell startup,
905 and in that case, PWD would be undefined. If this is an interactive
906 login shell, see if $HOME is the current working directory, and if
907 that's not the same string as $PWD, set PWD=$HOME. */
912 SHELL_VAR
*temp_var
, *home_var
;
913 char *temp_string
, *home_string
, *current_dir
;
915 home_var
= find_variable ("HOME");
916 home_string
= home_var
? value_cell (home_var
) : (char *)NULL
;
918 temp_var
= find_variable ("PWD");
919 /* Follow posix rules for importing PWD */
920 if (temp_var
&& imported_p (temp_var
) &&
921 (temp_string
= value_cell (temp_var
)) &&
922 temp_string
[0] == '/' &&
923 same_file (temp_string
, ".", (struct stat
*)NULL
, (struct stat
*)NULL
))
925 current_dir
= sh_canonpath (temp_string
, PATH_CHECKDOTDOT
|PATH_CHECKEXISTS
);
926 if (current_dir
== 0)
927 current_dir
= get_working_directory ("shell_init");
929 set_working_directory (current_dir
);
930 if (posixly_correct
&& current_dir
)
932 temp_var
= bind_variable ("PWD", current_dir
, 0);
933 set_auto_export (temp_var
);
937 else if (home_string
&& interactive_shell
&& login_shell
&&
938 same_file (home_string
, ".", (struct stat
*)NULL
, (struct stat
*)NULL
))
940 set_working_directory (home_string
);
941 temp_var
= bind_variable ("PWD", home_string
, 0);
942 set_auto_export (temp_var
);
946 temp_string
= get_working_directory ("shell-init");
949 temp_var
= bind_variable ("PWD", temp_string
, 0);
950 set_auto_export (temp_var
);
955 /* According to the Single Unix Specification, v2, $OLDPWD is an
956 `environment variable' and therefore should be auto-exported. If we
957 don't find OLDPWD in the environment, or it doesn't name a directory,
958 make a dummy invisible variable for OLDPWD, and mark it as exported. */
959 temp_var
= find_variable ("OLDPWD");
960 #if defined (OLDPWD_CHECK_DIRECTORY)
961 if (temp_var
== 0 || value_cell (temp_var
) == 0 || file_isdir (value_cell (temp_var
)) == 0)
963 if (temp_var
== 0 || value_cell (temp_var
) == 0)
966 temp_var
= bind_variable ("OLDPWD", (char *)NULL
, 0);
967 VSETATTR (temp_var
, (att_exported
| att_invisible
));
971 /* Make a variable $PPID, which holds the pid of the shell's parent. */
975 char namebuf
[INT_STRLEN_BOUND(pid_t
) + 1], *name
;
978 name
= inttostr (getppid (), namebuf
, sizeof(namebuf
));
979 temp_var
= find_variable ("PPID");
981 VUNSETATTR (temp_var
, (att_readonly
| att_exported
));
982 temp_var
= bind_variable ("PPID", name
, 0);
983 VSETATTR (temp_var
, (att_readonly
| att_integer
));
989 char buff
[INT_STRLEN_BOUND(uid_t
) + 1], *b
;
990 register SHELL_VAR
*v
;
992 b
= inttostr (current_user
.uid
, buff
, sizeof (buff
));
993 v
= find_variable ("UID");
996 v
= bind_variable ("UID", b
, 0);
997 VSETATTR (v
, (att_readonly
| att_integer
));
1000 if (current_user
.euid
!= current_user
.uid
)
1001 b
= inttostr (current_user
.euid
, buff
, sizeof (buff
));
1003 v
= find_variable ("EUID");
1006 v
= bind_variable ("EUID", b
, 0);
1007 VSETATTR (v
, (att_readonly
| att_integer
));
1011 #if defined (ARRAY_VARS)
1017 char *s
, d
[32], b
[INT_STRLEN_BOUND(int) + 1];
1019 unbind_variable_noref ("BASH_VERSINFO");
1021 vv
= make_new_array_variable ("BASH_VERSINFO");
1022 av
= array_cell (vv
);
1023 strcpy (d
, dist_version
);
1024 s
= strchr (d
, '.');
1027 array_insert (av
, 0, d
);
1028 array_insert (av
, 1, s
);
1029 s
= inttostr (patch_level
, b
, sizeof (b
));
1030 array_insert (av
, 2, s
);
1031 s
= inttostr (build_version
, b
, sizeof (b
));
1032 array_insert (av
, 3, s
);
1033 array_insert (av
, 4, release_status
);
1034 array_insert (av
, 5, MACHTYPE
);
1036 VSETATTR (vv
, att_readonly
);
1038 #endif /* ARRAY_VARS */
1040 /* Set the environment variables $LINES and $COLUMNS in response to
1041 a window size change. */
1043 sh_set_lines_and_columns (lines
, cols
)
1046 char val
[INT_STRLEN_BOUND(int) + 1], *v
;
1048 #if defined (READLINE)
1049 /* If we are currently assigning to LINES or COLUMNS, don't do anything. */
1050 if (winsize_assignment
)
1054 v
= inttostr (lines
, val
, sizeof (val
));
1055 bind_variable ("LINES", v
, 0);
1057 v
= inttostr (cols
, val
, sizeof (val
));
1058 bind_variable ("COLUMNS", v
, 0);
1061 /* **************************************************************** */
1063 /* Printing variables and values */
1065 /* **************************************************************** */
1067 /* Print LIST (a list of shell variables) to stdout in such a way that
1068 they can be read back in. */
1070 print_var_list (list
)
1071 register SHELL_VAR
**list
;
1074 register SHELL_VAR
*var
;
1076 for (i
= 0; list
&& (var
= list
[i
]); i
++)
1077 if (invisible_p (var
) == 0)
1078 print_assignment (var
);
1081 /* Print LIST (a list of shell functions) to stdout in such a way that
1082 they can be read back in. */
1084 print_func_list (list
)
1085 register SHELL_VAR
**list
;
1088 register SHELL_VAR
*var
;
1090 for (i
= 0; list
&& (var
= list
[i
]); i
++)
1092 printf ("%s ", var
->name
);
1093 print_var_function (var
);
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. */
1102 print_assignment (var
)
1105 if (var_isset (var
) == 0)
1108 if (function_p (var
))
1110 printf ("%s", var
->name
);
1111 print_var_function (var
);
1114 #if defined (ARRAY_VARS)
1115 else if (array_p (var
))
1116 print_array_assignment (var
, 0);
1117 else if (assoc_p (var
))
1118 print_assoc_assignment (var
, 0);
1119 #endif /* ARRAY_VARS */
1122 printf ("%s=", var
->name
);
1123 print_var_value (var
, 1);
1128 /* Print the value cell of VAR, a shell variable. Do not print
1129 the name, nor leading/trailing newline. If QUOTE is non-zero,
1130 and the value contains shell metacharacters, quote the value
1131 in such a way that it can be read back in. */
1133 print_var_value (var
, quote
)
1139 if (var_isset (var
) == 0)
1142 if (quote
&& posixly_correct
== 0 && ansic_shouldquote (value_cell (var
)))
1144 t
= ansic_quote (value_cell (var
), 0, (int *)0);
1148 else if (quote
&& sh_contains_shell_metas (value_cell (var
)))
1150 t
= sh_single_quote (value_cell (var
));
1155 printf ("%s", value_cell (var
));
1158 /* Print the function cell of VAR, a shell variable. Do not
1159 print the name, nor leading/trailing newline. */
1161 print_var_function (var
)
1166 if (function_p (var
) && var_isset (var
))
1168 x
= named_function_string ((char *)NULL
, function_cell(var
), FUNC_MULTILINE
|FUNC_EXTERNAL
);
1173 /* **************************************************************** */
1175 /* Dynamic Variables */
1177 /* **************************************************************** */
1179 /* DYNAMIC VARIABLES
1181 These are variables whose values are generated anew each time they are
1182 referenced. These are implemented using a pair of function pointers
1183 in the struct variable: assign_func, which is called from bind_variable
1184 and, if arrays are compiled into the shell, some of the functions in
1185 arrayfunc.c, and dynamic_value, which is called from find_variable.
1187 assign_func is called from bind_variable_internal, if
1188 bind_variable_internal discovers that the variable being assigned to
1189 has such a function. The function is called as
1190 SHELL_VAR *temp = (*(entry->assign_func)) (entry, value, ind)
1191 and the (SHELL_VAR *)temp is returned as the value of bind_variable. It
1192 is usually ENTRY (self). IND is an index for an array variable, and
1195 dynamic_value is called from find_variable_internal to return a `new'
1196 value for the specified dynamic variable. If this function is NULL,
1197 the variable is treated as a `normal' shell variable. If it is not,
1198 however, then this function is called like this:
1199 tempvar = (*(var->dynamic_value)) (var);
1201 Sometimes `tempvar' will replace the value of `var'. Other times, the
1202 shell will simply use the string value. Pretty object-oriented, huh?
1204 Be warned, though: if you `unset' a special variable, it loses its
1205 special meaning, even if you subsequently set it.
1207 The special assignment code would probably have been better put in
1208 subst.c: do_assignment_internal, in the same style as
1209 stupidly_hack_special_variables, but I wanted the changes as
1210 localized as possible. */
1212 #define INIT_DYNAMIC_VAR(var, val, gfunc, afunc) \
1215 v = bind_variable (var, (val), 0); \
1216 v->dynamic_value = gfunc; \
1217 v->assign_func = afunc; \
1221 #define INIT_DYNAMIC_ARRAY_VAR(var, gfunc, afunc) \
1224 v = make_new_array_variable (var); \
1225 v->dynamic_value = gfunc; \
1226 v->assign_func = afunc; \
1230 #define INIT_DYNAMIC_ASSOC_VAR(var, gfunc, afunc) \
1233 v = make_new_assoc_variable (var); \
1234 v->dynamic_value = gfunc; \
1235 v->assign_func = afunc; \
1240 null_assign (self
, value
, unused
, key
)
1249 #if defined (ARRAY_VARS)
1251 null_array_assign (self
, value
, ind
, key
)
1261 /* Degenerate `dynamic_value' function; just returns what's passed without
1270 #if defined (ARRAY_VARS)
1271 /* A generic dynamic array variable initializer. Initialize array variable
1272 NAME with dynamic value function GETFUNC and assignment function SETFUNC. */
1274 init_dynamic_array_var (name
, getfunc
, setfunc
, attrs
)
1276 sh_var_value_func_t
*getfunc
;
1277 sh_var_assign_func_t
*setfunc
;
1282 v
= find_variable (name
);
1285 INIT_DYNAMIC_ARRAY_VAR (name
, getfunc
, setfunc
);
1287 VSETATTR (v
, attrs
);
1292 init_dynamic_assoc_var (name
, getfunc
, setfunc
, attrs
)
1294 sh_var_value_func_t
*getfunc
;
1295 sh_var_assign_func_t
*setfunc
;
1300 v
= find_variable (name
);
1303 INIT_DYNAMIC_ASSOC_VAR (name
, getfunc
, setfunc
);
1305 VSETATTR (v
, attrs
);
1310 /* Set the string value of VAR to the string representation of VALUE.
1311 Right now this takes an INTMAX_T because that's what itos needs. If
1312 FLAGS&1, we force the integer attribute on. */
1313 static inline SHELL_VAR
*
1314 set_int_value (SHELL_VAR
*var
, intmax_t value
, int flags
)
1319 FREE (value_cell (var
));
1320 var_setvalue (var
, p
);
1322 VSETATTR (var
, att_integer
);
1326 static inline SHELL_VAR
*
1327 set_string_value (SHELL_VAR
*var
, const char *value
, int flags
)
1331 if (value
&& *value
)
1332 p
= savestring (value
);
1335 p
= (char *)xmalloc (1);
1338 FREE (value_cell (var
));
1339 var_setvalue (var
, p
);
1343 /* The value of $SECONDS. This is the number of seconds since shell
1344 invocation, or, the number of seconds since the last assignment + the
1345 value of the last assignment. */
1346 static intmax_t seconds_value_assigned
;
1349 assign_seconds (self
, value
, unused
, key
)
1358 if (integer_p (self
))
1359 nval
= evalexp (value
, 0, &expok
);
1361 expok
= legal_number (value
, &nval
);
1362 seconds_value_assigned
= expok
? nval
: 0;
1363 gettimeofday (&shellstart
, NULL
);
1364 shell_start_time
= shellstart
.tv_sec
;
1365 return (set_int_value (self
, nval
, integer_p (self
) != 0));
1372 time_t time_since_start
;
1375 gettimeofday(&tv
, NULL
);
1376 time_since_start
= tv
.tv_sec
- shell_start_time
;
1377 return (set_int_value (var
, seconds_value_assigned
+ time_since_start
, 1));
1385 v
= find_variable ("SECONDS");
1388 if (legal_number (value_cell(v
), &seconds_value_assigned
) == 0)
1389 seconds_value_assigned
= 0;
1391 INIT_DYNAMIC_VAR ("SECONDS", (v
? value_cell (v
) : (char *)NULL
), get_seconds
, assign_seconds
);
1395 /* Functions for $RANDOM and $SRANDOM */
1397 int last_random_value
;
1398 static int seeded_subshell
= 0;
1401 assign_random (self
, value
, unused
, key
)
1410 if (integer_p (self
))
1411 seedval
= evalexp (value
, 0, &expok
);
1413 expok
= legal_number (value
, &seedval
);
1417 if (subshell_environment
)
1418 seeded_subshell
= getpid ();
1419 return (set_int_value (self
, seedval
, integer_p (self
) != 0));
1423 get_random_number ()
1427 /* Reset for command and process substitution. */
1429 if (subshell_environment
&& seeded_subshell
!= pid
)
1432 seeded_subshell
= pid
;
1437 while (rv
== last_random_value
);
1439 return (last_random_value
= rv
);
1448 rv
= get_random_number ();
1449 return (set_int_value (var
, rv
, 1));
1458 rv
= get_urandom32 ();
1459 return (set_int_value (var
, rv
, 1));
1463 assign_lineno (var
, value
, unused
, key
)
1471 if (value
== 0 || *value
== '\0' || legal_number (value
, &new_value
) == 0)
1473 line_number
= line_number_base
= new_value
;
1474 return (set_int_value (var
, line_number
, integer_p (var
) != 0));
1477 /* Function which returns the current line number. */
1484 ln
= executing_line_number ();
1485 return (set_int_value (var
, ln
, 0));
1489 assign_subshell (var
, value
, unused
, key
)
1497 if (value
== 0 || *value
== '\0' || legal_number (value
, &new_value
) == 0)
1499 subshell_level
= new_value
;
1507 return (set_int_value (var
, subshell_level
, 0));
1511 get_epochseconds (var
)
1517 return (set_int_value (var
, now
, 0));
1521 get_epochrealtime (var
)
1527 gettimeofday (&tv
, NULL
);
1528 snprintf (buf
, sizeof (buf
), "%u%c%06u", (unsigned)tv
.tv_sec
,
1530 (unsigned)tv
.tv_usec
);
1532 return (set_string_value (var
, buf
, 0));
1542 return (set_int_value (var
, pid
, 1));
1546 get_bash_argv0 (var
)
1549 return (set_string_value (var
, dollar_vars
[0], 0));
1552 static char *static_shell_name
= 0;
1555 assign_bash_argv0 (var
, value
, unused
, key
)
1566 FREE (dollar_vars
[0]);
1567 dollar_vars
[0] = savestring (value
);
1569 /* Need these gyrations because shell_name isn't dynamically allocated */
1570 vlen
= STRLEN (value
);
1571 static_shell_name
= xrealloc (static_shell_name
, vlen
+ 1);
1572 strcpy (static_shell_name
, value
);
1574 shell_name
= static_shell_name
;
1583 v
= find_variable ("BASH_ARGV0");
1584 if (v
&& imported_p (v
))
1585 assign_bash_argv0 (v
, value_cell (v
), 0, 0);
1589 get_bash_command (var
)
1594 p
= the_printed_command_except_trap
? the_printed_command_except_trap
: "";
1595 return (set_string_value (var
, p
, 0));
1598 #if defined (HISTORY)
1605 /* Do the same adjustment here we do in parse.y:prompt_history_number,
1606 assuming that we are in one of two states: decoding this as part of
1607 the prompt string, in which case we do not want to assume that the
1608 command has been saved to the history and the history number incremented,
1609 or the expansion is part of the current command being executed and has
1610 already been saved to history and the history number incremented.
1611 Right now we use EXECUTING as the determinant. */
1612 n
= history_number () - executing
;
1613 return (set_int_value (var
, n
, 0));
1617 #if defined (READLINE)
1618 /* When this function returns, VAR->value points to malloced memory. */
1620 get_comp_wordbreaks (var
)
1623 /* If we don't have anything yet, assign a default value. */
1624 if (rl_completer_word_break_characters
== 0 && bash_readline_initialized
== 0)
1625 enable_hostname_completion (perform_hostname_completion
);
1627 return (set_string_value (var
, rl_completer_word_break_characters
, 0));
1630 /* When this function returns, rl_completer_word_break_characters points to
1633 assign_comp_wordbreaks (self
, value
, unused
, key
)
1639 if (rl_completer_word_break_characters
&&
1640 rl_completer_word_break_characters
!= rl_basic_word_break_characters
)
1641 free ((void *)rl_completer_word_break_characters
);
1643 rl_completer_word_break_characters
= savestring (value
);
1646 #endif /* READLINE */
1648 #if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
1650 assign_dirstack (self
, value
, ind
, key
)
1656 set_dirstack_element (ind
, 1, value
);
1667 l
= get_directory_stack (0);
1668 a
= array_from_word_list (l
);
1669 array_dispose (array_cell (self
));
1671 var_setarray (self
, a
);
1674 #endif /* PUSHD AND POPD && ARRAY_VARS */
1676 #if defined (ARRAY_VARS)
1677 /* We don't want to initialize the group set with a call to getgroups()
1678 unless we're asked to, but we only want to do it once. */
1686 static char **group_set
= (char **)NULL
;
1690 group_set
= get_group_list (&ng
);
1691 a
= array_cell (self
);
1692 for (i
= 0; i
< ng
; i
++)
1693 array_insert (a
, i
, group_set
[i
]);
1698 # if defined (DEBUGGER)
1700 get_bashargcv (self
)
1703 static int self_semaphore
= 0;
1705 /* Backwards compatibility: if we refer to BASH_ARGV or BASH_ARGC at the
1706 top level without enabling debug mode, and we don't have an instance
1707 of the variable set, initialize the arg arrays.
1708 This will already have been done if debugging_mode != 0. */
1709 if (self_semaphore
== 0 && variable_context
== 0 && debugging_mode
== 0) /* don't do it for shell functions */
1720 build_hashcmd (self
)
1726 BUCKET_CONTENTS
*item
;
1728 h
= assoc_cell (self
);
1732 if (hashed_filenames
== 0 || HASH_ENTRIES (hashed_filenames
) == 0)
1734 var_setvalue (self
, (char *)NULL
);
1738 h
= assoc_create (hashed_filenames
->nbuckets
);
1739 for (i
= 0; i
< hashed_filenames
->nbuckets
; i
++)
1741 for (item
= hash_items (i
, hashed_filenames
); item
; item
= item
->next
)
1743 k
= savestring (item
->key
);
1744 v
= pathdata(item
)->path
;
1745 assoc_insert (h
, k
, v
);
1749 var_setvalue (self
, (char *)h
);
1757 build_hashcmd (self
);
1762 assign_hashcmd (self
, value
, ind
, key
)
1768 #if defined (RESTRICTED_SHELL)
1773 if (strchr (value
, '/'))
1775 sh_restricted (value
);
1776 return (SHELL_VAR
*)NULL
;
1778 /* If we are changing the hash table in a restricted shell, make sure the
1779 target pathname can be found using a $PATH search. */
1780 full_path
= find_user_command (value
);
1781 if (full_path
== 0 || *full_path
== 0 || executable_file (full_path
) == 0)
1783 sh_notfound (value
);
1785 return ((SHELL_VAR
*)NULL
);
1790 phash_insert (key
, value
, 0, 0);
1791 return (build_hashcmd (self
));
1796 build_aliasvar (self
)
1802 BUCKET_CONTENTS
*item
;
1804 h
= assoc_cell (self
);
1808 if (aliases
== 0 || HASH_ENTRIES (aliases
) == 0)
1810 var_setvalue (self
, (char *)NULL
);
1814 h
= assoc_create (aliases
->nbuckets
);
1815 for (i
= 0; i
< aliases
->nbuckets
; i
++)
1817 for (item
= hash_items (i
, aliases
); item
; item
= item
->next
)
1819 k
= savestring (item
->key
);
1820 v
= ((alias_t
*)(item
->data
))->value
;
1821 assoc_insert (h
, k
, v
);
1825 var_setvalue (self
, (char *)h
);
1833 build_aliasvar (self
);
1838 assign_aliasvar (self
, value
, ind
, key
)
1844 if (legal_alias_name (key
, 0) == 0)
1846 report_error (_("`%s': invalid alias name"), key
);
1849 add_alias (key
, value
);
1850 return (build_aliasvar (self
));
1854 #endif /* ARRAY_VARS */
1856 /* If ARRAY_VARS is not defined, this just returns the name of any
1857 currently-executing function. If we have arrays, it's a call stack. */
1862 #if ! defined (ARRAY_VARS)
1863 if (variable_context
&& this_shell_function
)
1864 return (set_string_value (self
, this_shell_function
->name
, 0));
1870 make_funcname_visible (on_or_off
)
1875 v
= find_variable ("FUNCNAME");
1876 if (v
== 0 || v
->dynamic_value
== 0)
1880 VUNSETATTR (v
, att_invisible
);
1882 VSETATTR (v
, att_invisible
);
1886 init_funcname_var ()
1890 v
= find_variable ("FUNCNAME");
1893 #if defined (ARRAY_VARS)
1894 INIT_DYNAMIC_ARRAY_VAR ("FUNCNAME", get_funcname
, null_array_assign
);
1896 INIT_DYNAMIC_VAR ("FUNCNAME", (char *)NULL
, get_funcname
, null_assign
);
1898 VSETATTR (v
, att_invisible
|att_noassign
);
1903 initialize_dynamic_variables ()
1907 v
= init_seconds_var ();
1909 INIT_DYNAMIC_VAR ("BASH_ARGV0", (char *)NULL
, get_bash_argv0
, assign_bash_argv0
);
1911 INIT_DYNAMIC_VAR ("BASH_COMMAND", (char *)NULL
, get_bash_command
, (sh_var_assign_func_t
*)NULL
);
1912 INIT_DYNAMIC_VAR ("BASH_SUBSHELL", (char *)NULL
, get_subshell
, assign_subshell
);
1914 INIT_DYNAMIC_VAR ("RANDOM", (char *)NULL
, get_random
, assign_random
);
1915 VSETATTR (v
, att_integer
);
1916 INIT_DYNAMIC_VAR ("SRANDOM", (char *)NULL
, get_urandom
, (sh_var_assign_func_t
*)NULL
);
1917 VSETATTR (v
, att_integer
);
1918 INIT_DYNAMIC_VAR ("LINENO", (char *)NULL
, get_lineno
, assign_lineno
);
1919 VSETATTR (v
, att_regenerate
);
1921 INIT_DYNAMIC_VAR ("BASHPID", (char *)NULL
, get_bashpid
, null_assign
);
1922 VSETATTR (v
, att_integer
);
1924 INIT_DYNAMIC_VAR ("EPOCHSECONDS", (char *)NULL
, get_epochseconds
, null_assign
);
1925 VSETATTR (v
, att_regenerate
);
1926 INIT_DYNAMIC_VAR ("EPOCHREALTIME", (char *)NULL
, get_epochrealtime
, null_assign
);
1927 VSETATTR (v
, att_regenerate
);
1929 #if defined (HISTORY)
1930 INIT_DYNAMIC_VAR ("HISTCMD", (char *)NULL
, get_histcmd
, (sh_var_assign_func_t
*)NULL
);
1931 VSETATTR (v
, att_integer
);
1934 #if defined (READLINE)
1935 INIT_DYNAMIC_VAR ("COMP_WORDBREAKS", (char *)NULL
, get_comp_wordbreaks
, assign_comp_wordbreaks
);
1938 #if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
1939 v
= init_dynamic_array_var ("DIRSTACK", get_dirstack
, assign_dirstack
, 0);
1940 #endif /* PUSHD_AND_POPD && ARRAY_VARS */
1942 #if defined (ARRAY_VARS)
1943 v
= init_dynamic_array_var ("GROUPS", get_groupset
, null_array_assign
, att_noassign
);
1945 # if defined (DEBUGGER)
1946 v
= init_dynamic_array_var ("BASH_ARGC", get_bashargcv
, null_array_assign
, att_noassign
|att_nounset
);
1947 v
= init_dynamic_array_var ("BASH_ARGV", get_bashargcv
, null_array_assign
, att_noassign
|att_nounset
);
1948 # endif /* DEBUGGER */
1949 v
= init_dynamic_array_var ("BASH_SOURCE", get_self
, null_array_assign
, att_noassign
|att_nounset
);
1950 v
= init_dynamic_array_var ("BASH_LINENO", get_self
, null_array_assign
, att_noassign
|att_nounset
);
1952 v
= init_dynamic_assoc_var ("BASH_CMDS", get_hashcmd
, assign_hashcmd
, att_nofree
);
1953 # if defined (ALIAS)
1954 v
= init_dynamic_assoc_var ("BASH_ALIASES", get_aliasvar
, assign_aliasvar
, att_nofree
);
1958 v
= init_funcname_var ();
1961 /* **************************************************************** */
1963 /* Retrieving variables and values */
1965 /* **************************************************************** */
1972 return (var
->value
!= 0);
1979 return (var
->value
== 0);
1983 /* How to get a pointer to the shell variable or function named NAME.
1984 HASHED_VARS is a pointer to the hash table containing the list
1985 of interest (either variables or functions). */
1988 hash_lookup (name
, hashed_vars
)
1990 HASH_TABLE
*hashed_vars
;
1992 BUCKET_CONTENTS
*bucket
;
1994 bucket
= hash_search (name
, hashed_vars
, 0);
1995 /* If we find the name in HASHED_VARS, set LAST_TABLE_SEARCHED to that
1998 last_table_searched
= hashed_vars
;
1999 return (bucket
? (SHELL_VAR
*)bucket
->data
: (SHELL_VAR
*)NULL
);
2003 var_lookup (name
, vcontext
)
2005 VAR_CONTEXT
*vcontext
;
2010 v
= (SHELL_VAR
*)NULL
;
2011 for (vc
= vcontext
; vc
; vc
= vc
->down
)
2012 if (v
= hash_lookup (name
, vc
->table
))
2018 /* Look up the variable entry named NAME. If SEARCH_TEMPENV is non-zero,
2019 then also search the temporarily built list of exported variables.
2020 The lookup order is:
2022 shell_variables list
2026 find_variable_internal (name
, flags
)
2031 int search_tempenv
, force_tempenv
;
2034 var
= (SHELL_VAR
*)NULL
;
2036 force_tempenv
= (flags
& FV_FORCETEMPENV
);
2038 /* If explicitly requested, first look in the temporary environment for
2039 the variable. This allows constructs such as "foo=x eval 'echo $foo'"
2040 to get the `exported' value of $foo. This happens if we are executing
2041 a function or builtin, or if we are looking up a variable in a
2042 "subshell environment". */
2043 search_tempenv
= force_tempenv
|| (expanding_redir
== 0 && subshell_environment
);
2045 if (search_tempenv
&& temporary_env
)
2046 var
= hash_lookup (name
, temporary_env
);
2050 if ((flags
& FV_SKIPINVISIBLE
) == 0)
2051 var
= var_lookup (name
, shell_variables
);
2054 /* essentially var_lookup expanded inline so we can check for
2056 for (vc
= shell_variables
; vc
; vc
= vc
->down
)
2058 var
= hash_lookup (name
, vc
->table
);
2059 if (var
&& invisible_p (var
))
2068 return ((SHELL_VAR
*)NULL
);
2070 return (var
->dynamic_value
? (*(var
->dynamic_value
)) (var
) : var
);
2073 /* Look up and resolve the chain of nameref variables starting at V all the
2074 way to NULL or non-nameref. */
2076 find_variable_nameref (v
)
2081 SHELL_VAR
*orig
, *oldv
;
2085 while (v
&& nameref_p (v
))
2088 if (level
> NAMEREF_MAX
)
2089 return ((SHELL_VAR
*)0); /* error message here? */
2090 newname
= nameref_cell (v
);
2091 if (newname
== 0 || *newname
== '\0')
2092 return ((SHELL_VAR
*)0);
2095 if (expanding_redir
== 0 && (assigning_in_environment
|| executing_builtin
))
2096 flags
|= FV_FORCETEMPENV
;
2097 /* We don't handle array subscripts here. */
2098 v
= find_variable_internal (newname
, flags
);
2099 if (v
== orig
|| v
== oldv
)
2101 internal_warning (_("%s: circular name reference"), orig
->name
);
2103 /* XXX - provisional change - circular refs go to
2104 global scope for resolution, without namerefs. */
2105 if (variable_context
&& v
->context
)
2106 return (find_global_variable_noref (v
->name
));
2109 return ((SHELL_VAR
*)0);
2115 /* Resolve the chain of nameref variables for NAME. XXX - could change later */
2117 find_variable_last_nameref (name
, vflags
)
2125 nv
= v
= find_variable_noref (name
);
2127 while (v
&& nameref_p (v
))
2130 if (level
> NAMEREF_MAX
)
2131 return ((SHELL_VAR
*)0); /* error message here? */
2132 newname
= nameref_cell (v
);
2133 if (newname
== 0 || *newname
== '\0')
2134 return ((vflags
&& invisible_p (v
)) ? v
: (SHELL_VAR
*)0);
2137 if (expanding_redir
== 0 && (assigning_in_environment
|| executing_builtin
))
2138 flags
|= FV_FORCETEMPENV
;
2139 /* We don't accommodate array subscripts here. */
2140 v
= find_variable_internal (newname
, flags
);
2145 /* Resolve the chain of nameref variables for NAME. XXX - could change later */
2147 find_global_variable_last_nameref (name
, vflags
)
2155 nv
= v
= find_global_variable_noref (name
);
2157 while (v
&& nameref_p (v
))
2160 if (level
> NAMEREF_MAX
)
2161 return ((SHELL_VAR
*)0); /* error message here? */
2162 newname
= nameref_cell (v
);
2163 if (newname
== 0 || *newname
== '\0')
2164 return ((vflags
&& invisible_p (v
)) ? v
: (SHELL_VAR
*)0);
2166 /* We don't accommodate array subscripts here. */
2167 v
= find_global_variable_noref (newname
);
2173 find_nameref_at_context (v
, vc
)
2177 SHELL_VAR
*nv
, *nv2
;
2183 while (nv
&& nameref_p (nv
))
2186 if (level
> NAMEREF_MAX
)
2187 return (&nameref_maxloop_value
);
2188 newname
= nameref_cell (nv
);
2189 if (newname
== 0 || *newname
== '\0')
2190 return ((SHELL_VAR
*)NULL
);
2191 nv2
= hash_lookup (newname
, vc
->table
);
2199 /* Do nameref resolution from the VC, which is the local context for some
2200 function or builtin, `up' the chain to the global variables context. If
2201 NVCP is not NULL, return the variable context where we finally ended the
2202 nameref resolution (so the bind_variable_internal can use the correct
2203 variable context and hash table). */
2205 find_variable_nameref_context (v
, vc
, nvcp
)
2210 SHELL_VAR
*nv
, *nv2
;
2213 /* Look starting at the current context all the way `up' */
2214 for (nv
= v
, nvc
= vc
; nvc
; nvc
= nvc
->down
)
2216 nv2
= find_nameref_at_context (nv
, nvc
);
2217 if (nv2
== &nameref_maxloop_value
)
2218 return (nv2
); /* XXX */
2224 if (nameref_p (nv
) == 0)
2227 return (nameref_p (nv
) ? (SHELL_VAR
*)NULL
: nv
);
2230 /* Do nameref resolution from the VC, which is the local context for some
2231 function or builtin, `up' the chain to the global variables context. If
2232 NVCP is not NULL, return the variable context where we finally ended the
2233 nameref resolution (so the bind_variable_internal can use the correct
2234 variable context and hash table). */
2236 find_variable_last_nameref_context (v
, vc
, nvcp
)
2241 SHELL_VAR
*nv
, *nv2
;
2244 /* Look starting at the current context all the way `up' */
2245 for (nv
= v
, nvc
= vc
; nvc
; nvc
= nvc
->down
)
2247 nv2
= find_nameref_at_context (nv
, nvc
);
2248 if (nv2
== &nameref_maxloop_value
)
2249 return (nv2
); /* XXX */
2256 return (nameref_p (nv
) ? nv
: (SHELL_VAR
*)NULL
);
2260 find_variable_nameref_for_create (name
, flags
)
2266 /* See if we have a nameref pointing to a variable that hasn't been
2268 var
= find_variable_last_nameref (name
, 1);
2269 if ((flags
&1) && var
&& nameref_p (var
) && invisible_p (var
))
2271 internal_warning (_("%s: removing nameref attribute"), name
);
2272 VUNSETATTR (var
, att_nameref
);
2274 if (var
&& nameref_p (var
))
2276 if (legal_identifier (nameref_cell (var
)) == 0)
2278 sh_invalidid (nameref_cell (var
) ? nameref_cell (var
) : "");
2279 return ((SHELL_VAR
*)INVALID_NAMEREF_VALUE
);
2286 find_variable_nameref_for_assignment (name
, flags
)
2292 /* See if we have a nameref pointing to a variable that hasn't been
2294 var
= find_variable_last_nameref (name
, 1);
2295 if (var
&& nameref_p (var
) && invisible_p (var
)) /* XXX - flags */
2297 internal_warning (_("%s: removing nameref attribute"), name
);
2298 VUNSETATTR (var
, att_nameref
);
2300 if (var
&& nameref_p (var
))
2302 if (valid_nameref_value (nameref_cell (var
), 1) == 0)
2304 sh_invalidid (nameref_cell (var
) ? nameref_cell (var
) : "");
2305 return ((SHELL_VAR
*)INVALID_NAMEREF_VALUE
);
2311 /* If find_variable (name) returns NULL, check that it's not a nameref
2312 referencing a variable that doesn't exist. If it is, return the new
2313 name. If not, return the original name. Kind of like the previous
2314 function, but dealing strictly with names. This takes assignment flags
2315 so it can deal with the various assignment modes used by `declare'. */
2317 nameref_transform_name (name
, flags
)
2325 if (flags
& ASS_MKLOCAL
)
2327 v
= find_variable_last_nameref (name
, 1);
2328 /* If we're making local variables, only follow namerefs that point to
2329 non-existent variables at the same variable context. */
2330 if (v
&& v
->context
!= variable_context
)
2333 else if (flags
& ASS_MKGLOBAL
)
2334 v
= (flags
& ASS_CHKLOCAL
) ? find_variable_last_nameref (name
, 1)
2335 : find_global_variable_last_nameref (name
, 1);
2336 if (v
&& nameref_p (v
) && valid_nameref_value (nameref_cell (v
), 1))
2337 return nameref_cell (v
);
2341 /* Find a variable, forcing a search of the temporary environment first */
2343 find_variable_tempenv (name
)
2348 var
= find_variable_internal (name
, FV_FORCETEMPENV
);
2349 if (var
&& nameref_p (var
))
2350 var
= find_variable_nameref (var
);
2354 /* Find a variable, not forcing a search of the temporary environment first */
2356 find_variable_notempenv (name
)
2361 var
= find_variable_internal (name
, 0);
2362 if (var
&& nameref_p (var
))
2363 var
= find_variable_nameref (var
);
2368 find_global_variable (name
)
2373 var
= var_lookup (name
, global_variables
);
2374 if (var
&& nameref_p (var
))
2375 var
= find_variable_nameref (var
); /* XXX - find_global_variable_noref? */
2378 return ((SHELL_VAR
*)NULL
);
2380 return (var
->dynamic_value
? (*(var
->dynamic_value
)) (var
) : var
);
2384 find_global_variable_noref (name
)
2389 var
= var_lookup (name
, global_variables
);
2392 return ((SHELL_VAR
*)NULL
);
2394 return (var
->dynamic_value
? (*(var
->dynamic_value
)) (var
) : var
);
2398 find_shell_variable (name
)
2403 var
= var_lookup (name
, shell_variables
);
2404 if (var
&& nameref_p (var
))
2405 var
= find_variable_nameref (var
);
2408 return ((SHELL_VAR
*)NULL
);
2410 return (var
->dynamic_value
? (*(var
->dynamic_value
)) (var
) : var
);
2413 /* Look up the variable entry named NAME. Returns the entry or NULL. */
2415 find_variable (name
)
2421 last_table_searched
= 0;
2423 if (expanding_redir
== 0 && (assigning_in_environment
|| executing_builtin
))
2424 flags
|= FV_FORCETEMPENV
;
2425 v
= find_variable_internal (name
, flags
);
2426 if (v
&& nameref_p (v
))
2427 v
= find_variable_nameref (v
);
2431 /* Find the first instance of NAME in the variable context chain; return first
2432 one found without att_invisible set; return 0 if no non-invisible instances
2435 find_variable_no_invisible (name
)
2441 last_table_searched
= 0;
2442 flags
= FV_SKIPINVISIBLE
;
2443 if (expanding_redir
== 0 && (assigning_in_environment
|| executing_builtin
))
2444 flags
|= FV_FORCETEMPENV
;
2445 v
= find_variable_internal (name
, flags
);
2446 if (v
&& nameref_p (v
))
2447 v
= find_variable_nameref (v
);
2451 /* Find the first instance of NAME in the variable context chain; return first
2452 one found even if att_invisible set. */
2454 find_variable_for_assignment (name
)
2460 last_table_searched
= 0;
2462 if (expanding_redir
== 0 && (assigning_in_environment
|| executing_builtin
))
2463 flags
|= FV_FORCETEMPENV
;
2464 v
= find_variable_internal (name
, flags
);
2465 if (v
&& nameref_p (v
))
2466 v
= find_variable_nameref (v
);
2471 find_variable_noref (name
)
2478 if (expanding_redir
== 0 && (assigning_in_environment
|| executing_builtin
))
2479 flags
|= FV_FORCETEMPENV
;
2480 v
= find_variable_internal (name
, flags
);
2484 /* Look up the function entry whose name matches STRING.
2485 Returns the entry or NULL. */
2487 find_function (name
)
2490 return (hash_lookup (name
, shell_functions
));
2493 /* Find the function definition for the shell function named NAME. Returns
2494 the entry or NULL. */
2496 find_function_def (name
)
2499 #if defined (DEBUGGER)
2500 return ((FUNCTION_DEF
*)hash_lookup (name
, shell_function_defs
));
2502 return ((FUNCTION_DEF
*)0);
2506 /* Return the value of VAR. VAR is assumed to have been the result of a
2507 lookup without any subscript, if arrays are compiled into the shell. */
2509 get_variable_value (var
)
2513 return ((char *)NULL
);
2514 #if defined (ARRAY_VARS)
2515 else if (array_p (var
))
2516 return (array_reference (array_cell (var
), 0));
2517 else if (assoc_p (var
))
2518 return (assoc_reference (assoc_cell (var
), "0"));
2521 return (value_cell (var
));
2524 /* Return the string value of a variable. Return NULL if the variable
2525 doesn't exist. Don't cons a new string. This is a potential memory
2526 leak if the variable is found in the temporary environment, but doesn't
2527 leak in practice. Since functions and variables have separate name
2528 spaces, returns NULL if var_name is a shell function only. */
2530 get_string_value (var_name
)
2531 const char *var_name
;
2535 var
= find_variable (var_name
);
2536 return ((var
) ? get_variable_value (var
) : (char *)NULL
);
2539 /* This is present for use by the tilde and readline libraries. */
2541 sh_get_env_value (v
)
2544 return get_string_value (v
);
2547 /* **************************************************************** */
2549 /* Creating and setting variables */
2551 /* **************************************************************** */
2554 var_sametype (v1
, v2
)
2558 if (v1
== 0 || v2
== 0)
2560 #if defined (ARRAY_VARS)
2561 else if (assoc_p (v1
) && assoc_p (v2
))
2563 else if (array_p (v1
) && array_p (v2
))
2565 else if (array_p (v1
) || array_p (v2
))
2567 else if (assoc_p (v1
) || assoc_p (v2
))
2575 validate_inherited_value (var
, type
)
2579 #if defined (ARRAY_VARS)
2580 if (type
== att_array
&& assoc_p (var
))
2582 else if (type
== att_assoc
&& array_p (var
))
2586 return 1; /* should we run convert_var_to_array here or let the caller? */
2589 /* Set NAME to VALUE if NAME has no value. */
2591 set_if_not (name
, value
)
2596 if (shell_variables
== 0)
2597 create_variable_tables ();
2599 v
= find_variable (name
);
2601 v
= bind_variable_internal (name
, value
, global_variables
->table
, HASH_NOSRCH
, 0);
2605 /* Create a local variable referenced by NAME. */
2607 make_local_variable (name
, flags
)
2611 SHELL_VAR
*new_var
, *old_var
, *old_ref
;
2616 /* We don't want to follow the nameref chain when making local variables; we
2617 just want to create them. */
2618 old_ref
= find_variable_noref (name
);
2619 if (old_ref
&& nameref_p (old_ref
) == 0)
2621 /* local foo; local foo; is a no-op. */
2622 old_var
= find_variable (name
);
2623 if (old_ref
== 0 && old_var
&& local_p (old_var
) && old_var
->context
== variable_context
)
2626 /* local -n foo; local -n foo; is a no-op. */
2627 if (old_ref
&& local_p (old_ref
) && old_ref
->context
== variable_context
)
2630 /* From here on, we want to use the refvar, not the variable it references */
2634 was_tmpvar
= old_var
&& tempvar_p (old_var
);
2635 /* If we're making a local variable in a shell function, the temporary env
2636 has already been merged into the function's variable context stack. We
2637 can assume that a temporary var in the same context appears in the same
2638 VAR_CONTEXT and can safely be returned without creating a new variable
2639 (which results in duplicate names in the same VAR_CONTEXT->table */
2640 /* We can't just test tmpvar_p because variables in the temporary env given
2641 to a shell function appear in the function's local variable VAR_CONTEXT
2642 but retain their tempvar attribute. We want temporary variables that are
2643 found in temporary_env, hence the test for last_table_searched, which is
2644 set in hash_lookup and only (so far) checked here. */
2645 if (was_tmpvar
&& old_var
->context
== variable_context
&& last_table_searched
!= temporary_env
)
2647 VUNSETATTR (old_var
, att_invisible
); /* XXX */
2648 /* We still want to flag this variable as local, though, and set things
2649 up so that it gets treated as a local variable. */
2651 /* Since we found the variable in a temporary environment, this will
2653 for (vc
= shell_variables
; vc
; vc
= vc
->down
)
2654 if (vc_isfuncenv (vc
) && vc
->scope
== variable_context
)
2656 goto set_local_var_flags
;
2661 /* If we want to change to "inherit the old variable's value" semantics,
2662 here is where to save the old value. */
2663 old_value
= was_tmpvar
? value_cell (old_var
) : (char *)NULL
;
2665 for (vc
= shell_variables
; vc
; vc
= vc
->down
)
2666 if (vc_isfuncenv (vc
) && vc
->scope
== variable_context
)
2671 internal_error (_("make_local_variable: no function context at current scope"));
2672 return ((SHELL_VAR
*)NULL
);
2674 else if (vc
->table
== 0)
2675 vc
->table
= hash_create (TEMPENV_HASH_BUCKETS
);
2677 /* Since this is called only from the local/declare/typeset code, we can
2678 call builtin_error here without worry (of course, it will also work
2679 for anything that sets this_command_name). Variables with the `noassign'
2680 attribute may not be made local. The test against old_var's context
2681 level is to disallow local copies of readonly global variables (since I
2682 believe that this could be a security hole). Readonly copies of calling
2683 function local variables are OK. */
2684 if (old_var
&& (noassign_p (old_var
) ||
2685 (readonly_p (old_var
) && old_var
->context
== 0)))
2687 if (readonly_p (old_var
))
2689 else if (noassign_p (old_var
))
2690 builtin_error (_("%s: variable may not be assigned value"), name
);
2692 /* Let noassign variables through with a warning */
2693 if (readonly_p (old_var
))
2695 return ((SHELL_VAR
*)NULL
);
2699 new_var
= make_new_variable (name
, vc
->table
);
2702 new_var
= make_new_variable (name
, vc
->table
);
2704 /* If we found this variable in one of the temporary environments,
2705 inherit its value. Watch to see if this causes problems with
2706 things like `x=4 local x'. XXX - see above for temporary env
2707 variables with the same context level as variable_context */
2708 /* XXX - we should only do this if the variable is not an array. */
2709 /* If we want to change the local variable semantics to "inherit
2710 the old variable's value" here is where to set it. And we would
2711 need to use copy_variable (currently unused) to do it for all
2712 possible variable values. */
2714 var_setvalue (new_var
, savestring (old_value
));
2715 else if (localvar_inherit
|| (flags
& MKLOC_INHERIT
))
2717 /* This may not make sense for nameref variables that are shadowing
2718 variables with the same name, but we don't know that yet. */
2719 #if defined (ARRAY_VARS)
2720 if (assoc_p (old_var
))
2721 var_setassoc (new_var
, assoc_copy (assoc_cell (old_var
)));
2722 else if (array_p (old_var
))
2723 var_setarray (new_var
, array_copy (array_cell (old_var
)));
2724 else if (value_cell (old_var
))
2726 if (value_cell (old_var
))
2728 var_setvalue (new_var
, savestring (value_cell (old_var
)));
2730 var_setvalue (new_var
, (char *)NULL
);
2733 if (localvar_inherit
|| (flags
& MKLOC_INHERIT
))
2735 /* It doesn't make sense to inherit the nameref attribute */
2736 new_var
->attributes
= old_var
->attributes
& ~att_nameref
;
2737 new_var
->dynamic_value
= old_var
->dynamic_value
;
2738 new_var
->assign_func
= old_var
->assign_func
;
2741 /* We inherit the export attribute, but no others. */
2742 new_var
->attributes
= exported_p (old_var
) ? att_exported
: 0;
2745 set_local_var_flags
:
2746 vc
->flags
|= VC_HASLOCAL
;
2748 new_var
->context
= variable_context
;
2749 VSETATTR (new_var
, att_local
);
2754 /* value_cell will be 0 if localvar_inherit == 0 or there was no old variable
2755 with the same name or the old variable was invisible */
2756 if (was_tmpvar
== 0 && value_cell (new_var
) == 0)
2757 VSETATTR (new_var
, att_invisible
); /* XXX */
2761 /* Create a new shell variable with name NAME. */
2763 new_shell_variable (name
)
2768 entry
= (SHELL_VAR
*)xmalloc (sizeof (SHELL_VAR
));
2770 entry
->name
= savestring (name
);
2771 var_setvalue (entry
, (char *)NULL
);
2772 CLEAR_EXPORTSTR (entry
);
2774 entry
->dynamic_value
= (sh_var_value_func_t
*)NULL
;
2775 entry
->assign_func
= (sh_var_assign_func_t
*)NULL
;
2777 entry
->attributes
= 0;
2779 /* Always assume variables are to be made at toplevel!
2780 make_local_variable has the responsibility of changing the
2781 variable context. */
2787 /* Create a new shell variable with name NAME and add it to the hash table
2790 make_new_variable (name
, table
)
2795 BUCKET_CONTENTS
*elt
;
2797 entry
= new_shell_variable (name
);
2799 /* Make sure we have a shell_variables hash table to add to. */
2800 if (shell_variables
== 0)
2801 create_variable_tables ();
2803 elt
= hash_insert (savestring (name
), table
, HASH_NOSRCH
);
2804 elt
->data
= (PTR_T
)entry
;
2809 #if defined (ARRAY_VARS)
2811 make_new_array_variable (name
)
2817 entry
= make_new_variable (name
, global_variables
->table
);
2818 array
= array_create ();
2820 var_setarray (entry
, array
);
2821 VSETATTR (entry
, att_array
);
2826 make_local_array_variable (name
, flags
)
2834 assoc_ok
= flags
& MKLOC_ASSOCOK
;
2836 var
= make_local_variable (name
, flags
& MKLOC_INHERIT
); /* XXX for now */
2837 /* If ASSOC_OK is non-zero, assume that we are ok with letting an assoc
2838 variable return to the caller without converting it. The caller will
2839 either flag an error or do the conversion itself. */
2840 if (var
== 0 || array_p (var
) || (assoc_ok
&& assoc_p (var
)))
2843 /* Validate any value we inherited from a variable instance at a previous
2844 scope and discard anything that's invalid. */
2845 if (localvar_inherit
&& assoc_p (var
))
2847 internal_warning (_("%s: cannot inherit value from incompatible type"), name
);
2848 VUNSETATTR (var
, att_assoc
);
2849 dispose_variable_value (var
);
2850 array
= array_create ();
2851 var_setarray (var
, array
);
2853 else if (localvar_inherit
)
2854 var
= convert_var_to_array (var
); /* XXX */
2857 dispose_variable_value (var
);
2858 array
= array_create ();
2859 var_setarray (var
, array
);
2862 VSETATTR (var
, att_array
);
2867 make_new_assoc_variable (name
)
2873 entry
= make_new_variable (name
, global_variables
->table
);
2874 hash
= assoc_create (ASSOC_HASH_BUCKETS
);
2876 var_setassoc (entry
, hash
);
2877 VSETATTR (entry
, att_assoc
);
2882 make_local_assoc_variable (name
, flags
)
2890 array_ok
= flags
& MKLOC_ARRAYOK
;
2892 var
= make_local_variable (name
, flags
& MKLOC_INHERIT
); /* XXX for now */
2893 /* If ARRAY_OK is non-zero, assume that we are ok with letting an array
2894 variable return to the caller without converting it. The caller will
2895 either flag an error or do the conversion itself. */
2896 if (var
== 0 || assoc_p (var
) || (array_ok
&& array_p (var
)))
2899 /* Validate any value we inherited from a variable instance at a previous
2900 scope and discard anything that's invalid. */
2901 if (localvar_inherit
&& array_p (var
))
2903 internal_warning (_("%s: cannot inherit value from incompatible type"), name
);
2904 VUNSETATTR (var
, att_array
);
2905 dispose_variable_value (var
);
2906 hash
= assoc_create (ASSOC_HASH_BUCKETS
);
2907 var_setassoc (var
, hash
);
2909 else if (localvar_inherit
)
2910 var
= convert_var_to_assoc (var
); /* XXX */
2913 dispose_variable_value (var
);
2914 hash
= assoc_create (ASSOC_HASH_BUCKETS
);
2915 var_setassoc (var
, hash
);
2918 VSETATTR (var
, att_assoc
);
2924 make_variable_value (var
, value
, flags
)
2929 char *retval
, *oval
;
2930 intmax_t lval
, rval
;
2931 int expok
, olen
, op
;
2933 /* If this variable has had its type set to integer (via `declare -i'),
2934 then do expression evaluation on it and store the result. The
2935 functions in expr.c (evalexp()) and bind_int_variable() are responsible
2936 for turning off the integer flag if they don't want further
2937 evaluation done. Callers that find it inconvenient to do this can set
2938 the ASS_NOEVAL flag. For the special case of arithmetic expression
2939 evaluation, the caller can set ASS_NOLONGJMP to avoid jumping out to
2941 if ((flags
& ASS_NOEVAL
) == 0 && integer_p (var
))
2943 if (flags
& ASS_APPEND
)
2945 oval
= value_cell (var
);
2946 lval
= evalexp (oval
, 0, &expok
); /* ksh93 seems to do this */
2949 if (flags
& ASS_NOLONGJMP
)
2953 top_level_cleanup ();
2954 jump_to_top_level (DISCARD
);
2958 rval
= evalexp (value
, 0, &expok
);
2961 if (flags
& ASS_NOLONGJMP
)
2965 top_level_cleanup ();
2966 jump_to_top_level (DISCARD
);
2969 /* This can be fooled if the variable's value changes while evaluating
2970 `rval'. We can change it if we move the evaluation of lval to here. */
2971 if (flags
& ASS_APPEND
)
2973 retval
= itos (rval
);
2975 #if defined (CASEMOD_ATTRS)
2976 else if ((flags
& ASS_NOEVAL
) == 0 && (capcase_p (var
) || uppercase_p (var
) || lowercase_p (var
)))
2978 if (flags
& ASS_APPEND
)
2980 oval
= get_variable_value (var
);
2981 if (oval
== 0) /* paranoia */
2983 olen
= STRLEN (oval
);
2984 retval
= (char *)xmalloc (olen
+ (value
? STRLEN (value
) : 0) + 1);
2985 strcpy (retval
, oval
);
2987 strcpy (retval
+olen
, value
);
2990 retval
= savestring (value
);
2993 retval
= (char *)xmalloc (1);
2996 op
= capcase_p (var
) ? CASE_CAPITALIZE
2997 : (uppercase_p (var
) ? CASE_UPPER
: CASE_LOWER
);
2998 oval
= sh_modcase (retval
, (char *)0, op
);
3002 #endif /* CASEMOD_ATTRS */
3006 if (flags
& ASS_APPEND
)
3008 oval
= get_variable_value (var
);
3009 if (oval
== 0) /* paranoia */
3011 olen
= STRLEN (oval
);
3012 retval
= (char *)xmalloc (olen
+ (value
? STRLEN (value
) : 0) + 1);
3013 strcpy (retval
, oval
);
3015 strcpy (retval
+olen
, value
);
3018 retval
= savestring (value
);
3021 retval
= (char *)xmalloc (1);
3026 retval
= (char *)NULL
;
3031 /* If we can optimize appending to string variables, say so */
3033 can_optimize_assignment (entry
, value
, aflags
)
3038 if ((aflags
& ASS_APPEND
) == 0)
3040 #if defined (ARRAY_VARS)
3041 if (array_p (entry
) || assoc_p (entry
))
3044 if (integer_p (entry
) || uppercase_p (entry
) || lowercase_p (entry
) || capcase_p (entry
))
3046 if (readonly_p (entry
) || noassign_p (entry
))
3051 /* right now we optimize appends to string variables */
3053 optimized_assignment (entry
, value
, aflags
)
3061 v
= value_cell (entry
);
3063 vlen
= STRLEN (value
);
3065 new = (char *)xrealloc (v
, len
+ vlen
+ 8); /* for now */
3072 strcpy (new + len
, value
);
3073 var_setvalue (entry
, new);
3077 /* Bind a variable NAME to VALUE in the HASH_TABLE TABLE, which may be the
3078 temporary environment (but usually is not). HFLAGS controls how NAME
3079 is looked up in TABLE; AFLAGS controls how VALUE is assigned */
3081 bind_variable_internal (name
, value
, table
, hflags
, aflags
)
3087 char *newval
, *tname
;
3088 SHELL_VAR
*entry
, *tentry
;
3090 entry
= (hflags
& HASH_NOSRCH
) ? (SHELL_VAR
*)NULL
: hash_lookup (name
, table
);
3091 /* Follow the nameref chain here if this is the global variables table */
3092 if (entry
&& nameref_p (entry
) && (invisible_p (entry
) == 0) && table
== global_variables
->table
)
3094 entry
= find_global_variable (entry
->name
);
3095 /* Let's see if we have a nameref referencing a variable that hasn't yet
3098 entry
= find_variable_last_nameref (name
, 0); /* XXX */
3099 if (entry
== 0) /* just in case */
3103 /* The first clause handles `declare -n ref; ref=x;' or `declare -n ref;
3105 if (entry
&& invisible_p (entry
) && nameref_p (entry
))
3107 if ((aflags
& ASS_FORCE
) == 0 && value
&& valid_nameref_value (value
, 0) == 0)
3109 sh_invalidid (value
);
3110 return ((SHELL_VAR
*)NULL
);
3114 else if (entry
&& nameref_p (entry
))
3116 newval
= nameref_cell (entry
); /* XXX - newval can't be NULL here */
3117 if (valid_nameref_value (newval
, 0) == 0)
3119 sh_invalidid (newval
);
3120 return ((SHELL_VAR
*)NULL
);
3122 #if defined (ARRAY_VARS)
3123 /* declare -n foo=x[2] ; foo=bar */
3124 if (valid_array_reference (newval
, 0))
3126 tname
= array_variable_name (newval
, 0, (char **)0, (int *)0);
3127 if (tname
&& (tentry
= find_variable_noref (tname
)) && nameref_p (tentry
))
3129 /* nameref variables can't be arrays */
3130 internal_warning (_("%s: removing nameref attribute"), name_cell (tentry
));
3131 FREE (value_cell (tentry
)); /* XXX - bash-4.3 compat */
3132 var_setvalue (tentry
, (char *)NULL
);
3133 VUNSETATTR (tentry
, att_nameref
);
3137 /* entry == nameref variable; tentry == array variable;
3138 newval == x[2]; value = bar
3139 We don't need to call make_variable_value here, since
3140 assign_array_element will eventually do it itself based on
3141 newval and aflags. */
3143 entry
= assign_array_element (newval
, value
, aflags
|ASS_NAMEREF
, (array_eltstate_t
*)0);
3150 entry
= make_new_variable (newval
, table
);
3151 var_setvalue (entry
, make_variable_value (entry
, value
, aflags
));
3154 else if (entry
== 0)
3156 entry
= make_new_variable (name
, table
);
3157 var_setvalue (entry
, make_variable_value (entry
, value
, aflags
)); /* XXX */
3159 else if (entry
->assign_func
) /* array vars have assign functions now */
3161 if ((readonly_p (entry
) && (aflags
& ASS_FORCE
) == 0) || noassign_p (entry
))
3163 if (readonly_p (entry
))
3164 err_readonly (name_cell (entry
));
3168 INVALIDATE_EXPORTSTR (entry
);
3169 newval
= (aflags
& ASS_APPEND
) ? make_variable_value (entry
, value
, aflags
) : value
;
3170 if (assoc_p (entry
))
3171 entry
= (*(entry
->assign_func
)) (entry
, newval
, -1, savestring ("0"));
3172 else if (array_p (entry
))
3173 entry
= (*(entry
->assign_func
)) (entry
, newval
, 0, 0);
3175 entry
= (*(entry
->assign_func
)) (entry
, newval
, -1, 0);
3176 if (newval
!= value
)
3183 if ((readonly_p (entry
) && (aflags
& ASS_FORCE
) == 0) || noassign_p (entry
))
3185 if (readonly_p (entry
))
3186 err_readonly (name_cell (entry
));
3190 /* Variables which are bound are visible. */
3191 VUNSETATTR (entry
, att_invisible
);
3193 /* If we can optimize the assignment, do so and return. Right now, we
3194 optimize appends to string variables. */
3195 if (can_optimize_assignment (entry
, value
, aflags
))
3197 INVALIDATE_EXPORTSTR (entry
);
3198 optimized_assignment (entry
, value
, aflags
);
3200 if (mark_modified_vars
)
3201 VSETATTR (entry
, att_exported
);
3203 if (exported_p (entry
))
3204 array_needs_making
= 1;
3209 #if defined (ARRAY_VARS)
3210 if (assoc_p (entry
) || array_p (entry
))
3211 newval
= make_array_variable_value (entry
, 0, "0", value
, aflags
);
3214 newval
= make_variable_value (entry
, value
, aflags
); /* XXX */
3216 /* Invalidate any cached export string */
3217 INVALIDATE_EXPORTSTR (entry
);
3219 #if defined (ARRAY_VARS)
3220 /* XXX -- this bears looking at again -- XXX */
3221 /* If an existing array variable x is being assigned to with x=b or
3222 `read x' or something of that nature, silently convert it to
3223 x[0]=b or `read x[0]'. */
3224 if (assoc_p (entry
))
3226 assoc_insert (assoc_cell (entry
), savestring ("0"), newval
);
3229 else if (array_p (entry
))
3231 array_insert (array_cell (entry
), 0, newval
);
3237 FREE (value_cell (entry
));
3238 var_setvalue (entry
, newval
);
3242 if (mark_modified_vars
)
3243 VSETATTR (entry
, att_exported
);
3245 if (exported_p (entry
))
3246 array_needs_making
= 1;
3251 /* Bind a variable NAME to VALUE. This conses up the name
3252 and value strings. If we have a temporary environment, we bind there
3253 first, then we bind into shell_variables. */
3256 bind_variable (name
, value
, flags
)
3262 VAR_CONTEXT
*vc
, *nvc
;
3264 if (shell_variables
== 0)
3265 create_variable_tables ();
3267 /* If we have a temporary environment, look there first for the variable,
3268 and, if found, modify the value there before modifying it in the
3269 shell_variables table. This allows sourced scripts to modify values
3270 given to them in a temporary environment while modifying the variable
3271 value that the caller sees. */
3272 if (temporary_env
&& value
) /* XXX - can value be null here? */
3273 bind_tempenv_variable (name
, value
);
3275 /* XXX -- handle local variables here. */
3276 for (vc
= shell_variables
; vc
; vc
= vc
->down
)
3278 if (vc_isfuncenv (vc
) || vc_isbltnenv (vc
))
3280 v
= hash_lookup (name
, vc
->table
);
3282 if (v
&& nameref_p (v
))
3284 /* This starts at the context where we found the nameref. If we
3285 want to start the name resolution over again at the original
3286 context, this is where we need to change it */
3287 nv
= find_variable_nameref_context (v
, vc
, &nvc
);
3290 nv
= find_variable_last_nameref_context (v
, vc
, &nvc
);
3291 if (nv
&& nameref_p (nv
))
3293 /* If this nameref variable doesn't have a value yet,
3294 set the value. Otherwise, assign using the value as
3296 if (nameref_cell (nv
) == 0)
3297 return (bind_variable_internal (nv
->name
, value
, nvc
->table
, 0, flags
));
3298 #if defined (ARRAY_VARS)
3299 else if (valid_array_reference (nameref_cell (nv
), 0))
3300 return (assign_array_element (nameref_cell (nv
), value
, flags
, (array_eltstate_t
*)0));
3303 return (bind_variable_internal (nameref_cell (nv
), value
, nvc
->table
, 0, flags
));
3305 else if (nv
== &nameref_maxloop_value
)
3307 internal_warning (_("%s: circular name reference"), v
->name
);
3308 return (bind_global_variable (v
->name
, value
, flags
));
3313 else if (nv
== &nameref_maxloop_value
)
3315 internal_warning (_("%s: circular name reference"), v
->name
);
3316 return (bind_global_variable (v
->name
, value
, flags
));
3322 return (bind_variable_internal (v
->name
, value
, nvc
->table
, 0, flags
));
3325 /* bind_variable_internal will handle nameref resolution in this case */
3326 return (bind_variable_internal (name
, value
, global_variables
->table
, 0, flags
));
3330 bind_global_variable (name
, value
, flags
)
3335 if (shell_variables
== 0)
3336 create_variable_tables ();
3338 /* bind_variable_internal will handle nameref resolution in this case */
3339 return (bind_variable_internal (name
, value
, global_variables
->table
, 0, flags
));
3343 bind_invalid_envvar (name
, value
, flags
)
3348 if (invalid_env
== 0)
3349 invalid_env
= hash_create (64); /* XXX */
3350 return (bind_variable_internal (name
, value
, invalid_env
, HASH_NOSRCH
, flags
));
3353 /* Make VAR, a simple shell variable, have value VALUE. Once assigned a
3354 value, variables are no longer invisible. This is a duplicate of part
3355 of the internals of bind_variable. If the variable is exported, or
3356 all modified variables should be exported, mark the variable for export
3357 and note that the export environment needs to be recreated. */
3359 bind_variable_value (var
, value
, aflags
)
3367 invis
= invisible_p (var
);
3368 VUNSETATTR (var
, att_invisible
);
3370 if (var
->assign_func
)
3372 /* If we're appending, we need the old value, so use
3373 make_variable_value */
3374 t
= (aflags
& ASS_APPEND
) ? make_variable_value (var
, value
, aflags
) : value
;
3375 (*(var
->assign_func
)) (var
, t
, -1, 0);
3376 if (t
!= value
&& t
)
3381 t
= make_variable_value (var
, value
, aflags
);
3382 if ((aflags
& (ASS_NAMEREF
|ASS_FORCE
)) == ASS_NAMEREF
&& check_selfref (name_cell (var
), t
, 0))
3384 if (variable_context
)
3385 internal_warning (_("%s: circular name reference"), name_cell (var
));
3388 internal_error (_("%s: nameref variable self references not allowed"), name_cell (var
));
3391 VSETATTR (var
, att_invisible
); /* XXX */
3392 return ((SHELL_VAR
*)NULL
);
3395 if ((aflags
& ASS_NAMEREF
) && (valid_nameref_value (t
, 0) == 0))
3399 VSETATTR (var
, att_invisible
); /* XXX */
3400 return ((SHELL_VAR
*)NULL
);
3402 FREE (value_cell (var
));
3403 var_setvalue (var
, t
);
3406 INVALIDATE_EXPORTSTR (var
);
3408 if (mark_modified_vars
)
3409 VSETATTR (var
, att_exported
);
3411 if (exported_p (var
))
3412 array_needs_making
= 1;
3417 /* Bind/create a shell variable with the name LHS to the RHS.
3418 This creates or modifies a variable such that it is an integer.
3420 This used to be in expr.c, but it is here so that all of the
3421 variable binding stuff is localized. Since we don't want any
3422 recursive evaluation from bind_variable() (possible without this code,
3423 since bind_variable() calls the evaluator for variables with the integer
3424 attribute set), we temporarily turn off the integer attribute for each
3425 variable we set here, then turn it back on after binding as necessary. */
3428 bind_int_variable (lhs
, rhs
, flags
)
3432 register SHELL_VAR
*v
;
3433 int isint
, isarr
, implicitarray
, vflags
, avflags
;
3435 isint
= isarr
= implicitarray
= 0;
3436 #if defined (ARRAY_VARS)
3437 /* Don't rely on VA_NOEXPAND being 1, set it explicitly */
3438 vflags
= (flags
& ASS_NOEXPAND
) ? VA_NOEXPAND
: 0;
3439 if (flags
& ASS_ONEWORD
)
3440 vflags
|= VA_ONEWORD
;
3441 if (valid_array_reference (lhs
, vflags
))
3445 /* Common code to translate between assignment and reference flags. */
3446 if (flags
& ASS_NOEXPAND
)
3447 avflags
|= AV_NOEXPAND
;
3448 if (flags
& ASS_ONEWORD
)
3449 avflags
|= AV_ONEWORD
;
3450 v
= array_variable_part (lhs
, avflags
, (char **)0, (int *)0);
3452 else if (legal_identifier (lhs
) == 0)
3455 return ((SHELL_VAR
*)NULL
);
3459 v
= find_variable (lhs
);
3463 isint
= integer_p (v
);
3464 VUNSETATTR (v
, att_integer
);
3465 #if defined (ARRAY_VARS)
3466 if (array_p (v
) && isarr
== 0)
3471 #if defined (ARRAY_VARS)
3473 v
= assign_array_element (lhs
, rhs
, flags
, (array_eltstate_t
*)0);
3474 else if (implicitarray
)
3475 v
= bind_array_variable (lhs
, 0, rhs
, 0); /* XXX - check on flags */
3478 v
= bind_variable (lhs
, rhs
, 0); /* why not use bind_variable_value? */
3483 VSETATTR (v
, att_integer
);
3484 VUNSETATTR (v
, att_invisible
);
3487 if (v
&& nameref_p (v
))
3488 internal_warning (_("%s: assigning integer to name reference"), lhs
);
3494 bind_var_to_int (var
, val
, flags
)
3499 char ibuf
[INT_STRLEN_BOUND (intmax_t) + 1], *p
;
3501 p
= fmtulong (val
, 10, ibuf
, sizeof (ibuf
), 0);
3502 return (bind_int_variable (var
, p
, flags
));
3505 /* Do a function binding to a variable. You pass the name and
3506 the command to bind to. This conses the name and command. */
3508 bind_function (name
, value
)
3514 entry
= find_function (name
);
3517 BUCKET_CONTENTS
*elt
;
3519 elt
= hash_insert (savestring (name
), shell_functions
, HASH_NOSRCH
);
3520 entry
= new_shell_variable (name
);
3521 elt
->data
= (PTR_T
)entry
;
3524 INVALIDATE_EXPORTSTR (entry
);
3526 if (var_isset (entry
))
3527 dispose_command (function_cell (entry
));
3530 var_setfunc (entry
, copy_command (value
));
3532 var_setfunc (entry
, 0);
3534 VSETATTR (entry
, att_function
);
3536 if (mark_modified_vars
)
3537 VSETATTR (entry
, att_exported
);
3539 VUNSETATTR (entry
, att_invisible
); /* Just to be sure */
3541 if (exported_p (entry
))
3542 array_needs_making
= 1;
3544 #if defined (PROGRAMMABLE_COMPLETION)
3545 set_itemlist_dirty (&it_functions
);
3551 #if defined (DEBUGGER)
3552 /* Bind a function definition, which includes source file and line number
3553 information in addition to the command, into the FUNCTION_DEF hash table.
3554 If (FLAGS & 1), overwrite any existing definition. If FLAGS == 0, leave
3555 any existing definition alone. */
3557 bind_function_def (name
, value
, flags
)
3559 FUNCTION_DEF
*value
;
3562 FUNCTION_DEF
*entry
;
3563 BUCKET_CONTENTS
*elt
;
3566 entry
= find_function_def (name
);
3567 if (entry
&& (flags
& 1))
3569 dispose_function_def_contents (entry
);
3570 entry
= copy_function_def_contents (value
, entry
);
3576 cmd
= value
->command
;
3578 entry
= copy_function_def (value
);
3579 value
->command
= cmd
;
3581 elt
= hash_insert (savestring (name
), shell_function_defs
, HASH_NOSRCH
);
3582 elt
->data
= (PTR_T
*)entry
;
3585 #endif /* DEBUGGER */
3587 /* Add STRING, which is of the form foo=bar, to the temporary environment
3588 HASH_TABLE (temporary_env). The functions in execute_cmd.c are
3589 responsible for moving the main temporary env to one of the other
3590 temporary environments. The expansion code in subst.c calls this. */
3592 assign_in_env (word
, flags
)
3597 char *name
, *temp
, *value
, *newname
;
3601 string
= word
->word
;
3604 offset
= assignment (string
, 0);
3605 newname
= name
= savestring (string
);
3606 value
= (char *)NULL
;
3608 if (name
[offset
] == '=')
3612 /* don't ignore the `+' when assigning temporary environment */
3613 if (name
[offset
- 1] == '+')
3615 name
[offset
- 1] = '\0';
3616 aflags
|= ASS_APPEND
;
3619 if (legal_identifier (name
) == 0)
3621 sh_invalidid (name
);
3626 var
= find_variable (name
);
3629 var
= find_variable_last_nameref (name
, 1);
3630 /* If we're assigning a value to a nameref variable in the temp
3631 environment, and the value of the nameref is valid for assignment,
3632 but the variable does not already exist, assign to the nameref
3633 target and add the target to the temporary environment. This is
3635 /* We use 2 in the call to valid_nameref_value because we don't want
3636 to allow array references here at all (newname will be used to
3637 create a variable directly below) */
3638 if (var
&& nameref_p (var
) && valid_nameref_value (nameref_cell (var
), 2))
3640 newname
= nameref_cell (var
);
3641 var
= 0; /* don't use it for append */
3645 newname
= name_cell (var
); /* no-op if not nameref */
3647 if (var
&& (readonly_p (var
) || noassign_p (var
)))
3649 if (readonly_p (var
))
3650 err_readonly (name
);
3654 temp
= name
+ offset
+ 1;
3656 value
= expand_assignment_string_to_string (temp
, 0);
3658 if (var
&& (aflags
& ASS_APPEND
))
3662 value
= (char *)xmalloc (1); /* like do_assignment_internal */
3665 temp
= make_variable_value (var
, value
, aflags
);
3671 if (temporary_env
== 0)
3672 temporary_env
= hash_create (TEMPENV_HASH_BUCKETS
);
3674 var
= hash_lookup (newname
, temporary_env
);
3676 var
= make_new_variable (newname
, temporary_env
);
3678 FREE (value_cell (var
));
3682 value
= (char *)xmalloc (1); /* see above */
3686 var_setvalue (var
, value
);
3687 var
->attributes
|= (att_exported
|att_tempvar
);
3688 var
->context
= variable_context
; /* XXX */
3690 INVALIDATE_EXPORTSTR (var
);
3691 var
->exportstr
= mk_env_string (newname
, value
, 0);
3693 array_needs_making
= 1;
3697 if (STREQ (newname
, "POSIXLY_CORRECT") || STREQ (newname
, "POSIX_PEDANDTIC"))
3698 save_posix_options (); /* XXX one level of saving right now */
3699 stupidly_hack_special_variables (newname
);
3702 if (echo_command_at_execute
)
3703 /* The Korn shell prints the `+ ' in front of assignment statements,
3705 xtrace_print_assignment (name
, value
, 0, 1);
3711 /* **************************************************************** */
3713 /* Copying variables */
3715 /* **************************************************************** */
3717 #ifdef INCLUDE_UNUSED
3718 /* Copy VAR to a new data structure and return that structure. */
3723 SHELL_VAR
*copy
= (SHELL_VAR
*)NULL
;
3727 copy
= (SHELL_VAR
*)xmalloc (sizeof (SHELL_VAR
));
3729 copy
->attributes
= var
->attributes
;
3730 copy
->name
= savestring (var
->name
);
3732 if (function_p (var
))
3733 var_setfunc (copy
, copy_command (function_cell (var
)));
3734 #if defined (ARRAY_VARS)
3735 else if (array_p (var
))
3736 var_setarray (copy
, array_copy (array_cell (var
)));
3737 else if (assoc_p (var
))
3738 var_setassoc (copy
, assoc_copy (assoc_cell (var
)));
3740 else if (nameref_cell (var
)) /* XXX - nameref */
3741 var_setref (copy
, savestring (nameref_cell (var
)));
3742 else if (value_cell (var
)) /* XXX - nameref */
3743 var_setvalue (copy
, savestring (value_cell (var
)));
3745 var_setvalue (copy
, (char *)NULL
);
3747 copy
->dynamic_value
= var
->dynamic_value
;
3748 copy
->assign_func
= var
->assign_func
;
3750 copy
->exportstr
= COPY_EXPORTSTR (var
);
3752 copy
->context
= var
->context
;
3758 /* **************************************************************** */
3760 /* Deleting and unsetting variables */
3762 /* **************************************************************** */
3764 /* Dispose of the information attached to VAR. */
3766 dispose_variable_value (var
)
3769 if (function_p (var
))
3770 dispose_command (function_cell (var
));
3771 #if defined (ARRAY_VARS)
3772 else if (array_p (var
))
3773 array_dispose (array_cell (var
));
3774 else if (assoc_p (var
))
3775 assoc_dispose (assoc_cell (var
));
3777 else if (nameref_p (var
))
3778 FREE (nameref_cell (var
));
3780 FREE (value_cell (var
));
3784 dispose_variable (var
)
3790 if (nofree_p (var
) == 0)
3791 dispose_variable_value (var
);
3793 FREE_EXPORTSTR (var
);
3797 if (exported_p (var
))
3798 array_needs_making
= 1;
3803 /* Unset the shell variable referenced by NAME. Unsetting a nameref variable
3804 unsets the variable it resolves to but leaves the nameref alone. */
3806 unbind_variable (name
)
3812 v
= var_lookup (name
, shell_variables
);
3813 nv
= (v
&& nameref_p (v
)) ? find_variable_nameref (v
) : (SHELL_VAR
*)NULL
;
3815 r
= nv
? makunbound (nv
->name
, shell_variables
) : makunbound (name
, shell_variables
);
3819 /* Unbind NAME, where NAME is assumed to be a nameref variable */
3821 unbind_nameref (name
)
3826 v
= var_lookup (name
, shell_variables
);
3827 if (v
&& nameref_p (v
))
3828 return makunbound (name
, shell_variables
);
3832 /* Unbind the first instance of NAME, whether it's a nameref or not */
3834 unbind_variable_noref (name
)
3839 v
= var_lookup (name
, shell_variables
);
3841 return makunbound (name
, shell_variables
);
3846 unbind_global_variable (name
)
3852 v
= var_lookup (name
, global_variables
);
3853 /* This starts at the current scope, just like find_global_variable; should we
3854 use find_global_variable_nameref here? */
3855 nv
= (v
&& nameref_p (v
)) ? find_variable_nameref (v
) : (SHELL_VAR
*)NULL
;
3857 r
= nv
? makunbound (nv
->name
, shell_variables
) : makunbound (name
, global_variables
);
3862 unbind_global_variable_noref (name
)
3867 v
= var_lookup (name
, global_variables
);
3869 return makunbound (name
, global_variables
);
3874 check_unbind_variable (name
)
3879 v
= find_variable (name
);
3880 if (v
&& readonly_p (v
))
3882 internal_error (_("%s: cannot unset: readonly %s"), name
, "variable");
3885 else if (v
&& non_unsettable_p (v
))
3887 internal_error (_("%s: cannot unset"), name
);
3890 return (unbind_variable (name
));
3893 /* Unset the shell function named NAME. */
3898 BUCKET_CONTENTS
*elt
;
3901 elt
= hash_remove (name
, shell_functions
, 0);
3906 #if defined (PROGRAMMABLE_COMPLETION)
3907 set_itemlist_dirty (&it_functions
);
3910 func
= (SHELL_VAR
*)elt
->data
;
3913 if (exported_p (func
))
3914 array_needs_making
++;
3915 dispose_variable (func
);
3924 #if defined (DEBUGGER)
3926 unbind_function_def (name
)
3929 BUCKET_CONTENTS
*elt
;
3930 FUNCTION_DEF
*funcdef
;
3932 elt
= hash_remove (name
, shell_function_defs
, 0);
3937 funcdef
= (FUNCTION_DEF
*)elt
->data
;
3939 dispose_function_def (funcdef
);
3946 #endif /* DEBUGGER */
3949 delete_var (name
, vc
)
3953 BUCKET_CONTENTS
*elt
;
3957 for (elt
= (BUCKET_CONTENTS
*)NULL
, v
= vc
; v
; v
= v
->down
)
3958 if (elt
= hash_remove (name
, v
->table
, 0))
3964 old_var
= (SHELL_VAR
*)elt
->data
;
3968 dispose_variable (old_var
);
3972 /* Make the variable associated with NAME go away. HASH_LIST is the
3973 hash table from which this variable should be deleted (either
3974 shell_variables or shell_functions).
3975 Returns non-zero if the variable couldn't be found. */
3977 makunbound (name
, vc
)
3981 BUCKET_CONTENTS
*elt
, *new_elt
;
3986 for (elt
= (BUCKET_CONTENTS
*)NULL
, v
= vc
; v
; v
= v
->down
)
3987 if (elt
= hash_remove (name
, v
->table
, 0))
3993 old_var
= (SHELL_VAR
*)elt
->data
;
3995 if (old_var
&& exported_p (old_var
))
3996 array_needs_making
++;
3998 /* If we're unsetting a local variable and we're still executing inside
3999 the function, just mark the variable as invisible. The function
4000 eventually called by pop_var_context() will clean it up later. This
4001 must be done so that if the variable is subsequently assigned a new
4002 value inside the function, the `local' attribute is still present.
4003 We also need to add it back into the correct hash table. */
4004 if (old_var
&& local_p (old_var
) &&
4005 (old_var
->context
== variable_context
|| (localvar_unset
&& old_var
->context
< variable_context
)))
4007 if (nofree_p (old_var
))
4008 var_setvalue (old_var
, (char *)NULL
);
4009 #if defined (ARRAY_VARS)
4010 else if (array_p (old_var
))
4011 array_dispose (array_cell (old_var
));
4012 else if (assoc_p (old_var
))
4013 assoc_dispose (assoc_cell (old_var
));
4015 else if (nameref_p (old_var
))
4016 FREE (nameref_cell (old_var
));
4018 FREE (value_cell (old_var
));
4019 /* Reset the attributes. Preserve the export attribute if the variable
4020 came from a temporary environment. Make sure it stays local, and
4021 make it invisible. */
4022 old_var
->attributes
= (exported_p (old_var
) && tempvar_p (old_var
)) ? att_exported
: 0;
4023 VSETATTR (old_var
, att_local
);
4024 VSETATTR (old_var
, att_invisible
);
4025 var_setvalue (old_var
, (char *)NULL
);
4026 INVALIDATE_EXPORTSTR (old_var
);
4028 new_elt
= hash_insert (savestring (old_var
->name
), v
->table
, 0);
4029 new_elt
->data
= (PTR_T
)old_var
;
4030 stupidly_hack_special_variables (old_var
->name
);
4037 /* Have to save a copy of name here, because it might refer to
4038 old_var->name. If so, stupidly_hack_special_variables will
4039 reference freed memory. */
4040 t
= savestring (name
);
4045 dispose_variable (old_var
);
4046 stupidly_hack_special_variables (t
);
4052 /* Get rid of all of the variables in the current context. */
4054 kill_all_local_variables ()
4058 for (vc
= shell_variables
; vc
; vc
= vc
->down
)
4059 if (vc_isfuncenv (vc
) && vc
->scope
== variable_context
)
4064 if (vc
->table
&& vc_haslocals (vc
))
4066 delete_all_variables (vc
->table
);
4067 hash_dispose (vc
->table
);
4069 vc
->table
= (HASH_TABLE
*)NULL
;
4073 free_variable_hash_data (data
)
4078 var
= (SHELL_VAR
*)data
;
4079 dispose_variable (var
);
4082 /* Delete the entire contents of the hash table. */
4084 delete_all_variables (hashed_vars
)
4085 HASH_TABLE
*hashed_vars
;
4087 hash_flush (hashed_vars
, free_variable_hash_data
);
4090 /* **************************************************************** */
4092 /* Setting variable attributes */
4094 /* **************************************************************** */
4096 #define FIND_OR_MAKE_VARIABLE(name, entry) \
4099 entry = find_variable (name); \
4102 entry = bind_variable (name, "", 0); \
4103 if (entry) entry->attributes |= att_invisible; \
4108 /* Make the variable associated with NAME be readonly.
4109 If NAME does not exist yet, create it. */
4111 set_var_read_only (name
)
4116 FIND_OR_MAKE_VARIABLE (name
, entry
);
4117 VSETATTR (entry
, att_readonly
);
4120 #ifdef INCLUDE_UNUSED
4121 /* Make the function associated with NAME be readonly.
4122 If NAME does not exist, we just punt, like auto_export code below. */
4124 set_func_read_only (name
)
4129 entry
= find_function (name
);
4131 VSETATTR (entry
, att_readonly
);
4134 /* Make the variable associated with NAME be auto-exported.
4135 If NAME does not exist yet, create it. */
4137 set_var_auto_export (name
)
4142 FIND_OR_MAKE_VARIABLE (name
, entry
);
4143 set_auto_export (entry
);
4146 /* Make the function associated with NAME be auto-exported. */
4148 set_func_auto_export (name
)
4153 entry
= find_function (name
);
4155 set_auto_export (entry
);
4159 /* **************************************************************** */
4161 /* Creating lists of variables */
4163 /* **************************************************************** */
4166 vlist_alloc (nentries
)
4171 vlist
= (VARLIST
*)xmalloc (sizeof (VARLIST
));
4172 vlist
->list
= (SHELL_VAR
**)xmalloc ((nentries
+ 1) * sizeof (SHELL_VAR
*));
4173 vlist
->list_size
= nentries
;
4174 vlist
->list_len
= 0;
4175 vlist
->list
[0] = (SHELL_VAR
*)NULL
;
4181 vlist_realloc (vlist
, n
)
4186 return (vlist
= vlist_alloc (n
));
4187 if (n
> vlist
->list_size
)
4189 vlist
->list_size
= n
;
4190 vlist
->list
= (SHELL_VAR
**)xrealloc (vlist
->list
, (vlist
->list_size
+ 1) * sizeof (SHELL_VAR
*));
4196 vlist_add (vlist
, var
, flags
)
4203 for (i
= 0; i
< vlist
->list_len
; i
++)
4204 if (STREQ (var
->name
, vlist
->list
[i
]->name
))
4206 if (i
< vlist
->list_len
)
4209 if (i
>= vlist
->list_size
)
4210 vlist
= vlist_realloc (vlist
, vlist
->list_size
+ 16);
4212 vlist
->list
[vlist
->list_len
++] = var
;
4213 vlist
->list
[vlist
->list_len
] = (SHELL_VAR
*)NULL
;
4216 /* Map FUNCTION over the variables in VAR_HASH_TABLE. Return an array of the
4217 variables for which FUNCTION returns a non-zero value. A NULL value
4218 for FUNCTION means to use all variables. */
4220 map_over (function
, vc
)
4221 sh_var_map_func_t
*function
;
4229 for (nentries
= 0, v
= vc
; v
; v
= v
->down
)
4230 nentries
+= HASH_ENTRIES (v
->table
);
4233 return (SHELL_VAR
**)NULL
;
4235 vlist
= vlist_alloc (nentries
);
4237 for (v
= vc
; v
; v
= v
->down
)
4238 flatten (v
->table
, function
, vlist
, 0);
4246 map_over_funcs (function
)
4247 sh_var_map_func_t
*function
;
4252 if (shell_functions
== 0 || HASH_ENTRIES (shell_functions
) == 0)
4253 return ((SHELL_VAR
**)NULL
);
4255 vlist
= vlist_alloc (HASH_ENTRIES (shell_functions
));
4257 flatten (shell_functions
, function
, vlist
, 0);
4264 /* Flatten VAR_HASH_TABLE, applying FUNC to each member and adding those
4265 elements for which FUNC succeeds to VLIST->list. FLAGS is reserved
4266 for future use. Only unique names are added to VLIST. If FUNC is
4267 NULL, each variable in VAR_HASH_TABLE is added to VLIST. If VLIST is
4268 NULL, FUNC is applied to each SHELL_VAR in VAR_HASH_TABLE. If VLIST
4269 and FUNC are both NULL, nothing happens. */
4271 flatten (var_hash_table
, func
, vlist
, flags
)
4272 HASH_TABLE
*var_hash_table
;
4273 sh_var_map_func_t
*func
;
4278 register BUCKET_CONTENTS
*tlist
;
4282 if (var_hash_table
== 0 || (HASH_ENTRIES (var_hash_table
) == 0) || (vlist
== 0 && func
== 0))
4285 for (i
= 0; i
< var_hash_table
->nbuckets
; i
++)
4287 for (tlist
= hash_items (i
, var_hash_table
); tlist
; tlist
= tlist
->next
)
4289 var
= (SHELL_VAR
*)tlist
->data
;
4291 r
= func
? (*func
) (var
) : 1;
4293 vlist_add (vlist
, var
, flags
);
4299 sort_variables (array
)
4302 qsort (array
, strvec_len ((char **)array
), sizeof (SHELL_VAR
*), (QSFUNC
*)qsort_var_comp
);
4306 qsort_var_comp (var1
, var2
)
4307 SHELL_VAR
**var1
, **var2
;
4311 if ((result
= (*var1
)->name
[0] - (*var2
)->name
[0]) == 0)
4312 result
= strcmp ((*var1
)->name
, (*var2
)->name
);
4317 /* Apply FUNC to each variable in SHELL_VARIABLES, adding each one for
4318 which FUNC succeeds to an array of SHELL_VAR *s. Returns the array. */
4321 sh_var_map_func_t
*func
;
4325 list
= map_over (func
, shell_variables
);
4326 if (list
/* && posixly_correct */)
4327 sort_variables (list
);
4331 /* Apply FUNC to each variable in SHELL_FUNCTIONS, adding each one for
4332 which FUNC succeeds to an array of SHELL_VAR *s. Returns the array. */
4335 sh_var_map_func_t
*func
;
4339 list
= map_over_funcs (func
);
4340 if (list
/* && posixly_correct */)
4341 sort_variables (list
);
4345 /* Create a NULL terminated array of all the shell variables. */
4347 all_shell_variables ()
4349 return (vapply ((sh_var_map_func_t
*)NULL
));
4352 /* Create a NULL terminated array of all the shell functions. */
4354 all_shell_functions ()
4356 return (fapply ((sh_var_map_func_t
*)NULL
));
4363 return (invisible_p (var
) == 0);
4367 all_visible_functions ()
4369 return (fapply (visible_var
));
4373 all_visible_variables ()
4375 return (vapply (visible_var
));
4378 /* Return non-zero if the variable VAR is visible and exported. Array
4379 variables cannot be exported. */
4381 visible_and_exported (var
)
4384 return (invisible_p (var
) == 0 && exported_p (var
));
4387 /* Candidate variables for the export environment are either valid variables
4388 with the export attribute or invalid variables inherited from the initial
4389 environment and simply passed through. */
4391 export_environment_candidate (var
)
4394 return (exported_p (var
) && (invisible_p (var
) == 0 || imported_p (var
)));
4397 /* Return non-zero if VAR is a local variable in the current context and
4400 local_and_exported (var
)
4403 return (invisible_p (var
) == 0 && local_p (var
) && var
->context
== variable_context
&& exported_p (var
));
4407 all_exported_variables ()
4409 return (vapply (visible_and_exported
));
4413 local_exported_variables ()
4415 return (vapply (local_and_exported
));
4419 variable_in_context (var
)
4422 return (local_p (var
) && var
->context
== variable_context
);
4426 visible_variable_in_context (var
)
4429 return (invisible_p (var
) == 0 && local_p (var
) && var
->context
== variable_context
);
4433 all_local_variables (visible_only
)
4440 vc
= shell_variables
;
4441 for (vc
= shell_variables
; vc
; vc
= vc
->down
)
4442 if (vc_isfuncenv (vc
) && vc
->scope
== variable_context
)
4447 internal_error (_("all_local_variables: no function context at current scope"));
4448 return (SHELL_VAR
**)NULL
;
4450 if (vc
->table
== 0 || HASH_ENTRIES (vc
->table
) == 0 || vc_haslocals (vc
) == 0)
4451 return (SHELL_VAR
**)NULL
;
4453 vlist
= vlist_alloc (HASH_ENTRIES (vc
->table
));
4456 flatten (vc
->table
, visible_variable_in_context
, vlist
, 0);
4458 flatten (vc
->table
, variable_in_context
, vlist
, 0);
4463 sort_variables (ret
);
4467 #if defined (ARRAY_VARS)
4468 /* Return non-zero if the variable VAR is visible and an array. */
4470 visible_array_vars (var
)
4473 return (invisible_p (var
) == 0 && (array_p (var
) || assoc_p (var
)));
4477 all_array_variables ()
4479 return (vapply (visible_array_vars
));
4481 #endif /* ARRAY_VARS */
4484 all_variables_matching_prefix (prefix
)
4487 SHELL_VAR
**varlist
;
4489 int vind
, rind
, plen
;
4491 plen
= STRLEN (prefix
);
4492 varlist
= all_visible_variables ();
4493 for (vind
= 0; varlist
&& varlist
[vind
]; vind
++)
4495 if (varlist
== 0 || vind
== 0)
4496 return ((char **)NULL
);
4497 rlist
= strvec_create (vind
+ 1);
4498 for (vind
= rind
= 0; varlist
[vind
]; vind
++)
4500 if (plen
== 0 || STREQN (prefix
, varlist
[vind
]->name
, plen
))
4501 rlist
[rind
++] = savestring (varlist
[vind
]->name
);
4503 rlist
[rind
] = (char *)0;
4509 /* **************************************************************** */
4511 /* Managing temporary variable scopes */
4513 /* **************************************************************** */
4515 /* Make variable NAME have VALUE in the temporary environment. */
4517 bind_tempenv_variable (name
, value
)
4523 var
= temporary_env
? hash_lookup (name
, temporary_env
) : (SHELL_VAR
*)NULL
;
4527 FREE (value_cell (var
));
4528 var_setvalue (var
, savestring (value
));
4529 INVALIDATE_EXPORTSTR (var
);
4535 /* Find a variable in the temporary environment that is named NAME.
4536 Return the SHELL_VAR *, or NULL if not found. */
4538 find_tempenv_variable (name
)
4541 return (temporary_env
? hash_lookup (name
, temporary_env
) : (SHELL_VAR
*)NULL
);
4544 char **tempvar_list
;
4547 /* Take a variable from an assignment statement preceding a posix special
4548 builtin (including `return') and create a global variable from it. This
4549 is called from merge_temporary_env, which is only called when in posix
4552 push_posix_temp_var (data
)
4556 HASH_TABLE
*binding_table
;
4558 var
= (SHELL_VAR
*)data
;
4560 /* Just like do_assignment_internal(). This makes assignments preceding
4561 special builtins act like standalone assignment statements when in
4562 posix mode, satisfying the posix requirement that this affect the
4563 "current execution environment." */
4564 v
= bind_variable (var
->name
, value_cell (var
), ASS_FORCE
|ASS_NOLONGJMP
);
4566 /* XXX - do we need to worry about array variables here? */
4568 /* If this modifies an existing local variable, v->context will be non-zero.
4569 If it comes back with v->context == 0, we bound at the global context.
4570 Set binding_table appropriately. It doesn't matter whether it's correct
4571 if the variable is local, only that it's not global_variables->table */
4572 binding_table
= v
->context
? shell_variables
->table
: global_variables
->table
;
4574 /* global variables are no longer temporary and don't need propagating. */
4575 if (v
->context
== 0)
4576 var
->attributes
&= ~(att_tempvar
|att_propagate
);
4580 v
->attributes
|= var
->attributes
; /* preserve tempvar attribute if appropriate */
4581 /* If we don't bind a local variable, propagate the value. If we bind a
4582 local variable (the "current execution environment"), keep it as local
4583 and don't propagate it to the calling environment. */
4584 if (v
->context
> 0 && local_p (v
) == 0)
4585 v
->attributes
|= att_propagate
;
4587 v
->attributes
&= ~att_propagate
;
4590 if (find_special_var (var
->name
) >= 0)
4591 tempvar_list
[tvlist_ind
++] = savestring (var
->name
);
4593 dispose_variable (var
);
4596 /* Push the variable described by (SHELL_VAR *)DATA down to the next
4597 variable context from the temporary environment. This can be called
4599 1. propagate_temp_var: which is called to propagate variables in
4600 assignments like `var=value declare -x var' to the surrounding
4603 In this case, the variable should have the att_propagate flag set and
4604 we can create variables in the current scope.
4607 push_temp_var (data
)
4611 HASH_TABLE
*binding_table
;
4613 var
= (SHELL_VAR
*)data
;
4615 binding_table
= shell_variables
->table
;
4616 if (binding_table
== 0)
4618 if (shell_variables
== global_variables
)
4619 /* shouldn't happen */
4620 binding_table
= shell_variables
->table
= global_variables
->table
= hash_create (VARIABLES_HASH_BUCKETS
);
4622 binding_table
= shell_variables
->table
= hash_create (TEMPENV_HASH_BUCKETS
);
4625 v
= bind_variable_internal (var
->name
, value_cell (var
), binding_table
, 0, ASS_FORCE
|ASS_NOLONGJMP
);
4627 /* XXX - should we set the context here? It shouldn't matter because of how
4628 assign_in_env works, but we do it anyway. */
4630 v
->context
= shell_variables
->scope
;
4632 if (binding_table
== global_variables
->table
) /* XXX */
4633 var
->attributes
&= ~(att_tempvar
|att_propagate
);
4636 var
->attributes
|= att_propagate
; /* XXX - propagate more than once? */
4637 if (binding_table
== shell_variables
->table
)
4638 shell_variables
->flags
|= VC_HASTMPVAR
;
4641 v
->attributes
|= var
->attributes
;
4643 if (find_special_var (var
->name
) >= 0)
4644 tempvar_list
[tvlist_ind
++] = savestring (var
->name
);
4646 dispose_variable (var
);
4649 /* Take a variable described by DATA and push it to the surrounding scope if
4650 the PROPAGATE attribute is set. That gets set by push_temp_var if we are
4651 taking a variable like `var=value declare -x var' and propagating it to
4652 the enclosing scope. */
4654 propagate_temp_var (data
)
4659 var
= (SHELL_VAR
*)data
;
4660 if (tempvar_p (var
) && (var
->attributes
& att_propagate
))
4661 push_temp_var (data
);
4664 if (find_special_var (var
->name
) >= 0)
4665 tempvar_list
[tvlist_ind
++] = savestring (var
->name
);
4666 dispose_variable (var
);
4670 /* Free the storage used in the hash table for temporary
4671 environment variables. PUSHF is a function to be called
4672 to free each hash table entry. It takes care of pushing variables
4673 to previous scopes if appropriate. PUSHF stores names of variables
4674 that require special handling (e.g., IFS) on tempvar_list, so this
4675 function can call stupidly_hack_special_variables on all the
4676 variables in the list when the temporary hash table is destroyed. */
4678 dispose_temporary_env (pushf
)
4679 sh_free_func_t
*pushf
;
4682 HASH_TABLE
*disposer
;
4684 tempvar_list
= strvec_create (HASH_ENTRIES (temporary_env
) + 1);
4685 tempvar_list
[tvlist_ind
= 0] = 0;
4687 disposer
= temporary_env
;
4688 temporary_env
= (HASH_TABLE
*)NULL
;
4690 hash_flush (disposer
, pushf
);
4691 hash_dispose (disposer
);
4693 tempvar_list
[tvlist_ind
] = 0;
4695 array_needs_making
= 1;
4697 for (i
= 0; i
< tvlist_ind
; i
++)
4698 stupidly_hack_special_variables (tempvar_list
[i
]);
4700 strvec_dispose (tempvar_list
);
4706 dispose_used_env_vars ()
4710 dispose_temporary_env (propagate_temp_var
);
4711 maybe_make_export_env ();
4715 /* Take all of the shell variables in the temporary environment HASH_TABLE
4716 and make shell variables from them at the current variable context.
4717 Right now, this is only called in Posix mode to implement the historical
4718 accident of creating global variables from assignment statements preceding
4719 special builtins, but we check in case this acquires another caller later. */
4721 merge_temporary_env ()
4724 dispose_temporary_env (posixly_correct
? push_posix_temp_var
: push_temp_var
);
4727 /* Temporary function to use if we want to separate function and special
4728 builtin behavior. */
4730 merge_function_temporary_env ()
4733 dispose_temporary_env (push_temp_var
);
4737 flush_temporary_env ()
4741 hash_flush (temporary_env
, free_variable_hash_data
);
4742 hash_dispose (temporary_env
);
4743 temporary_env
= (HASH_TABLE
*)NULL
;
4747 /* **************************************************************** */
4749 /* Creating and manipulating the environment */
4751 /* **************************************************************** */
4753 static inline char *
4754 mk_env_string (name
, value
, attributes
)
4755 const char *name
, *value
;
4758 size_t name_len
, value_len
;
4760 int isfunc
, isarray
;
4762 name_len
= strlen (name
);
4763 value_len
= STRLEN (value
);
4765 isfunc
= attributes
& att_function
;
4766 #if defined (ARRAY_VARS) && defined (ARRAY_EXPORT)
4767 isarray
= attributes
& (att_array
|att_assoc
);
4770 /* If we are exporting a shell function, construct the encoded function
4772 if (isfunc
&& value
)
4774 p
= (char *)xmalloc (BASHFUNC_PREFLEN
+ name_len
+ BASHFUNC_SUFFLEN
+ value_len
+ 2);
4776 memcpy (q
, BASHFUNC_PREFIX
, BASHFUNC_PREFLEN
);
4777 q
+= BASHFUNC_PREFLEN
;
4778 memcpy (q
, name
, name_len
);
4780 memcpy (q
, BASHFUNC_SUFFIX
, BASHFUNC_SUFFLEN
);
4781 q
+= BASHFUNC_SUFFLEN
;
4783 #if defined (ARRAY_VARS) && defined (ARRAY_EXPORT)
4784 else if (isarray
&& value
)
4786 if (attributes
& att_assoc
)
4787 p
= (char *)xmalloc (BASHASSOC_PREFLEN
+ name_len
+ BASHASSOC_SUFFLEN
+ value_len
+ 2);
4789 p
= (char *)xmalloc (BASHARRAY_PREFLEN
+ name_len
+ BASHARRAY_SUFFLEN
+ value_len
+ 2);
4791 if (attributes
& att_assoc
)
4793 memcpy (q
, BASHASSOC_PREFIX
, BASHASSOC_PREFLEN
);
4794 q
+= BASHASSOC_PREFLEN
;
4798 memcpy (q
, BASHARRAY_PREFIX
, BASHARRAY_PREFLEN
);
4799 q
+= BASHARRAY_PREFLEN
;
4801 memcpy (q
, name
, name_len
);
4803 /* These are actually the same currently */
4804 if (attributes
& att_assoc
)
4806 memcpy (q
, BASHASSOC_SUFFIX
, BASHASSOC_SUFFLEN
);
4807 q
+= BASHARRAY_SUFFLEN
;
4811 memcpy (q
, BASHARRAY_SUFFIX
, BASHARRAY_SUFFLEN
);
4812 q
+= BASHARRAY_SUFFLEN
;
4818 p
= (char *)xmalloc (2 + name_len
+ value_len
);
4819 memcpy (p
, name
, name_len
);
4824 if (value
&& *value
)
4828 t
= dequote_escapes (value
);
4829 value_len
= STRLEN (t
);
4830 memcpy (q
+ 1, t
, value_len
+ 1);
4834 memcpy (q
+ 1, value
, value_len
+ 1);
4853 internal_error (_("%s has null exportstr"), v
->name
);
4856 if (legal_variable_starter ((unsigned char)*s
) == 0)
4858 internal_error (_("invalid character %d in exportstr for %s"), *s
, v
->name
);
4861 for (s
= v
->exportstr
+ 1; s
&& *s
; s
++)
4865 if (legal_variable_char ((unsigned char)*s
) == 0)
4867 internal_error (_("invalid character %d in exportstr for %s"), *s
, v
->name
);
4873 internal_error (_("no `=' in exportstr for %s"), v
->name
);
4880 #if defined (ARRAY_VARS)
4881 # define USE_EXPORTSTR (value == var->exportstr && array_p (var) == 0 && assoc_p (var) == 0)
4883 # define USE_EXPORTSTR (value == var->exportstr)
4887 make_env_array_from_var_list (vars
)
4890 register int i
, list_index
;
4891 register SHELL_VAR
*var
;
4892 char **list
, *value
;
4894 list
= strvec_create ((1 + strvec_len ((char **)vars
)));
4896 for (i
= 0, list_index
= 0; var
= vars
[i
]; i
++)
4898 #if defined (__CYGWIN__)
4899 /* We don't use the exportstr stuff on Cygwin at all. */
4900 INVALIDATE_EXPORTSTR (var
);
4903 /* If the value is generated dynamically, generate it here. */
4904 if (regen_p (var
) && var
->dynamic_value
)
4906 var
= (*(var
->dynamic_value
)) (var
);
4907 INVALIDATE_EXPORTSTR (var
);
4911 value
= var
->exportstr
;
4912 else if (function_p (var
))
4913 value
= named_function_string ((char *)NULL
, function_cell (var
), 0);
4914 #if defined (ARRAY_VARS)
4915 else if (array_p (var
))
4917 value
= array_to_assign (array_cell (var
), 0);
4919 continue; /* XXX array vars cannot yet be exported */
4920 # endif /* ARRAY_EXPORT */
4921 else if (assoc_p (var
))
4923 value
= assoc_to_assign (assoc_cell (var
), 0);
4925 continue; /* XXX associative array vars cannot yet be exported */
4926 # endif /* ARRAY_EXPORT */
4929 value
= value_cell (var
);
4933 /* Gee, I'd like to get away with not using savestring() if we're
4934 using the cached exportstr... */
4935 list
[list_index
] = USE_EXPORTSTR
? savestring (value
)
4936 : mk_env_string (var
->name
, value
, var
->attributes
);
4938 if (USE_EXPORTSTR
== 0)
4939 SAVE_EXPORTSTR (var
, list
[list_index
]);
4942 #undef USE_EXPORTSTR
4944 #if defined (ARRAY_VARS) && defined (ARRAY_EXPORT)
4945 if (array_p (var
) || assoc_p (var
))
4951 list
[list_index
] = (char *)NULL
;
4955 /* Make an array of assignment statements from the hash table
4956 HASHED_VARS which contains SHELL_VARs. Only visible, exported
4957 variables are eligible. */
4959 make_var_export_array (vcxt
)
4966 vars
= map_over (visible_and_exported
, vcxt
);
4968 vars
= map_over (export_environment_candidate
, vcxt
);
4972 return (char **)NULL
;
4974 list
= make_env_array_from_var_list (vars
);
4981 make_func_export_array ()
4986 vars
= map_over_funcs (visible_and_exported
);
4988 return (char **)NULL
;
4990 list
= make_env_array_from_var_list (vars
);
4996 /* Add ENVSTR to the end of the exported environment, EXPORT_ENV. */
4997 #define add_to_export_env(envstr,do_alloc) \
5000 if (export_env_index >= (export_env_size - 1)) \
5002 export_env_size += 16; \
5003 export_env = strvec_resize (export_env, export_env_size); \
5004 environ = export_env; \
5006 export_env[export_env_index++] = (do_alloc) ? savestring (envstr) : envstr; \
5007 export_env[export_env_index] = (char *)NULL; \
5010 /* Add ASSIGN to EXPORT_ENV, or supersede a previous assignment in the
5011 array with the same left-hand side. Return the new EXPORT_ENV. */
5013 add_or_supercede_exported_var (assign
, do_alloc
)
5020 equal_offset
= assignment (assign
, 0);
5021 if (equal_offset
== 0)
5022 return (export_env
);
5024 /* If this is a function, then only supersede the function definition.
5025 We do this by including the `=() {' in the comparison, like
5026 initialize_shell_variables does. */
5027 if (assign
[equal_offset
+ 1] == '(' &&
5028 strncmp (assign
+ equal_offset
+ 2, ") {", 3) == 0) /* } */
5031 for (i
= 0; i
< export_env_index
; i
++)
5033 if (STREQN (assign
, export_env
[i
], equal_offset
+ 1))
5035 free (export_env
[i
]);
5036 export_env
[i
] = do_alloc
? savestring (assign
) : assign
;
5037 return (export_env
);
5040 add_to_export_env (assign
, do_alloc
);
5041 return (export_env
);
5045 add_temp_array_to_env (temp_array
, do_alloc
, do_supercede
)
5047 int do_alloc
, do_supercede
;
5051 if (temp_array
== 0)
5054 for (i
= 0; temp_array
[i
]; i
++)
5057 export_env
= add_or_supercede_exported_var (temp_array
[i
], do_alloc
);
5059 add_to_export_env (temp_array
[i
], do_alloc
);
5065 /* Make the environment array for the command about to be executed, if the
5066 array needs making. Otherwise, do nothing. If a shell action could
5067 change the array that commands receive for their environment, then the
5068 code should `array_needs_making++'.
5070 The order to add to the array is:
5072 list of var contexts whose head is shell_variables
5075 This is the shell variable lookup order. We add only new variable
5076 names at each step, which allows local variables and variables in
5077 the temporary environments to shadow variables in the global (or
5078 any previous) scope.
5082 n_shell_variables ()
5087 for (n
= 0, vc
= shell_variables
; vc
; vc
= vc
->down
)
5088 n
+= HASH_ENTRIES (vc
->table
);
5098 v
= find_variable (name
);
5099 if (v
&& exported_p (v
))
5101 array_needs_making
= 1;
5102 maybe_make_export_env ();
5109 maybe_make_export_env ()
5111 register char **temp_array
;
5113 VAR_CONTEXT
*tcxt
, *icxt
;
5115 if (array_needs_making
)
5118 strvec_flush (export_env
);
5120 /* Make a guess based on how many shell variables and functions we
5121 have. Since there will always be array variables, and array
5122 variables are not (yet) exported, this will always be big enough
5123 for the exported variables and functions. */
5124 new_size
= n_shell_variables () + HASH_ENTRIES (shell_functions
) + 1 +
5125 HASH_ENTRIES (temporary_env
) + HASH_ENTRIES (invalid_env
);
5126 if (new_size
> export_env_size
)
5128 export_env_size
= new_size
;
5129 export_env
= strvec_resize (export_env
, export_env_size
);
5130 environ
= export_env
;
5132 export_env
[export_env_index
= 0] = (char *)NULL
;
5134 /* Make a dummy variable context from the temporary_env, stick it on
5135 the front of shell_variables, call make_var_export_array on the
5136 whole thing to flatten it, and convert the list of SHELL_VAR *s
5137 to the form needed by the environment. */
5140 tcxt
= new_var_context ((char *)NULL
, 0);
5141 tcxt
->table
= temporary_env
;
5142 tcxt
->down
= shell_variables
;
5145 tcxt
= shell_variables
;
5149 icxt
= new_var_context ((char *)NULL
, 0);
5150 icxt
->table
= invalid_env
;
5156 temp_array
= make_var_export_array (icxt
);
5158 add_temp_array_to_env (temp_array
, 0, 0);
5163 if (tcxt
!= shell_variables
)
5166 #if defined (RESTRICTED_SHELL)
5167 /* Restricted shells may not export shell functions. */
5168 temp_array
= restricted
? (char **)0 : make_func_export_array ();
5170 temp_array
= make_func_export_array ();
5173 add_temp_array_to_env (temp_array
, 0, 0);
5175 array_needs_making
= 0;
5179 /* This is an efficiency hack. PWD and OLDPWD are auto-exported, so
5180 we will need to remake the exported environment every time we
5181 change directories. `_' is always put into the environment for
5182 every external command, so without special treatment it will always
5183 cause the environment to be remade.
5185 If there is no other reason to make the exported environment, we can
5186 just update the variables in place and mark the exported environment
5187 as no longer needing a remake. */
5189 update_export_env_inplace (env_prefix
, preflen
, value
)
5196 evar
= (char *)xmalloc (STRLEN (value
) + preflen
+ 1);
5197 strcpy (evar
, env_prefix
);
5199 strcpy (evar
+ preflen
, value
);
5200 export_env
= add_or_supercede_exported_var (evar
, 0);
5203 /* We always put _ in the environment as the name of this command. */
5205 put_command_name_into_env (command_name
)
5208 update_export_env_inplace ("_=", 2, command_name
);
5211 /* **************************************************************** */
5213 /* Managing variable contexts */
5215 /* **************************************************************** */
5217 /* Allocate and return a new variable context with NAME and FLAGS.
5218 NAME can be NULL. */
5221 new_var_context (name
, flags
)
5227 vc
= (VAR_CONTEXT
*)xmalloc (sizeof (VAR_CONTEXT
));
5228 vc
->name
= name
? savestring (name
) : (char *)NULL
;
5229 vc
->scope
= variable_context
;
5232 vc
->up
= vc
->down
= (VAR_CONTEXT
*)NULL
;
5233 vc
->table
= (HASH_TABLE
*)NULL
;
5238 /* Free a variable context and its data, including the hash table. Dispose
5239 all of the variables. */
5241 dispose_var_context (vc
)
5248 delete_all_variables (vc
->table
);
5249 hash_dispose (vc
->table
);
5255 /* Set VAR's scope level to the current variable context. */
5260 return (var
->context
= variable_context
);
5263 /* Make a new variable context with NAME and FLAGS and a HASH_TABLE of
5264 temporary variables, and push it onto shell_variables. This is
5265 for shell functions. */
5267 push_var_context (name
, flags
, tempvars
)
5270 HASH_TABLE
*tempvars
;
5273 int posix_func_behavior
;
5275 /* As of IEEE Std 1003.1-2017, assignment statements preceding shell
5276 functions no longer behave like assignment statements preceding
5277 special builtins, and do not persist in the current shell environment.
5278 This is austin group interp #654, though nobody implements it yet. */
5279 posix_func_behavior
= 0;
5281 vc
= new_var_context (name
, flags
);
5282 /* Posix interp 1009, temporary assignments preceding function calls modify
5283 the current environment *before* the command is executed. */
5284 if (posix_func_behavior
&& (flags
& VC_FUNCENV
) && tempvars
== temporary_env
)
5285 merge_temporary_env ();
5288 vc
->table
= tempvars
;
5289 /* Have to do this because the temp environment was created before
5290 variable_context was incremented. */
5291 /* XXX - only need to do it if flags&VC_FUNCENV */
5292 flatten (tempvars
, set_context
, (VARLIST
*)NULL
, 0);
5293 vc
->flags
|= VC_HASTMPVAR
;
5295 vc
->down
= shell_variables
;
5296 shell_variables
->up
= vc
;
5298 return (shell_variables
= vc
);
5301 /* This can be called from one of two code paths:
5302 1. pop_scope, which implements the posix rules for propagating variable
5303 assignments preceding special builtins to the surrounding scope
5304 (push_builtin_var -- isbltin == 1);
5305 2. pop_var_context, which is called from pop_context and implements the
5306 posix rules for propagating variable assignments preceding function
5307 calls to the surrounding scope (push_func_var -- isbltin == 0)
5309 It takes variables out of a temporary environment hash table. We take the
5314 push_posix_tempvar_internal (var
, isbltin
)
5319 int posix_var_behavior
;
5321 /* As of IEEE Std 1003.1-2017, assignment statements preceding shell
5322 functions no longer behave like assignment statements preceding
5323 special builtins, and do not persist in the current shell environment.
5324 This is austin group interp #654, though nobody implements it yet. */
5325 posix_var_behavior
= posixly_correct
&& isbltin
;
5328 if (local_p (var
) && STREQ (var
->name
, "-"))
5330 set_current_options (value_cell (var
));
5333 /* This takes variable assignments preceding special builtins that can execute
5334 multiple commands (source, eval, etc.) and performs the equivalent of
5335 an assignment statement to modify the closest enclosing variable (the
5336 posix "current execution environment"). This makes the behavior the same
5337 as push_posix_temp_var; but the circumstances of calling are slightly
5339 else if (tempvar_p (var
) && posix_var_behavior
)
5341 /* similar to push_posix_temp_var */
5342 v
= bind_variable (var
->name
, value_cell (var
), ASS_FORCE
|ASS_NOLONGJMP
);
5345 v
->attributes
|= var
->attributes
;
5346 if (v
->context
== 0)
5347 v
->attributes
&= ~(att_tempvar
|att_propagate
);
5348 /* XXX - set att_propagate here if v->context > 0? */
5351 else if (tempvar_p (var
) && propagate_p (var
))
5353 /* Make sure we have a hash table to store the variable in while it is
5354 being propagated down to the global variables table. Create one if
5356 if ((vc_isfuncenv (shell_variables
) || vc_istempenv (shell_variables
)) && shell_variables
->table
== 0)
5357 shell_variables
->table
= hash_create (VARIABLES_HASH_BUCKETS
);
5358 v
= bind_variable_internal (var
->name
, value_cell (var
), shell_variables
->table
, 0, 0);
5359 /* XXX - should we set v->context here? */
5361 v
->context
= shell_variables
->scope
;
5362 if (shell_variables
== global_variables
)
5363 var
->attributes
&= ~(att_tempvar
|att_propagate
);
5365 shell_variables
->flags
|= VC_HASTMPVAR
;
5367 v
->attributes
|= var
->attributes
;
5370 stupidly_hack_special_variables (var
->name
); /* XXX */
5372 #if defined (ARRAY_VARS)
5373 if (v
&& (array_p (var
) || assoc_p (var
)))
5375 FREE (value_cell (v
));
5377 var_setarray (v
, array_copy (array_cell (var
)));
5379 var_setassoc (v
, assoc_copy (assoc_cell (var
)));
5383 dispose_variable (var
);
5387 push_func_var (data
)
5392 var
= (SHELL_VAR
*)data
;
5393 push_posix_tempvar_internal (var
, 0);
5397 push_builtin_var (data
)
5402 var
= (SHELL_VAR
*)data
;
5403 push_posix_tempvar_internal (var
, 1);
5406 /* Pop the top context off of VCXT and dispose of it, returning the rest of
5411 VAR_CONTEXT
*ret
, *vcxt
;
5413 vcxt
= shell_variables
;
5414 if (vc_isfuncenv (vcxt
) == 0)
5416 internal_error (_("pop_var_context: head of shell_variables not a function context"));
5420 if (ret
= vcxt
->down
)
5422 ret
->up
= (VAR_CONTEXT
*)NULL
;
5423 shell_variables
= ret
;
5425 hash_flush (vcxt
->table
, push_func_var
);
5426 dispose_var_context (vcxt
);
5429 internal_error (_("pop_var_context: no global_variables context"));
5433 delete_local_contexts (vcxt
)
5438 for (v
= vcxt
; v
!= global_variables
; v
= t
)
5441 dispose_var_context (v
);
5445 /* Delete the HASH_TABLEs for all variable contexts beginning at VCXT, and
5446 all of the VAR_CONTEXTs except GLOBAL_VARIABLES. */
5448 delete_all_contexts (vcxt
)
5451 delete_local_contexts (vcxt
);
5452 delete_all_variables (global_variables
->table
);
5453 shell_variables
= global_variables
;
5456 /* Reset the context so we are not executing in a shell function. Only call
5457 this if you are getting ready to exit the shell. */
5459 reset_local_contexts ()
5461 delete_local_contexts (shell_variables
);
5462 shell_variables
= global_variables
;
5463 variable_context
= 0;
5466 /* **************************************************************** */
5468 /* Pushing and Popping temporary variable scopes */
5470 /* **************************************************************** */
5473 push_scope (flags
, tmpvars
)
5475 HASH_TABLE
*tmpvars
;
5477 return (push_var_context ((char *)NULL
, flags
, tmpvars
));
5481 push_exported_var (data
)
5486 var
= (SHELL_VAR
*)data
;
5488 /* If a temp var had its export attribute set, or it's marked to be
5489 propagated, bind it in the previous scope before disposing it. */
5490 /* XXX - This isn't exactly right, because all tempenv variables have the
5491 export attribute set. */
5492 if (tempvar_p (var
) && exported_p (var
) && (var
->attributes
& att_propagate
))
5494 var
->attributes
&= ~att_tempvar
; /* XXX */
5495 v
= bind_variable_internal (var
->name
, value_cell (var
), shell_variables
->table
, 0, 0);
5496 if (shell_variables
== global_variables
)
5497 var
->attributes
&= ~att_propagate
;
5500 v
->attributes
|= var
->attributes
;
5501 v
->context
= shell_variables
->scope
;
5505 stupidly_hack_special_variables (var
->name
); /* XXX */
5507 dispose_variable (var
);
5510 /* This is called to propagate variables in the temporary environment of a
5511 special builtin (if IS_SPECIAL != 0) or exported variables that are the
5512 result of a builtin like `source' or `command' that can operate on the
5513 variables in its temporary environment. In the first case, we call
5514 push_builtin_var, which does the right thing. */
5516 pop_scope (is_special
)
5519 VAR_CONTEXT
*vcxt
, *ret
;
5522 vcxt
= shell_variables
;
5523 if (vc_istempscope (vcxt
) == 0)
5525 internal_error (_("pop_scope: head of shell_variables not a temporary environment scope"));
5528 is_bltinenv
= vc_isbltnenv (vcxt
); /* XXX - for later */
5532 ret
->up
= (VAR_CONTEXT
*)NULL
;
5534 shell_variables
= ret
;
5536 /* Now we can take care of merging variables in VCXT into set of scopes
5537 whose head is RET (shell_variables). */
5542 hash_flush (vcxt
->table
, push_builtin_var
);
5544 hash_flush (vcxt
->table
, push_exported_var
);
5545 hash_dispose (vcxt
->table
);
5549 sv_ifs ("IFS"); /* XXX here for now */
5552 /* **************************************************************** */
5554 /* Pushing and Popping function contexts */
5556 /* **************************************************************** */
5558 struct saved_dollar_vars
{
5564 static struct saved_dollar_vars
*dollar_arg_stack
= (struct saved_dollar_vars
*)NULL
;
5565 static int dollar_arg_stack_slots
;
5566 static int dollar_arg_stack_index
;
5568 /* Functions to manipulate dollar_vars array. Need to keep these in sync with
5569 whatever remember_args() does. */
5576 ret
= strvec_create (10);
5577 for (i
= 1; i
< 10; i
++)
5579 ret
[i
] = dollar_vars
[i
];
5580 dollar_vars
[i
] = (char *)NULL
;
5586 restore_dollar_vars (args
)
5591 for (i
= 1; i
< 10; i
++)
5592 dollar_vars
[i
] = args
[i
];
5600 for (i
= 1; i
< 10; i
++)
5602 FREE (dollar_vars
[i
]);
5603 dollar_vars
[i
] = (char *)NULL
;
5608 free_saved_dollar_vars (args
)
5613 for (i
= 1; i
< 10; i
++)
5617 /* Do what remember_args (xxx, 1) would have done. */
5619 clear_dollar_vars ()
5621 free_dollar_vars ();
5622 dispose_words (rest_of_args
);
5624 rest_of_args
= (WORD_LIST
*)NULL
;
5628 /* XXX - should always be followed by remember_args () */
5630 push_context (name
, is_subshell
, tempvars
)
5631 char *name
; /* function name */
5633 HASH_TABLE
*tempvars
;
5635 if (is_subshell
== 0)
5636 push_dollar_vars ();
5638 push_var_context (name
, VC_FUNCENV
, tempvars
);
5641 /* Only called when subshell == 0, so we don't need to check, and can
5642 unconditionally pop the dollar vars off the stack. */
5650 sv_ifs ("IFS"); /* XXX here for now */
5653 /* Save the existing positional parameters on a stack. */
5657 if (dollar_arg_stack_index
+ 2 > dollar_arg_stack_slots
)
5659 dollar_arg_stack
= (struct saved_dollar_vars
*)
5660 xrealloc (dollar_arg_stack
, (dollar_arg_stack_slots
+= 10)
5661 * sizeof (struct saved_dollar_vars
));
5664 dollar_arg_stack
[dollar_arg_stack_index
].count
= posparam_count
;
5665 dollar_arg_stack
[dollar_arg_stack_index
].first_ten
= save_dollar_vars ();
5666 dollar_arg_stack
[dollar_arg_stack_index
++].rest
= rest_of_args
;
5667 rest_of_args
= (WORD_LIST
*)NULL
;
5670 dollar_arg_stack
[dollar_arg_stack_index
].first_ten
= (char **)NULL
;
5671 dollar_arg_stack
[dollar_arg_stack_index
].rest
= (WORD_LIST
*)NULL
;
5674 /* Restore the positional parameters from our stack. */
5678 if (dollar_arg_stack
== 0 || dollar_arg_stack_index
== 0)
5681 /* Wipe out current values */
5682 clear_dollar_vars ();
5684 rest_of_args
= dollar_arg_stack
[--dollar_arg_stack_index
].rest
;
5685 restore_dollar_vars (dollar_arg_stack
[dollar_arg_stack_index
].first_ten
);
5686 free (dollar_arg_stack
[dollar_arg_stack_index
].first_ten
);
5687 posparam_count
= dollar_arg_stack
[dollar_arg_stack_index
].count
;
5689 dollar_arg_stack
[dollar_arg_stack_index
].first_ten
= (char **)NULL
;
5690 dollar_arg_stack
[dollar_arg_stack_index
].rest
= (WORD_LIST
*)NULL
;
5691 dollar_arg_stack
[dollar_arg_stack_index
].count
= 0;
5693 set_dollar_vars_unchanged ();
5694 invalidate_cached_quoted_dollar_at ();
5698 dispose_saved_dollar_vars ()
5700 if (dollar_arg_stack
== 0 || dollar_arg_stack_index
== 0)
5703 dispose_words (dollar_arg_stack
[--dollar_arg_stack_index
].rest
);
5704 free_saved_dollar_vars (dollar_arg_stack
[dollar_arg_stack_index
].first_ten
);
5705 free (dollar_arg_stack
[dollar_arg_stack_index
].first_ten
);
5707 dollar_arg_stack
[dollar_arg_stack_index
].first_ten
= (char **)NULL
;
5708 dollar_arg_stack
[dollar_arg_stack_index
].rest
= (WORD_LIST
*)NULL
;
5709 dollar_arg_stack
[dollar_arg_stack_index
].count
= 0;
5712 /* Initialize BASH_ARGV and BASH_ARGC after turning on extdebug after the
5713 shell is initialized */
5717 if (bash_argv_initialized
== 0)
5720 bash_argv_initialized
= 1;
5729 list
= list_rest_of_args ();
5731 dispose_words (list
);
5734 /* Manipulate the special BASH_ARGV and BASH_ARGC variables. */
5740 #if defined (ARRAY_VARS) && defined (DEBUGGER)
5741 SHELL_VAR
*bash_argv_v
, *bash_argc_v
;
5742 ARRAY
*bash_argv_a
, *bash_argc_a
;
5747 GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v
, bash_argv_a
);
5748 GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v
, bash_argc_a
);
5750 for (l
= list
, i
= 0; l
; l
= l
->next
, i
++)
5751 array_push (bash_argv_a
, l
->word
->word
);
5754 array_push (bash_argc_a
, t
);
5756 #endif /* ARRAY_VARS && DEBUGGER */
5759 /* Remove arguments from BASH_ARGV array. Pop top element off BASH_ARGC
5760 array and use that value as the count of elements to remove from
5765 #if defined (ARRAY_VARS) && defined (DEBUGGER)
5766 SHELL_VAR
*bash_argv_v
, *bash_argc_v
;
5767 ARRAY
*bash_argv_a
, *bash_argc_a
;
5771 GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v
, bash_argv_a
);
5772 GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v
, bash_argc_a
);
5774 ce
= array_unshift_element (bash_argc_a
);
5775 if (ce
== 0 || legal_number (element_value (ce
), &i
) == 0)
5779 array_pop (bash_argv_a
);
5780 array_dispose_element (ce
);
5781 #endif /* ARRAY_VARS && DEBUGGER */
5784 /*************************************************
5786 * Functions to manage special variables *
5788 *************************************************/
5790 /* Extern declarations for variables this code has to manage. */
5792 /* An alist of name.function for each special variable. Most of the
5793 functions don't do much, and in fact, this would be faster with a
5794 switch statement, but by the end of this file, I am sick of switch
5797 #define SET_INT_VAR(name, intvar) intvar = find_variable (name) != 0
5799 /* This table will be sorted with qsort() the first time it's accessed. */
5800 struct name_and_function
{
5802 sh_sv_func_t
*function
;
5805 static struct name_and_function special_vars
[] = {
5806 { "BASH_COMPAT", sv_shcompat
},
5807 { "BASH_XTRACEFD", sv_xtracefd
},
5809 #if defined (JOB_CONTROL)
5810 { "CHILD_MAX", sv_childmax
},
5813 #if defined (READLINE)
5814 # if defined (STRICT_POSIX)
5815 { "COLUMNS", sv_winsize
},
5817 { "COMP_WORDBREAKS", sv_comp_wordbreaks
},
5820 { "EXECIGNORE", sv_execignore
},
5822 { "FUNCNEST", sv_funcnest
},
5824 { "GLOBIGNORE", sv_globignore
},
5826 #if defined (HISTORY)
5827 { "HISTCONTROL", sv_history_control
},
5828 { "HISTFILESIZE", sv_histsize
},
5829 { "HISTIGNORE", sv_histignore
},
5830 { "HISTSIZE", sv_histsize
},
5831 { "HISTTIMEFORMAT", sv_histtimefmt
},
5834 #if defined (__CYGWIN__)
5835 { "HOME", sv_home
},
5838 #if defined (READLINE)
5839 { "HOSTFILE", sv_hostfile
},
5843 { "IGNOREEOF", sv_ignoreeof
},
5845 { "LANG", sv_locale
},
5846 { "LC_ALL", sv_locale
},
5847 { "LC_COLLATE", sv_locale
},
5848 { "LC_CTYPE", sv_locale
},
5849 { "LC_MESSAGES", sv_locale
},
5850 { "LC_NUMERIC", sv_locale
},
5851 { "LC_TIME", sv_locale
},
5853 #if defined (READLINE) && defined (STRICT_POSIX)
5854 { "LINES", sv_winsize
},
5857 { "MAIL", sv_mail
},
5858 { "MAILCHECK", sv_mail
},
5859 { "MAILPATH", sv_mail
},
5861 { "OPTERR", sv_opterr
},
5862 { "OPTIND", sv_optind
},
5864 { "PATH", sv_path
},
5865 { "POSIXLY_CORRECT", sv_strict_posix
},
5867 #if defined (READLINE)
5868 { "TERM", sv_terminal
},
5869 { "TERMCAP", sv_terminal
},
5870 { "TERMINFO", sv_terminal
},
5871 #endif /* READLINE */
5873 { "TEXTDOMAIN", sv_locale
},
5874 { "TEXTDOMAINDIR", sv_locale
},
5876 #if defined (HAVE_TZSET)
5880 #if defined (HISTORY) && defined (BANG_HISTORY)
5881 { "histchars", sv_histchars
},
5882 #endif /* HISTORY && BANG_HISTORY */
5884 { "ignoreeof", sv_ignoreeof
},
5886 { (char *)0, (sh_sv_func_t
*)0 }
5889 #define N_SPECIAL_VARS (sizeof (special_vars) / sizeof (special_vars[0]) - 1)
5892 sv_compare (sv1
, sv2
)
5893 struct name_and_function
*sv1
, *sv2
;
5897 if ((r
= sv1
->name
[0] - sv2
->name
[0]) == 0)
5898 r
= strcmp (sv1
->name
, sv2
->name
);
5903 find_special_var (name
)
5908 for (i
= 0; special_vars
[i
].name
; i
++)
5910 r
= special_vars
[i
].name
[0] - name
[0];
5912 r
= strcmp (special_vars
[i
].name
, name
);
5916 /* Can't match any of rest of elements in sorted list. Take this out
5917 if it causes problems in certain environments. */
5923 /* The variable in NAME has just had its state changed. Check to see if it
5924 is one of the special ones where something special happens. */
5926 stupidly_hack_special_variables (name
)
5929 static int sv_sorted
= 0;
5932 if (sv_sorted
== 0) /* shouldn't need, but it's fairly cheap. */
5934 qsort (special_vars
, N_SPECIAL_VARS
, sizeof (special_vars
[0]),
5935 (QSFUNC
*)sv_compare
);
5939 i
= find_special_var (name
);
5941 (*(special_vars
[i
].function
)) (name
);
5944 /* Special variables that need hooks to be run when they are unset as part
5945 of shell reinitialization should have their sv_ functions run here. */
5947 reinit_special_variables ()
5949 #if defined (READLINE)
5950 sv_comp_wordbreaks ("COMP_WORDBREAKS");
5952 sv_globignore ("GLOBIGNORE");
5953 sv_opterr ("OPTERR");
5962 v
= find_variable ("IFS");
5966 /* What to do just after the PATH variable has changed. */
5975 /* What to do just after one of the MAILxxxx variables has changed. NAME
5976 is the name of the variable. This is called with NAME set to one of
5977 MAIL, MAILCHECK, or MAILPATH. */
5982 /* If the time interval for checking the files has changed, then
5983 reset the mail timer. Otherwise, one of the pathname vars
5984 to the users mailbox has changed, so rebuild the array of
5986 if (name
[4] == 'C') /* if (strcmp (name, "MAILCHECK") == 0) */
5987 reset_mail_timer ();
5991 remember_mail_dates ();
6002 v
= find_variable (name
);
6005 else if (legal_number (value_cell (v
), &num
) == 0)
6011 /* What to do when EXECIGNORE changes. */
6013 sv_execignore (name
)
6016 setup_exec_ignore (name
);
6019 /* What to do when GLOBIGNORE changes. */
6021 sv_globignore (name
)
6024 if (privileged_mode
== 0)
6025 setup_glob_ignore (name
);
6028 #if defined (READLINE)
6030 sv_comp_wordbreaks (name
)
6035 sv
= find_variable (name
);
6037 reset_completer_word_break_chars ();
6040 /* What to do just after one of the TERMxxx variables has changed.
6041 If we are an interactive shell, then try to reset the terminal
6042 information in readline. */
6047 if (interactive_shell
&& no_line_editing
== 0)
6048 rl_reset_terminal (get_string_value ("TERM"));
6057 v
= find_variable (name
);
6059 clear_hostname_list ();
6061 hostname_list_initialized
= 0;
6064 #if defined (STRICT_POSIX)
6065 /* In strict posix mode, we allow assignments to LINES and COLUMNS (and values
6066 found in the initial environment) to override the terminal size reported by
6076 if (posixly_correct
== 0 || interactive_shell
== 0 || no_line_editing
)
6079 v
= find_variable (name
);
6080 if (v
== 0 || var_isset (v
) == 0)
6081 rl_reset_screen_size ();
6084 if (legal_number (value_cell (v
), &xd
) == 0)
6086 winsize_assignment
= 1;
6087 d
= xd
; /* truncate */
6088 if (name
[0] == 'L') /* LINES */
6089 rl_set_screen_size (d
, -1);
6091 rl_set_screen_size (-1, d
);
6092 winsize_assignment
= 0;
6095 #endif /* STRICT_POSIX */
6096 #endif /* READLINE */
6098 /* Update the value of HOME in the export environment so tilde expansion will
6100 #if defined (__CYGWIN__)
6104 array_needs_making
= 1;
6105 maybe_make_export_env ();
6109 #if defined (HISTORY)
6110 /* What to do after the HISTSIZE or HISTFILESIZE variables change.
6111 If there is a value for this HISTSIZE (and it is numeric), then stifle
6112 the history. Otherwise, if there is NO value for this variable,
6113 unstifle the history. If name is HISTFILESIZE, and its value is
6114 numeric, truncate the history file to hold no more than that many
6124 temp
= get_string_value (name
);
6128 if (legal_number (temp
, &num
))
6131 if (hmax
< 0 && name
[4] == 'S')
6132 unstifle_history (); /* unstifle history if HISTSIZE < 0 */
6133 else if (name
[4] == 'S')
6135 stifle_history (hmax
);
6136 hmax
= where_history ();
6137 if (history_lines_this_session
> hmax
)
6138 history_lines_this_session
= hmax
;
6140 else if (hmax
>= 0) /* truncate HISTFILE if HISTFILESIZE >= 0 */
6142 history_truncate_file (get_string_value ("HISTFILE"), hmax
);
6143 /* If we just shrank the history file to fewer lines than we've
6144 already read, make sure we adjust our idea of how many lines
6145 we have read from the file. */
6146 if (hmax
< history_lines_in_file
)
6147 history_lines_in_file
= hmax
;
6151 else if (name
[4] == 'S')
6152 unstifle_history ();
6155 /* What to do after the HISTIGNORE variable changes. */
6157 sv_histignore (name
)
6160 setup_history_ignore (name
);
6163 /* What to do after the HISTCONTROL variable changes. */
6165 sv_history_control (name
)
6172 history_control
= 0;
6173 temp
= get_string_value (name
);
6175 if (temp
== 0 || *temp
== 0)
6179 while (val
= extract_colon_unit (temp
, &tptr
))
6181 if (STREQ (val
, "ignorespace"))
6182 history_control
|= HC_IGNSPACE
;
6183 else if (STREQ (val
, "ignoredups"))
6184 history_control
|= HC_IGNDUPS
;
6185 else if (STREQ (val
, "ignoreboth"))
6186 history_control
|= HC_IGNBOTH
;
6187 else if (STREQ (val
, "erasedups"))
6188 history_control
|= HC_ERASEDUPS
;
6194 #if defined (BANG_HISTORY)
6195 /* Setting/unsetting of the history expansion character. */
6202 temp
= get_string_value (name
);
6205 history_expansion_char
= *temp
;
6206 if (temp
[0] && temp
[1])
6208 history_subst_char
= temp
[1];
6210 history_comment_char
= temp
[2];
6215 history_expansion_char
= '!';
6216 history_subst_char
= '^';
6217 history_comment_char
= '#';
6220 #endif /* BANG_HISTORY */
6223 sv_histtimefmt (name
)
6228 if (v
= find_variable (name
))
6230 if (history_comment_char
== 0)
6231 history_comment_char
= '#';
6233 history_write_timestamps
= (v
!= 0);
6235 #endif /* HISTORY */
6237 #if defined (HAVE_TZSET)
6244 v
= find_variable (name
);
6245 if (v
&& exported_p (v
))
6246 array_needs_making
= 1;
6248 array_needs_making
= 1;
6250 if (array_needs_making
)
6252 maybe_make_export_env ();
6258 /* If the variable exists, then the value of it can be the number
6259 of times we actually ignore the EOF. The default is small,
6260 (smaller than csh, anyway). */
6268 eof_encountered
= 0;
6270 tmp_var
= find_variable (name
);
6271 ignoreeof
= tmp_var
&& var_isset (tmp_var
);
6272 temp
= tmp_var
? value_cell (tmp_var
) : (char *)NULL
;
6274 eof_encountered_limit
= (*temp
&& all_digits (temp
)) ? atoi (temp
) : 10;
6275 set_shellopts (); /* make sure `ignoreeof' is/is not in $SHELLOPTS */
6286 var
= find_variable ("OPTIND");
6287 tt
= var
? get_variable_value (var
) : (char *)NULL
;
6289 /* Assume that if var->context < variable_context and variable_context > 0
6290 then we are restoring the variables's previous state while returning
6296 /* According to POSIX, setting OPTIND=1 resets the internal state
6298 if (s
< 0 || s
== 1)
6312 tt
= get_string_value ("OPTERR");
6313 sh_opterr
= (tt
&& *tt
) ? atoi (tt
) : 1;
6317 sv_strict_posix (name
)
6322 var
= find_variable (name
);
6323 posixly_correct
= var
&& var_isset (var
);
6324 posix_initialize (posixly_correct
);
6325 #if defined (READLINE)
6326 if (interactive_shell
)
6327 posix_readline_initialize (posixly_correct
);
6328 #endif /* READLINE */
6329 set_shellopts (); /* make sure `posix' is/is not in $SHELLOPTS */
6339 v
= get_string_value (name
);
6340 if (name
[0] == 'L' && name
[1] == 'A') /* LANG */
6341 r
= set_lang (name
, v
);
6343 r
= set_locale_var (name
, v
); /* LC_*, TEXTDOMAIN* */
6346 if (r
== 0 && posixly_correct
)
6347 set_exit_status (EXECUTION_FAILURE
);
6351 #if defined (ARRAY_VARS)
6353 set_pipestatus_array (ps
, nproc
)
6361 char *t
, tbuf
[INT_STRLEN_BOUND(int) + 1];
6363 v
= find_variable ("PIPESTATUS");
6365 v
= make_new_array_variable ("PIPESTATUS");
6366 if (array_p (v
) == 0)
6367 return; /* Do nothing if not an array variable. */
6370 if (a
== 0 || array_num_elements (a
) == 0)
6372 for (i
= 0; i
< nproc
; i
++) /* was ps[i] != -1, not i < nproc */
6374 t
= inttostr (ps
[i
], tbuf
, sizeof (tbuf
));
6375 array_insert (a
, i
, t
);
6381 if (array_num_elements (a
) == nproc
&& nproc
== 1)
6383 #ifndef ALT_ARRAY_IMPLEMENTATION
6384 ae
= element_forw (a
->head
);
6386 ae
= a
->elements
[0];
6388 ARRAY_ELEMENT_REPLACE (ae
, itos (ps
[0]));
6390 else if (array_num_elements (a
) <= nproc
)
6392 /* modify in array_num_elements members in place, then add */
6393 #ifndef ALT_ARRAY_IMPLEMENTATION
6396 for (i
= 0; i
< array_num_elements (a
); i
++)
6398 #ifndef ALT_ARRAY_IMPLEMENTATION
6399 ae
= element_forw (ae
);
6401 ae
= a
->elements
[i
];
6403 ARRAY_ELEMENT_REPLACE (ae
, itos (ps
[i
]));
6406 for ( ; i
< nproc
; i
++)
6408 t
= inttostr (ps
[i
], tbuf
, sizeof (tbuf
));
6409 array_insert (a
, i
, t
);
6414 #ifndef ALT_ARRAY_IMPLEMENTATION
6415 /* deleting elements. it's faster to rebuild the array. */
6417 for (i
= 0; i
< nproc
; i
++)
6419 t
= inttostr (ps
[i
], tbuf
, sizeof (tbuf
));
6420 array_insert (a
, i
, t
);
6423 /* deleting elements. replace the first NPROC, free the rest */
6424 for (i
= 0; i
< nproc
; i
++)
6426 ae
= a
->elements
[i
];
6427 ARRAY_ELEMENT_REPLACE (ae
, itos (ps
[i
]));
6429 for ( ; i
<= array_max_index (a
); i
++)
6431 array_dispose_element (a
->elements
[i
]);
6432 a
->elements
[i
] = (ARRAY_ELEMENT
*)NULL
;
6435 /* bookkeeping usually taken care of by array_insert */
6436 set_max_index (a
, nproc
- 1);
6437 set_first_index (a
, 0);
6438 set_num_elements (a
, nproc
);
6439 #endif /* ALT_ARRAY_IMPLEMENTATION */
6444 save_pipestatus_array ()
6449 v
= find_variable ("PIPESTATUS");
6450 if (v
== 0 || array_p (v
) == 0 || array_cell (v
) == 0)
6451 return ((ARRAY
*)NULL
);
6453 a
= array_copy (array_cell (v
));
6459 restore_pipestatus_array (a
)
6465 v
= find_variable ("PIPESTATUS");
6466 /* XXX - should we still assign even if existing value is NULL? */
6467 if (v
== 0 || array_p (v
) == 0 || array_cell (v
) == 0)
6470 a2
= array_cell (v
);
6471 var_setarray (v
, a
);
6478 set_pipestatus_from_exit (s
)
6481 #if defined (ARRAY_VARS)
6482 static int v
[2] = { 0, -1 };
6485 set_pipestatus_array (v
, 1);
6498 v
= find_variable (name
);
6506 if (t
== 0 || *t
== 0)
6510 fd
= (int)strtol (t
, &e
, 10);
6511 if (e
!= t
&& *e
== '\0' && sh_validfd (fd
))
6513 fp
= fdopen (fd
, "w");
6515 internal_error (_("%s: %s: cannot open as FILE"), name
, value_cell (v
));
6517 xtrace_set (fd
, fp
);
6520 internal_error (_("%s: %s: invalid value for trace file descriptor"), name
, value_cell (v
));
6524 #define MIN_COMPAT_LEVEL 31
6532 int tens
, ones
, compatval
;
6534 v
= find_variable (name
);
6537 shell_compatibility_level
= DEFAULT_COMPAT_LEVEL
;
6538 set_compatibility_opts ();
6541 val
= value_cell (v
);
6542 if (val
== 0 || *val
== '\0')
6544 shell_compatibility_level
= DEFAULT_COMPAT_LEVEL
;
6545 set_compatibility_opts ();
6548 /* Handle decimal-like compatibility version specifications: 4.2 */
6549 if (ISDIGIT (val
[0]) && val
[1] == '.' && ISDIGIT (val
[2]) && val
[3] == 0)
6551 tens
= val
[0] - '0';
6552 ones
= val
[2] - '0';
6553 compatval
= tens
*10 + ones
;
6555 /* Handle integer-like compatibility version specifications: 42 */
6556 else if (ISDIGIT (val
[0]) && ISDIGIT (val
[1]) && val
[2] == 0)
6558 tens
= val
[0] - '0';
6559 ones
= val
[1] - '0';
6560 compatval
= tens
*10 + ones
;
6565 internal_error (_("%s: %s: compatibility value out of range"), name
, val
);
6566 shell_compatibility_level
= DEFAULT_COMPAT_LEVEL
;
6567 set_compatibility_opts ();
6571 if (compatval
< MIN_COMPAT_LEVEL
|| compatval
> DEFAULT_COMPAT_LEVEL
)
6574 shell_compatibility_level
= compatval
;
6575 set_compatibility_opts ();
6578 #if defined (JOB_CONTROL)
6586 tt
= get_string_value (name
);
6587 s
= (tt
&& *tt
) ? atoi (tt
) : 0;