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);

Reply via email to