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