Add Win32 unlink/rename file.
authorBruce Momjian
Tue, 22 Apr 2003 02:18:48 +0000 (02:18 +0000)
committerBruce Momjian
Tue, 22 Apr 2003 02:18:48 +0000 (02:18 +0000)
src/port/dirmod.c [new file with mode: 0644]

diff --git a/src/port/dirmod.c b/src/port/dirmod.c
new file mode 100644 (file)
index 0000000..15afbc1
--- /dev/null
@@ -0,0 +1,138 @@
+#ifndef TEST_VERSION
+
+#undef rename
+#undef unlink
+
+int pgrename(const char *from, const char *to)
+{
+   int loops = 0;
+
+   while (!MoveFileEx(from, to, MOVEFILE_REPLACE_EXISTING))
+   {
+       if (GetLastError() != ERROR_ACCESS_DENIED)
+           /* set errno? */
+           return -1;
+       Sleep(100); /* ms */
+       if (loops == 10)
+#ifndef FRONTEND
+           elog(LOG, "Unable to rename %s to %s, continuing to try", from, to);
+#else
+           fprintf(stderr, "Unable to rename %s to %s, continuing to try\n", from, to);
+#endif
+       loops++;
+   }
+
+   if (loops > 10)
+#ifndef FRONTEND
+       elog(LOG, "Completed rename of %s to %s", from, to);
+#else
+       fprintf(stderr, "Completed rename of %s to %s\n", from, to);
+#endif
+   return 0;
+}
+
+
+int pgunlink(const char *path)
+{
+   int loops = 0;
+
+   while (unlink(path))
+   {
+       if (errno != EACCES)
+           /* set errno? */
+           return -1;
+       Sleep(100); /* ms */
+       if (loops == 10)
+#ifndef FRONTEND
+           elog(LOG, "Unable to unlink %s, continuing to try", path);
+#else
+           fprintf(stderr, "Unable to unlink %s, continuing to try\n", path);
+#endif
+       loops++;
+   }
+
+   if (loops > 10)
+#ifndef FRONTEND
+       elog(LOG, "Completed unlink of %s", path);
+#else
+       fprintf(stderr, "Completed unlink of %s\n", path);
+#endif
+   return 0;
+}
+
+
+#else
+
+
+/*
+ *  Illustrates problem with Win32 rename() and unlink()
+ * under concurrent access.
+ *
+ * Run with arg '1', then less than 5 seconds later, run with
+ *  arg '2' (rename) or '3'(unlink) to see the problem.
+ */
+#include 
+#include 
+#include 
+#include 
+
+#define halt(str) \
+do { \
+   fputs(str, stderr); \
+   exit(1); \
+} while (0)
+
+int
+main(int argc, char* argv[])
+{
+   FILE *fd;
+
+   if (argc != 2)
+       halt("Arg must be '1' (test), '2' (rename), or '3' (unlink)\n"
+            "Run '1' first, then less than 5 seconds later, run\n"
+            "'2' to test rename, or '3' to test unlink.\n");
+
+   if (atoi(argv[1]) == 1)
+   {
+       if ((fd = fopen("/rtest.txt", "w")) == NULL)
+           halt("Can not create file\n");
+       fclose(fd);
+       if ((fd = fopen("/rtest.txt", "r")) == NULL)
+           halt("Can not open file\n");
+       Sleep(5000);
+   }
+   else if (atoi(argv[1]) == 2)
+   {
+       unlink("/rtest.new");
+       if ((fd = fopen("/rtest.new", "w")) == NULL)
+           halt("Can not create file\n");
+       fclose(fd);
+       while (!MoveFileEx("/rtest.new", "/rtest.txt", MOVEFILE_REPLACE_EXISTING))
+       {
+           if (GetLastError() != ERROR_ACCESS_DENIED)
+               halt("Unknown failure\n");
+           else
+               fprintf(stderr, "move failed\n");
+           Sleep(500);
+       }
+       halt("move successful\n");
+   }
+   else if (atoi(argv[1]) == 3)
+   {
+       while (unlink("/rtest.txt"))
+       {
+           if (errno != EACCES)
+               halt("Unknown failure\n");
+           else
+               fprintf(stderr, "unlink failed\n");
+           Sleep(500);
+       }
+       halt("unlink successful\n");
+   }
+   else    
+       halt("invalid arg\n");
+
+   return 0;
+}
+#endif