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

📄 findcmd.c

📁 android-w.song.android.widget
💻 C
📖 第 1 页 / 共 2 页
字号:
/* findcmd.c -- Functions to search for commands by name. *//* Copyright (C) 1997-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"#include <stdio.h>#include "chartypes.h"#include "bashtypes.h"#if !defined (_MINIX) && defined (HAVE_SYS_FILE_H)#  include <sys/file.h>#endif#include "filecntl.h"#include "posixstat.h"#if defined (HAVE_UNISTD_H)#  include <unistd.h>#endif#include <errno.h>#include "bashansi.h"#include "memalloc.h"#include "shell.h"#include "flags.h"#include "hashlib.h"#include "pathexp.h"#include "hashcmd.h"#include "findcmd.h"	/* matching prototypes and declarations */#if !defined (errno)extern int errno;#endifextern int posixly_correct;/* Static functions defined and used in this file. */static char *_find_user_command_internal __P((const char *, int));static char *find_user_command_internal __P((const char *, int));static char *find_user_command_in_path __P((const char *, char *, int));static char *find_in_path_element __P((const char *, char *, int, int, struct stat *));static char *find_absolute_program __P((const char *, int));static char *get_next_path_element __P((char *, int *));/* The file name which we would try to execute, except that it isn't   possible to execute it.  This is the first file that matches the   name that we are looking for while we are searching $PATH for a   suitable one to execute.  If we cannot find a suitable executable   file, then we use this one. */static char *file_to_lose_on;/* Non-zero if we should stat every command found in the hash table to   make sure it still exists. */int check_hashed_filenames;/* DOT_FOUND_IN_SEARCH becomes non-zero when find_user_command ()   encounters a `.' as the directory pathname while scanning the   list of possible pathnames; i.e., if `.' comes before the directory   containing the file of interest. */int dot_found_in_search = 0;/* Return some flags based on information about this file.   The EXISTS bit is non-zero if the file is found.   The EXECABLE bit is non-zero the file is executble.   Zero is returned if the file is not found. */intfile_status (name)     const char *name;{  struct stat finfo;  int r;  /* Determine whether this file exists or not. */  if (stat (name, &finfo) < 0)    return (0);  /* If the file is a directory, then it is not "executable" in the     sense of the shell. */  if (S_ISDIR (finfo.st_mode))    return (FS_EXISTS|FS_DIRECTORY);  r = FS_EXISTS;#if defined (HAVE_EACCESS)  /* Use eaccess(2) if we have it to take things like ACLs and other     file access mechanisms into account.  eaccess uses the effective     user and group IDs, not the real ones.  We could use sh_eaccess,     but we don't want any special treatment for /dev/fd. */  if (eaccess (name, X_OK) == 0)    r |= FS_EXECABLE;  if (eaccess (name, R_OK) == 0)    r |= FS_READABLE;  return r;#elif defined (AFS)  /* We have to use access(2) to determine access because AFS does not     support Unix file system semantics.  This may produce wrong     answers for non-AFS files when ruid != euid.  I hate AFS. */  if (access (name, X_OK) == 0)    r |= FS_EXECABLE;  if (access (name, R_OK) == 0)    r |= FS_READABLE;  return r;#else /* !HAVE_EACCESS && !AFS */  /* Find out if the file is actually executable.  By definition, the     only other criteria is that the file has an execute bit set that     we can use.  The same with whether or not a file is readable. */  /* Root only requires execute permission for any of owner, group or     others to be able to exec a file, and can read any file. */  if (current_user.euid == (uid_t)0)    {      r |= FS_READABLE;      if (finfo.st_mode & S_IXUGO)	r |= FS_EXECABLE;      return r;    }  /* If we are the owner of the file, the owner bits apply. */  if (current_user.euid == finfo.st_uid)    {      if (finfo.st_mode & S_IXUSR)	r |= FS_EXECABLE;      if (finfo.st_mode & S_IRUSR)	r |= FS_READABLE;    }  /* If we are in the owning group, the group permissions apply. */  else if (group_member (finfo.st_gid))    {      if (finfo.st_mode & S_IXGRP)	r |= FS_EXECABLE;      if (finfo.st_mode & S_IRGRP)	r |= FS_READABLE;    }  /* Else we check whether `others' have permission to execute the file */  else    {      if (finfo.st_mode & S_IXOTH)	r |= FS_EXECABLE;      if (finfo.st_mode & S_IROTH)	r |= FS_READABLE;    }  return r;#endif /* !AFS */}/* Return non-zero if FILE exists and is executable.   Note that this function is the definition of what an   executable file is; do not change this unless YOU know   what an executable file is. */intexecutable_file (file)     const char *file;{  int s;  s = file_status (file);#if defined EISDIR  if (s & FS_DIRECTORY)    errno = EISDIR;	/* let's see if we can improve error messages */#endif  return ((s & FS_EXECABLE) && ((s & FS_DIRECTORY) == 0));}intis_directory (file)     const char *file;{  return (file_status (file) & FS_DIRECTORY);}intexecutable_or_directory (file)     const char *file;{  int s;  s = file_status (file);  return ((s & FS_EXECABLE) || (s & FS_DIRECTORY));}/* Locate the executable file referenced by NAME, searching along   the contents of the shell PATH variable.  Return a new string   which is the full pathname to the file, or NULL if the file   couldn't be found.  If a file is found that isn't executable,   and that is the only match, then return that. */char *find_user_command (name)     const char *name;{  return (find_user_command_internal (name, FS_EXEC_PREFERRED|FS_NODIRS));}/* Locate the file referenced by NAME, searching along the contents   of the shell PATH variable.  Return a new string which is the full   pathname to the file, or NULL if the file couldn't be found.  This   returns the first readable file found; designed to be used to look   for shell scripts or files to source. */char *find_path_file (name)     const char *name;{  return (find_user_command_internal (name, FS_READABLE));}static char *_find_user_command_internal (name, flags)     const char *name;     int flags;{  char *path_list, *cmd;  SHELL_VAR *var;  /* Search for the value of PATH in both the temporary environments and     in the regular list of variables. */  if (var = find_variable_internal ("PATH", 1))	/* XXX could be array? */    path_list = value_cell (var);  else    path_list = (char *)NULL;  if (path_list == 0 || *path_list == '\0')    return (savestring (name));  cmd = find_user_command_in_path (name, path_list, flags);  return (cmd);}static char *find_user_command_internal (name, flags)     const char *name;     int flags;{#ifdef __WIN32__  char *res, *dotexe;  dotexe = (char *)xmalloc (strlen (name) + 5);  strcpy (dotexe, name);  strcat (dotexe, ".exe");  res = _find_user_command_internal (dotexe, flags);  free (dotexe);  if (res == 0)    res = _find_user_command_internal (name, flags);  return res;#else  return (_find_user_command_internal (name, flags));#endif}/* Return the next element from PATH_LIST, a colon separated list of   paths.  PATH_INDEX_POINTER is the address of an index into PATH_LIST;   the index is modified by this function.   Return the next element of PATH_LIST or NULL if there are no more. */static char *get_next_path_element (path_list, path_index_pointer)     char *path_list;     int *path_index_pointer;{  char *path;  path = extract_colon_unit (path_list, path_index_pointer);  if (path == 0)    return (path);  if (*path == '\0')    {      free (path);      path = savestring (".");    }  return (path);}/* Look for PATHNAME in $PATH.  Returns either the hashed command   corresponding to PATHNAME or the first instance of PATHNAME found   in $PATH.  Returns a newly-allocated string. */char *search_for_command (pathname)     const char *pathname;{  char *hashed_file, *command;  int temp_path, st;  SHELL_VAR *path;  hashed_file = command = (char *)NULL;

⌨️ 快捷键说明

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