diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c index 5df2eb8..ac6760d 100644 --- a/src/bin/pg_basebackup/pg_basebackup.c +++ b/src/bin/pg_basebackup/pg_basebackup.c @@ -1119,13 +1119,31 @@ update_tablespace_symlink(Oid oid, const char *old_dir) if (strcmp(old_dir, new_dir) != 0) { + struct stat st; char *linkloc = psprintf("%s/pg_tblspc/%d", basedir, oid); - if (unlink(linkloc) != 0 && errno != ENOENT) + /* + * On Windows, junction points act like directories so we must be able to + * apply rmdir; in general it seems best to make this code work like the + * symlink removal code in destroy_tablespace_directories. + */ + if (lstat(linkloc, &st) == 0 && S_ISDIR(st.st_mode)) { - fprintf(stderr, _("%s: could not remove symbolic link \"%s\": %s"), - progname, linkloc, strerror(errno)); - disconnect_and_exit(1); + if (rmdir(linkloc) < 0) + { + fprintf(stderr, _("%s: could not remove directory \"%s\": %s"), + progname, linkloc, strerror(errno)); + disconnect_and_exit(1); + } + } + else + { + if (unlink(linkloc) < 0 && errno != ENOENT) + { + fprintf(stderr, _("%s: could not remove symbolic link \"%s\": %s"), + progname, linkloc, strerror(errno)); + disconnect_and_exit(1); + } } if (symlink(new_dir, linkloc) != 0) {