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

📄 glob.c

📁 压缩包中包含LINUX下多个命令的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	  dirname = getenv ("HOME");#ifdef _AMIGA	  if (dirname == NULL || dirname[0] == '\0')	    dirname = "SYS:";#else#ifdef WIN32	  if (dirname == NULL || dirname[0] == '\0')            dirname = "c:/users/default"; /* poor default */#else	  if (dirname == NULL || dirname[0] == '\0')	    {	      extern char *getlogin __P ((void));	      char *name = getlogin ();	      if (name != NULL)		{		  struct passwd *p = getpwnam (name);		  if (p != NULL)		    dirname = p->pw_dir;		}	    }	  if (dirname == NULL || dirname[0] == '\0')	    dirname = (char *) "~"; /* No luck.  */#endif /* WIN32 */#endif	}      else	{#ifdef _AMIGA	  if (dirname == NULL || dirname[0] == '\0')	    dirname = "SYS:";#else#ifdef WIN32	  if (dirname == NULL || dirname[0] == '\0')            dirname = "c:/users/default"; /* poor default */#else	  /* Look up specific user's home directory.  */	  struct passwd *p = getpwnam (dirname + 1);	  if (p != NULL)	    dirname = p->pw_dir;#endif /* WIN32 */#endif	}    }#endif	/* Not VMS.  */  if (glob_pattern_p (dirname, !(flags & GLOB_NOESCAPE)))    {      /* The directory name contains metacharacters, so we	 have to glob for the directory, and then glob for	 the pattern in each directory found.  */      glob_t dirs;      register int i;      status = glob (dirname,		     ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE)) |		      GLOB_NOSORT),		     errfunc, &dirs);      if (status != 0)	return status;      /* We have successfully globbed the preceding directory name.	 For each name we found, call glob_in_dir on it and FILENAME,	 appending the results to PGLOB.  */      for (i = 0; i < dirs.gl_pathc; ++i)	{	  int oldcount;#ifdef	SHELL	  {	    /* Make globbing interruptible in the bash shell. */	    extern int interrupt_state;	    if (interrupt_state)	      {		globfree (&dirs);		globfree (&files);		return GLOB_ABEND;	      }	  }#endif /* SHELL.  */	  oldcount = pglob->gl_pathc;	  status = glob_in_dir (filename, dirs.gl_pathv[i],				(flags | GLOB_APPEND) & ~GLOB_NOCHECK,				errfunc, pglob);	  if (status == GLOB_NOMATCH)	    /* No matches in this directory.  Try the next.  */	    continue;	  if (status != 0)	    {	      globfree (&dirs);	      globfree (pglob);	      return status;	    }	  /* Stick the directory on the front of each name.  */	  if (prefix_array (dirs.gl_pathv[i],			    &pglob->gl_pathv[oldcount],			    pglob->gl_pathc - oldcount))	    {	      globfree (&dirs);	      globfree (pglob);	      return GLOB_NOSPACE;	    }	}      flags |= GLOB_MAGCHAR;      if (pglob->gl_pathc == oldcount)	/* No matches.  */	if (flags & GLOB_NOCHECK)	  {	    size_t len = strlen (pattern) + 1;	    char *patcopy = (char *) malloc (len);	    if (patcopy == NULL)	      return GLOB_NOSPACE;	    memcpy (patcopy, pattern, len);	    pglob->gl_pathv	      = (char **) realloc (pglob->gl_pathv,				   (pglob->gl_pathc +				    ((flags & GLOB_DOOFFS) ?				     pglob->gl_offs : 0) +				    1 + 1) *				   sizeof (char *));	    if (pglob->gl_pathv == NULL)	      {		free (patcopy);		return GLOB_NOSPACE;	      }	    if (flags & GLOB_DOOFFS)	      while (pglob->gl_pathc < pglob->gl_offs)		pglob->gl_pathv[pglob->gl_pathc++] = NULL;	    pglob->gl_pathv[pglob->gl_pathc++] = patcopy;	    pglob->gl_pathv[pglob->gl_pathc] = NULL;	    pglob->gl_flags = flags;	  }	else	  return GLOB_NOMATCH;    }  else    {      status = glob_in_dir (filename, dirname, flags, errfunc, pglob);      if (status != 0)	return status;      if (dirlen > 0)	{	  /* Stick the directory on the front of each name.  */	  if (prefix_array (dirname,			    &pglob->gl_pathv[oldcount],			    pglob->gl_pathc - oldcount))	    {	      globfree (pglob);	      return GLOB_NOSPACE;	    }	}    }  if (flags & GLOB_MARK)    {      /* Append slashes to directory names.  */      int i;      struct stat st;      for (i = oldcount; i < pglob->gl_pathc; ++i)	if (((flags & GLOB_ALTDIRFUNC) ?	     (*pglob->gl_stat) (pglob->gl_pathv[i], &st) :	     __stat (pglob->gl_pathv[i], &st)) == 0 &&	    S_ISDIR (st.st_mode))	  { 	    size_t len = strlen (pglob->gl_pathv[i]) + 2;	    char *new = realloc (pglob->gl_pathv[i], len); 	    if (new == NULL)	      {		globfree (pglob);		return GLOB_NOSPACE;	      }	    strcpy (&new[len - 2], "/");	    pglob->gl_pathv[i] = new;	  }    }  if (!(flags & GLOB_NOSORT))    /* Sort the vector.  */    qsort ((__ptr_t) &pglob->gl_pathv[oldcount],	   pglob->gl_pathc - oldcount,	   sizeof (char *), collated_compare);  return 0;}/* Free storage allocated in PGLOB by a previous `glob' call.  */voidglobfree (pglob)     register glob_t *pglob;{  if (pglob->gl_pathv != NULL)    {      register int i;      for (i = 0; i < pglob->gl_pathc; ++i)	if (pglob->gl_pathv[i] != NULL)	  free ((__ptr_t) pglob->gl_pathv[i]);      free ((__ptr_t) pglob->gl_pathv);    }}/* Do a collated comparison of A and B.  */static intcollated_compare (a, b)     const __ptr_t a;     const __ptr_t b;{  const char *const s1 = *(const char *const * const) a;  const char *const s2 = *(const char *const * const) b;  if (s1 == s2)    return 0;  if (s1 == NULL)    return 1;  if (s2 == NULL)    return -1;  return strcoll (s1, s2);}/* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's   elements in place.  Return nonzero if out of memory, zero if successful.   A slash is inserted between DIRNAME and each elt of ARRAY,   unless DIRNAME is just "/".  Each old element of ARRAY is freed.  */static intprefix_array (dirname, array, n)     const char *dirname;     char **array;     size_t n;{  register size_t i;  size_t dirlen = strlen (dirname);  if (dirlen == 1 && dirname[0] == '/')    /* DIRNAME is just "/", so normal prepending would get us "//foo".       We want "/foo" instead, so don't prepend any chars from DIRNAME.  */    dirlen = 0;  for (i = 0; i < n; ++i)    {      size_t eltlen = strlen (array[i]) + 1;      char *new = (char *) malloc (dirlen + 1 + eltlen);      if (new == NULL)	{	  while (i > 0)	    free ((__ptr_t) array[--i]);	  return 1;	}      memcpy (new, dirname, dirlen);      new[dirlen] = '/';      memcpy (&new[dirlen + 1], array[i], eltlen);      free ((__ptr_t) array[i]);      array[i] = new;    }  return 0;}/* Return nonzero if PATTERN contains any metacharacters.   Metacharacters can be quoted with backslashes if QUOTE is nonzero.  */static intglob_pattern_p (pattern, quote)     const char *pattern;     int quote;{  register const char *p;  int open = 0;  for (p = pattern; *p != '\0'; ++p)    switch (*p)      {      case '?':      case '*':	return 1;      case '\\':	if (quote && p[1] != '\0')	  ++p;	break;      case '[':	open = 1;	break;      case ']':	if (open)	  return 1;	break;      }  return 0;}/* Like `glob', but PATTERN is a final pathname component,   and matches are searched for in DIRECTORY.   The GLOB_NOSORT bit in FLAGS is ignored.  No sorting is ever done.   The GLOB_APPEND flag is assumed to be set (always appends).  */static intglob_in_dir (pattern, directory, flags, errfunc, pglob)     const char *pattern;     const char *directory;     int flags;     int (*errfunc) __P ((const char *, int));     glob_t *pglob;{  __ptr_t stream;  struct globlink    {      struct globlink *next;      char *name;    };  struct globlink *names = NULL;  size_t nfound = 0;  if (!glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE)))    {      stream = NULL;      flags |= GLOB_NOCHECK;    }  else    {      flags |= GLOB_MAGCHAR;      stream = ((flags & GLOB_ALTDIRFUNC) ?		(*pglob->gl_opendir) (directory) :		(__ptr_t) opendir (directory));      if (stream == NULL)	{	  if ((errfunc != NULL && (*errfunc) (directory, errno)) ||	      (flags & GLOB_ERR))	    return GLOB_ABEND;	}      else	while (1)	  {	    const char *name;	    size_t len;	    struct dirent *d = ((flags & GLOB_ALTDIRFUNC) ?				(*pglob->gl_readdir) (stream) :				readdir ((DIR *) stream));	    if (d == NULL)	      break;	    if (! REAL_DIR_ENTRY (d))	      continue;	    name = d->d_name;	    if (fnmatch (pattern, name,			 (!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0) |			 ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)#ifdef _AMIGA			 | FNM_CASEFOLD#endif			 ) == 0)	      {		struct globlink *new		  = (struct globlink *) __alloca (sizeof (struct globlink));		len = NAMLEN (d);		new->name		  = (char *) malloc (len + 1);		if (new->name == NULL)		  goto memory_error;		memcpy ((__ptr_t) new->name, name, len);		new->name[len] = '\0';		new->next = names;		names = new;		++nfound;	      }	  }    }  if (nfound == 0 && (flags & GLOB_NOMAGIC) &&      ! glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE)))    flags |= GLOB_NOCHECK;  if (nfound == 0 && (flags & GLOB_NOCHECK))    {      size_t len = strlen (pattern);      nfound = 1;      names = (struct globlink *) __alloca (sizeof (struct globlink));      names->next = NULL;      names->name = (char *) malloc (len + 1);      if (names->name == NULL)	goto memory_error;      memcpy (names->name, pattern, len);      names->name[len] = '\0';    }  pglob->gl_pathv    = (char **) realloc (pglob->gl_pathv,			 (pglob->gl_pathc +			  ((flags & GLOB_DOOFFS) ? pglob->gl_offs : 0) +			  nfound + 1) *			 sizeof (char *));  if (pglob->gl_pathv == NULL)    goto memory_error;  if (flags & GLOB_DOOFFS)    while (pglob->gl_pathc < pglob->gl_offs)      pglob->gl_pathv[pglob->gl_pathc++] = NULL;  for (; names != NULL; names = names->next)    pglob->gl_pathv[pglob->gl_pathc++] = names->name;  pglob->gl_pathv[pglob->gl_pathc] = NULL;  pglob->gl_flags = flags;  if (stream != NULL)    {      int save = errno;      if (flags & GLOB_ALTDIRFUNC)	(*pglob->gl_closedir) (stream);      else	closedir ((DIR *) stream);      errno = save;    }  return nfound == 0 ? GLOB_NOMATCH : 0; memory_error:  {    int save = errno;    if (flags & GLOB_ALTDIRFUNC)      (*pglob->gl_closedir) (stream);    else      closedir ((DIR *) stream);    errno = save;  }  while (names != NULL)    {      if (names->name != NULL)	free ((__ptr_t) names->name);      names = names->next;    }  return GLOB_NOSPACE;}#endif	/* Not ELIDE_CODE.  */

⌨️ 快捷键说明

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