version 1.11, 2016/10/18 23:13:25 |
version 1.13, 2017/02/15 15:58:46 |
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 *); |
|
|
#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2]))) |
#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2]))) |
Line 77 static unsigned short fts_stat(FTS *, FTSENT *); |
|
Line 78 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; |
|
|
/* Options check. */ |
/* Options check. */ |
if (options & ~FTS_OPTIONMASK) { |
if (options & ~FTS_OPTIONMASK) { |
Line 99 fts_open(char * const *argv, int options, void *dummy) |
|
Line 101 fts_open(char * const *argv, int options, void *dummy) |
|
/* 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 114 fts_open(char * const *argv, int options, void *dummy) |
|
Line 117 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) { |
if ((p = fts_alloc(sp, *argv, strlen(*argv))) == NULL) |
if ((p = fts_alloc(sp, *argv, strlen(*argv))) == NULL) |
goto mem3; |
goto mem3; |
p->fts_level = FTS_ROOTLEVEL; |
p->fts_level = FTS_ROOTLEVEL; |
Line 126 fts_open(char * const *argv, int options, void *dummy) |
|
Line 129 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 203 fts_close(FTS *sp) |
|
Line 216 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 490 mem1: saved_errno = errno; |
|
Line 504 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 544 fts_stat(FTS *sp, FTSENT *p) |
|
Line 562 fts_stat(FTS *sp, FTSENT *p) |
|
if (S_ISREG(sbp->st_mode)) |
if (S_ISREG(sbp->st_mode)) |
return (FTS_F); |
return (FTS_F); |
return (FTS_DEFAULT); |
return (FTS_DEFAULT); |
|
} |
|
|
|
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; |
|
|
|
sp->fts_nitems = nitems + 40; |
|
if ((a = reallocarray(sp->fts_array, |
|
sp->fts_nitems, sizeof(FTSENT *))) == NULL) { |
|
free(sp->fts_array); |
|
sp->fts_array = NULL; |
|
sp->fts_nitems = 0; |
|
return (head); |
|
} |
|
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 *), 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 * |
static FTSENT * |