On 2022-08-06 08:02, Thomas Munro wrote:

Pushed.

Hmm, this stuff could *really* use a little test framework that's run
by check-world, that exercises these various replacement operations.
But I also suspect that problems in this area are likely to be due to
concurrency.  It's hard to make a simple test that simulates the case
where a file is unlinked between system calls within stat() and hits
the STATUS_DELETE_PENDING case.  That check is code I cargo-culted in
this patch.  So much of the stuff we've had in the tree relating to
that area has been wrong in the past...

Hello, hackers!

initdb on my windows 10 system stopped working after the commit
c5cb8f3b: "Provide lstat() for Windows."
The error message is: creating directory C:/HOME/data ... initdb:
error: could not create directory "C:/HOME": File exists

"C:/HOME" is the junction point to the second volume on my hard drive -
"\??\Volume{GUID}\" which name pgreadlink() erroneously strips here:
https://github.com/postgres/postgres/blob/7e29a79a46d30dc236d097825ab849158929d977/src/port/dirmod.c#L357.
So initdb could not stat the file with name "Volume{GUID}", tried to
create it and failed.
With the attached patch initdb works fine again.

--
regards,

Roman
diff --git a/src/port/dirmod.c b/src/port/dirmod.c
index 2818bfd2e95..9d73620a6ba 100644
--- a/src/port/dirmod.c
+++ b/src/port/dirmod.c
@@ -354,7 +354,8 @@ pgreadlink(const char *path, char *buf, size_t size)
 	 * If the path starts with "\??\", which it will do in most (all?) cases,
 	 * strip those out.
 	 */
-	if (r > 4 && strncmp(buf, "\\??\\", 4) == 0)
+	if (r > 4 && strncmp(buf, "\\??\\", 4) == 0 &&
+		strncmp(buf, "\\??\\Volume", 10) != 0)
 	{
 		memmove(buf, buf + 4, strlen(buf + 4) + 1);
 		r -= 4;

Reply via email to