⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 variables.c

📁 android-w.song.android.widget
💻 C
📖 第 1 页 / 共 5 页
字号:
/* variables.c -- Functions for hacking shell variables. *//* Copyright (C) 1987-2010 Free Software Foundation, Inc.   This file is part of GNU Bash, the Bourne Again SHell.   Bash is free software: you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation, either version 3 of the License, or   (at your option) any later version.   Bash is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with Bash.  If not, see <http://www.gnu.org/licenses/>.*/#include "config.h"#include "bashtypes.h"#include "posixstat.h"#include "posixtime.h"#if defined (__QNX__)#  if defined (__QNXNTO__)#    include <sys/netmgr.h>#  else#    include <sys/vc.h>#  endif /* !__QNXNTO__ */#endif /* __QNX__ */#if defined (HAVE_UNISTD_H)#  include <unistd.h>#endif#include <stdio.h>#include "chartypes.h"#if defined (HAVE_PWD_H)#  include <pwd.h>#endif#include "bashansi.h"#include "bashintl.h"#define NEED_XTRACE_SET_DECL#include "shell.h"#include "flags.h"#include "execute_cmd.h"#include "findcmd.h"#include "mailcheck.h"#include "input.h"#include "hashcmd.h"#include "pathexp.h"#include "alias.h"#include "builtins/getopt.h"#include "builtins/common.h"#if defined (READLINE)#  include "bashline.h"#  include <readline/readline.h>#else#  include <tilde/tilde.h>#endif#if defined (HISTORY)#  include "bashhist.h"#  include <readline/history.h>#endif /* HISTORY */#if defined (PROGRAMMABLE_COMPLETION)#  include "pcomplete.h"#endif#define TEMPENV_HASH_BUCKETS	4	/* must be power of two */#define ifsname(s)	((s)[0] == 'I' && (s)[1] == 'F' && (s)[2] == 'S' && (s)[3] == '\0')extern char **environ;/* Variables used here and defined in other files. */extern int posixly_correct;extern int line_number, line_number_base;extern int subshell_environment, indirection_level, subshell_level;extern int build_version, patch_level;extern int expanding_redir;extern char *dist_version, *release_status;extern char *shell_name;extern char *primary_prompt, *secondary_prompt;extern char *current_host_name;extern sh_builtin_func_t *this_shell_builtin;extern SHELL_VAR *this_shell_function;extern char *the_printed_command_except_trap;extern char *this_command_name;extern char *command_execution_string;extern time_t shell_start_time;extern int assigning_in_environment;extern int executing_builtin;extern int funcnest_max;#if defined (READLINE)extern int no_line_editing;extern int perform_hostname_completion;#endif/* The list of shell variables that the user has created at the global   scope, or that came from the environment. */VAR_CONTEXT *global_variables = (VAR_CONTEXT *)NULL;/* The current list of shell variables, including function scopes */VAR_CONTEXT *shell_variables = (VAR_CONTEXT *)NULL;/* The list of shell functions that the user has created, or that came from   the environment. */HASH_TABLE *shell_functions = (HASH_TABLE *)NULL;#if defined (DEBUGGER)/* The table of shell function definitions that the user defined or that   came from the environment. */HASH_TABLE *shell_function_defs = (HASH_TABLE *)NULL;#endif/* The current variable context.  This is really a count of how deep into   executing functions we are. */int variable_context = 0;/* The set of shell assignments which are made only in the environment   for a single command. */HASH_TABLE *temporary_env = (HASH_TABLE *)NULL;/* Set to non-zero if an assignment error occurs while putting variables   into the temporary environment. */int tempenv_assign_error;/* Some funky variables which are known about specially.  Here is where   "$*", "$1", and all the cruft is kept. */char *dollar_vars[10];WORD_LIST *rest_of_args = (WORD_LIST *)NULL;/* The value of $$. */pid_t dollar_dollar_pid;/* Non-zero means that we have to remake EXPORT_ENV. */int array_needs_making = 1;/* The number of times BASH has been executed.  This is set   by initialize_variables (). */int shell_level = 0;/* An array which is passed to commands as their environment.  It is   manufactured from the union of the initial environment and the   shell variables that are marked for export. */char **export_env = (char **)NULL;static int export_env_index;static int export_env_size;#if defined (READLINE)static int winsize_assignment;		/* currently assigning to LINES or COLUMNS */#endif/* Some forward declarations. */static void create_variable_tables __P((void));static void set_machine_vars __P((void));static void set_home_var __P((void));static void set_shell_var __P((void));static char *get_bash_name __P((void));static void initialize_shell_level __P((void));static void uidset __P((void));#if defined (ARRAY_VARS)static void make_vers_array __P((void));#endifstatic SHELL_VAR *null_assign __P((SHELL_VAR *, char *, arrayind_t, char *));#if defined (ARRAY_VARS)static SHELL_VAR *null_array_assign __P((SHELL_VAR *, char *, arrayind_t, char *));#endifstatic SHELL_VAR *get_self __P((SHELL_VAR *));#if defined (ARRAY_VARS)static SHELL_VAR *init_dynamic_array_var __P((char *, sh_var_value_func_t *, sh_var_assign_func_t *, int));static SHELL_VAR *init_dynamic_assoc_var __P((char *, sh_var_value_func_t *, sh_var_assign_func_t *, int));#endifstatic SHELL_VAR *assign_seconds __P((SHELL_VAR *, char *, arrayind_t, char *));static SHELL_VAR *get_seconds __P((SHELL_VAR *));static SHELL_VAR *init_seconds_var __P((void));static int brand __P((void));static void sbrand __P((unsigned long));		/* set bash random number generator. */static void seedrand __P((void));			/* seed generator randomly */static SHELL_VAR *assign_random __P((SHELL_VAR *, char *, arrayind_t, char *));static SHELL_VAR *get_random __P((SHELL_VAR *));static SHELL_VAR *assign_lineno __P((SHELL_VAR *, char *, arrayind_t, char *));static SHELL_VAR *get_lineno __P((SHELL_VAR *));static SHELL_VAR *assign_subshell __P((SHELL_VAR *, char *, arrayind_t, char *));static SHELL_VAR *get_subshell __P((SHELL_VAR *));static SHELL_VAR *get_bashpid __P((SHELL_VAR *));#if defined (HISTORY)static SHELL_VAR *get_histcmd __P((SHELL_VAR *));#endif#if defined (READLINE)static SHELL_VAR *get_comp_wordbreaks __P((SHELL_VAR *));static SHELL_VAR *assign_comp_wordbreaks __P((SHELL_VAR *, char *, arrayind_t, char *));#endif#if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)static SHELL_VAR *assign_dirstack __P((SHELL_VAR *, char *, arrayind_t, char *));static SHELL_VAR *get_dirstack __P((SHELL_VAR *));#endif#if defined (ARRAY_VARS)static SHELL_VAR *get_groupset __P((SHELL_VAR *));static SHELL_VAR *build_hashcmd __P((SHELL_VAR *));static SHELL_VAR *get_hashcmd __P((SHELL_VAR *));static SHELL_VAR *assign_hashcmd __P((SHELL_VAR *,  char *, arrayind_t, char *));#  if defined (ALIAS)static SHELL_VAR *build_aliasvar __P((SHELL_VAR *));static SHELL_VAR *get_aliasvar __P((SHELL_VAR *));static SHELL_VAR *assign_aliasvar __P((SHELL_VAR *,  char *, arrayind_t, char *));#  endif#endifstatic SHELL_VAR *get_funcname __P((SHELL_VAR *));static SHELL_VAR *init_funcname_var __P((void));static void initialize_dynamic_variables __P((void));static SHELL_VAR *hash_lookup __P((const char *, HASH_TABLE *));static SHELL_VAR *new_shell_variable __P((const char *));static SHELL_VAR *make_new_variable __P((const char *, HASH_TABLE *));static SHELL_VAR *bind_variable_internal __P((const char *, char *, HASH_TABLE *, int, int));static void dispose_variable_value __P((SHELL_VAR *));static void free_variable_hash_data __P((PTR_T));static VARLIST *vlist_alloc __P((int));static VARLIST *vlist_realloc __P((VARLIST *, int));static void vlist_add __P((VARLIST *, SHELL_VAR *, int));static void flatten __P((HASH_TABLE *, sh_var_map_func_t *, VARLIST *, int));static int qsort_var_comp __P((SHELL_VAR **, SHELL_VAR **));static SHELL_VAR **vapply __P((sh_var_map_func_t *));static SHELL_VAR **fapply __P((sh_var_map_func_t *));static int visible_var __P((SHELL_VAR *));static int visible_and_exported __P((SHELL_VAR *));static int export_environment_candidate __P((SHELL_VAR *));static int local_and_exported __P((SHELL_VAR *));static int variable_in_context __P((SHELL_VAR *));#if defined (ARRAY_VARS)static int visible_array_vars __P((SHELL_VAR *));#endifstatic SHELL_VAR *bind_tempenv_variable __P((const char *, char *));static void push_temp_var __P((PTR_T));static void propagate_temp_var __P((PTR_T));static void dispose_temporary_env __P((sh_free_func_t *));     static inline char *mk_env_string __P((const char *, const char *));static char **make_env_array_from_var_list __P((SHELL_VAR **));static char **make_var_export_array __P((VAR_CONTEXT *));static char **make_func_export_array __P((void));static void add_temp_array_to_env __P((char **, int, int));static int n_shell_variables __P((void));static int set_context __P((SHELL_VAR *));static void push_func_var __P((PTR_T));static void push_exported_var __P((PTR_T));static inline int find_special_var __P((const char *));static voidcreate_variable_tables (){  if (shell_variables == 0)    {      shell_variables = global_variables = new_var_context ((char *)NULL, 0);      shell_variables->scope = 0;      shell_variables->table = hash_create (0);    }  if (shell_functions == 0)    shell_functions = hash_create (0);#if defined (DEBUGGER)  if (shell_function_defs == 0)    shell_function_defs = hash_create (0);#endif}/* Initialize the shell variables from the current environment.   If PRIVMODE is nonzero, don't import functions from ENV or   parse $SHELLOPTS. */voidinitialize_shell_variables (env, privmode)     char **env;     int privmode;{  char *name, *string, *temp_string;  int c, char_index, string_index, string_length;  SHELL_VAR *temp_var;  create_variable_tables ();  for (string_index = 0; string = env[string_index++]; )    {      char_index = 0;      name = string;      while ((c = *string++) && c != '=')	;      if (string[-1] == '=')	char_index = string - name - 1;      /* If there are weird things in the environment, like `=xxx' or a	 string without an `=', just skip them. */      if (char_index == 0)	continue;      /* ASSERT(name[char_index] == '=') */      name[char_index] = '\0';      /* Now, name = env variable name, string = env variable value, and	 char_index == strlen (name) */      temp_var = (SHELL_VAR *)NULL;      /* If exported function, define it now.  Don't import functions from	 the environment in privileged mode. */      if (privmode == 0 && read_but_dont_execute == 0 && STREQN ("() {", string, 4))	{	  string_length = strlen (string);	  temp_string = (char *)xmalloc (3 + string_length + char_index);	  strcpy (temp_string, name);	  temp_string[char_index] = ' ';	  strcpy (temp_string + char_index + 1, string);	  parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST);	  /* Ancient backwards compatibility.  Old versions of bash exported	     functions like name()=() {...} */	  if (name[char_index - 1] == ')' && name[char_index - 2] == '(')	    name[char_index - 2] = '\0';	  if (temp_var = find_function (name))	    {	      VSETATTR (temp_var, (att_exported|att_imported));	      array_needs_making = 1;	    }	  else	    report_error (_("error importing function definition for `%s'"), name);	  /* ( */	  if (name[char_index - 1] == ')' && name[char_index - 2] == '\0')	    name[char_index - 2] = '(';		/* ) */	}#if defined (ARRAY_VARS)#  if 0      /* Array variables may not yet be exported. */      else if (*string == '(' && string[1] == '[' && string[strlen (string) - 1] == ')')	{	  string_length = 1;	  temp_string = extract_array_assignment_list (string, &string_length);	  temp_var = assign_array_from_string (name, temp_string);	  FREE (temp_string);	  VSETATTR (temp_var, (att_exported | att_imported));	  array_needs_making = 1;	}#  endif#endif#if 0      else if (legal_identifier (name))#else      else#endif	{	  temp_var = bind_variable (name, string, 0);	  if (temp_var)	    {	      if (legal_identifier (name))		VSETATTR (temp_var, (att_exported | att_imported));	      else		VSETATTR (temp_var, (att_exported | att_imported | att_invisible));	      array_needs_making = 1;	    }	}      name[char_index] = '=';      /* temp_var can be NULL if it was an exported function with a syntax	 error (a different bug, but it still shouldn't dump core). */      if (temp_var && function_p (temp_var) == 0)	/* XXX not yet */	{	  CACHE_IMPORTSTR (temp_var, name);	}    }  set_pwd ();  /* Set up initial value of $_ */  temp_var = set_if_not ("_", dollar_vars[0]);  /* Remember this pid. */  dollar_dollar_pid = getpid ();  /* Now make our own defaults in case the vars that we think are     important are missing. */  temp_var = set_if_not ("PATH", DEFAULT_PATH_VALUE);#if 0  set_auto_export (temp_var);	/* XXX */#endif  temp_var = set_if_not ("TERM", "dumb");#if 0  set_auto_export (temp_var);	/* XXX */#endif#if defined (__QNX__)  /* set node id -- don't import it from the environment */  {    char node_name[22];#  if defined (__QNXNTO__)    netmgr_ndtostr(ND2S_LOCAL_STR, ND_LOCAL_NODE, node_name, sizeof(node_name));#  else    qnx_nidtostr (getnid (), node_name, sizeof (node_name));#  endif    temp_var = bind_variable ("NODE", node_name, 0);    set_auto_export (temp_var);  }#endif  /* set up the prompts. */  if (interactive_shell)    {#if defined (PROMPT_STRING_DECODE)      set_if_not ("PS1", primary_prompt);#else      if (current_user.uid == -1)	get_current_user_info ();      set_if_not ("PS1", current_user.euid == 0 ? "# " : primary_prompt);#endif      set_if_not ("PS2", secondary_prompt);    }  set_if_not ("PS4", "+ ");  /* Don't allow IFS to be imported from the environment. */  temp_var = bind_variable ("IFS", " \t\n", 0);  setifs (temp_var);  /* Magic machine types.  Pretty convenient. */  set_machine_vars ();  /* Default MAILCHECK for interactive shells.  Defer the creation of a     default MAILPATH until the startup files are read, because MAIL     names a mail file if MAILPATH is not set, and we should provide a     default only if neither is set. */  if (interactive_shell)    {      temp_var = set_if_not ("MAILCHECK", posixly_correct ? "600" : "60");      VSETATTR (temp_var, att_integer);    }  /* Do some things with shell level. */  initialize_shell_level ();  set_ppid ();  /* Initialize the `getopts' stuff. */  temp_var = bind_variable ("OPTIND", "1", 0);  VSETATTR (temp_var, att_integer);  getopts_reset (0);  bind_variable ("OPTERR", "1", 0);  sh_opterr = 1;  if (login_shell == 1 && posixly_correct == 0)    set_home_var ();  /* Get the full pathname to THIS shell, and set the BASH variable     to it. */  name = get_bash_name ();  temp_var = bind_variable ("BASH", name, 0);  free (name);  /* Make the exported environment variable SHELL be the user's login     shell.  Note that the `tset' command looks at this variable     to determine what style of commands to output; if it ends in "csh",     then C-shell commands are output, else Bourne shell commands. */  set_shell_var ();  /* Make a variable called BASH_VERSION which contains the version info. */  bind_variable ("BASH_VERSION", shell_version_string (), 0);#if defined (ARRAY_VARS)  make_vers_array ();#endif  if (command_execution_string)    bind_variable ("BASH_EXECUTION_STRING", command_execution_string, 0);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -