Skip to content

Commit b952f0e

Browse files
committed
Add Win32 unlink/rename file.
1 parent dfc6649 commit b952f0e

File tree

1 file changed

+138
-0
lines changed

1 file changed

+138
-0
lines changed

src/port/dirmod.c

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
#ifndef TEST_VERSION
2+
3+
#undef rename
4+
#undef unlink
5+
6+
int pgrename(const char *from, const char *to)
7+
{
8+
int loops = 0;
9+
10+
while (!MoveFileEx(from, to, MOVEFILE_REPLACE_EXISTING))
11+
{
12+
if (GetLastError() != ERROR_ACCESS_DENIED)
13+
/* set errno? */
14+
return -1;
15+
Sleep(100); /* ms */
16+
if (loops == 10)
17+
#ifndef FRONTEND
18+
elog(LOG, "Unable to rename %s to %s, continuing to try", from, to);
19+
#else
20+
fprintf(stderr, "Unable to rename %s to %s, continuing to try\n", from, to);
21+
#endif
22+
loops++;
23+
}
24+
25+
if (loops > 10)
26+
#ifndef FRONTEND
27+
elog(LOG, "Completed rename of %s to %s", from, to);
28+
#else
29+
fprintf(stderr, "Completed rename of %s to %s\n", from, to);
30+
#endif
31+
return 0;
32+
}
33+
34+
35+
int pgunlink(const char *path)
36+
{
37+
int loops = 0;
38+
39+
while (unlink(path))
40+
{
41+
if (errno != EACCES)
42+
/* set errno? */
43+
return -1;
44+
Sleep(100); /* ms */
45+
if (loops == 10)
46+
#ifndef FRONTEND
47+
elog(LOG, "Unable to unlink %s, continuing to try", path);
48+
#else
49+
fprintf(stderr, "Unable to unlink %s, continuing to try\n", path);
50+
#endif
51+
loops++;
52+
}
53+
54+
if (loops > 10)
55+
#ifndef FRONTEND
56+
elog(LOG, "Completed unlink of %s", path);
57+
#else
58+
fprintf(stderr, "Completed unlink of %s\n", path);
59+
#endif
60+
return 0;
61+
}
62+
63+
64+
#else
65+
66+
67+
/*
68+
* Illustrates problem with Win32 rename() and unlink()
69+
* under concurrent access.
70+
*
71+
* Run with arg '1', then less than 5 seconds later, run with
72+
* arg '2' (rename) or '3'(unlink) to see the problem.
73+
*/
74+
75+
#include <stdio.h>
76+
#include <stdlib.h>
77+
#include <errno.h>
78+
#include <windows.h>
79+
80+
#define halt(str) \
81+
do { \
82+
fputs(str, stderr); \
83+
exit(1); \
84+
} while (0)
85+
86+
int
87+
main(int argc, char* argv[])
88+
{
89+
FILE *fd;
90+
91+
if (argc != 2)
92+
halt("Arg must be '1' (test), '2' (rename), or '3' (unlink)\n"
93+
"Run '1' first, then less than 5 seconds later, run\n"
94+
"'2' to test rename, or '3' to test unlink.\n");
95+
96+
if (atoi(argv[1]) == 1)
97+
{
98+
if ((fd = fopen("/rtest.txt", "w")) == NULL)
99+
halt("Can not create file\n");
100+
fclose(fd);
101+
if ((fd = fopen("/rtest.txt", "r")) == NULL)
102+
halt("Can not open file\n");
103+
Sleep(5000);
104+
}
105+
else if (atoi(argv[1]) == 2)
106+
{
107+
unlink("/rtest.new");
108+
if ((fd = fopen("/rtest.new", "w")) == NULL)
109+
halt("Can not create file\n");
110+
fclose(fd);
111+
while (!MoveFileEx("/rtest.new", "/rtest.txt", MOVEFILE_REPLACE_EXISTING))
112+
{
113+
if (GetLastError() != ERROR_ACCESS_DENIED)
114+
halt("Unknown failure\n");
115+
else
116+
fprintf(stderr, "move failed\n");
117+
Sleep(500);
118+
}
119+
halt("move successful\n");
120+
}
121+
else if (atoi(argv[1]) == 3)
122+
{
123+
while (unlink("/rtest.txt"))
124+
{
125+
if (errno != EACCES)
126+
halt("Unknown failure\n");
127+
else
128+
fprintf(stderr, "unlink failed\n");
129+
Sleep(500);
130+
}
131+
halt("unlink successful\n");
132+
}
133+
else
134+
halt("invalid arg\n");
135+
136+
return 0;
137+
}
138+
#endif

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy