aboutsummaryrefslogtreecommitdiffstats
path: root/util/folder/fts.cpp
diff options
context:
space:
mode:
authorleo <leo@yandex-team.ru>2022-02-10 16:46:40 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:46:40 +0300
commit99609724f661f7e21d1cb08e8d80e87c3632fdb3 (patch)
tree49e222ea1c5804306084bb3ae065bb702625360f /util/folder/fts.cpp
parent980edcd3304699edf9d4e4d6a656e585028e2a72 (diff)
downloadydb-99609724f661f7e21d1cb08e8d80e87c3632fdb3.tar.gz
Restoring authorship annotation for <leo@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'util/folder/fts.cpp')
-rw-r--r--util/folder/fts.cpp1284
1 files changed, 642 insertions, 642 deletions
diff --git a/util/folder/fts.cpp b/util/folder/fts.cpp
index 809a589032..0e6a6f86eb 100644
--- a/util/folder/fts.cpp
+++ b/util/folder/fts.cpp
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -12,8 +12,8 @@
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -232,20 +232,20 @@ yreallocf(void* ptr, size_t size)
{
void* nptr;
- nptr = realloc(ptr, size);
+ nptr = realloc(ptr, size);
if (!nptr && ptr) {
- free(ptr);
+ free(ptr);
}
- return (nptr);
+ return (nptr);
}
FTS* yfts_open(char* const* argv, int options, int (*compar)(const FTSENT**, const FTSENT**))
{
FTS* sp;
- FTSENT *p, *root;
- int nitems;
- FTSENT *parent, *tmp;
- int len;
+ FTSENT *p, *root;
+ int nitems;
+ FTSENT *parent, *tmp;
+ int len;
errno = 0;
@@ -255,122 +255,122 @@ FTS* yfts_open(char* const* argv, int options, int (*compar)(const FTSENT**, con
return nullptr;
}
- /* Options check. */
- if (options & ~FTS_OPTIONMASK) {
- errno = EINVAL;
+ /* Options check. */
+ if (options & ~FTS_OPTIONMASK) {
+ errno = EINVAL;
return nullptr;
- }
+ }
- /* Allocate/initialize the stream */
+ /* Allocate/initialize the stream */
if ((sp = (FTS*)malloc(sizeof(FTS))) == nullptr) {
return nullptr;
}
- memset(sp, 0, sizeof(FTS));
- sp->fts_compar = compar;
- sp->fts_options = options;
+ memset(sp, 0, sizeof(FTS));
+ sp->fts_compar = compar;
+ sp->fts_options = options;
- /* Shush, GCC. */
+ /* Shush, GCC. */
tmp = nullptr;
- /* Logical walks turn on NOCHDIR; symbolic links are too hard. */
+ /* Logical walks turn on NOCHDIR; symbolic links are too hard. */
if (ISSET(FTS_LOGICAL)) {
- SET(FTS_NOCHDIR);
+ SET(FTS_NOCHDIR);
}
- /*
- * Start out with 1K of path space, and enough, in any case,
- * to hold the user's paths.
- */
+ /*
+ * Start out with 1K of path space, and enough, in any case,
+ * to hold the user's paths.
+ */
if (fts_palloc(sp, MAX(fts_maxarglen(argv), MAXPATHLEN))) {
- goto mem1;
+ goto mem1;
}
- /* Allocate/initialize root's parent. */
+ /* Allocate/initialize root's parent. */
if ((parent = fts_alloc(sp, "", 0)) == nullptr) {
- goto mem2;
+ goto mem2;
}
- parent->fts_level = FTS_ROOTPARENTLEVEL;
+ parent->fts_level = FTS_ROOTPARENTLEVEL;
- /* Allocate/initialize root(s). */
+ /* Allocate/initialize root(s). */
for (root = nullptr, nitems = 0; *argv; ++argv, ++nitems) {
- /* Don't allow zero-length paths. */
+ /* Don't allow zero-length paths. */
len = strlen(*argv);
//Any subsequent windows call will expect no trailing slashes so we will remove them here
#ifdef _win_
while (len && ((*argv)[len - 1] == '\\' || (*argv)[len - 1] == '/')) {
- --len;
- }
+ --len;
+ }
#endif
- if (len == 0) {
- errno = ENOENT;
- goto mem3;
- }
+ if (len == 0) {
+ errno = ENOENT;
+ goto mem3;
+ }
- p = fts_alloc(sp, *argv, len);
- p->fts_level = FTS_ROOTLEVEL;
- p->fts_parent = parent;
- p->fts_accpath = p->fts_name;
- p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW));
+ p = fts_alloc(sp, *argv, len);
+ p->fts_level = FTS_ROOTLEVEL;
+ p->fts_parent = parent;
+ p->fts_accpath = p->fts_name;
+ p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW));
p->fts_type = yfts_type_from_info(p->fts_info);
- /* Command-line "." and ".." are real directories. */
+ /* Command-line "." and ".." are real directories. */
if (p->fts_info == FTS_DOT) {
- p->fts_info = FTS_D;
+ p->fts_info = FTS_D;
}
- /*
- * If comparison routine supplied, traverse in sorted
- * order; otherwise traverse in the order specified.
- */
- if (compar) {
- p->fts_link = root;
- root = p;
- } else {
+ /*
+ * If comparison routine supplied, traverse in sorted
+ * order; otherwise traverse in the order specified.
+ */
+ if (compar) {
+ p->fts_link = root;
+ root = p;
+ } else {
p->fts_link = nullptr;
if (root == nullptr) {
- tmp = root = p;
+ tmp = root = p;
} else {
- tmp->fts_link = p;
- tmp = p;
- }
- }
- }
+ tmp->fts_link = p;
+ tmp = p;
+ }
+ }
+ }
if (compar && nitems > 1) {
- root = fts_sort(sp, root, nitems);
+ root = fts_sort(sp, root, nitems);
}
- /*
- * Allocate a dummy pointer and make yfts_read think that we've just
- * finished the node before the root(s); set p->fts_info to FTS_INIT
- * so that everything about the "current" node is ignored.
- */
+ /*
+ * Allocate a dummy pointer and make yfts_read think that we've just
+ * finished the node before the root(s); set p->fts_info to FTS_INIT
+ * so that everything about the "current" node is ignored.
+ */
if ((sp->fts_cur = fts_alloc(sp, "", 0)) == nullptr) {
- goto mem3;
+ goto mem3;
}
sp->fts_cur->fts_level = FTS_ROOTLEVEL;
- sp->fts_cur->fts_link = root;
- sp->fts_cur->fts_info = FTS_INIT;
+ sp->fts_cur->fts_link = root;
+ sp->fts_cur->fts_info = FTS_INIT;
- /*
- * If using chdir(2), grab a file descriptor pointing to dot to ensure
- * that we can get back here; this could be avoided for some paths,
- * but almost certainly not worth the effort. Slashes, symbolic links,
- * and ".." are all fairly nasty problems. Note, if we can't get the
- * descriptor we run anyway, just more slowly.
- */
+ /*
+ * If using chdir(2), grab a file descriptor pointing to dot to ensure
+ * that we can get back here; this could be avoided for some paths,
+ * but almost certainly not worth the effort. Slashes, symbolic links,
+ * and ".." are all fairly nasty problems. Note, if we can't get the
+ * descriptor we run anyway, just more slowly.
+ */
if (!ISSET(FTS_NOCHDIR) && valid_dird(sp->fts_rfd = get_cwdd())) {
- SET(FTS_NOCHDIR);
+ SET(FTS_NOCHDIR);
}
- return (sp);
+ return (sp);
mem3:
fts_lfree(root);
- free(parent);
+ free(parent);
mem2:
free(sp->fts_path);
mem1:
@@ -381,72 +381,72 @@ mem1:
static void
fts_load(FTS* sp, FTSENT* p)
{
- size_t len;
+ size_t len;
char* cp;
- /*
- * Load the stream structure for the next traversal. Since we don't
- * actually enter the directory until after the preorder visit, set
- * the fts_accpath field specially so the chdir gets done to the right
- * place and the user can access the first node. From yfts_open it's
- * known that the path will fit.
- */
- len = p->fts_pathlen = p->fts_namelen;
- memmove((void*)sp->fts_path, (void*)p->fts_name, len + 1);
+ /*
+ * Load the stream structure for the next traversal. Since we don't
+ * actually enter the directory until after the preorder visit, set
+ * the fts_accpath field specially so the chdir gets done to the right
+ * place and the user can access the first node. From yfts_open it's
+ * known that the path will fit.
+ */
+ len = p->fts_pathlen = p->fts_namelen;
+ memmove((void*)sp->fts_path, (void*)p->fts_name, len + 1);
if ((cp = strrchr(p->fts_name, LOCSLASH_C)) != nullptr && (cp != p->fts_name || cp[1])) {
- len = strlen(++cp);
- memmove((void*)p->fts_name, (void*)cp, len + 1);
- p->fts_namelen = (u_short)len;
- }
- p->fts_accpath = p->fts_path = sp->fts_path;
- sp->fts_dev = p->fts_dev;
+ len = strlen(++cp);
+ memmove((void*)p->fts_name, (void*)cp, len + 1);
+ p->fts_namelen = (u_short)len;
+ }
+ p->fts_accpath = p->fts_path = sp->fts_path;
+ sp->fts_dev = p->fts_dev;
}
int yfts_close(FTS* sp)
{
- FTSENT *freep, *p;
- int saved_errno;
-
- /*
- * This still works if we haven't read anything -- the dummy structure
- * points to the root list, so we step through to the end of the root
- * list which has a valid parent pointer.
- */
- if (sp->fts_cur) {
- for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {
- freep = p;
- p = p->fts_link ? p->fts_link : p->fts_parent;
- free(freep);
- }
- free(p);
- }
-
- /* Free up child linked list, sort array, path buffer. */
+ FTSENT *freep, *p;
+ int saved_errno;
+
+ /*
+ * This still works if we haven't read anything -- the dummy structure
+ * points to the root list, so we step through to the end of the root
+ * list which has a valid parent pointer.
+ */
+ if (sp->fts_cur) {
+ for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {
+ freep = p;
+ p = p->fts_link ? p->fts_link : p->fts_parent;
+ free(freep);
+ }
+ free(p);
+ }
+
+ /* Free up child linked list, sort array, path buffer. */
if (sp->fts_child) {
- fts_lfree(sp->fts_child);
+ fts_lfree(sp->fts_child);
}
if (sp->fts_array) {
- free(sp->fts_array);
+ free(sp->fts_array);
}
- free(sp->fts_path);
+ free(sp->fts_path);
- /* Return to original directory, save errno if necessary. */
- if (!ISSET(FTS_NOCHDIR)) {
+ /* Return to original directory, save errno if necessary. */
+ if (!ISSET(FTS_NOCHDIR)) {
saved_errno = chdir_dird(sp->fts_rfd) ? errno : 0;
close_dird(sp->fts_rfd);
- /* Set errno and return. */
- if (saved_errno != 0) {
- /* Free up the stream pointer. */
- free(sp);
- errno = saved_errno;
- return (-1);
- }
- }
-
- /* Free up the stream pointer. */
- free(sp);
- return (0);
+ /* Set errno and return. */
+ if (saved_errno != 0) {
+ /* Free up the stream pointer. */
+ free(sp);
+ errno = saved_errno;
+ return (-1);
+ }
+ }
+
+ /* Free up the stream pointer. */
+ free(sp);
+ return (0);
}
/*
@@ -460,200 +460,200 @@ int yfts_close(FTS* sp)
FTSENT*
yfts_read(FTS* sp) {
- FTSENT *p, *tmp;
- int instr;
+ FTSENT *p, *tmp;
+ int instr;
char* t;
- int saved_errno;
+ int saved_errno;
ClearLastSystemError();
- /* If finished or unrecoverable error, return NULL. */
+ /* If finished or unrecoverable error, return NULL. */
if (sp->fts_cur == nullptr || ISSET(FTS_STOP)) {
return nullptr;
}
- /* Set current node pointer. */
- p = sp->fts_cur;
+ /* Set current node pointer. */
+ p = sp->fts_cur;
- /* Save and zero out user instructions. */
- instr = p->fts_instr;
- p->fts_instr = FTS_NOINSTR;
+ /* Save and zero out user instructions. */
+ instr = p->fts_instr;
+ p->fts_instr = FTS_NOINSTR;
- /* Any type of file may be re-visited; re-stat and re-turn. */
- if (instr == FTS_AGAIN) {
- p->fts_info = fts_stat(sp, p, 0);
+ /* Any type of file may be re-visited; re-stat and re-turn. */
+ if (instr == FTS_AGAIN) {
+ p->fts_info = fts_stat(sp, p, 0);
p->fts_type = yfts_type_from_info(p->fts_info);
- return (p);
- }
-
- /*
- * Following a symlink -- SLNONE test allows application to see
- * SLNONE and recover. If indirecting through a symlink, have
- * keep a pointer to current location. If unable to get that
- * pointer, follow fails.
- */
- if (instr == FTS_FOLLOW &&
- (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) {
- p->fts_info = fts_stat(sp, p, 1);
+ return (p);
+ }
+
+ /*
+ * Following a symlink -- SLNONE test allows application to see
+ * SLNONE and recover. If indirecting through a symlink, have
+ * keep a pointer to current location. If unable to get that
+ * pointer, follow fails.
+ */
+ if (instr == FTS_FOLLOW &&
+ (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) {
+ p->fts_info = fts_stat(sp, p, 1);
p->fts_type = yfts_type_from_info(p->fts_info);
- if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
- if (valid_dird(p->fts_symfd = get_cwdd())) {
- p->fts_errno = errno;
- p->fts_info = FTS_ERR;
+ if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
+ if (valid_dird(p->fts_symfd = get_cwdd())) {
+ p->fts_errno = errno;
+ p->fts_info = FTS_ERR;
} else {
- p->fts_flags |= FTS_SYMFOLLOW;
+ p->fts_flags |= FTS_SYMFOLLOW;
}
- }
- return (p);
- }
-
- /* Directory in pre-order. */
- if (p->fts_info == FTS_D) {
- /* If skipped or crossed mount point, do post-order visit. */
- if (instr == FTS_SKIP ||
- (ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev)) {
+ }
+ return (p);
+ }
+
+ /* Directory in pre-order. */
+ if (p->fts_info == FTS_D) {
+ /* If skipped or crossed mount point, do post-order visit. */
+ if (instr == FTS_SKIP ||
+ (ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev)) {
if (p->fts_flags & FTS_SYMFOLLOW) {
- close_dird(p->fts_symfd);
+ close_dird(p->fts_symfd);
}
- if (sp->fts_child) {
- fts_lfree(sp->fts_child);
+ if (sp->fts_child) {
+ fts_lfree(sp->fts_child);
sp->fts_child = nullptr;
- }
- p->fts_info = FTS_DP;
- return (p);
- }
-
- /* Rebuild if only read the names and now traversing. */
- if (sp->fts_child && ISSET(FTS_NAMEONLY)) {
- CLR(FTS_NAMEONLY);
- fts_lfree(sp->fts_child);
+ }
+ p->fts_info = FTS_DP;
+ return (p);
+ }
+
+ /* Rebuild if only read the names and now traversing. */
+ if (sp->fts_child && ISSET(FTS_NAMEONLY)) {
+ CLR(FTS_NAMEONLY);
+ fts_lfree(sp->fts_child);
sp->fts_child = nullptr;
- }
-
- /*
- * Cd to the subdirectory.
- *
- * If have already read and now fail to chdir, whack the list
- * to make the names come out right, and set the parent errno
- * so the application will eventually get an error condition.
- * Set the FTS_DONTCHDIR flag so that when we logically change
- * directories back to the parent we don't do a chdir.
- *
- * If haven't read do so. If the read fails, fts_build sets
- * FTS_STOP or the fts_info field of the node.
- */
- if (sp->fts_child) {
- if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) {
- p->fts_errno = errno;
- p->fts_flags |= FTS_DONTCHDIR;
+ }
+
+ /*
+ * Cd to the subdirectory.
+ *
+ * If have already read and now fail to chdir, whack the list
+ * to make the names come out right, and set the parent errno
+ * so the application will eventually get an error condition.
+ * Set the FTS_DONTCHDIR flag so that when we logically change
+ * directories back to the parent we don't do a chdir.
+ *
+ * If haven't read do so. If the read fails, fts_build sets
+ * FTS_STOP or the fts_info field of the node.
+ */
+ if (sp->fts_child) {
+ if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) {
+ p->fts_errno = errno;
+ p->fts_flags |= FTS_DONTCHDIR;
for (p = sp->fts_child; p; p = p->fts_link) {
- p->fts_accpath =
- p->fts_parent->fts_accpath;
+ p->fts_accpath =
+ p->fts_parent->fts_accpath;
}
- }
+ }
} else if ((sp->fts_child = fts_build(sp, BREAD)) == nullptr) {
if (ISSET(FTS_STOP)) {
return nullptr;
}
- return (p);
- }
- p = sp->fts_child;
+ return (p);
+ }
+ p = sp->fts_child;
sp->fts_child = nullptr;
- goto name;
- }
+ goto name;
+ }
- /* Move to the next node on this level. */
+ /* Move to the next node on this level. */
next:
tmp = p;
if ((p = p->fts_link) != nullptr) {
- free(tmp);
-
- /*
- * If reached the top, return to the original directory (or
- * the root of the tree), and load the paths for the next root.
- */
- if (p->fts_level == FTS_ROOTLEVEL) {
- if (FCHDIR(sp, sp->fts_rfd)) {
- SET(FTS_STOP);
+ free(tmp);
+
+ /*
+ * If reached the top, return to the original directory (or
+ * the root of the tree), and load the paths for the next root.
+ */
+ if (p->fts_level == FTS_ROOTLEVEL) {
+ if (FCHDIR(sp, sp->fts_rfd)) {
+ SET(FTS_STOP);
return nullptr;
- }
- fts_load(sp, p);
- return (sp->fts_cur = p);
- }
-
- /*
- * User may have called yfts_set on the node. If skipped,
- * ignore. If followed, get a file descriptor so we can
- * get back if necessary.
- */
+ }
+ fts_load(sp, p);
+ return (sp->fts_cur = p);
+ }
+
+ /*
+ * User may have called yfts_set on the node. If skipped,
+ * ignore. If followed, get a file descriptor so we can
+ * get back if necessary.
+ */
if (p->fts_instr == FTS_SKIP) {
- goto next;
+ goto next;
}
- if (p->fts_instr == FTS_FOLLOW) {
- p->fts_info = fts_stat(sp, p, 1);
+ if (p->fts_instr == FTS_FOLLOW) {
+ p->fts_info = fts_stat(sp, p, 1);
p->fts_type = yfts_type_from_info(p->fts_info);
- if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
- if (valid_dird(p->fts_symfd =
+ if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
+ if (valid_dird(p->fts_symfd =
get_cwdd())) {
- p->fts_errno = errno;
- p->fts_info = FTS_ERR;
+ p->fts_errno = errno;
+ p->fts_info = FTS_ERR;
} else {
- p->fts_flags |= FTS_SYMFOLLOW;
+ p->fts_flags |= FTS_SYMFOLLOW;
}
- }
- p->fts_instr = FTS_NOINSTR;
- }
+ }
+ p->fts_instr = FTS_NOINSTR;
+ }
name:
t = sp->fts_path + NAPPEND(p->fts_parent);
- *t++ = LOCSLASH_C;
- memmove(t, p->fts_name, (size_t)p->fts_namelen + 1);
- return (sp->fts_cur = p);
- }
-
- /* Move up to the parent node. */
- p = tmp->fts_parent;
- free(tmp);
-
- if (p->fts_level == FTS_ROOTPARENTLEVEL) {
- /*
- * Done; free everything up and set errno to 0 so the user
- * can distinguish between error and EOF.
- */
- free(p);
- errno = 0;
+ *t++ = LOCSLASH_C;
+ memmove(t, p->fts_name, (size_t)p->fts_namelen + 1);
+ return (sp->fts_cur = p);
+ }
+
+ /* Move up to the parent node. */
+ p = tmp->fts_parent;
+ free(tmp);
+
+ if (p->fts_level == FTS_ROOTPARENTLEVEL) {
+ /*
+ * Done; free everything up and set errno to 0 so the user
+ * can distinguish between error and EOF.
+ */
+ free(p);
+ errno = 0;
return (sp->fts_cur = nullptr);
- }
-
- /* NUL terminate the pathname. */
- sp->fts_path[p->fts_pathlen] = '\0';
-
- /*
- * Return to the parent directory. If at a root node or came through
- * a symlink, go back through the file descriptor. Otherwise, cd up
- * one directory.
- */
- if (p->fts_level == FTS_ROOTLEVEL) {
- if (FCHDIR(sp, sp->fts_rfd)) {
- SET(FTS_STOP);
+ }
+
+ /* NUL terminate the pathname. */
+ sp->fts_path[p->fts_pathlen] = '\0';
+
+ /*
+ * Return to the parent directory. If at a root node or came through
+ * a symlink, go back through the file descriptor. Otherwise, cd up
+ * one directory.
+ */
+ if (p->fts_level == FTS_ROOTLEVEL) {
+ if (FCHDIR(sp, sp->fts_rfd)) {
+ SET(FTS_STOP);
return nullptr;
- }
- } else if (p->fts_flags & FTS_SYMFOLLOW) {
- if (FCHDIR(sp, p->fts_symfd)) {
- saved_errno = errno;
- close_dird(p->fts_symfd);
- errno = saved_errno;
- SET(FTS_STOP);
+ }
+ } else if (p->fts_flags & FTS_SYMFOLLOW) {
+ if (FCHDIR(sp, p->fts_symfd)) {
+ saved_errno = errno;
+ close_dird(p->fts_symfd);
+ errno = saved_errno;
+ SET(FTS_STOP);
return nullptr;
- }
- close_dird(p->fts_symfd);
- } else if (!(p->fts_flags & FTS_DONTCHDIR) &&
+ }
+ close_dird(p->fts_symfd);
+ } else if (!(p->fts_flags & FTS_DONTCHDIR) &&
fts_safe_changedir(sp, p->fts_parent, -1, "..")) {
SET(FTS_STOP);
return nullptr;
- }
- p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP;
- return (sp->fts_cur = p);
+ }
+ p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP;
+ return (sp->fts_cur = p);
}
/*
@@ -666,87 +666,87 @@ next:
int yfts_set(FTS* sp, FTSENT* p, int instr)
{
(void)sp; //Unused
- if (instr && instr != FTS_AGAIN && instr != FTS_FOLLOW &&
- instr != FTS_NOINSTR && instr != FTS_SKIP) {
- errno = EINVAL;
- return (1);
- }
- p->fts_instr = (u_short)instr;
- return (0);
+ if (instr && instr != FTS_AGAIN && instr != FTS_FOLLOW &&
+ instr != FTS_NOINSTR && instr != FTS_SKIP) {
+ errno = EINVAL;
+ return (1);
+ }
+ p->fts_instr = (u_short)instr;
+ return (0);
}
FTSENT*
yfts_children(FTS* sp, int instr)
{
FTSENT* p;
- dird fd;
- if (instr && instr != FTS_NAMEONLY) {
- errno = EINVAL;
+ dird fd;
+ if (instr && instr != FTS_NAMEONLY) {
+ errno = EINVAL;
return nullptr;
- }
+ }
- /* Set current node pointer. */
- p = sp->fts_cur;
+ /* Set current node pointer. */
+ p = sp->fts_cur;
- /*
- * Errno set to 0 so user can distinguish empty directory from
- * an error.
- */
- errno = 0;
+ /*
+ * Errno set to 0 so user can distinguish empty directory from
+ * an error.
+ */
+ errno = 0;
- /* Fatal errors stop here. */
+ /* Fatal errors stop here. */
if (ISSET(FTS_STOP)) {
return nullptr;
}
- /* Return logical hierarchy of user's arguments. */
+ /* Return logical hierarchy of user's arguments. */
if (p->fts_info == FTS_INIT) {
- return (p->fts_link);
+ return (p->fts_link);
}
- /*
- * If not a directory being visited in pre-order, stop here. Could
- * allow FTS_DNR, assuming the user has fixed the problem, but the
- * same effect is available with FTS_AGAIN.
- */
+ /*
+ * If not a directory being visited in pre-order, stop here. Could
+ * allow FTS_DNR, assuming the user has fixed the problem, but the
+ * same effect is available with FTS_AGAIN.
+ */
if (p->fts_info != FTS_D /* && p->fts_info != FTS_DNR */) {
return nullptr;
}
- /* Free up any previous child list. */
+ /* Free up any previous child list. */
if (sp->fts_child) {
- fts_lfree(sp->fts_child);
+ fts_lfree(sp->fts_child);
}
- if (instr == FTS_NAMEONLY) {
- SET(FTS_NAMEONLY);
- instr = BNAMES;
+ if (instr == FTS_NAMEONLY) {
+ SET(FTS_NAMEONLY);
+ instr = BNAMES;
} else {
- instr = BCHILD;
+ instr = BCHILD;
}
- /*
- * If using chdir on a relative path and called BEFORE yfts_read does
- * its chdir to the root of a traversal, we can lose -- we need to
- * chdir into the subdirectory, and we don't know where the current
- * directory is, so we can't get back so that the upcoming chdir by
- * yfts_read will work.
- */
- if (p->fts_level != FTS_ROOTLEVEL || p->fts_accpath[0] == LOCSLASH_C ||
+ /*
+ * If using chdir on a relative path and called BEFORE yfts_read does
+ * its chdir to the root of a traversal, we can lose -- we need to
+ * chdir into the subdirectory, and we don't know where the current
+ * directory is, so we can't get back so that the upcoming chdir by
+ * yfts_read will work.
+ */
+ if (p->fts_level != FTS_ROOTLEVEL || p->fts_accpath[0] == LOCSLASH_C ||
ISSET(FTS_NOCHDIR)) {
- return (sp->fts_child = fts_build(sp, instr));
+ return (sp->fts_child = fts_build(sp, instr));
}
if (valid_dird(fd = get_cwdd())) {
return nullptr;
}
- sp->fts_child = fts_build(sp, instr);
- if (chdir_dird(fd)) {
+ sp->fts_child = fts_build(sp, instr);
+ if (chdir_dird(fd)) {
close_dird(fd);
return nullptr;
}
- close_dird(fd);
- return (sp->fts_child);
+ close_dird(fd);
+ return (sp->fts_child);
}
static inline struct dirent* yreaddir(DIR* dir, struct dirent* de) {
@@ -780,9 +780,9 @@ static FTSENT*
fts_build(FTS* sp, int type)
{
struct dirent* dp;
- FTSENT *p, *head;
- int nitems;
- FTSENT *cur, *tail;
+ FTSENT *p, *head;
+ int nitems;
+ FTSENT *cur, *tail;
#ifdef _win_
dird dirpd;
@@ -792,71 +792,71 @@ fts_build(FTS* sp, int type)
#endif
void* oldaddr;
- int cderrno, descend, len, level, maxlen, nlinks, saved_errno,
- nostat, doadjust;
+ int cderrno, descend, len, level, maxlen, nlinks, saved_errno,
+ nostat, doadjust;
char* cp;
- /* Set current node pointer. */
- cur = sp->fts_cur;
+ /* Set current node pointer. */
+ cur = sp->fts_cur;
- /*
- * Open the directory for reading. If this fails, we're done.
- * If being called from yfts_read, set the fts_info field.
- */
+ /*
+ * Open the directory for reading. If this fails, we're done.
+ * If being called from yfts_read, set the fts_info field.
+ */
#ifdef FTS_WHITEOUT
- if (ISSET(FTS_WHITEOUT))
+ if (ISSET(FTS_WHITEOUT))
oflag = DTF_NODUP | DTF_REWIND;
- else
+ else
oflag = DTF_HIDEW | DTF_NODUP | DTF_REWIND;
#else
#define __opendir2(path, flag) opendir(path)
#endif
if ((dirp = __opendir2(cur->fts_accpath, oflag)) == nullptr) {
- if (type == BREAD) {
- cur->fts_info = FTS_DNR;
- cur->fts_errno = errno;
- }
+ if (type == BREAD) {
+ cur->fts_info = FTS_DNR;
+ cur->fts_errno = errno;
+ }
return nullptr;
- }
+ }
#ifdef _win_
dirpd = get_dird(cur->fts_accpath);
#endif
- /*
- * Nlinks is the number of possible entries of type directory in the
- * directory if we're cheating on stat calls, 0 if we're not doing
- * any stat calls at all, -1 if we're doing stats on everything.
- */
- if (type == BNAMES) {
- nlinks = 0;
- /* Be quiet about nostat, GCC. */
- nostat = 0;
- } else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL)) {
- nlinks = cur->fts_nlink - (ISSET(FTS_SEEDOT) ? 0 : 2);
- nostat = 1;
- } else {
- nlinks = -1;
- nostat = 0;
- }
-
- /*
- * If we're going to need to stat anything or we want to descend
- * and stay in the directory, chdir. If this fails we keep going,
- * but set a flag so we don't chdir after the post-order visit.
- * We won't be able to stat anything, but we can still return the
- * names themselves. Note, that since yfts_read won't be able to
- * chdir into the directory, it will have to return different path
- * names than before, i.e. "a/b" instead of "b". Since the node
- * has already been visited in pre-order, have to wait until the
- * post-order visit to return the error. There is a special case
- * here, if there was nothing to stat then it's not an error to
- * not be able to stat. This is all fairly nasty. If a program
- * needed sorted entries or stat information, they had better be
- * checking FTS_NS on the returned nodes.
- */
- cderrno = 0;
- if (nlinks || type == BREAD) {
+ /*
+ * Nlinks is the number of possible entries of type directory in the
+ * directory if we're cheating on stat calls, 0 if we're not doing
+ * any stat calls at all, -1 if we're doing stats on everything.
+ */
+ if (type == BNAMES) {
+ nlinks = 0;
+ /* Be quiet about nostat, GCC. */
+ nostat = 0;
+ } else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL)) {
+ nlinks = cur->fts_nlink - (ISSET(FTS_SEEDOT) ? 0 : 2);
+ nostat = 1;
+ } else {
+ nlinks = -1;
+ nostat = 0;
+ }
+
+ /*
+ * If we're going to need to stat anything or we want to descend
+ * and stay in the directory, chdir. If this fails we keep going,
+ * but set a flag so we don't chdir after the post-order visit.
+ * We won't be able to stat anything, but we can still return the
+ * names themselves. Note, that since yfts_read won't be able to
+ * chdir into the directory, it will have to return different path
+ * names than before, i.e. "a/b" instead of "b". Since the node
+ * has already been visited in pre-order, have to wait until the
+ * post-order visit to return the error. There is a special case
+ * here, if there was nothing to stat then it's not an error to
+ * not be able to stat. This is all fairly nasty. If a program
+ * needed sorted entries or stat information, they had better be
+ * checking FTS_NS on the returned nodes.
+ */
+ cderrno = 0;
+ if (nlinks || type == BREAD) {
#ifndef _win_
if (fts_safe_changedir(sp, cur, dirfd(dirp), nullptr)) {
#else
@@ -864,12 +864,12 @@ fts_build(FTS* sp, int type)
#endif
if (nlinks && type == BREAD) {
- cur->fts_errno = errno;
+ cur->fts_errno = errno;
}
- cur->fts_flags |= FTS_DONTCHDIR;
- descend = 0;
- cderrno = errno;
- (void)closedir(dirp);
+ cur->fts_flags |= FTS_DONTCHDIR;
+ descend = 0;
+ cderrno = errno;
+ (void)closedir(dirp);
dirp = nullptr;
#ifdef _win_
close_dird(dirpd);
@@ -878,107 +878,107 @@ fts_build(FTS* sp, int type)
Y_UNUSED(invalidDirD);
#endif
} else {
- descend = 1;
+ descend = 1;
}
} else {
- descend = 0;
- }
-
- /*
- * Figure out the max file name length that can be stored in the
- * current path -- the inner loop allocates more path as necessary.
- * We really wouldn't have to do the maxlen calculations here, we
- * could do them in yfts_read before returning the path, but it's a
- * lot easier here since the length is part of the dirent structure.
- *
- * If not changing directories set a pointer so that can just append
- * each new name into the path.
- */
- len = NAPPEND(cur);
- if (ISSET(FTS_NOCHDIR)) {
- cp = sp->fts_path + len;
- *cp++ = LOCSLASH_C;
- } else {
- /* GCC, you're too verbose. */
+ descend = 0;
+ }
+
+ /*
+ * Figure out the max file name length that can be stored in the
+ * current path -- the inner loop allocates more path as necessary.
+ * We really wouldn't have to do the maxlen calculations here, we
+ * could do them in yfts_read before returning the path, but it's a
+ * lot easier here since the length is part of the dirent structure.
+ *
+ * If not changing directories set a pointer so that can just append
+ * each new name into the path.
+ */
+ len = NAPPEND(cur);
+ if (ISSET(FTS_NOCHDIR)) {
+ cp = sp->fts_path + len;
+ *cp++ = LOCSLASH_C;
+ } else {
+ /* GCC, you're too verbose. */
cp = nullptr;
- }
+ }
++len;
- maxlen = sp->fts_pathlen - len;
+ maxlen = sp->fts_pathlen - len;
- level = cur->fts_level + 1;
+ level = cur->fts_level + 1;
- /* Read the directory, attaching each entry to the `link' pointer. */
- doadjust = 0;
+ /* Read the directory, attaching each entry to the `link' pointer. */
+ doadjust = 0;
//to ensure enough buffer
TTempBuf dpe;
for (head = tail = nullptr, nitems = 0; dirp && (dp = yreaddir(dirp, (struct dirent*)dpe.Data())) != nullptr;) {
if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name)) {
- continue;
+ continue;
}
if ((p = fts_alloc(sp, dp->d_name, (int)strlen(dp->d_name))) == nullptr) {
- goto mem1;
+ goto mem1;
}
if (strlen(dp->d_name) >= (size_t)maxlen) { /* include space for NUL */
- oldaddr = sp->fts_path;
+ oldaddr = sp->fts_path;
if (fts_palloc(sp, strlen(dp->d_name) + len + 1)) {
- /*
- * No more memory for path or structures. Save
- * errno, free up the current structure and the
- * structures already allocated.
- */
+ /*
+ * No more memory for path or structures. Save
+ * errno, free up the current structure and the
+ * structures already allocated.
+ */
mem1:
saved_errno = errno;
if (p) {
- free(p);
+ free(p);
}
- fts_lfree(head);
- (void)closedir(dirp);
+ fts_lfree(head);
+ (void)closedir(dirp);
#ifdef _win_
close_dird(dirpd);
#endif
- cur->fts_info = FTS_ERR;
- SET(FTS_STOP);
- errno = saved_errno;
+ cur->fts_info = FTS_ERR;
+ SET(FTS_STOP);
+ errno = saved_errno;
return nullptr;
- }
- /* Did realloc() change the pointer? */
- if (oldaddr != sp->fts_path) {
- doadjust = 1;
+ }
+ /* Did realloc() change the pointer? */
+ if (oldaddr != sp->fts_path) {
+ doadjust = 1;
if (ISSET(FTS_NOCHDIR)) {
- cp = sp->fts_path + len;
+ cp = sp->fts_path + len;
}
- }
- maxlen = sp->fts_pathlen - len;
- }
-
- if (len + strlen(dp->d_name) >= USHRT_MAX) {
- /*
- * In an FTSENT, fts_pathlen is a u_short so it is
- * possible to wraparound here. If we do, free up
- * the current structure and the structures already
- * allocated, then error out with ENAMETOOLONG.
- */
- free(p);
- fts_lfree(head);
- (void)closedir(dirp);
+ }
+ maxlen = sp->fts_pathlen - len;
+ }
+
+ if (len + strlen(dp->d_name) >= USHRT_MAX) {
+ /*
+ * In an FTSENT, fts_pathlen is a u_short so it is
+ * possible to wraparound here. If we do, free up
+ * the current structure and the structures already
+ * allocated, then error out with ENAMETOOLONG.
+ */
+ free(p);
+ fts_lfree(head);
+ (void)closedir(dirp);
#ifdef _win_
close_dird(dirpd);
#endif
- cur->fts_info = FTS_ERR;
- SET(FTS_STOP);
- errno = ENAMETOOLONG;
+ cur->fts_info = FTS_ERR;
+ SET(FTS_STOP);
+ errno = ENAMETOOLONG;
return nullptr;
- }
- p->fts_level = (short)level;
- p->fts_parent = sp->fts_cur;
- p->fts_pathlen = u_short(len + strlen(dp->d_name));
+ }
+ p->fts_level = (short)level;
+ p->fts_parent = sp->fts_cur;
+ p->fts_pathlen = u_short(len + strlen(dp->d_name));
#ifdef FTS_WHITEOUT
- if (dp->d_type == DT_WHT)
- p->fts_flags |= FTS_ISW;
+ if (dp->d_type == DT_WHT)
+ p->fts_flags |= FTS_ISW;
#endif
#ifdef _DIRENT_HAVE_D_TYPE
@@ -992,252 +992,252 @@ fts_build(FTS* sp, int type)
#endif
// coverity[dead_error_line]: false positive
- if (cderrno) {
- if (nlinks) {
- p->fts_info = FTS_NS;
- p->fts_errno = cderrno;
+ if (cderrno) {
+ if (nlinks) {
+ p->fts_info = FTS_NS;
+ p->fts_errno = cderrno;
} else {
- p->fts_info = FTS_NSOK;
+ p->fts_info = FTS_NSOK;
}
- p->fts_accpath = cur->fts_accpath;
- } else if (nlinks == 0
+ p->fts_accpath = cur->fts_accpath;
+ } else if (nlinks == 0
#ifdef DT_DIR
|| (nostat &&
dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN)
#endif
) {
- p->fts_accpath =
- ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name;
- p->fts_info = FTS_NSOK;
- } else {
- /* Build a file name for fts_stat to stat. */
- if (ISSET(FTS_NOCHDIR)) {
- p->fts_accpath = p->fts_path;
- memmove((void*)cp, (void*)p->fts_name, (size_t)p->fts_namelen + 1);
+ p->fts_accpath =
+ ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name;
+ p->fts_info = FTS_NSOK;
+ } else {
+ /* Build a file name for fts_stat to stat. */
+ if (ISSET(FTS_NOCHDIR)) {
+ p->fts_accpath = p->fts_path;
+ memmove((void*)cp, (void*)p->fts_name, (size_t)p->fts_namelen + 1);
} else {
- p->fts_accpath = p->fts_name;
+ p->fts_accpath = p->fts_name;
}
- /* Stat it. */
- p->fts_info = fts_stat(sp, p, 0);
+ /* Stat it. */
+ p->fts_info = fts_stat(sp, p, 0);
p->fts_type = yfts_type_from_info(p->fts_info);
- /* Decrement link count if applicable. */
- if (nlinks > 0 && (p->fts_info == FTS_D ||
+ /* Decrement link count if applicable. */
+ if (nlinks > 0 && (p->fts_info == FTS_D ||
p->fts_info == FTS_DC || p->fts_info == FTS_DOT)) {
- --nlinks;
+ --nlinks;
}
- }
+ }
- /* We walk in directory order so "ls -f" doesn't get upset. */
+ /* We walk in directory order so "ls -f" doesn't get upset. */
p->fts_link = nullptr;
if (head == nullptr) {
- head = tail = p;
+ head = tail = p;
} else {
- tail->fts_link = p;
- tail = p;
- }
- ++nitems;
- }
+ tail->fts_link = p;
+ tail = p;
+ }
+ ++nitems;
+ }
if (dirp) {
- (void)closedir(dirp);
+ (void)closedir(dirp);
#ifdef _win_
close_dird(dirpd);
#endif
}
- /*
- * If realloc() changed the address of the path, adjust the
- * addresses for the rest of the tree and the dir list.
- */
+ /*
+ * If realloc() changed the address of the path, adjust the
+ * addresses for the rest of the tree and the dir list.
+ */
if (doadjust) {
- fts_padjust(sp);
+ fts_padjust(sp);
}
- /*
- * If not changing directories, reset the path back to original
- * state.
- */
- if (ISSET(FTS_NOCHDIR)) {
+ /*
+ * If not changing directories, reset the path back to original
+ * state.
+ */
+ if (ISSET(FTS_NOCHDIR)) {
if (len == sp->fts_pathlen || nitems == 0) {
- --cp;
+ --cp;
}
- *cp = '\0';
- }
-
- /*
- * If descended after called from yfts_children or after called from
- * yfts_read and nothing found, get back. At the root level we use
- * the saved fd; if one of yfts_open()'s arguments is a relative path
- * to an empty directory, we wind up here with no other way back. If
- * can't get back, we're done.
- */
- if (descend && (type == BCHILD || !nitems) &&
+ *cp = '\0';
+ }
+
+ /*
+ * If descended after called from yfts_children or after called from
+ * yfts_read and nothing found, get back. At the root level we use
+ * the saved fd; if one of yfts_open()'s arguments is a relative path
+ * to an empty directory, we wind up here with no other way back. If
+ * can't get back, we're done.
+ */
+ if (descend && (type == BCHILD || !nitems) &&
(cur->fts_level == FTS_ROOTLEVEL ? FCHDIR(sp, sp->fts_rfd) : fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) {
- cur->fts_info = FTS_ERR;
- SET(FTS_STOP);
+ cur->fts_info = FTS_ERR;
+ SET(FTS_STOP);
fts_lfree(head);
return nullptr;
- }
+ }
- /* If didn't find anything, return NULL. */
- if (!nitems) {
+ /* If didn't find anything, return NULL. */
+ if (!nitems) {
if (type == BREAD) {
- cur->fts_info = FTS_DP;
+ cur->fts_info = FTS_DP;
}
fts_lfree(head);
return nullptr;
- }
+ }
- /* Sort the entries. */
+ /* Sort the entries. */
if (sp->fts_compar && nitems > 1) {
- head = fts_sort(sp, head, nitems);
+ head = fts_sort(sp, head, nitems);
}
- return (head);
+ return (head);
}
static u_short
fts_stat(FTS* sp, FTSENT* p, int follow)
{
- dev_t dev;
- ino_t ino;
+ dev_t dev;
+ ino_t ino;
stat_struct *sbp, sb;
- int saved_errno;
- /* If user needs stat info, stat buffer already allocated. */
- sbp = ISSET(FTS_NOSTAT) ? &sb : p->fts_statp;
+ int saved_errno;
+ /* If user needs stat info, stat buffer already allocated. */
+ sbp = ISSET(FTS_NOSTAT) ? &sb : p->fts_statp;
#ifdef FTS_WHITEOUT
- /* check for whiteout */
- if (p->fts_flags & FTS_ISW) {
- if (sbp != &sb) {
+ /* check for whiteout */
+ if (p->fts_flags & FTS_ISW) {
+ if (sbp != &sb) {
memset(sbp, '\0', sizeof(*sbp));
- sbp->st_mode = S_IFWHT;
- }
- return (FTS_W);
- }
+ sbp->st_mode = S_IFWHT;
+ }
+ return (FTS_W);
+ }
#endif
- /*
- * If doing a logical walk, or application requested FTS_FOLLOW, do
- * a stat(2). If that fails, check for a non-existent symlink. If
- * fail, set the errno from the stat call.
- */
- if (ISSET(FTS_LOGICAL) || follow) {
+ /*
+ * If doing a logical walk, or application requested FTS_FOLLOW, do
+ * a stat(2). If that fails, check for a non-existent symlink. If
+ * fail, set the errno from the stat call.
+ */
+ if (ISSET(FTS_LOGICAL) || follow) {
if (STAT_FUNC(p->fts_accpath, sbp)) {
- saved_errno = errno;
- if (!lstat(p->fts_accpath, sbp)) {
- errno = 0;
- return (FTS_SLNONE);
- }
- p->fts_errno = saved_errno;
+ saved_errno = errno;
+ if (!lstat(p->fts_accpath, sbp)) {
+ errno = 0;
+ return (FTS_SLNONE);
+ }
+ p->fts_errno = saved_errno;
memset(sbp, 0, sizeof(stat_struct));
return (FTS_NS);
- }
+ }
} else if (lstat(p->fts_accpath, sbp)) {
- p->fts_errno = errno;
+ p->fts_errno = errno;
memset(sbp, 0, sizeof(stat_struct));
- return (FTS_NS);
- }
+ return (FTS_NS);
+ }
if (S_ISDIR(sbp->st_mode)) {
- /*
- * Set the device/inode. Used to find cycles and check for
- * crossing mount points. Also remember the link count, used
- * in fts_build to limit the number of stat calls. It is
- * understood that these fields are only referenced if fts_info
- * is set to FTS_D.
- */
- dev = p->fts_dev = sbp->st_dev;
- ino = p->fts_ino = sbp->st_ino;
- p->fts_nlink = sbp->st_nlink;
+ /*
+ * Set the device/inode. Used to find cycles and check for
+ * crossing mount points. Also remember the link count, used
+ * in fts_build to limit the number of stat calls. It is
+ * understood that these fields are only referenced if fts_info
+ * is set to FTS_D.
+ */
+ dev = p->fts_dev = sbp->st_dev;
+ ino = p->fts_ino = sbp->st_ino;
+ p->fts_nlink = sbp->st_nlink;
const char* fts_name_x = p->fts_name;
if (ISDOT(fts_name_x)) {
- return (FTS_DOT);
+ return (FTS_DOT);
}
/*
- * Cycle detection is done by brute force when the directory
- * is first encountered. If the tree gets deep enough or the
- * number of symbolic links to directories is high enough,
- * something faster might be worthwhile.
- */
+ * Cycle detection is done by brute force when the directory
+ * is first encountered. If the tree gets deep enough or the
+ * number of symbolic links to directories is high enough,
+ * something faster might be worthwhile.
+ */
//There is no way to detect symlink or mount cycles on win32
#ifndef _win_
FTSENT* t;
- for (t = p->fts_parent;
+ for (t = p->fts_parent;
t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent) {
- if (ino == t->fts_ino && dev == t->fts_dev) {
- p->fts_cycle = t;
- return (FTS_DC);
- }
+ if (ino == t->fts_ino && dev == t->fts_dev) {
+ p->fts_cycle = t;
+ return (FTS_DC);
+ }
}
#endif /*_win_*/
- return (FTS_D);
- }
+ return (FTS_D);
+ }
if (S_ISLNK(sbp->st_mode)) {
- return (FTS_SL);
+ return (FTS_SL);
}
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) {
+ 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;
+ sp->fts_nitems = nitems + 40;
if ((a = (struct _ftsent**)realloc(sp->fts_array,
sp->fts_nitems * sizeof(FTSENT*))) == nullptr) {
if (sp->fts_array) {
- free(sp->fts_array);
+ free(sp->fts_array);
}
sp->fts_array = nullptr;
- sp->fts_nitems = 0;
- return (head);
- }
- sp->fts_array = a;
- }
+ sp->fts_nitems = 0;
+ return (head);
+ }
+ sp->fts_array = a;
+ }
for (ap = sp->fts_array, p = head; p; p = p->fts_link) {
- *ap++ = p;
+ *ap++ = p;
}
qsort((void*)sp->fts_array, (size_t)nitems, sizeof(FTSENT*), (int (*)(const void*, const void*))sp->fts_compar);
for (head = *(ap = sp->fts_array); --nitems; ++ap) {
- ap[0]->fts_link = ap[1];
+ ap[0]->fts_link = ap[1];
}
ap[0]->fts_link = nullptr;
- return (head);
+ return (head);
}
static FTSENT*
fts_alloc(FTS* sp, const char* name, int namelen)
{
FTSENT* p;
- size_t len;
-
- /*
- * The file name is a variable length array and no stat structure is
- * necessary if the user has set the nostat bit. Allocate the FTSENT
- * structure, the file name and the stat structure in one chunk, but
- * be careful that the stat structure is reasonably aligned. Since the
- * fts_name field is declared to be of size 1, the fts_name pointer is
- * namelen + 2 before the first possible address of the stat structure.
- */
- len = sizeof(FTSENT) + namelen;
+ size_t len;
+
+ /*
+ * The file name is a variable length array and no stat structure is
+ * necessary if the user has set the nostat bit. Allocate the FTSENT
+ * structure, the file name and the stat structure in one chunk, but
+ * be careful that the stat structure is reasonably aligned. Since the
+ * fts_name field is declared to be of size 1, the fts_name pointer is
+ * namelen + 2 before the first possible address of the stat structure.
+ */
+ len = sizeof(FTSENT) + namelen;
if (!ISSET(FTS_NOSTAT)) {
len += sizeof(stat_struct) + ALIGNBYTES;
}
@@ -1245,22 +1245,22 @@ fts_alloc(FTS* sp, const char* name, int namelen)
return nullptr;
}
- /* Copy the name and guarantee NUL termination. */
- memmove((void*)p->fts_name, (void*)name, (size_t)namelen);
- p->fts_name[namelen] = '\0';
+ /* Copy the name and guarantee NUL termination. */
+ memmove((void*)p->fts_name, (void*)name, (size_t)namelen);
+ p->fts_name[namelen] = '\0';
if (!ISSET(FTS_NOSTAT)) {
p->fts_statp = (stat_struct*)ALIGN(p->fts_name + namelen + 2);
}
- p->fts_namelen = (u_short)namelen;
- p->fts_path = sp->fts_path;
- p->fts_errno = 0;
- p->fts_flags = 0;
- p->fts_instr = FTS_NOINSTR;
- p->fts_number = 0;
+ p->fts_namelen = (u_short)namelen;
+ p->fts_path = sp->fts_path;
+ p->fts_errno = 0;
+ p->fts_flags = 0;
+ p->fts_instr = FTS_NOINSTR;
+ p->fts_number = 0;
p->fts_pointer = nullptr;
p->fts_type = FTS_NSOK;
- return (p);
+ return (p);
}
static void
@@ -1268,11 +1268,11 @@ fts_lfree(FTSENT* head)
{
FTSENT* p;
- /* Free a linked list of structures. */
+ /* Free a linked list of structures. */
while ((p = head) != nullptr) {
- head = head->fts_link;
- free(p);
- }
+ head = head->fts_link;
+ free(p);
+ }
}
/*
@@ -1284,7 +1284,7 @@ fts_lfree(FTSENT* head)
static int
fts_palloc(FTS* sp, size_t more)
{
- sp->fts_pathlen += more + 256;
+ sp->fts_pathlen += more + 256;
sp->fts_path = (char*)yreallocf(sp->fts_path, (size_t)sp->fts_pathlen);
return (sp->fts_path == nullptr);
}
@@ -1292,19 +1292,19 @@ fts_palloc(FTS* sp, size_t more)
static void
ADJUST(FTSENT* p, void* addr)
{
- if ((p)->fts_accpath >= (p)->fts_path &&
- (p)->fts_accpath < (p)->fts_path + (p)->fts_pathlen) {
+ if ((p)->fts_accpath >= (p)->fts_path &&
+ (p)->fts_accpath < (p)->fts_path + (p)->fts_pathlen) {
if (p->fts_accpath != p->fts_path) {
- errx(1, "fts ADJUST: accpath %p path %p",
+ errx(1, "fts ADJUST: accpath %p path %p",
p->fts_accpath, p->fts_path);
}
if (p->fts_level != 0) {
- errx(1, "fts ADJUST: level %d not 0", p->fts_level);
+ errx(1, "fts ADJUST: level %d not 0", p->fts_level);
}
- (p)->fts_accpath =
+ (p)->fts_accpath =
(char*)addr + ((p)->fts_accpath - (p)->fts_path);
- }
- (p)->fts_path = (char*)addr;
+ }
+ (p)->fts_path = (char*)addr;
}
/*
@@ -1323,29 +1323,29 @@ fts_padjust(FTS* sp)
(p)->fts_accpath = (addr); \
(p)->fts_path = addr; \
}
- /* Adjust the current set of children. */
+ /* Adjust the current set of children. */
for (p = sp->fts_child; p; p = p->fts_link) {
- ADJUST(p, addr);
+ ADJUST(p, addr);
}
- /* Adjust the rest of the tree. */
- for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {
- ADJUST(p, addr);
- p = p->fts_link ? p->fts_link : p->fts_parent;
- }
+ /* Adjust the rest of the tree. */
+ for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {
+ ADJUST(p, addr);
+ p = p->fts_link ? p->fts_link : p->fts_parent;
+ }
}
static size_t
fts_maxarglen(char* const* argv)
{
- size_t len, max;
+ size_t len, max;
for (max = 0; *argv; ++argv) {
if ((len = strlen(*argv)) > max) {
- max = len;
+ max = len;
}
}
- return (max + 1);
+ return (max + 1);
}
/*
@@ -1358,33 +1358,33 @@ fts_maxarglen(char* const* argv)
static int
fts_safe_changedir(FTS* sp, FTSENT* p, int fd, const char* path)
{
- int ret, oerrno, newfd;
+ int ret, oerrno, newfd;
stat_struct sb;
- newfd = fd;
+ newfd = fd;
if (ISSET(FTS_NOCHDIR)) {
- return (0);
+ return (0);
}
if (fd < 0 && (newfd = open(path, O_RDONLY, 0)) < 0) {
- return (-1);
+ return (-1);
+ }
+ if (fstat(newfd, &sb)) {
+ ret = -1;
+ goto bail;
}
- if (fstat(newfd, &sb)) {
- ret = -1;
- goto bail;
- }
- if (p->fts_dev != sb.st_dev || p->fts_ino != sb.st_ino) {
+ if (p->fts_dev != sb.st_dev || p->fts_ino != sb.st_ino) {
errno = ENOENT; /* disinformation */
- ret = -1;
- goto bail;
- }
- ret = fchdir(newfd);
+ ret = -1;
+ goto bail;
+ }
+ ret = fchdir(newfd);
bail:
- oerrno = errno;
+ oerrno = errno;
if (fd < 0) {
- (void)close(newfd);
+ (void)close(newfd);
}
- errno = oerrno;
- return (ret);
+ errno = oerrno;
+ return (ret);
}
#else
static int