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

📄 evalfile.c

📁 android-w.song.android.widget
💻 C
字号:
/* evalfile.c - read and evaluate commands from a file or file descriptor *//* Copyright (C) 1996-2009 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>#if defined (HAVE_UNISTD_H)#  include <unistd.h>#endif#include "../bashtypes.h"#include "posixstat.h"#include "filecntl.h"#include <stdio.h>#include <signal.h>#include <errno.h>#include "../bashansi.h"#include "../bashintl.h"#include "../shell.h"#include "../jobs.h"#include "../builtins.h"#include "../flags.h"#include "../input.h"#include "../execute_cmd.h"#include "../trap.h"#if defined (HISTORY)#  include "../bashhist.h"#endif#include <typemax.h>#include "common.h"#if !defined (errno)extern int errno;#endif/* Flags for _evalfile() */#define FEVAL_ENOENTOK		0x001#define FEVAL_BUILTIN		0x002#define FEVAL_UNWINDPROT	0x004#define FEVAL_NONINT		0x008#define FEVAL_LONGJMP		0x010#define FEVAL_HISTORY		0x020#define FEVAL_CHECKBINARY	0x040#define FEVAL_REGFILE		0x080#define FEVAL_NOPUSHARGS	0x100extern int posixly_correct;extern int indirection_level, subshell_environment;extern int return_catch_flag, return_catch_value;extern int last_command_exit_value;extern int executing_command_builtin;/* How many `levels' of sourced files we have. */int sourcelevel = 0;static int_evalfile (filename, flags)     const char *filename;     int flags;{  volatile int old_interactive;  procenv_t old_return_catch;  int return_val, fd, result, pflags, i, nnull;  ssize_t nr;			/* return value from read(2) */  char *string;  struct stat finfo;  size_t file_size;  sh_vmsg_func_t *errfunc;#if defined (ARRAY_VARS)  SHELL_VAR *funcname_v, *nfv, *bash_source_v, *bash_lineno_v;  ARRAY *funcname_a, *bash_source_a, *bash_lineno_a;#  if defined (DEBUGGER)  SHELL_VAR *bash_argv_v, *bash_argc_v;  ARRAY *bash_argv_a, *bash_argc_a;#  endif  char *t, tt[2];#endif  USE_VAR(pflags);#if defined (ARRAY_VARS)  GET_ARRAY_FROM_VAR ("FUNCNAME", funcname_v, funcname_a);  GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a);  GET_ARRAY_FROM_VAR ("BASH_LINENO", bash_lineno_v, bash_lineno_a);#  if defined (DEBUGGER)  GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a);  GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);#  endif#endif    fd = open (filename, O_RDONLY);  if (fd < 0 || (fstat (fd, &finfo) == -1))    {file_error_and_exit:      if (((flags & FEVAL_ENOENTOK) == 0) || errno != ENOENT)	file_error (filename);      if (flags & FEVAL_LONGJMP)	{	  last_command_exit_value = 1;	  jump_to_top_level (EXITPROG);	}      return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE      				      : ((errno == ENOENT) ? 0 : -1));    }  errfunc = ((flags & FEVAL_BUILTIN) ? builtin_error : internal_error);  if (S_ISDIR (finfo.st_mode))    {      (*errfunc) (_("%s: is a directory"), filename);      return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);    }  else if ((flags & FEVAL_REGFILE) && S_ISREG (finfo.st_mode) == 0)    {      (*errfunc) (_("%s: not a regular file"), filename);      return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);    }  file_size = (size_t)finfo.st_size;  /* Check for overflow with large files. */  if (file_size != finfo.st_size || file_size + 1 < file_size)    {      (*errfunc) (_("%s: file is too large"), filename);      return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);    }        if (S_ISREG (finfo.st_mode) && file_size <= SSIZE_MAX)    {      string = (char *)xmalloc (1 + file_size);      nr = read (fd, string, file_size);      if (nr >= 0)	string[nr] = '\0';    }  else    nr = zmapfd (fd, &string, 0);  return_val = errno;  close (fd);  errno = return_val;  if (nr < 0)		/* XXX was != file_size, not < 0 */    {      free (string);      goto file_error_and_exit;    }  if (nr == 0)    {      free (string);      return ((flags & FEVAL_BUILTIN) ? EXECUTION_SUCCESS : 1);    }        if ((flags & FEVAL_CHECKBINARY) &&       check_binary_file (string, (nr > 80) ? 80 : nr))    {      free (string);      (*errfunc) (_("%s: cannot execute binary file"), filename);      return ((flags & FEVAL_BUILTIN) ? EX_BINARY_FILE : -1);    }  i = strlen (string);  if (i < nr)    {      for (nnull = i = 0; i < nr; i++)	if (string[i] == '\0')          {	    memmove (string+i, string+i+1, nr - i);	    nr--;	    /* Even if the `check binary' flag is not set, we want to avoid	       sourcing files with more than 256 null characters -- that	       probably indicates a binary file. */	    if ((flags & FEVAL_BUILTIN) && ++nnull > 256)	      {		free (string);		(*errfunc) (_("%s: cannot execute binary file"), filename);		return ((flags & FEVAL_BUILTIN) ? EX_BINARY_FILE : -1);	      }          }    }  if (flags & FEVAL_UNWINDPROT)    {      begin_unwind_frame ("_evalfile");      unwind_protect_int (return_catch_flag);      unwind_protect_jmp_buf (return_catch);      if (flags & FEVAL_NONINT)	unwind_protect_int (interactive);      unwind_protect_int (sourcelevel);    }  else    {      COPY_PROCENV (return_catch, old_return_catch);      if (flags & FEVAL_NONINT)	old_interactive = interactive;    }  if (flags & FEVAL_NONINT)    interactive = 0;  return_catch_flag++;  sourcelevel++;#if defined (ARRAY_VARS)  array_push (bash_source_a, (char *)filename);  t = itos (executing_line_number ());  array_push (bash_lineno_a, t);  free (t);  array_push (funcname_a, "source");	/* not exactly right */#  if defined (DEBUGGER)  /* Have to figure out a better way to do this when `source' is supplied     arguments */  if ((flags & FEVAL_NOPUSHARGS) == 0)    {      array_push (bash_argv_a, (char *)filename);      tt[0] = '1'; tt[1] = '\0';      array_push (bash_argc_a, tt);    }#  endif#endif  /* set the flags to be passed to parse_and_execute */  pflags = SEVAL_RESETLINE;  pflags |= (flags & FEVAL_HISTORY) ? 0 : SEVAL_NOHIST;  if (flags & FEVAL_BUILTIN)    result = EXECUTION_SUCCESS;  return_val = setjmp (return_catch);  /* If `return' was seen outside of a function, but in the script, then     force parse_and_execute () to clean up. */  if (return_val)    {      parse_and_execute_cleanup ();      result = return_catch_value;    }  else    result = parse_and_execute (string, filename, pflags);  if (flags & FEVAL_UNWINDPROT)    run_unwind_frame ("_evalfile");  else    {      if (flags & FEVAL_NONINT)	interactive = old_interactive;      return_catch_flag--;      sourcelevel--;      COPY_PROCENV (old_return_catch, return_catch);    }#if defined (ARRAY_VARS)  /* These two variables cannot be unset, and cannot be affected by the     sourced file. */  array_pop (bash_source_a);  array_pop (bash_lineno_a);  /* FUNCNAME can be unset, and so can potentially be changed by the     sourced file. */  GET_ARRAY_FROM_VAR ("FUNCNAME", nfv, funcname_a);  if (nfv == funcname_v)    array_pop (funcname_a);#  if defined (DEBUGGER)  if ((flags & FEVAL_NOPUSHARGS) == 0)    {      array_pop (bash_argc_a);      array_pop (bash_argv_a);    }#  endif#endif  return ((flags & FEVAL_BUILTIN) ? result : 1);}intmaybe_execute_file (fname, force_noninteractive)     const char *fname;     int force_noninteractive;{  char *filename;  int result, flags;  filename = bash_tilde_expand (fname, 0);  flags = FEVAL_ENOENTOK;  if (force_noninteractive)    flags |= FEVAL_NONINT;  result = _evalfile (filename, flags);  free (filename);  return result;}#if defined (HISTORY)intfc_execute_file (filename)     const char *filename;{  int flags;  /* We want these commands to show up in the history list if     remember_on_history is set. */  flags = FEVAL_ENOENTOK|FEVAL_HISTORY|FEVAL_REGFILE;  return (_evalfile (filename, flags));}#endif /* HISTORY */intsource_file (filename, sflags)     const char *filename;     int sflags;{  int flags, rval;  flags = FEVAL_BUILTIN|FEVAL_UNWINDPROT|FEVAL_NONINT;  if (sflags)    flags |= FEVAL_NOPUSHARGS;  /* POSIX shells exit if non-interactive and file error. */  if (posixly_correct && interactive_shell == 0 && executing_command_builtin == 0)    flags |= FEVAL_LONGJMP;  rval = _evalfile (filename, flags);  run_return_trap ();  return rval;}

⌨️ 快捷键说明

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