[BACK]Return to compat_fts.c CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / mandoc

Diff for /mandoc/compat_fts.c between version 1.9 and 1.16

version 1.9, 2015/03/18 19:29:48 version 1.16, 2020/06/14 23:08:35
Line 59  static void  fts_load(FTS *, FTSENT *);
Line 59  static void  fts_load(FTS *, FTSENT *);
 static size_t    fts_maxarglen(char * const *);  static size_t    fts_maxarglen(char * const *);
 static void      fts_padjust(FTS *, FTSENT *);  static void      fts_padjust(FTS *, FTSENT *);
 static int       fts_palloc(FTS *, size_t);  static int       fts_palloc(FTS *, size_t);
   static FTSENT   *fts_sort(FTS *, FTSENT *, int);
 static unsigned short    fts_stat(FTS *, FTSENT *);  static unsigned short    fts_stat(FTS *, FTSENT *);
   
   typedef int (*qsort_compar_proto)(const void *, const void *);
   
 #define ISDOT(a)        (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))  #define ISDOT(a)        (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
 #ifndef O_DIRECTORY  
 #define O_DIRECTORY     0  
 #endif  
 #ifndef O_CLOEXEC  #ifndef O_CLOEXEC
 #define O_CLOEXEC       0  #define O_CLOEXEC       0
 #endif  #endif
Line 74  static unsigned short  fts_stat(FTS *, FTSENT *);
Line 74  static unsigned short  fts_stat(FTS *, FTSENT *);
 #define SET(opt)        (sp->fts_options |= (opt))  #define SET(opt)        (sp->fts_options |= (opt))
   
 FTS *  FTS *
 fts_open(char * const *argv, int options, void *dummy)  fts_open(char * const *argv, int options,
       int (*compar)(const FTSENT **, const FTSENT **))
 {  {
         FTS *sp;          FTS *sp;
         FTSENT *p, *root;          FTSENT *p, *root;
         int nitems;          int nitems;
         FTSENT *parent, *tmp;          FTSENT *parent, *prev;
         size_t len;  
   
         /* Options check. */          /* Options check. */
         if (options & ~FTS_OPTIONMASK) {          if (options & ~FTS_OPTIONMASK) {
Line 88  fts_open(char * const *argv, int options, void *dummy)
Line 88  fts_open(char * const *argv, int options, void *dummy)
                 return (NULL);                  return (NULL);
         }          }
   
           /* At least one path must be specified. */
           if (*argv == NULL) {
                   errno = EINVAL;
                   return (NULL);
           }
   
         /* Allocate/initialize the stream */          /* Allocate/initialize the stream */
         if ((sp = calloc(1, sizeof(FTS))) == NULL)          if ((sp = calloc(1, sizeof(FTS))) == NULL)
                 return (NULL);                  return (NULL);
           sp->fts_compar = compar;
         sp->fts_options = options;          sp->fts_options = options;
   
         /*          /*
Line 106  fts_open(char * const *argv, int options, void *dummy)
Line 113  fts_open(char * const *argv, int options, void *dummy)
         parent->fts_level = FTS_ROOTPARENTLEVEL;          parent->fts_level = FTS_ROOTPARENTLEVEL;
   
         /* Allocate/initialize root(s). */          /* Allocate/initialize root(s). */
         for (root = NULL, nitems = 0; *argv; ++argv, ++nitems) {          for (root = prev = NULL, nitems = 0; *argv; ++argv, ++nitems) {
                 /* Don't allow zero-length paths. */                  if ((p = fts_alloc(sp, *argv, strlen(*argv))) == NULL)
                 if ((len = strlen(*argv)) == 0) {  
                         errno = ENOENT;  
                         goto mem3;                          goto mem3;
                 }  
   
                 if ((p = fts_alloc(sp, *argv, len)) == NULL)  
                         goto mem3;  
                 p->fts_level = FTS_ROOTLEVEL;                  p->fts_level = FTS_ROOTLEVEL;
                 p->fts_parent = parent;                  p->fts_parent = parent;
                 p->fts_accpath = p->fts_name;                  p->fts_accpath = p->fts_name;
Line 124  fts_open(char * const *argv, int options, void *dummy)
Line 125  fts_open(char * const *argv, int options, void *dummy)
                 if (p->fts_info == FTS_DOT)                  if (p->fts_info == FTS_DOT)
                         p->fts_info = FTS_D;                          p->fts_info = FTS_D;
   
                 p->fts_link = NULL;                  /*
                 if (root == NULL)                   * If comparison routine supplied, traverse in sorted
                         tmp = root = p;                   * order; otherwise traverse in the order specified.
                 else {                   */
                         tmp->fts_link = p;                  if (compar) {
                         tmp = p;                          p->fts_link = root;
                           root = p;
                   } else {
                           p->fts_link = NULL;
                           if (root == NULL)
                                   root = p;
                           else
                                   prev->fts_link = p;
                           prev = p;
                 }                  }
         }          }
           if (compar && nitems > 1)
                   root = fts_sort(sp, root, nitems);
   
         /*          /*
          * Allocate a dummy pointer and make fts_read think that we've just           * Allocate a dummy pointer and make fts_read think that we've just
Line 201  fts_close(FTS *sp)
Line 212  fts_close(FTS *sp)
         /* Free up child linked list, sort array, path buffer, stream ptr.*/          /* Free up child linked list, sort array, path buffer, stream ptr.*/
         if (sp->fts_child)          if (sp->fts_child)
                 fts_lfree(sp->fts_child);                  fts_lfree(sp->fts_child);
           free(sp->fts_array);
         free(sp->fts_path);          free(sp->fts_path);
         free(sp);          free(sp);
   
Line 317  name:  t = sp->fts_path + NAPPEND(p->fts_parent);
Line 329  name:  t = sp->fts_path + NAPPEND(p->fts_parent);
  * semantics to fts using fts_set.  An error return is allowed for similar   * semantics to fts using fts_set.  An error return is allowed for similar
  * reasons.   * reasons.
  */   */
 /* ARGSUSED */  
 int  int
 fts_set(FTS *sp, FTSENT *p, int instr)  fts_set(FTS *sp, FTSENT *p, int instr)
 {  {
Line 416  fts_build(FTS *sp)
Line 427  fts_build(FTS *sp)
                                  * structures already allocated.                                   * structures already allocated.
                                  */                                   */
 mem1:                           saved_errno = errno;  mem1:                           saved_errno = errno;
                                 if (p)                                  free(p);
                                         free(p);  
                                 fts_lfree(head);                                  fts_lfree(head);
                                 (void)closedir(dirp);                                  (void)closedir(dirp);
                                 cur->fts_info = FTS_ERR;                                  cur->fts_info = FTS_ERR;
Line 490  mem1:    saved_errno = errno;
Line 500  mem1:    saved_errno = errno;
                 cur->fts_info = FTS_DP;                  cur->fts_info = FTS_DP;
                 return (NULL);                  return (NULL);
         }          }
   
           /* Sort the entries. */
           if (sp->fts_compar && nitems > 1)
                   head = fts_sort(sp, head, nitems);
         return (head);          return (head);
 }  }
   
Line 547  fts_stat(FTS *sp, FTSENT *p)
Line 561  fts_stat(FTS *sp, FTSENT *p)
 }  }
   
 static FTSENT *  static FTSENT *
   fts_sort(FTS *sp, FTSENT *head, int nitems)
   {
           FTSENT **ap, *p;
   
           /*
            * Construct an array of pointers to the structures and call qsort(3).
            * Reassemble the array in the order returned by qsort.  If unable to
            * sort for memory reasons, return the directory entries in their
            * current order.  Allocate enough space for the current needs plus
            * 40 so don't realloc one entry at a time.
            */
           if (nitems > sp->fts_nitems) {
                   struct _ftsent **a;
   
                   if ((a = reallocarray(sp->fts_array,
                       nitems + 40, sizeof(FTSENT *))) == NULL) {
                           free(sp->fts_array);
                           sp->fts_array = NULL;
                           sp->fts_nitems = 0;
                           return (head);
                   }
                   sp->fts_nitems = nitems + 40;
                   sp->fts_array = a;
           }
           for (ap = sp->fts_array, p = head; p; p = p->fts_link)
                   *ap++ = p;
           qsort(sp->fts_array, nitems, sizeof(FTSENT *),
               (qsort_compar_proto)sp->fts_compar);
           for (head = *(ap = sp->fts_array); --nitems; ++ap)
                   ap[0]->fts_link = ap[1];
           ap[0]->fts_link = NULL;
           return (head);
   }
   
   static FTSENT *
 fts_alloc(FTS *sp, const char *name, size_t namelen)  fts_alloc(FTS *sp, const char *name, size_t namelen)
 {  {
         FTSENT *p;          FTSENT *p;
Line 597  fts_palloc(FTS *sp, size_t more)
Line 646  fts_palloc(FTS *sp, size_t more)
          */           */
         more += 256;          more += 256;
         if (sp->fts_pathlen + more < sp->fts_pathlen) {          if (sp->fts_pathlen + more < sp->fts_pathlen) {
                 if (sp->fts_path)                  free(sp->fts_path);
                         free(sp->fts_path);  
                 sp->fts_path = NULL;                  sp->fts_path = NULL;
                 errno = ENAMETOOLONG;                  errno = ENAMETOOLONG;
                 return (1);                  return (1);
         }          }
         sp->fts_pathlen += more;          p = recallocarray(sp->fts_path, sp->fts_pathlen,
         p = realloc(sp->fts_path, sp->fts_pathlen);              sp->fts_pathlen + more, 1);
         if (p == NULL) {          if (p == NULL) {
                 if (sp->fts_path)                  free(sp->fts_path);
                         free(sp->fts_path);  
                 sp->fts_path = NULL;                  sp->fts_path = NULL;
                 return (1);                  return (1);
         }          }
           sp->fts_pathlen += more;
         sp->fts_path = p;          sp->fts_path = p;
         return (0);          return (0);
 }  }

Legend:
Removed from v.1.9  
changed lines
  Added in v.1.16

CVSweb