[BACK]Return to glob.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libc / gen

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/lib/libc/gen/glob.c between version 1.23.4.2 and 1.24

version 1.23.4.2, 2011/04/24 15:41:10 version 1.24, 2009/04/08 16:28:50
Line 87  __RCSID("$NetBSD$");
Line 87  __RCSID("$NetBSD$");
 #define NO_GETPW_R  #define NO_GETPW_R
 #endif  #endif
   
 #define GLOB_LIMIT_STRING       65536   /* number of readdirs */  #if !defined(ARG_MAX)
 #define GLOB_LIMIT_STAT         128     /* number of stat system calls */  #include <limits.h>
 #define GLOB_LIMIT_READDIR      16384   /* total buffer size of path strings */  #define ARG_MAX _POSIX_ARG_MAX
 #define GLOB_LIMIT_PATH         1024    /* number of path elements */  #endif
 #define GLOB_LIMIT_BRACE        128     /* Number of brace calls */  
   
 struct glob_limit {  
         size_t l_string;  
         size_t l_stat;  
         size_t l_readdir;  
         size_t l_brace;  
 };  
   
 /*  /*
  * XXX: For NetBSD 1.4.x compatibility. (kill me l8r)   * XXX: For NetBSD 1.4.x compatibility. (kill me l8r)
Line 163  static int  g_lstat(Char *, __gl_stat_t 
Line 155  static int  g_lstat(Char *, __gl_stat_t 
 static DIR      *g_opendir(Char *, glob_t *);  static DIR      *g_opendir(Char *, glob_t *);
 static Char     *g_strchr(const Char *, int);  static Char     *g_strchr(const Char *, int);
 static int       g_stat(Char *, __gl_stat_t *, glob_t *);  static int       g_stat(Char *, __gl_stat_t *, glob_t *);
 static int       glob0(const Char *, glob_t *, struct glob_limit *);  static int       glob0(const Char *, glob_t *);
 static int       glob1(Char *, glob_t *, struct glob_limit *);  static int       glob1(Char *, glob_t *, size_t *);
 static int       glob2(Char *, Char *, Char *, const Char *, glob_t *,  static int       glob2(Char *, Char *, Char *, Char *, glob_t *,
     struct glob_limit *);      size_t *);
 static int       glob3(Char *, Char *, Char *, const Char *, const Char *,  static int       glob3(Char *, Char *, Char *, Char *, Char *, glob_t *,
     glob_t *, struct glob_limit *);      size_t *);
 static int       globextend(const Char *, glob_t *, struct glob_limit *);  static int       globextend(const Char *, glob_t *, size_t *);
 static const Char *globtilde(const Char *, Char *, size_t, glob_t *);  static const Char *globtilde(const Char *, Char *, size_t, glob_t *);
 static int       globexp1(const Char *, glob_t *, struct glob_limit *);  static int       globexp1(const Char *, glob_t *);
 static int       globexp2(const Char *, const Char *, glob_t *, int *,  static int       globexp2(const Char *, const Char *, glob_t *, int *);
     struct glob_limit *);  static int       match(Char *, Char *, Char *);
 static int       match(const Char *, const Char *, const Char *);  
 #ifdef DEBUG  #ifdef DEBUG
 static void      qprintf(const char *, Char *);  static void      qprintf(const char *, Char *);
 #endif  #endif
Line 186  glob(const char *pattern, int flags, int
Line 177  glob(const char *pattern, int flags, int
         const u_char *patnext;          const u_char *patnext;
         int c;          int c;
         Char *bufnext, *bufend, patbuf[MAXPATHLEN+1];          Char *bufnext, *bufend, patbuf[MAXPATHLEN+1];
         struct glob_limit limit = { 0, 0, 0, 0 };  
   
         _DIAGASSERT(pattern != NULL);          _DIAGASSERT(pattern != NULL);
   
Line 222  glob(const char *pattern, int flags, int
Line 212  glob(const char *pattern, int flags, int
         *bufnext = EOS;          *bufnext = EOS;
   
         if (flags & GLOB_BRACE)          if (flags & GLOB_BRACE)
             return globexp1(patbuf, pglob, &limit);              return globexp1(patbuf, pglob);
         else          else
             return glob0(patbuf, pglob, &limit);              return glob0(patbuf, pglob);
 }  }
   
 /*  /*
Line 233  glob(const char *pattern, int flags, int
Line 223  glob(const char *pattern, int flags, int
  * characters   * characters
  */   */
 static int  static int
 globexp1(const Char *pattern, glob_t *pglob, struct glob_limit *limit)  globexp1(const Char *pattern, glob_t *pglob)
 {  {
         const Char* ptr = pattern;          const Char* ptr = pattern;
         int rv;          int rv;
Line 241  globexp1(const Char *pattern, glob_t *pg
Line 231  globexp1(const Char *pattern, glob_t *pg
         _DIAGASSERT(pattern != NULL);          _DIAGASSERT(pattern != NULL);
         _DIAGASSERT(pglob != NULL);          _DIAGASSERT(pglob != NULL);
   
         if ((pglob->gl_flags & GLOB_LIMIT) &&  
             limit->l_brace++ >= GLOB_LIMIT_BRACE) {  
                 errno = 0;  
                 return GLOB_NOSPACE;  
         }  
   
         /* Protect a single {}, for find(1), like csh */          /* Protect a single {}, for find(1), like csh */
         if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS)          if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS)
                 return glob0(pattern, pglob, limit);                  return glob0(pattern, pglob);
   
         while ((ptr = (const Char *) g_strchr(ptr, LBRACE)) != NULL)          while ((ptr = (const Char *) g_strchr(ptr, LBRACE)) != NULL)
                 if (!globexp2(ptr, pattern, pglob, &rv, limit))                  if (!globexp2(ptr, pattern, pglob, &rv))
                         return rv;                          return rv;
   
         return glob0(pattern, pglob, limit);          return glob0(pattern, pglob);
 }  }
   
   
Line 265  globexp1(const Char *pattern, glob_t *pg
Line 249  globexp1(const Char *pattern, glob_t *pg
  * If it fails then it tries to glob the rest of the pattern and returns.   * If it fails then it tries to glob the rest of the pattern and returns.
  */   */
 static int  static int
 globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int *rv,  globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int *rv)
     struct glob_limit *limit)  
 {  {
         int     i;          int     i;
         Char   *lm, *ls;          Char   *lm, *ls;
Line 311  globexp2(const Char *ptr, const Char *pa
Line 294  globexp2(const Char *ptr, const Char *pa
                  * we use `pattern', not `patbuf' here so that that                   * we use `pattern', not `patbuf' here so that that
                  * unbalanced braces are passed to the match                   * unbalanced braces are passed to the match
                  */                   */
                 *rv = glob0(pattern, pglob, limit);                  *rv = glob0(pattern, pglob);
                 return 0;                  return 0;
         }          }
   
Line 358  globexp2(const Char *ptr, const Char *pa
Line 341  globexp2(const Char *ptr, const Char *pa
 #ifdef DEBUG  #ifdef DEBUG
                                 qprintf("globexp2:", patbuf);                                  qprintf("globexp2:", patbuf);
 #endif  #endif
                                 *rv = globexp1(patbuf, pglob, limit);                                  *rv = globexp1(patbuf, pglob);
   
                                 /* move after the comma, to the next string */                                  /* move after the comma, to the next string */
                                 pl = pm + 1;                                  pl = pm + 1;
Line 471  globtilde(const Char *pattern, Char *pat
Line 454  globtilde(const Char *pattern, Char *pat
  * to find no matches.   * to find no matches.
  */   */
 static int  static int
 glob0(const Char *pattern, glob_t *pglob, struct glob_limit *limit)  glob0(const Char *pattern, glob_t *pglob)
 {  {
         const Char *qpatnext;          const Char *qpatnext;
         int c, error;          int c, error;
         __gl_size_t oldpathc;          __gl_size_t oldpathc;
         Char *bufnext, patbuf[MAXPATHLEN+1];          Char *bufnext, patbuf[MAXPATHLEN+1];
           size_t limit = 0;
   
         _DIAGASSERT(pattern != NULL);          _DIAGASSERT(pattern != NULL);
         _DIAGASSERT(pglob != NULL);          _DIAGASSERT(pglob != NULL);
Line 539  glob0(const Char *pattern, glob_t *pglob
Line 523  glob0(const Char *pattern, glob_t *pglob
         qprintf("glob0:", patbuf);          qprintf("glob0:", patbuf);
 #endif  #endif
   
         if ((error = glob1(patbuf, pglob, limit)) != 0)          if ((error = glob1(patbuf, pglob, &limit)) != 0)
                 return error;                  return error;
   
         if (pglob->gl_pathc == oldpathc) {          if (pglob->gl_pathc == oldpathc) {
Line 553  glob0(const Char *pattern, glob_t *pglob
Line 537  glob0(const Char *pattern, glob_t *pglob
                 if ((pglob->gl_flags & GLOB_NOCHECK) ||                  if ((pglob->gl_flags & GLOB_NOCHECK) ||
                     ((pglob->gl_flags & (GLOB_NOMAGIC|GLOB_MAGCHAR))                      ((pglob->gl_flags & (GLOB_NOMAGIC|GLOB_MAGCHAR))
                      == GLOB_NOMAGIC)) {                       == GLOB_NOMAGIC)) {
                         return globextend(pattern, pglob, limit);                          return globextend(pattern, pglob, &limit);
                 } else {                  } else {
                         return GLOB_NOMATCH;                          return GLOB_NOMATCH;
                 }                  }
Line 577  compare(const void *p, const void *q)
Line 561  compare(const void *p, const void *q)
 }  }
   
 static int  static int
 glob1(Char *pattern, glob_t *pglob, struct glob_limit *limit)  glob1(Char *pattern, glob_t *pglob, size_t *limit)
 {  {
         Char pathbuf[MAXPATHLEN+1];          Char pathbuf[MAXPATHLEN+1];
   
Line 602  glob1(Char *pattern, glob_t *pglob, stru
Line 586  glob1(Char *pattern, glob_t *pglob, stru
  * meta characters.   * meta characters.
  */   */
 static int  static int
 glob2(Char *pathbuf, Char *pathend, Char *pathlim, const Char *pattern,  glob2(Char *pathbuf, Char *pathend, Char *pathlim, Char *pattern, glob_t *pglob,
     glob_t *pglob, struct glob_limit *limit)      size_t *limit)
 {  {
         __gl_stat_t sb;          __gl_stat_t sb;
         const Char *p;          Char *p, *q;
         Char *q;  
         int anymeta;          int anymeta;
         Char *pend;          Char *pend;
         ptrdiff_t diff;          ptrdiff_t diff;
Line 627  glob2(Char *pathbuf, Char *pathend, Char
Line 610  glob2(Char *pathbuf, Char *pathend, Char
                         if (g_lstat(pathbuf, &sb, pglob))                          if (g_lstat(pathbuf, &sb, pglob))
                                 return 0;                                  return 0;
   
                         if ((pglob->gl_flags & GLOB_LIMIT) &&  
                             limit->l_stat++ >= GLOB_LIMIT_STAT) {  
                                 errno = 0;  
                                 *pathend++ = SEP;  
                                 *pathend = EOS;  
                                 return GLOB_NOSPACE;  
                         }  
                         if (((pglob->gl_flags & GLOB_MARK) &&                          if (((pglob->gl_flags & GLOB_MARK) &&
                             pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) ||                              pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) ||
                             (S_ISLNK(sb.st_mode) &&                              (S_ISLNK(sb.st_mode) &&
Line 694  glob2(Char *pathbuf, Char *pathend, Char
Line 670  glob2(Char *pathbuf, Char *pathend, Char
 }  }
   
 static int  static int
 glob3(Char *pathbuf, Char *pathend, Char *pathlim, const Char *pattern,  glob3(Char *pathbuf, Char *pathend, Char *pathlim, Char *pattern,
     const Char *restpattern, glob_t *pglob, struct glob_limit *limit)      Char *restpattern, glob_t *pglob, size_t *limit)
 {  {
         struct dirent *dp;          struct dirent *dp;
         DIR *dirp;          DIR *dirp;
Line 750  glob3(Char *pathbuf, Char *pathend, Char
Line 726  glob3(Char *pathbuf, Char *pathend, Char
                 u_char *sc;                  u_char *sc;
                 Char *dc;                  Char *dc;
   
                 if ((pglob->gl_flags & GLOB_LIMIT) &&  
                     limit->l_readdir++ >= GLOB_LIMIT_READDIR) {  
                         errno = 0;  
                         *pathend++ = SEP;  
                         *pathend = EOS;  
                         return GLOB_NOSPACE;  
                 }  
   
                 /*                  /*
                  * Initial DOT must be matched literally, unless we have                   * Initial DOT must be matched literally, unless we have
                  * GLOB_PERIOD set.                   * GLOB_PERIOD set.
Line 804  glob3(Char *pathbuf, Char *pathend, Char
Line 772  glob3(Char *pathbuf, Char *pathend, Char
                         *pathend = EOS;                          *pathend = EOS;
                         continue;                          continue;
                 }                  }
                 error = glob2(pathbuf, --dc, pathlim, restpattern, pglob,                  error = glob2(pathbuf, --dc, pathlim, restpattern, pglob, limit);
                     limit);  
                 if (error)                  if (error)
                         break;                          break;
         }          }
Line 840  glob3(Char *pathbuf, Char *pathend, Char
Line 807  glob3(Char *pathbuf, Char *pathend, Char
  *      gl_pathv points to (gl_offs + gl_pathc + 1) items.   *      gl_pathv points to (gl_offs + gl_pathc + 1) items.
  */   */
 static int  static int
 globextend(const Char *path, glob_t *pglob, struct glob_limit *limit)  globextend(const Char *path, glob_t *pglob, size_t *limit)
 {  {
         char **pathv;          char **pathv;
         size_t i, newsize, len;          size_t i, newsize, len;
Line 851  globextend(const Char *path, glob_t *pgl
Line 818  globextend(const Char *path, glob_t *pgl
         _DIAGASSERT(pglob != NULL);          _DIAGASSERT(pglob != NULL);
   
         newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs);          newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs);
         if ((pglob->gl_flags & GLOB_LIMIT) &&  
             newsize > GLOB_LIMIT_PATH * sizeof(*pathv))  
                 goto nospace;  
         pathv = pglob->gl_pathv ? realloc(pglob->gl_pathv, newsize) :          pathv = pglob->gl_pathv ? realloc(pglob->gl_pathv, newsize) :
             malloc(newsize);              malloc(newsize);
         if (pathv == NULL)          if (pathv == NULL)
Line 870  globextend(const Char *path, glob_t *pgl
Line 834  globextend(const Char *path, glob_t *pgl
         for (p = path; *p++;)          for (p = path; *p++;)
                 continue;                  continue;
         len = (size_t)(p - path);          len = (size_t)(p - path);
         limit->l_string += len;          *limit += len;
         if ((copy = malloc(len)) != NULL) {          if ((copy = malloc(len)) != NULL) {
                 if (g_Ctoc(path, copy, len)) {                  if (g_Ctoc(path, copy, len)) {
                         free(copy);                          free(copy);
Line 880  globextend(const Char *path, glob_t *pgl
Line 844  globextend(const Char *path, glob_t *pgl
         }          }
         pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;          pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
   
         if ((pglob->gl_flags & GLOB_LIMIT) &&          if ((pglob->gl_flags & GLOB_LIMIT) && (newsize + *limit) >= ARG_MAX) {
             (newsize + limit->l_string) >= GLOB_LIMIT_STRING)                  errno = 0;
                 goto nospace;                  return GLOB_NOSPACE;
           }
   
         return copy == NULL ? GLOB_NOSPACE : 0;          return copy == NULL ? GLOB_NOSPACE : 0;
 nospace:  
         errno = 0;  
         return GLOB_NOSPACE;  
 }  }
   
   
Line 896  nospace:
Line 858  nospace:
  * pattern causes a recursion level.   * pattern causes a recursion level.
  */   */
 static int  static int
 match(const Char *name, const Char *pat, const Char *patend)  match(Char *name, Char *pat, Char *patend)
 {  {
         int ok, negate_range;          int ok, negate_range;
         Char c, k;          Char c, k;
Line 965  globfree(glob_t *pglob)
Line 927  globfree(glob_t *pglob)
         }          }
 }  }
   
   #ifndef __LIBC12_SOURCE__
   int
   glob_pattern_p(const char *pattern, int quote)
   {
           int range = 0;
   
           for (; *pattern; pattern++)
                   switch (*pattern) {
                   case QUESTION:
                   case STAR:
                           return 1;
   
                   case QUOTE:
                           if (quote && pattern[1] != '\0')
                                 ++pattern;
                           break;
   
                   case LBRACKET:
                           range = 1;
                           break;
   
                   case RBRACKET:
                           if (range)
                                 return 1;
                           break;
                   default:
                           break;
                   }
   
             return 0;
   }
   #endif
   
 static DIR *  static DIR *
 g_opendir(Char *str, glob_t *pglob)  g_opendir(Char *str, glob_t *pglob)
 {  {

Legend:
Removed from v.1.23.4.2  
changed lines
  Added in v.1.24

CVSweb <webmaster@jp.NetBSD.org>