Cloud storage: try to work around weird Windows rename issue

In some cases the rename of the cache directory would fail in my testing.
Based on code that Lubomir provided, this tries a Windows specific
implementation of folder rename if the QDir based one fails for some
reason - but obviously only if we are running on Windows.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Dirk Hohndel 2015-09-26 12:35:21 -04:00
parent b1dca1176f
commit 8e76456149
3 changed files with 51 additions and 1 deletions

1
dive.h
View file

@ -682,6 +682,7 @@ struct user_info {
extern void subsurface_user_info(struct user_info *);
extern int subsurface_rename(const char *path, const char *newpath);
extern int subsurface_dir_rename(const char *path, const char *newpath);
extern int subsurface_open(const char *path, int oflags, mode_t mode);
extern FILE *subsurface_fopen(const char *path, const char *mode);
extern void *subsurface_opendir(const char *path);

View file

@ -644,7 +644,12 @@ extern "C" char *move_away(const char *old_path)
if (!oldDir.rename(old_path, newPath)) {
if (verbose)
qDebug() << "rename of" << old_path << "to" << newPath << "failed";
return strdup("");
// this next one we only try on Windows... if we are on a different platform
// we simply give up and return an empty string
#ifdef WIN32
if (subsurface_dir_rename(old_path, qPrintable(newPath)) == 0)
#endif
return strdup("");
}
return strdup(qPrintable(newPath));
}

View file

@ -188,6 +188,50 @@ int subsurface_rename(const char *path, const char *newpath)
return ret;
}
// if the QDir based rename fails, we try this one
int subsurface_dir_rename(const char *path, const char *newpath)
{
// check if the folder exists
BOOL exists = FALSE;
DWORD attrib = GetFileAttributes(path);
if (attrib != INVALID_FILE_ATTRIBUTES && attrib & FILE_ATTRIBUTE_DIRECTORY)
exists = TRUE;
if (!exists && verbose) {
fprintf(stderr, "folder not found or path is not a folder: %s\n", path);
return EXIT_FAILURE;
}
// list of error codes:
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms681381(v=vs.85).aspx
DWORD errorCode;
// if this fails something has already obatained (more) exclusive access to the folder
HANDLE h = CreateFile(path, GENERIC_WRITE, FILE_SHARE_WRITE |
FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
if (h == INVALID_HANDLE_VALUE) {
errorCode = GetLastError();
if (verbose)
fprintf(stderr, "cannot obtain exclusive write access for folder: %u\n", (unsigned int)errorCode );
return EXIT_FAILURE;
} else {
if (verbose)
fprintf(stderr, "exclusive write access obtained...closing handle!");
CloseHandle(h);
// attempt to rename
BOOL result = MoveFile(path, newpath);
if (!result) {
errorCode = GetLastError();
if (verbose)
fprintf(stderr, "rename failed: %u\n", (unsigned int)errorCode);
return EXIT_FAILURE;
}
if (verbose > 1)
fprintf(stderr, "folder rename success: %s ---> %s\n", path, newpath);
}
return EXIT_SUCCESS;
}
int subsurface_open(const char *path, int oflags, mode_t mode)
{
int ret = -1;