Cygwin, correct rename

When renaming a file, Windows first opens it, renames it and then closes it.
We then must decrease the target openFiles count.
This commit is contained in:
benrubson 2018-03-26 22:23:09 +02:00
parent be0c616d38
commit 27394cd198
3 changed files with 36 additions and 5 deletions

View File

@ -171,6 +171,15 @@ void EncFS_Context::eraseNode(const char *path,
Lock lock(contextMutex);
auto it = openFiles.find(std::string(path));
#ifdef __CYGWIN__
// When renaming a file, Windows first opens it, renames it and then closes it
// Filenode may have then been renamed too
if (it == openFiles.end()) {
RLOG(WARNING) << "Filenode to erase not found, file has certainly be renamed: "
<< path;
return;
}
#endif
rAssert(it != openFiles.end());
auto &list = it->second;

View File

@ -599,12 +599,27 @@ int DirNode::rename(const char *fromPlaintext, const char *toPlaintext) {
if (renameOp) {
renameOp->undo();
}
} else if (preserve_mtime) {
}
else {
#ifdef __CYGWIN__
// When renaming a file, Windows first opens it, renames it and then closes it
// We then must decrease the target openFiles count
// We could recreate the source so that close will not (silently) fails,
// however it will update modification time of the file, so break what we do below.
// Let's simply warn in eraseNode().
if (!isDirectory(toCName.c_str())) {
std::shared_ptr<FileNode> toNode = findOrCreate(toPlaintext);
ctx->eraseNode(toPlaintext, toNode);
//ctx->putNode(fromPlaintext, toNode);
}
#endif
if (preserve_mtime) {
struct utimbuf ut;
ut.actime = st.st_atime;
ut.modtime = st.st_mtime;
::utime(toCName.c_str(), &ut);
}
}
} catch (encfs::Error &err) {
// exception from renameNode, just show the error and continue..
RLOG(WARNING) << err.what();

View File

@ -167,6 +167,13 @@ static int withFileNode(const char *opName, const char *path,
if (fi != nullptr && fi->fh != 0) {
auto node = ctx->lookupFuseFh(fi->fh);
if (node == nullptr) {
#ifdef __CYGWIN__
if (strcmp(opName, "flush") == 0) {
RLOG(WARNING) << "Filenode to flush not found, file has certainly be renamed: "
<< path;
return 0;
}
#endif
auto msg = "fh=" + std::to_string(fi->fh) + " not found in fuseFhMap";
throw Error(msg.c_str());
}