Skip to content

Commit 5fc88c5

Browse files
committed
Replace pgwin32_is_junction() with lstat().
Now that lstat() reports junction points with S_IFLNK/S_ISLINK(), and unlink() can unlink them, there is no need for conditional code for Windows in a few places. That was expressed by testing for WIN32 or S_ISLNK, which we can now constant-fold. The coding around pgwin32_is_junction() was a bit suspect anyway, as we never checked for errors, and we also know that errors can be spuriously reported because of transient sharing violations on this OS. The lstat()-based code has handling for that. This also reverts 4fc6b6e on master only. That was done because lstat() didn't previously work for symlinks (junction points), but now it does. Tested-by: Andrew Dunstan <andrew@dunslane.net> Discussion: https://postgr.es/m/CA%2BhUKGLfOOeyZpm5ByVcAt7x5Pn-%3DxGRNCvgiUPVVzjFLtnY0w%40mail.gmail.com
1 parent f357233 commit 5fc88c5

File tree

10 files changed

+2
-78
lines changed

10 files changed

+2
-78
lines changed

src/backend/commands/tablespace.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -792,8 +792,7 @@ destroy_tablespace_directories(Oid tablespaceoid, bool redo)
792792
/*
793793
* Try to remove the symlink. We must however deal with the possibility
794794
* that it's a directory instead of a symlink --- this could happen during
795-
* WAL replay (see TablespaceCreateDbspace), and it is also the case on
796-
* Windows where junction points lstat() as directories.
795+
* WAL replay (see TablespaceCreateDbspace).
797796
*
798797
* Note: in the redo case, we'll return true if this final step fails;
799798
* there's no point in retrying it. Also, ENOENT should provoke no more
@@ -823,7 +822,6 @@ destroy_tablespace_directories(Oid tablespaceoid, bool redo)
823822
linkloc)));
824823
}
825824
}
826-
#ifdef S_ISLNK
827825
else if (S_ISLNK(st.st_mode))
828826
{
829827
if (unlink(linkloc) < 0)
@@ -836,7 +834,6 @@ destroy_tablespace_directories(Oid tablespaceoid, bool redo)
836834
linkloc)));
837835
}
838836
}
839-
#endif
840837
else
841838
{
842839
/* Refuse to remove anything that's not a directory or symlink */
@@ -914,7 +911,6 @@ remove_tablespace_symlink(const char *linkloc)
914911
errmsg("could not remove directory \"%s\": %m",
915912
linkloc)));
916913
}
917-
#ifdef S_ISLNK
918914
else if (S_ISLNK(st.st_mode))
919915
{
920916
if (unlink(linkloc) < 0 && errno != ENOENT)
@@ -923,7 +919,6 @@ remove_tablespace_symlink(const char *linkloc)
923919
errmsg("could not remove symbolic link \"%s\": %m",
924920
linkloc)));
925921
}
926-
#endif
927922
else
928923
{
929924
/* Refuse to remove anything that's not a directory or symlink */

src/backend/replication/basebackup.c

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,13 +1322,7 @@ sendDir(bbsink *sink, const char *path, int basepathlen, bool sizeonly,
13221322
}
13231323

13241324
/* Allow symbolic links in pg_tblspc only */
1325-
if (strcmp(path, "./pg_tblspc") == 0 &&
1326-
#ifndef WIN32
1327-
S_ISLNK(statbuf.st_mode)
1328-
#else
1329-
pgwin32_is_junction(pathbuf)
1330-
#endif
1331-
)
1325+
if (strcmp(path, "./pg_tblspc") == 0 && S_ISLNK(statbuf.st_mode))
13321326
{
13331327
char linkpath[MAXPGPATH];
13341328
int rllen;
@@ -1798,11 +1792,7 @@ static void
17981792
convert_link_to_directory(const char *pathbuf, struct stat *statbuf)
17991793
{
18001794
/* If symlink, write it as a directory anyway */
1801-
#ifndef WIN32
18021795
if (S_ISLNK(statbuf->st_mode))
1803-
#else
1804-
if (pgwin32_is_junction(pathbuf))
1805-
#endif
18061796
statbuf->st_mode = S_IFDIR | pg_dir_create_mode;
18071797
}
18081798

src/backend/storage/file/fd.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3365,7 +3365,6 @@ SyncDataDirectory(void)
33653365
*/
33663366
xlog_is_symlink = false;
33673367

3368-
#ifndef WIN32
33693368
{
33703369
struct stat st;
33713370

@@ -3377,10 +3376,6 @@ SyncDataDirectory(void)
33773376
else if (S_ISLNK(st.st_mode))
33783377
xlog_is_symlink = true;
33793378
}
3380-
#else
3381-
if (pgwin32_is_junction("pg_wal"))
3382-
xlog_is_symlink = true;
3383-
#endif
33843379

33853380
#ifdef HAVE_SYNCFS
33863381
if (recovery_init_sync_method == RECOVERY_INIT_SYNC_METHOD_SYNCFS)

src/backend/utils/adt/misc.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -283,9 +283,7 @@ pg_tablespace_location(PG_FUNCTION_ARGS)
283283
char sourcepath[MAXPGPATH];
284284
char targetpath[MAXPGPATH];
285285
int rllen;
286-
#ifndef WIN32
287286
struct stat st;
288-
#endif
289287

290288
/*
291289
* It's useful to apply this function to pg_class.reltablespace, wherein
@@ -314,10 +312,6 @@ pg_tablespace_location(PG_FUNCTION_ARGS)
314312
* created with allow_in_place_tablespaces enabled. If a directory is
315313
* found, a relative path to the data directory is returned.
316314
*/
317-
#ifdef WIN32
318-
if (!pgwin32_is_junction(sourcepath))
319-
PG_RETURN_TEXT_P(cstring_to_text(sourcepath));
320-
#else
321315
if (lstat(sourcepath, &st) < 0)
322316
{
323317
ereport(ERROR,
@@ -328,7 +322,6 @@ pg_tablespace_location(PG_FUNCTION_ARGS)
328322

329323
if (!S_ISLNK(st.st_mode))
330324
PG_RETURN_TEXT_P(cstring_to_text(sourcepath));
331-
#endif
332325

333326
/*
334327
* In presence of a link or a junction point, return the path pointing to.

src/bin/pg_checksums/pg_checksums.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -384,11 +384,7 @@ scan_directory(const char *basedir, const char *subdir, bool sizeonly)
384384
if (!sizeonly)
385385
scan_file(fn, segmentno);
386386
}
387-
#ifndef WIN32
388387
else if (S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode))
389-
#else
390-
else if (S_ISDIR(st.st_mode) || pgwin32_is_junction(fn))
391-
#endif
392388
{
393389
/*
394390
* If going through the entries of pg_tblspc, we assume to operate

src/bin/pg_rewind/file_ops.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -431,11 +431,7 @@ recurse_dir(const char *datadir, const char *parentpath,
431431
/* recurse to handle subdirectories */
432432
recurse_dir(datadir, path, callback);
433433
}
434-
#ifndef WIN32
435434
else if (S_ISLNK(fst.st_mode))
436-
#else
437-
else if (pgwin32_is_junction(fullpath))
438-
#endif
439435
{
440436
char link_target[MAXPGPATH];
441437
int len;

src/common/file_utils.c

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ fsync_pgdata(const char *pg_data,
7979
*/
8080
xlog_is_symlink = false;
8181

82-
#ifndef WIN32
8382
{
8483
struct stat st;
8584

@@ -88,10 +87,6 @@ fsync_pgdata(const char *pg_data,
8887
else if (S_ISLNK(st.st_mode))
8988
xlog_is_symlink = true;
9089
}
91-
#else
92-
if (pgwin32_is_junction(pg_wal))
93-
xlog_is_symlink = true;
94-
#endif
9590

9691
/*
9792
* If possible, hint to the kernel that we're soon going to fsync the data
@@ -459,27 +454,9 @@ get_dirent_type(const char *path,
459454
result = PGFILETYPE_REG;
460455
else if (S_ISDIR(fst.st_mode))
461456
result = PGFILETYPE_DIR;
462-
#ifdef S_ISLNK
463457
else if (S_ISLNK(fst.st_mode))
464458
result = PGFILETYPE_LNK;
465-
#endif
466459
}
467460

468-
#if defined(WIN32) && !defined(_MSC_VER)
469-
470-
/*
471-
* If we're on native Windows (not Cygwin, which has its own POSIX
472-
* symlinks), but not using the MSVC compiler, then we're using a
473-
* readdir() emulation provided by the MinGW runtime that has no d_type.
474-
* Since the lstat() fallback code reports junction points as directories,
475-
* we need an extra system call to check if we should report them as
476-
* symlinks instead, following our convention.
477-
*/
478-
if (result == PGFILETYPE_DIR &&
479-
!look_through_symlinks &&
480-
pgwin32_is_junction(path))
481-
result = PGFILETYPE_LNK;
482-
#endif
483-
484461
return result;
485462
}

src/include/port.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,6 @@ extern int pgunlink(const char *path);
284284
#if defined(WIN32) && !defined(__CYGWIN__)
285285
extern int pgsymlink(const char *oldpath, const char *newpath);
286286
extern int pgreadlink(const char *path, char *buf, size_t size);
287-
extern bool pgwin32_is_junction(const char *path);
288287

289288
#define symlink(oldpath, newpath) pgsymlink(oldpath, newpath)
290289
#define readlink(path, buf, size) pgreadlink(path, buf, size)

src/include/port/win32_port.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,6 @@ int setitimer(int which, const struct itimerval *value, struct itimerval *oval
230230
*/
231231
extern int pgsymlink(const char *oldpath, const char *newpath);
232232
extern int pgreadlink(const char *path, char *buf, size_t size);
233-
extern bool pgwin32_is_junction(const char *path);
234233

235234
#define symlink(oldpath, newpath) pgsymlink(oldpath, newpath)
236235
#define readlink(path, buf, size) pgreadlink(path, buf, size)

src/port/dirmod.c

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -362,20 +362,4 @@ pgreadlink(const char *path, char *buf, size_t size)
362362
return r;
363363
}
364364

365-
/*
366-
* Assumes the file exists, so will return false if it doesn't
367-
* (since a nonexistent file is not a junction)
368-
*/
369-
bool
370-
pgwin32_is_junction(const char *path)
371-
{
372-
DWORD attr = GetFileAttributes(path);
373-
374-
if (attr == INVALID_FILE_ATTRIBUTES)
375-
{
376-
_dosmaperr(GetLastError());
377-
return false;
378-
}
379-
return ((attr & FILE_ATTRIBUTE_REPARSE_POINT) == FILE_ATTRIBUTE_REPARSE_POINT);
380-
}
381365
#endif /* defined(WIN32) && !defined(__CYGWIN__) */

0 commit comments

Comments
 (0)