Centralize stat calls to ensure consistency of time fields on windows
This commit is contained in:
parent
a1d4659d5b
commit
fad8f5151b
9 changed files with 52 additions and 18 deletions
|
@ -342,7 +342,7 @@ bool BeagleQueueIndexer::indexFiles(list<string>& files)
|
||||||
it++; continue;
|
it++; continue;
|
||||||
}
|
}
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(it->c_str(), &st) != 0) {
|
if (path_fileprops(*it, &st) != 0) {
|
||||||
LOGERR(("BeagleQueueIndexer::indexfiles: cant stat [%s]\n",
|
LOGERR(("BeagleQueueIndexer::indexfiles: cant stat [%s]\n",
|
||||||
it->c_str()));
|
it->c_str()));
|
||||||
it++; continue;
|
it++; continue;
|
||||||
|
|
|
@ -21,11 +21,11 @@
|
||||||
|
|
||||||
#include "debuglog.h"
|
#include "debuglog.h"
|
||||||
#include "cstr.h"
|
#include "cstr.h"
|
||||||
|
|
||||||
#include "fetcher.h"
|
#include "fetcher.h"
|
||||||
#include "fsfetcher.h"
|
#include "fsfetcher.h"
|
||||||
#include "fsindexer.h"
|
#include "fsindexer.h"
|
||||||
#include "debuglog.h"
|
#include "debuglog.h"
|
||||||
|
#include "pathut.h"
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ static bool urltopath(RclConfig* cnf,
|
||||||
bool follow = false;
|
bool follow = false;
|
||||||
cnf->getConfParam("followLinks", &follow);
|
cnf->getConfParam("followLinks", &follow);
|
||||||
|
|
||||||
if ((follow ? stat(fn.c_str(), &st) : lstat(fn.c_str(), &st))< 0) {
|
if (path_fileprops(fn, &st, follow) < 0) {
|
||||||
LOGERR(("FSDocFetcher::fetch: stat errno %d for [%s]\n",
|
LOGERR(("FSDocFetcher::fetch: stat errno %d for [%s]\n",
|
||||||
errno, fn.c_str()));
|
errno, fn.c_str()));
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -362,10 +362,9 @@ bool FsIndexer::indexFiles(list<string>& files, int flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct stat stb;
|
struct stat stb;
|
||||||
int ststat = follow ? stat(it->c_str(), &stb) :
|
int ststat = path_fileprops(*it, &stb, follow);
|
||||||
lstat(it->c_str(), &stb);
|
|
||||||
if (ststat != 0) {
|
if (ststat != 0) {
|
||||||
LOGERR(("FsIndexer::indexFiles: lstat(%s): %s", it->c_str(),
|
LOGERR(("FsIndexer::indexFiles: (l)stat %s: %s", it->c_str(),
|
||||||
strerror(errno)));
|
strerror(errno)));
|
||||||
it++;
|
it++;
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -195,7 +195,7 @@ void FileInterner::init(const string &f, const struct stat *stp, RclConfig *cnf,
|
||||||
m_fn = m_tfile;
|
m_fn = m_tfile;
|
||||||
// Stat the uncompressed file, mainly to get the size
|
// Stat the uncompressed file, mainly to get the size
|
||||||
struct stat ucstat;
|
struct stat ucstat;
|
||||||
if (stat(m_fn.c_str(), &ucstat) != 0) {
|
if (path_fileprops(m_fn, &ucstat) != 0) {
|
||||||
LOGERR(("FileInterner: can't stat the uncompressed file"
|
LOGERR(("FileInterner: can't stat the uncompressed file"
|
||||||
"[%s] errno %d\n", m_fn.c_str(), errno));
|
"[%s] errno %d\n", m_fn.c_str(), errno));
|
||||||
return;
|
return;
|
||||||
|
@ -1042,7 +1042,7 @@ bool FileInterner::isCompressed(const string& fn, RclConfig *cnf)
|
||||||
{
|
{
|
||||||
LOGDEB(("FileInterner::isCompressed: [%s]\n", fn.c_str()));
|
LOGDEB(("FileInterner::isCompressed: [%s]\n", fn.c_str()));
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (stat(fn.c_str(), &st) < 0) {
|
if (path_fileprops(fn, &st) < 0) {
|
||||||
LOGERR(("FileInterner::isCompressed: can't stat [%s]\n", fn.c_str()));
|
LOGERR(("FileInterner::isCompressed: can't stat [%s]\n", fn.c_str()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1066,7 +1066,7 @@ bool FileInterner::maybeUncompressToTemp(TempFile& temp, const string& fn,
|
||||||
{
|
{
|
||||||
LOGDEB(("FileInterner::maybeUncompressToTemp: [%s]\n", fn.c_str()));
|
LOGDEB(("FileInterner::maybeUncompressToTemp: [%s]\n", fn.c_str()));
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (stat(fn.c_str(), &st) < 0) {
|
if (path_fileprops(fn.c_str(), &st) < 0) {
|
||||||
LOGERR(("FileInterner::maybeUncompressToTemp: can't stat [%s]\n",
|
LOGERR(("FileInterner::maybeUncompressToTemp: can't stat [%s]\n",
|
||||||
fn.c_str()));
|
fn.c_str()));
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "safefcntl.h"
|
#include "safefcntl.h"
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include "safesysstat.h"
|
|
||||||
#include "safeunistd.h"
|
#include "safeunistd.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -56,7 +55,7 @@ bool MimeHandlerText::set_document_file(const string& mt, const string &fn)
|
||||||
// file size for oversize check
|
// file size for oversize check
|
||||||
long long fsize = path_filesize(m_fn);
|
long long fsize = path_filesize(m_fn);
|
||||||
if (fsize < 0) {
|
if (fsize < 0) {
|
||||||
LOGERR(("MimeHandlerText::set_document_file: stat(%s) errno %d\n",
|
LOGERR(("MimeHandlerText::set_document_file: stat %s errno %d\n",
|
||||||
m_fn.c_str(), errno));
|
m_fn.c_str(), errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -553,6 +553,9 @@ void UIPrefsDialog::delExtraDbPB_clicked()
|
||||||
|
|
||||||
static bool samedir(const string& dir1, const string& dir2)
|
static bool samedir(const string& dir1, const string& dir2)
|
||||||
{
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
return !dir1.compare(dir2);
|
||||||
|
#else
|
||||||
struct stat st1, st2;
|
struct stat st1, st2;
|
||||||
if (stat(dir1.c_str(), &st1))
|
if (stat(dir1.c_str(), &st1))
|
||||||
return false;
|
return false;
|
||||||
|
@ -562,6 +565,7 @@ static bool samedir(const string& dir1, const string& dir2)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIPrefsDialog::on_showTrayIconCB_clicked()
|
void UIPrefsDialog::on_showTrayIconCB_clicked()
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fnmatch.h>
|
#include <fnmatch.h>
|
||||||
#include "safesysstat.h"
|
#include "safesysstat.h"
|
||||||
|
@ -226,7 +225,7 @@ FsTreeWalker::Status FsTreeWalker::walk(const string& _top,
|
||||||
data->basedepth = slashcount(top); // Only used for breadthxx
|
data->basedepth = slashcount(top); // Only used for breadthxx
|
||||||
struct stat st;
|
struct stat st;
|
||||||
// We always follow symlinks at this point. Makes more sense.
|
// We always follow symlinks at this point. Makes more sense.
|
||||||
if (stat(top.c_str(), &st) == -1) {
|
if (path_fileprops(top, &st) == -1) {
|
||||||
// Note that we do not return an error if the stat call
|
// Note that we do not return an error if the stat call
|
||||||
// fails. A temp file may have gone away.
|
// fails. A temp file may have gone away.
|
||||||
data->logsyserr("stat", top);
|
data->logsyserr("stat", top);
|
||||||
|
@ -288,7 +287,7 @@ FsTreeWalker::Status FsTreeWalker::walk(const string& _top,
|
||||||
|
|
||||||
// If changing parent directory, advise our user.
|
// If changing parent directory, advise our user.
|
||||||
if (!nfather.empty()) {
|
if (!nfather.empty()) {
|
||||||
if (stat(nfather.c_str(), &st) == -1) {
|
if (path_fileprops(nfather, &st) == -1) {
|
||||||
data->logsyserr("stat", nfather);
|
data->logsyserr("stat", nfather);
|
||||||
return errno == ENOENT ? FtwOk : FtwError;
|
return errno == ENOENT ? FtwOk : FtwError;
|
||||||
}
|
}
|
||||||
|
@ -298,7 +297,7 @@ FsTreeWalker::Status FsTreeWalker::walk(const string& _top,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stat(dir.c_str(), &st) == -1) {
|
if (path_fileprops(dir, &st) == -1) {
|
||||||
data->logsyserr("stat", dir);
|
data->logsyserr("stat", dir);
|
||||||
return errno == ENOENT ? FtwOk : FtwError;
|
return errno == ENOENT ? FtwOk : FtwError;
|
||||||
}
|
}
|
||||||
|
@ -397,7 +396,8 @@ FsTreeWalker::Status FsTreeWalker::iwalk(const string &top,
|
||||||
|
|
||||||
fn = path_cat(top, ent->d_name);
|
fn = path_cat(top, ent->d_name);
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// readdir gets the useful attrs, no inode indirection on windows
|
// readdir gets the useful attrs, no inode indirection on windows,
|
||||||
|
// spare the path_fileprops() call, but make sure we mimick it.
|
||||||
memset(&st, 0, sizeof(st));
|
memset(&st, 0, sizeof(st));
|
||||||
st.st_mtime = ent->d_mtime;
|
st.st_mtime = ent->d_mtime;
|
||||||
st.st_size = ent->d_size;
|
st.st_size = ent->d_size;
|
||||||
|
@ -407,8 +407,7 @@ FsTreeWalker::Status FsTreeWalker::iwalk(const string &top,
|
||||||
// anyway.
|
// anyway.
|
||||||
st.st_ctime = st.st_mtime;
|
st.st_ctime = st.st_mtime;
|
||||||
#else
|
#else
|
||||||
int statret = (data->options & FtwFollow) ? stat(fn.c_str(), &st) :
|
int statret = path_fileprops(fn.c_str(), &st, data->options&FtwFollow);
|
||||||
lstat(fn.c_str(), &st);
|
|
||||||
if (statret == -1) {
|
if (statret == -1) {
|
||||||
data->logsyserr("stat", fn);
|
data->logsyserr("stat", fn);
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -710,6 +710,28 @@ long long path_filesize(const string& path)
|
||||||
return (long long)st.st_size;
|
return (long long)st.st_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int path_fileprops(const std::string path, struct stat *stp, bool follow)
|
||||||
|
{
|
||||||
|
if (!stp)
|
||||||
|
return -1;
|
||||||
|
memset(stp, 0, sizeof(struct stat));
|
||||||
|
struct stat mst;
|
||||||
|
int ret = follow ? stat(path.c_str(), &mst) : lstat(path.c_str(), &mst);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
stp->st_size = mst.st_size;
|
||||||
|
stp->st_mode = mst.st_mode;
|
||||||
|
stp->st_mtime = mst.st_mtime;
|
||||||
|
#ifdef _WIN32
|
||||||
|
stp->st_ctime = mst.st_mtime;
|
||||||
|
#else
|
||||||
|
stp->st_ino = mst.st_ino;
|
||||||
|
stp->st_dev = mst.st_dev;
|
||||||
|
stp->st_ctime = mst.st_ctime;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool path_exists(const string& path)
|
bool path_exists(const string& path)
|
||||||
{
|
{
|
||||||
return access(path.c_str(), 0) == 0;
|
return access(path.c_str(), 0) == 0;
|
||||||
|
|
|
@ -79,6 +79,17 @@ extern bool path_isdir(const std::string& path);
|
||||||
/// Retrieve file size
|
/// Retrieve file size
|
||||||
extern long long path_filesize(const std::string& path);
|
extern long long path_filesize(const std::string& path);
|
||||||
|
|
||||||
|
/// Retrieve essential file attributes. This is used rather than a
|
||||||
|
/// bare stat() to ensure consistent use of the time fields (on
|
||||||
|
/// windows, we set ctime=mtime as ctime is actually the creation
|
||||||
|
/// time, for which we have no use).
|
||||||
|
/// Only st_mtime, st_ctime, st_size, st_mode (file type bits) are set on
|
||||||
|
/// all systems. st_dev and st_ino are set for special posix usage.
|
||||||
|
/// The rest is zeroed.
|
||||||
|
struct stat;
|
||||||
|
extern int path_fileprops(const std::string path, struct stat *stp,
|
||||||
|
bool follow = true);
|
||||||
|
|
||||||
/// Check that path is traversable and last element exists
|
/// Check that path is traversable and last element exists
|
||||||
/// Returns true if last elt could be checked to exist. False may mean that
|
/// Returns true if last elt could be checked to exist. False may mean that
|
||||||
/// the file/dir does not exist or that an error occurred.
|
/// the file/dir does not exist or that an error occurred.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue