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