diff options
author | Karen Arutyunov <karen@codesynthesis.com> | 2018-09-05 19:59:54 +0300 |
---|---|---|
committer | Karen Arutyunov <karen@codesynthesis.com> | 2018-09-05 20:00:15 +0300 |
commit | d0616755700d996c0a43b276d2544b5e59ab7530 (patch) | |
tree | c8c4ad849f01f275784c75950c1e6868394b1b1b | |
parent | eaf13f53eeaba8f6ffe5f2e38ff51eefd273046d (diff) |
Keep trying to remove file for a second on Windows
The thinking is that there can be some Windows process analyzing newly created
files and so preventing their removal.
-rw-r--r-- | libbutl/filesystem.cxx | 55 |
1 files changed, 36 insertions, 19 deletions
diff --git a/libbutl/filesystem.cxx b/libbutl/filesystem.cxx index 3c10e8b..0729964 100644 --- a/libbutl/filesystem.cxx +++ b/libbutl/filesystem.cxx @@ -315,7 +315,7 @@ namespace butl #ifndef _WIN32 int ur (unlink (f)); #else - int ur (_unlink (f)); + int ur; // On Windows a file with the read-only attribute can not be deleted. This // can be the reason if the deletion fails with the 'permission denied' @@ -325,32 +325,49 @@ namespace butl // Yet another reason for the 'permission denied' failure can be a // directory symlink. // - if (ur != 0 && errno == EACCES) + // And also there are some unknown reasons for the 'permission denied' + // failure (see mventry() for details). If that's the case, we will keep + // trying to move the file for a second. + // + for (size_t i (0); i < 11; ++i) { - DWORD a (GetFileAttributes (f)); - if (a != INVALID_FILE_ATTRIBUTES) - { - bool readonly ((a & FILE_ATTRIBUTE_READONLY) != 0); + // Sleep 100 milliseconds before the removal retry. + // + if (i != 0) + Sleep (100); - // Note that we support only directory symlinks on Windows. - // - bool symlink ((a & FILE_ATTRIBUTE_REPARSE_POINT) != 0 && - (a & FILE_ATTRIBUTE_DIRECTORY) != 0); + ur = _unlink (f); - if (readonly || symlink) + if (ur != 0 && errno == EACCES) + { + DWORD a (GetFileAttributes (f)); + if (a != INVALID_FILE_ATTRIBUTES) { - bool restore (readonly && - SetFileAttributes (f, a & ~FILE_ATTRIBUTE_READONLY)); + bool readonly ((a & FILE_ATTRIBUTE_READONLY) != 0); - ur = symlink ? _rmdir (f) : _unlink (f); - - // Restoring the attribute is unlikely to fail as we managed to reset - // it earlier. + // Note that we support only directory symlinks on Windows. // - if (ur != 0 && restore) - SetFileAttributes (f, a); + bool symlink ((a & FILE_ATTRIBUTE_REPARSE_POINT) != 0 && + (a & FILE_ATTRIBUTE_DIRECTORY) != 0); + + if (readonly || symlink) + { + bool restore (readonly && + SetFileAttributes (f, a & ~FILE_ATTRIBUTE_READONLY)); + + ur = symlink ? _rmdir (f) : _unlink (f); + + // Restoring the attribute is unlikely to fail as we managed to + // reset it earlier. + // + if (ur != 0 && restore) + SetFileAttributes (f, a); + } } } + + if (ur == 0 || errno != EACCES) + break; } #endif |