Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 387803d

Browse files
committed
Fix lstat() for broken junction points on Windows.
When using junction points to emulate symlinks on Windows, one edge case was not handled correctly by commit c5cb8f3: if a junction point is broken (pointing to a non-existent path), we'd report ENOENT. This doesn't break any known use case, but was noticed while developing a test suite for these functions and is fixed here for completeness. Also add translation ERROR_CANT_RESOLVE_FILENAME -> ENOENT, as that is one of the errors Windows can report for some kinds of broken paths. Discussion: https://postgr.es/m/CA%2BhUKG%2BajSQ_8eu2AogTncOnZ5me2D-Cn66iN_-wZnRjLN%2Bicg%40mail.gmail.com
1 parent 4650036 commit 387803d

File tree

2 files changed

+25
-5
lines changed

2 files changed

+25
-5
lines changed

src/port/win32error.c

+3
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,9 @@ static const struct
167167
},
168168
{
169169
ERROR_INVALID_NAME, ENOENT
170+
},
171+
{
172+
ERROR_CANT_RESOLVE_FILENAME, ENOENT
170173
}
171174
};
172175

src/port/win32stat.c

+22-5
Original file line numberDiff line numberDiff line change
@@ -125,15 +125,30 @@ _pglstat64(const char *name, struct stat *buf)
125125

126126
hFile = pgwin32_open_handle(name, O_RDONLY, true);
127127
if (hFile == INVALID_HANDLE_VALUE)
128-
return -1;
129-
130-
ret = fileinfo_to_stat(hFile, buf);
128+
{
129+
if (errno == ENOENT)
130+
{
131+
/*
132+
* If it's a junction point pointing to a non-existent path, we'll
133+
* have ENOENT here (because pgwin32_open_handle does not use
134+
* FILE_FLAG_OPEN_REPARSE_POINT). In that case, we'll try again
135+
* with readlink() below, which will distinguish true ENOENT from
136+
* pseudo-symlink.
137+
*/
138+
memset(buf, 0, sizeof(*buf));
139+
ret = 0;
140+
}
141+
else
142+
return -1;
143+
}
144+
else
145+
ret = fileinfo_to_stat(hFile, buf);
131146

132147
/*
133148
* Junction points appear as directories to fileinfo_to_stat(), so we'll
134149
* need to do a bit more work to distinguish them.
135150
*/
136-
if (ret == 0 && S_ISDIR(buf->st_mode))
151+
if ((ret == 0 && S_ISDIR(buf->st_mode)) || hFile == INVALID_HANDLE_VALUE)
137152
{
138153
char next[MAXPGPATH];
139154
ssize_t size;
@@ -169,10 +184,12 @@ _pglstat64(const char *name, struct stat *buf)
169184
buf->st_mode &= ~S_IFDIR;
170185
buf->st_mode |= S_IFLNK;
171186
buf->st_size = size;
187+
ret = 0;
172188
}
173189
}
174190

175-
CloseHandle(hFile);
191+
if (hFile != INVALID_HANDLE_VALUE)
192+
CloseHandle(hFile);
176193
return ret;
177194
}
178195

0 commit comments

Comments
 (0)