aboutsummaryrefslogtreecommitdiffstats
path: root/util/folder
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
parent980edcd3304699edf9d4e4d6a656e585028e2a72 (diff)
downloadydb-99609724f661f7e21d1cb08e8d80e87c3632fdb3.tar.gz
Restoring authorship annotation for <leo@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'util/folder')
-rw-r--r--util/folder/dirut.cpp390
-rw-r--r--util/folder/dirut.h12
-rw-r--r--util/folder/dirut_ut.cpp8
-rw-r--r--util/folder/filelist.cpp2
-rw-r--r--util/folder/filelist.h10
-rw-r--r--util/folder/fts.cpp1284
6 files changed, 853 insertions, 853 deletions
diff --git a/util/folder/dirut.cpp b/util/folder/dirut.cpp
index 9a38a89ea0..ffc9b09f96 100644
--- a/util/folder/dirut.cpp
+++ b/util/folder/dirut.cpp
@@ -12,118 +12,118 @@
#include <util/system/yassert.h>
void SlashFolderLocal(TString& folder) {
- if (!folder)
- return;
-#ifdef _win32_
- size_t pos;
+ if (!folder)
+ return;
+#ifdef _win32_
+ size_t pos;
while ((pos = folder.find('/')) != TString::npos)
folder.replace(pos, 1, LOCSLASH_S);
-#endif
+#endif
if (folder[folder.size() - 1] != LOCSLASH_C)
- folder.append(LOCSLASH_S);
-}
-
-#ifndef _win32_
-
+ folder.append(LOCSLASH_S);
+}
+
+#ifndef _win32_
+
bool correctpath(TString& folder) {
- return resolvepath(folder, "/");
-}
-
+ return resolvepath(folder, "/");
+}
+
bool resolvepath(TString& folder, const TString& home) {
Y_ASSERT(home && home.at(0) == '/');
- if (!folder) {
- return false;
- }
- // may be from windows
+ if (!folder) {
+ return false;
+ }
+ // may be from windows
char* ptr = folder.begin();
while ((ptr = strchr(ptr, '\\')) != nullptr)
- *ptr = '/';
-
- if (folder.at(0) == '~') {
- if (folder.length() == 1 || folder.at(1) == '/') {
+ *ptr = '/';
+
+ if (folder.at(0) == '~') {
+ if (folder.length() == 1 || folder.at(1) == '/') {
folder = GetHomeDir() + (folder.data() + 1);
- } else {
+ } else {
char* buf = (char*)alloca(folder.length() + 1);
strcpy(buf, folder.data() + 1);
- char* p = strchr(buf, '/');
- if (p)
- *p++ = 0;
- passwd* pw = getpwnam(buf);
- if (pw) {
- folder = pw->pw_dir;
- folder += "/";
- if (p)
- folder += p;
- } else {
- return false; // unknown user
- }
- }
- }
- int len = folder.length() + home.length() + 1;
- char* path = (char*)alloca(len);
- if (folder.at(0) != '/') {
+ char* p = strchr(buf, '/');
+ if (p)
+ *p++ = 0;
+ passwd* pw = getpwnam(buf);
+ if (pw) {
+ folder = pw->pw_dir;
+ folder += "/";
+ if (p)
+ folder += p;
+ } else {
+ return false; // unknown user
+ }
+ }
+ }
+ int len = folder.length() + home.length() + 1;
+ char* path = (char*)alloca(len);
+ if (folder.at(0) != '/') {
strcpy(path, home.data());
strcpy(strrchr(path, '/') + 1, folder.data()); // the last char must be '/' if it's a dir
- } else {
+ } else {
strcpy(path, folder.data());
- }
+ }
len = strlen(path) + 1;
- // grabbed from url.cpp
+ // grabbed from url.cpp
char* newpath = (char*)alloca(len + 2);
const char** pp = (const char**)alloca(len * sizeof(char*));
- int i = 0;
- for (char* s = path; s;) {
- pp[i++] = s;
- s = strchr(s, '/');
- if (s)
- *s++ = 0;
- }
-
- for (int j = 1; j < i;) {
+ int i = 0;
+ for (char* s = path; s;) {
+ pp[i++] = s;
+ s = strchr(s, '/');
+ if (s)
+ *s++ = 0;
+ }
+
+ for (int j = 1; j < i;) {
const char*& p = pp[j];
if (strcmp(p, ".") == 0 || strcmp(p, "") == 0) {
if (j == i - 1) {
- p = "";
- break;
- } else {
+ p = "";
+ break;
+ } else {
memmove(pp + j, pp + j + 1, (i - j - 1) * sizeof(p));
--i;
- }
- } else if (strcmp(p, "..") == 0) {
+ }
+ } else if (strcmp(p, "..") == 0) {
if (j == i - 1) {
- if (j == 1) {
- p = "";
- } else {
+ if (j == 1) {
+ p = "";
+ } else {
--i;
pp[j - 1] = "";
- }
- break;
- } else {
- if (j == 1) {
+ }
+ break;
+ } else {
+ if (j == 1) {
memmove(pp + j, pp + j + 1, (i - j - 1) * sizeof(p));
--i;
- } else {
+ } else {
memmove(pp + j - 1, pp + j + 1, (i - j - 1) * sizeof(p));
i -= 2;
--j;
- }
- }
- } else
+ }
+ }
+ } else
++j;
- }
-
- char* s = newpath;
- for (int k = 0; k < i; k++) {
- s = strchr(strcpy(s, pp[k]), 0);
- *s++ = '/';
- }
- *(--s) = 0;
- folder = newpath;
- return true;
-}
-
-#else
-
+ }
+
+ char* s = newpath;
+ for (int k = 0; k < i; k++) {
+ s = strchr(strcpy(s, pp[k]), 0);
+ *s++ = '/';
+ }
+ *(--s) = 0;
+ folder = newpath;
+ return true;
+}
+
+#else
+
using dir_type = enum {
dt_empty,
dt_error,
@@ -131,17 +131,17 @@ using dir_type = enum {
dt_dir
};
-// precondition: *ptr != '\\' || *ptr == 0 (cause dt_error)
-// postcondition: *ptr != '\\'
+// precondition: *ptr != '\\' || *ptr == 0 (cause dt_error)
+// postcondition: *ptr != '\\'
template <typename T>
static int next_dir(T*& ptr) {
- int has_blank = 0;
- int has_dot = 0;
- int has_letter = 0;
- int has_ctrl = 0;
-
+ int has_blank = 0;
+ int has_dot = 0;
+ int has_letter = 0;
+ int has_ctrl = 0;
+
while (*ptr && *ptr != '\\') {
- int c = (unsigned char)*ptr++;
+ int c = (unsigned char)*ptr++;
switch (c) {
case ' ':
++has_blank;
@@ -164,23 +164,23 @@ static int next_dir(T*& ptr) {
++has_ctrl;
else
++has_letter;
- }
- }
- if (*ptr)
+ }
+ }
+ if (*ptr)
++ptr;
- if (has_ctrl)
- return dt_error;
- if (has_letter)
- return dt_dir;
- if (has_dot && has_blank)
- return dt_error;
- if (has_dot == 1)
- return dt_empty;
- if (has_dot == 2)
- return dt_up;
- return dt_error;
-}
-
+ if (has_ctrl)
+ return dt_error;
+ if (has_letter)
+ return dt_dir;
+ if (has_dot && has_blank)
+ return dt_error;
+ if (has_dot == 1)
+ return dt_empty;
+ if (has_dot == 2)
+ return dt_up;
+ return dt_error;
+}
+
using disk_type = enum {
dk_noflags = 0,
dk_unc = 1,
@@ -192,34 +192,34 @@ using disk_type = enum {
// root slash (if any) - part of disk
template <typename T>
static int skip_disk(T*& ptr) {
- int result = dk_noflags;
- if (!*ptr)
- return result;
- if (ptr[0] == '\\' && ptr[1] == '\\') {
+ int result = dk_noflags;
+ if (!*ptr)
+ return result;
+ if (ptr[0] == '\\' && ptr[1] == '\\') {
result |= dk_unc | dk_fromroot;
- ptr += 2;
- if (next_dir(ptr) != dt_dir)
+ ptr += 2;
+ if (next_dir(ptr) != dt_dir)
return dk_error; // has no host name
- if (next_dir(ptr) != dt_dir)
+ if (next_dir(ptr) != dt_dir)
return dk_error; // has no share name
- } else {
+ } else {
if (*ptr && *(ptr + 1) == ':') {
- result |= dk_hasdrive;
- ptr += 2;
- }
- if (*ptr == '\\' || *ptr == '/') {
+ result |= dk_hasdrive;
+ ptr += 2;
+ }
+ if (*ptr == '\\' || *ptr == '/') {
++ptr;
- result |= dk_fromroot;
- }
- }
- return result;
-}
-
+ result |= dk_fromroot;
+ }
+ }
+ return result;
+}
+
int correctpath(char* cpath, const char* path) {
if (!path || !*path) {
- *cpath = 0;
- return 1;
- }
+ *cpath = 0;
+ return 1;
+ }
char* ptr = (char*)path;
char* cptr = cpath;
int counter = 0;
@@ -238,14 +238,14 @@ int correctpath(char* cpath, const char* path) {
++ptr;
}
*cptr = 0;
- // replace '/' by '\'
- int dk = skip_disk(cpath);
+ // replace '/' by '\'
+ int dk = skip_disk(cpath);
+
+ if (dk == dk_error)
+ return 0;
- if (dk == dk_error)
- return 0;
-
char* ptr1 = ptr = cpath;
- int level = 0;
+ int level = 0;
while (*ptr) {
switch (next_dir(ptr)) {
case dt_dir:
@@ -253,8 +253,8 @@ int correctpath(char* cpath, const char* path) {
break;
case dt_empty:
memmove(ptr1, ptr, strlen(ptr) + 1);
- ptr = ptr1;
- break;
+ ptr = ptr1;
+ break;
case dt_up:
--level;
if (level >= 0) {
@@ -272,100 +272,100 @@ int correctpath(char* cpath, const char* path) {
memmove(cpath - 3, ptr, strlen(ptr) + 1);
return 1;
}
- }
+ }
if (dk & dk_fromroot)
return 0;
break;
case dt_error:
default:
- return 0;
- }
- ptr1 = ptr;
- }
-
+ return 0;
+ }
+ ptr1 = ptr;
+ }
+
if ((ptr > cpath || ptr == cpath && dk & dk_unc) && *(ptr - 1) == '\\')
*(ptr - 1) = 0;
- return 1;
-}
-
+ return 1;
+}
+
static inline int normchar(unsigned char c) {
return (c < 'a' || c > 'z') ? c : c - 32;
-}
-
+}
+
static inline char* strslashcat(char* a, const char* b) {
- size_t len = strlen(a);
+ size_t len = strlen(a);
if (len && a[len - 1] != '\\')
- a[len++] = '\\';
+ a[len++] = '\\';
strcpy(a + len, b);
- return a;
-}
-
+ return a;
+}
+
int resolvepath(char* apath, const char* rpath, const char* cpath) {
const char* redisk = rpath;
- if (!rpath || !*rpath)
- return 0;
- int rdt = skip_disk(redisk);
- if (rdt == dk_error)
- return 0;
+ if (!rpath || !*rpath)
+ return 0;
+ int rdt = skip_disk(redisk);
+ if (rdt == dk_error)
+ return 0;
if (rdt & dk_unc || rdt & dk_hasdrive && rdt & dk_fromroot) {
- return correctpath(apath, rpath);
- }
-
+ return correctpath(apath, rpath);
+ }
+
const char* cedisk = cpath;
- if (!cpath || !*cpath)
- return 0;
- int cdt = skip_disk(cedisk);
- if (cdt == dk_error)
- return 0;
-
+ if (!cpath || !*cpath)
+ return 0;
+ int cdt = skip_disk(cedisk);
+ if (cdt == dk_error)
+ return 0;
+
char* tpath = (char*)alloca(strlen(rpath) + strlen(cpath) + 3);
-
- // rdt&dk_hasdrive && !rdt&dk_fromroot
+
+ // rdt&dk_hasdrive && !rdt&dk_fromroot
if (rdt & dk_hasdrive) {
if (!(cdt & dk_fromroot))
- return 0;
+ return 0;
if (cdt & dk_hasdrive && normchar(*rpath) != normchar(*cpath))
- return 0;
- memcpy(tpath, rpath, 2);
- memcpy(tpath + 2, cedisk, strlen(cedisk) + 1);
- strslashcat(tpath, redisk);
-
+ return 0;
+ memcpy(tpath, rpath, 2);
+ memcpy(tpath + 2, cedisk, strlen(cedisk) + 1);
+ strslashcat(tpath, redisk);
+
// !rdt&dk_hasdrive && rdt&dk_fromroot
} else if (rdt & dk_fromroot) {
if (!(cdt & dk_hasdrive) && !(cdt & dk_unc))
- return 0;
+ return 0;
memcpy(tpath, cpath, cedisk - cpath);
tpath[cedisk - cpath] = 0;
- strslashcat(tpath, redisk);
-
+ strslashcat(tpath, redisk);
+
// !rdt&dk_hasdrive && !rdt&dk_fromroot
- } else {
+ } else {
if (!(cdt & dk_fromroot) || !(cdt & dk_hasdrive) && !(cdt & dk_unc))
- return 0;
- strslashcat(strcpy(tpath, cpath), redisk);
- }
-
- return correctpath(apath, tpath);
-}
-
+ return 0;
+ strslashcat(strcpy(tpath, cpath), redisk);
+ }
+
+ return correctpath(apath, tpath);
+}
+
bool correctpath(TString& filename) {
char* ptr = (char*)alloca(filename.size() + 2);
if (correctpath(ptr, filename.data())) {
- filename = ptr;
- return true;
- }
- return false;
-}
-
+ filename = ptr;
+ return true;
+ }
+ return false;
+}
+
bool resolvepath(TString& folder, const TString& home) {
char* ptr = (char*)alloca(folder.size() + 3 + home.size());
if (resolvepath(ptr, folder.data(), home.data())) {
- folder = ptr;
- return true;
- }
- return false;
-}
-
+ folder = ptr;
+ return true;
+ }
+ return false;
+}
+
#endif // !defined _win32_
char GetDirectorySeparator() {
diff --git a/util/folder/dirut.h b/util/folder/dirut.h
index 95e265dcd1..2537027b12 100644
--- a/util/folder/dirut.h
+++ b/util/folder/dirut.h
@@ -1,17 +1,17 @@
#pragma once
#include <util/system/defaults.h>
-#include <util/system/sysstat.h>
+#include <util/system/sysstat.h>
#include <util/system/fs.h>
#include <util/generic/string.h>
#include <util/generic/yexception.h>
-#include <sys/types.h>
-
+#include <sys/types.h>
+
#include <cerrno>
#include <cstdlib>
-#ifdef _win32_
+#ifdef _win32_
#include <util/system/winint.h>
#include <direct.h>
#include <malloc.h>
@@ -35,14 +35,14 @@ char* mkdtemp(char* path);
#ifndef DT_DIR
#include <sys/stat.h>
#endif
-#endif
+#endif
bool IsDir(const TString& path);
int mkpath(char* path, int mode = 0777);
TString GetHomeDir();
-
+
void MakeDirIfNotExist(const char* path, int mode = 0777);
inline void MakeDirIfNotExist(const TString& path, int mode = 0777) {
diff --git a/util/folder/dirut_ut.cpp b/util/folder/dirut_ut.cpp
index fd1cafcb7a..45ebfc842c 100644
--- a/util/folder/dirut_ut.cpp
+++ b/util/folder/dirut_ut.cpp
@@ -62,19 +62,19 @@ Y_UNIT_TEST_SUITE(TDirutTest) {
UNIT_ASSERT(resolvepath(path, base));
UNIT_ASSERT(path == canon);
}
-
+
Y_UNIT_TEST(TestResolvePath) {
-#ifdef _win_
+#ifdef _win_
DoTest("bar", "c:\\foo\\baz", "c:\\foo\\baz\\bar");
DoTest("c:\\foo\\bar", "c:\\bar\\baz", "c:\\foo\\bar");
-#else
+#else
DoTest("bar", "/foo/baz", "/foo/bar");
DoTest("/foo/bar", "/bar/baz", "/foo/bar");
#ifdef NDEBUG
DoTest("bar", "./baz", "./bar");
#if 0 // should we support, for consistency, single-label dirs
- DoTest("bar", "baz", "bar");
+ DoTest("bar", "baz", "bar");
#endif
#endif
#endif
diff --git a/util/folder/filelist.cpp b/util/folder/filelist.cpp
index 848b7af96f..b21fcdbf20 100644
--- a/util/folder/filelist.cpp
+++ b/util/folder/filelist.cpp
@@ -36,5 +36,5 @@ void TFileEntitiesList::Fill(const TString& dirname, TStringBuf prefix, TStringB
}
}
- Restart();
+ Restart();
}
diff --git a/util/folder/filelist.h b/util/folder/filelist.h
index 3dea0bb913..3f615fa4c2 100644
--- a/util/folder/filelist.h
+++ b/util/folder/filelist.h
@@ -18,7 +18,7 @@ public:
EM_FILES_DIRS_SLINKS = EM_FILES | EM_DIRS | EM_SLINKS
};
Y_DECLARE_FLAGS(EMask, EMaskFlag)
-
+
TFileEntitiesList(EMask mask)
: Mask(mask)
{
@@ -50,11 +50,11 @@ public:
void Fill(const TString& dirname, TStringBuf prefix, TStringBuf suffix, int depth, bool sort = false);
- void Restart() {
+ void Restart() {
Cur = FileNames.Data();
- CurName = 0;
- }
-
+ CurName = 0;
+ }
+
protected:
TBuffer FileNames;
size_t FileNamesSize, CurName;
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