remove struct stat from interfaces

This commit is contained in:
Jean-Francois Dockes
2020-03-31 11:17:07 +02:00
parent b5086139aa
commit 34d23589a2
23 changed files with 233 additions and 223 deletions
+4 -3
View File
@@ -37,12 +37,13 @@ public:
{
}
virtual FsTreeWalker::Status
processone(const string &, const struct stat *, FsTreeWalker::CbFlag);
processone(const string &, const struct PathStat *, FsTreeWalker::CbFlag);
DesktopDb::AppMap *m_appdefs;
};
FsTreeWalker::Status FstCb::processone(const string& fn, const struct stat *,
FsTreeWalker::CbFlag flg)
struct PathStat;
FsTreeWalker::Status FstCb::processone(
const string& fn, const struct PathStat*, FsTreeWalker::CbFlag flg)
{
if (flg != FsTreeWalker::FtwRegular)
return FsTreeWalker::FtwOk;
+13 -14
View File
@@ -21,7 +21,6 @@
#include <dirent.h>
#include <errno.h>
#include <fnmatch.h>
#include "safesysstat.h"
#include <cstring>
#include <algorithm>
@@ -228,8 +227,7 @@ static inline int slashcount(const string& p)
return n;
}
FsTreeWalker::Status FsTreeWalker::walk(const string& _top,
FsTreeWalkerCB& cb)
FsTreeWalker::Status FsTreeWalker::walk(const string& _top, FsTreeWalkerCB& cb)
{
string top = (data->options & FtwNoCanon) ? _top : path_canon(_top);
@@ -238,7 +236,7 @@ FsTreeWalker::Status FsTreeWalker::walk(const string& _top,
}
data->basedepth = slashcount(top); // Only used for breadthxx
struct stat st;
struct PathStat st;
// We always follow symlinks at this point. Makes more sense.
if (path_fileprops(top, &st) == -1) {
// Note that we do not return an error if the stat call
@@ -343,19 +341,19 @@ FsTreeWalker::Status FsTreeWalker::walk(const string& _top,
// This means that we always go into the top 'walk()' parameter if it is a
// directory, even if norecurse is set. Bug or Feature ?
FsTreeWalker::Status FsTreeWalker::iwalk(const string &top,
struct stat *stp,
struct PathStat *stp,
FsTreeWalkerCB& cb)
{
Status status = FtwOk;
bool nullpush = false;
// Tell user to process the top entry itself
if (S_ISDIR(stp->st_mode)) {
if (stp->pst_type == PathStat::PST_DIR) {
if ((status = cb.processone(top, stp, FtwDirEnter)) &
(FtwStop|FtwError)) {
return status;
}
} else if (S_ISREG(stp->st_mode)) {
} else if (stp->pst_type == PathStat::PST_REGULAR) {
return cb.processone(top, stp, FtwRegular);
} else {
return status;
@@ -377,7 +375,7 @@ FsTreeWalker::Status FsTreeWalker::iwalk(const string &top,
// For now, we'll ignore the "other kind of cycle" part and only monitor
// this is FtwFollow is set
if (data->options & FtwFollow) {
DirId dirid(stp->st_dev, stp->st_ino);
DirId dirid(stp->pst_dev, stp->pst_ino);
if (data->donedirs.find(dirid) != data->donedirs.end()) {
LOGINFO("Not processing [" << top <<
"] (already seen as other path)\n");
@@ -420,7 +418,7 @@ FsTreeWalker::Status FsTreeWalker::iwalk(const string &top,
struct DIRENT *ent;
while (errno = 0, ((ent = READDIR(d)) != 0)) {
string fn;
struct stat st;
struct PathStat st;
#ifdef _WIN32
string sdname;
if (!wchartoutf8(ent->d_name, sdname)) {
@@ -468,7 +466,7 @@ FsTreeWalker::Status FsTreeWalker::iwalk(const string &top,
continue;
}
if (S_ISDIR(st.st_mode)) {
if (st.pst_type == PathStat::PST_DIR) {
if (!o_nowalkfn.empty() && path_exists(path_cat(fn, o_nowalkfn))) {
continue;
}
@@ -498,7 +496,8 @@ FsTreeWalker::Status FsTreeWalker::iwalk(const string &top,
if ((status = cb.processone(top, &st, FtwDirReturn))
& (FtwStop|FtwError))
goto out;
} else if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
} else if (st.pst_type == PathStat::PST_REGULAR ||
st.pst_type == PathStat::PST_SYMLINK) {
// Filtering patterns match ?
if (!data->onlyNames.empty()) {
if (!inOnlyNames(dname))
@@ -536,14 +535,14 @@ int64_t fsTreeBytes(const string& topdir)
class bytesCB : public FsTreeWalkerCB {
public:
FsTreeWalker::Status processone(const string &path,
const struct stat *st,
const struct PathStat *st,
FsTreeWalker::CbFlag flg) {
if (flg == FsTreeWalker::FtwDirEnter ||
flg == FsTreeWalker::FtwRegular) {
#ifdef _WIN32
totalbytes += st->st_size;
totalbytes += st->pst_size;
#else
totalbytes += st->st_blocks * 512;
totalbytes += st->pst_blocks * 512;
#endif
}
return FsTreeWalker::FtwOk;
+19 -23
View File
@@ -19,13 +19,10 @@
#include <string>
#include <vector>
#ifndef NO_NAMESPACES
using std::string;
using std::vector;
#endif
struct PathStat;
class FsTreeWalkerCB;
struct stat;
/**
* Class implementing a unix directory recursive walk.
@@ -44,8 +41,7 @@ class FsTreeWalker {
// to not use the flag, which can be set from rclconfig by adding
// a value to the config file (skippedPathsNoFnmPathname)
static bool o_useFnmPathname;
static void setNoFnmPathname()
{
static void setNoFnmPathname() {
o_useFnmPathname = false;
}
@@ -53,8 +49,7 @@ class FsTreeWalker {
// directories as if they were in skippedPaths) if the file exists
// inside the directory.
static std::string o_nowalkfn;
static void setNoWalkFn(const std::string& nowalkfn)
{
static void setNoWalkFn(const std::string& nowalkfn) {
o_nowalkfn = nowalkfn;
}
@@ -97,34 +92,35 @@ class FsTreeWalker {
* @param cb the function object that will be called back for every
* file-system object (called both at entry and exit for directories).
*/
Status walk(const string &dir, FsTreeWalkerCB& cb);
Status walk(const std::string &dir, FsTreeWalkerCB& cb);
/** Get explanation for error */
string getReason();
std::string getReason();
int getErrCnt();
/**
* Add a pattern (file or dir) to be ignored (ie: #* , *~)
*/
bool addSkippedName(const string &pattern);
bool addSkippedName(const std::string &pattern);
/** Set the ignored patterns set */
bool setSkippedNames(const vector<string> &patterns);
bool setSkippedNames(const std::vector<std::string> &patterns);
/** Set the exclusive patterns set */
bool setOnlyNames(const vector<string> &patterns);
bool setOnlyNames(const std::vector<std::string> &patterns);
/** Same for skipped paths: this are paths, not names, under which we
do not descend (ie: /home/me/.recoll) */
bool addSkippedPath(const string &path);
bool addSkippedPath(const std::string &path);
/** Set the ignored paths list */
bool setSkippedPaths(const vector<string> &patterns);
bool setSkippedPaths(const std::vector<std::string> &patterns);
/** Test if path/name should be skipped. This can be used independently of
* an actual tree walk */
bool inSkippedPaths(const string& path, bool ckparents = false);
bool inSkippedNames(const string& name);
bool inOnlyNames(const string& name);
bool inSkippedPaths(const std::string& path, bool ckparents = false);
bool inSkippedNames(const std::string& name);
bool inOnlyNames(const std::string& name);
private:
Status iwalk(const string &dir, struct stat *stp, FsTreeWalkerCB& cb);
Status iwalk(const std::string &dir, struct PathStat *stp,
FsTreeWalkerCB& cb);
class Internal;
Internal *data;
};
@@ -134,11 +130,11 @@ class FsTreeWalkerCB {
virtual ~FsTreeWalkerCB() {}
// Only st_mtime, st_ctime, st_size, st_mode (filetype bits: dir/reg/lnk),
virtual FsTreeWalker::Status
processone(const string &, const struct stat *, FsTreeWalker::CbFlag)
= 0;
processone(const std::string&, const struct PathStat *,
FsTreeWalker::CbFlag) = 0;
};
// Utility function. Somewhat like du.
int64_t fsTreeBytes(const string& topdir);
int64_t fsTreeBytes(const std::string& topdir);
#endif /* _FSTREEWALK_H_INCLUDED_ */
+35 -14
View File
@@ -684,11 +684,12 @@ bool path_makepath(const string& ipath, int mode)
return true;
}
bool path_isdir(const string& path)
bool path_isdir(const string& path, bool follow)
{
struct STATBUF st;
SYSPATH(path, syspath);
if (LSTAT(syspath, &st) < 0) {
int ret = follow ? STAT(syspath, &st) : LSTAT(syspath, &st);
if (ret < 0) {
return false;
}
if (S_ISDIR(st.st_mode)) {
@@ -697,6 +698,20 @@ bool path_isdir(const string& path)
return false;
}
bool path_isfile(const string& path, bool follow)
{
struct STATBUF st;
SYSPATH(path, syspath);
int ret = follow ? STAT(syspath, &st) : LSTAT(syspath, &st);
if (ret < 0) {
return false;
}
if (S_ISREG(st.st_mode)) {
return true;
}
return false;
}
long long path_filesize(const string& path)
{
struct STATBUF st;
@@ -707,30 +722,36 @@ long long path_filesize(const string& path)
return (long long)st.st_size;
}
int path_fileprops(const std::string path, struct stat *stp, bool follow)
int path_fileprops(const std::string path, struct PathStat *stp, bool follow)
{
if (!stp) {
if (nullptr == stp) {
return -1;
}
memset(stp, 0, sizeof(struct stat));
memset(stp, 0, sizeof(struct PathStat));
struct STATBUF mst;
SYSPATH(path, syspath);
int ret = follow ? STAT(syspath, &mst) : LSTAT(syspath, &mst);
if (ret != 0) {
return ret;
}
stp->st_size = mst.st_size;
stp->st_mode = mst.st_mode;
stp->st_mtime = mst.st_mtime;
stp->pst_size = mst.st_size;
stp->pst_mode = mst.st_mode;
stp->pst_mtime = mst.st_mtime;
#ifdef _WIN32
stp->st_ctime = mst.st_mtime;
stp->pst_ctime = mst.st_mtime;
#else
stp->st_ino = mst.st_ino;
stp->st_dev = mst.st_dev;
stp->st_ctime = mst.st_ctime;
stp->st_blocks = mst.st_blocks;
stp->st_blksize = mst.st_blksize;
stp->pst_ino = mst.st_ino;
stp->pst_dev = mst.st_dev;
stp->pst_ctime = mst.st_ctime;
stp->pst_blocks = mst.st_blocks;
stp->pst_blksize = mst.st_blksize;
#endif
switch (mst.st_mode & S_IFMT) {
case S_IFDIR: stp->pst_type = PathStat::PST_DIR;break;
case S_IFLNK: stp->pst_type = PathStat::PST_SYMLINK;break;
case S_IFREG: stp->pst_type = PathStat::PST_REGULAR;break;
default: stp->pst_type = PathStat::PST_OTHER;break;
}
return 0;
}
+17 -6
View File
@@ -20,6 +20,7 @@
#include <string>
#include <vector>
#include <set>
#include <cstdint>
// Must be called in main thread before starting other threads
extern void pathut_init_mt();
@@ -66,7 +67,9 @@ extern std::string url_parentfolder(const std::string& url);
extern std::string url_gpath(const std::string& url);
/// Stat parameter and check if it's a directory
extern bool path_isdir(const std::string& path);
extern bool path_isdir(const std::string& path, bool follow = false);
/// Stat parameter and check if it's a regular file
extern bool path_isfile(const std::string& path, bool follow = false);
/// Retrieve file size
extern long long path_filesize(const std::string& path);
@@ -79,8 +82,19 @@ extern long long path_filesize(const std::string& path);
/// all systems. st_dev and st_ino are set for special posix usage.
/// The rest is zeroed.
/// @ret 0 for success
struct stat;
extern int path_fileprops(const std::string path, struct stat *stp,
struct PathStat {
enum PstType {PST_REGULAR, PST_SYMLINK, PST_DIR, PST_OTHER};
PstType pst_type;
int64_t pst_size;
uint64_t pst_mode;
int64_t pst_mtime;
int64_t pst_ctime;
uint64_t pst_ino;
uint64_t pst_dev;
uint64_t pst_blocks;
uint64_t pst_blksize;
};
extern int path_fileprops(const std::string path, struct PathStat *stp,
bool follow = true);
/// Check that path is traversable and last element exists
@@ -150,9 +164,6 @@ public:
/// Convert \ separators to /
void path_slashize(std::string& s);
void path_backslashize(std::string& s);
#include "safeunistd.h"
#else
#include <unistd.h>
#endif
/// Lock/pid file class. This is quite close to the pidfile_xxx