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