Call remove() repeatedly for ~1 sec. Have chaz_OS_remove() keep calling remove() repeatedly for up to 1 second before giving up. This is necessary because the existing workaround of renaming a file can fail with a permissions error under Windows if rapid-fire system calls happen too quickly.
Project: http://git-wip-us.apache.org/repos/asf/lucy-charmonizer/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy-charmonizer/commit/01dd8b43 Tree: http://git-wip-us.apache.org/repos/asf/lucy-charmonizer/tree/01dd8b43 Diff: http://git-wip-us.apache.org/repos/asf/lucy-charmonizer/diff/01dd8b43 Branch: refs/heads/master Commit: 01dd8b43c262984d75118368cdc646adbcef160c Parents: b04beeb Author: Marvin Humphrey <[email protected]> Authored: Thu Jul 17 19:09:26 2014 -0700 Committer: Marvin Humphrey <[email protected]> Committed: Tue Jul 22 15:40:25 2014 -0700 ---------------------------------------------------------------------- src/Charmonizer/Core/OperatingSystem.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy-charmonizer/blob/01dd8b43/src/Charmonizer/Core/OperatingSystem.c ---------------------------------------------------------------------- diff --git a/src/Charmonizer/Core/OperatingSystem.c b/src/Charmonizer/Core/OperatingSystem.c index 31db30c..3f0743d 100644 --- a/src/Charmonizer/Core/OperatingSystem.c +++ b/src/Charmonizer/Core/OperatingSystem.c @@ -18,6 +18,7 @@ #include <string.h> #include <stdarg.h> #include <ctype.h> +#include <time.h> #include "Charmonizer/Core/Compiler.h" #include "Charmonizer/Core/Util.h" @@ -144,13 +145,15 @@ chaz_OS_remove(const char *name) { * fail. As a workaround, files are renamed to a random name * before deletion. */ - int retval; + int retval = 0; static const size_t num_random_chars = 16; size_t name_len = strlen(name); size_t i; char *temp_name = (char*)malloc(name_len + num_random_chars + 1); + const char *working_name; + clock_t start, now; strcpy(temp_name, name); for (i = 0; i < num_random_chars; i++) { @@ -159,11 +162,26 @@ chaz_OS_remove(const char *name) { temp_name[name_len+num_random_chars] = '\0'; if (rename(name, temp_name) == 0) { - retval = !remove(temp_name); + working_name = temp_name; + } + else if (errno == ENOENT) { + /* No such file or directory, so no point in trying to remove it. + * (Technically ENOENT is POSIX but hopefully this works.) */ + free(temp_name); + return 0; } else { - // Error during rename, remove using old name. - retval = !remove(name); + /* Error during rename, remove using old name. */ + working_name = name; + } + + /* Try over and over again for around 1 second to delete the file. + * Ideally we would sleep between attempts, but sleep functionality is not + * portable. */ + start = now = clock(); + while (!retval && now - start < CLOCKS_PER_SEC) { + now = clock(); + retval = !remove(working_name); } free(temp_name);
