From 3555606af3a6505ddfd9038a40f01348f4b94164 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Wed, 27 Jul 2022 17:44:14 +1200
Subject: [PATCH v3 05/13] Remove configure probes for symlink/readlink, and
 dead code.

symlink() and readlink() are in SUSv2 and all targeted Unix systems have
them.  We have partial emulation on Windows.  Code that raised runtime
errors on systems without it has been dead for years, so we can remove
that and also references to such systems in the documentation.

Define vestigial HAVE_READLINK and HAVE_SYMLINK macros on Unix.  Our
Windows replacement functions based on junction points can't be used for
relative paths or for non-directories, so the macros can be used to
check for full symlink support.  The places that deal with tablespaces
can just use symlink functions without checking the macros.  (If they
did check the macros, they'd need to provide an #else branch with a
runtime or compile time error, and it'd be dead code.)

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CA+hUKGJ3LHeP9w5Fgzdr4G8AnEtJ=z=p6hGDEm4qYGEUX5B6fQ@mail.gmail.com
---
 configure                               |  5 +----
 configure.ac                            |  4 ----
 doc/src/sgml/ref/create_tablespace.sgml |  4 ----
 src/backend/access/transam/xlog.c       | 12 ------------
 src/backend/commands/tablespace.c       | 13 -------------
 src/backend/replication/basebackup.c    | 13 -------------
 src/backend/utils/adt/misc.c            |  8 --------
 src/bin/initdb/initdb.c                 |  4 ----
 src/bin/pg_basebackup/pg_basebackup.c   |  4 ----
 src/bin/pg_rewind/file_ops.c            |  5 -----
 src/common/exec.c                       |  4 ++++
 src/include/pg_config.h.in              |  6 ------
 src/include/port.h                      |  8 ++++++++
 src/tools/msvc/Solution.pm              |  2 --
 14 files changed, 13 insertions(+), 79 deletions(-)

diff --git a/configure b/configure
index 232f19a0cd..1f852078e7 100755
--- a/configure
+++ b/configure
@@ -16039,7 +16039,7 @@ fi
 LIBS_including_readline="$LIBS"
 LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'`
 
-for ac_func in backtrace_symbols clock_gettime copyfile fdatasync getifaddrs getpeerucred inet_pton kqueue mbstowcs_l memset_s poll posix_fallocate ppoll pthread_is_threaded_np readlink readv setproctitle setproctitle_fast strchrnul strsignal symlink syncfs sync_file_range uselocale wcstombs_l writev
+for ac_func in backtrace_symbols clock_gettime copyfile fdatasync getifaddrs getpeerucred inet_pton kqueue mbstowcs_l memset_s poll posix_fallocate ppoll pthread_is_threaded_np readv setproctitle setproctitle_fast strchrnul strsignal syncfs sync_file_range uselocale wcstombs_l writev
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -17083,9 +17083,6 @@ esac
  ;;
 esac
 
-
-$as_echo "#define HAVE_SYMLINK 1" >>confdefs.h
-
   ac_fn_c_check_type "$LINENO" "MINIDUMP_TYPE" "ac_cv_type_MINIDUMP_TYPE" "
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
diff --git a/configure.ac b/configure.ac
index 33dffe0ce5..ca0c65fbd9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1805,13 +1805,11 @@ AC_CHECK_FUNCS(m4_normalize([
 	posix_fallocate
 	ppoll
 	pthread_is_threaded_np
-	readlink
 	readv
 	setproctitle
 	setproctitle_fast
 	strchrnul
 	strsignal
-	symlink
 	syncfs
 	sync_file_range
 	uselocale
@@ -1963,8 +1961,6 @@ if test "$PORTNAME" = "win32"; then
   AC_LIBOBJ(win32security)
   AC_LIBOBJ(win32setlocale)
   AC_LIBOBJ(win32stat)
-  AC_DEFINE([HAVE_SYMLINK], 1,
-            [Define to 1 if you have the `symlink' function.])
   AC_CHECK_TYPES(MINIDUMP_TYPE, [pgac_minidump_type=yes], [pgac_minidump_type=no], [
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
diff --git a/doc/src/sgml/ref/create_tablespace.sgml b/doc/src/sgml/ref/create_tablespace.sgml
index 84fa7ee5e2..9d5ab02526 100644
--- a/doc/src/sgml/ref/create_tablespace.sgml
+++ b/doc/src/sgml/ref/create_tablespace.sgml
@@ -127,10 +127,6 @@ CREATE TABLESPACE <replaceable class="parameter">tablespace_name</replaceable>
  <refsect1>
   <title>Notes</title>
 
-  <para>
-   Tablespaces are only supported on systems that support symbolic links.
-  </para>
-
    <para>
     <command>CREATE TABLESPACE</command> cannot be executed inside a transaction
     block.
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 15ab8d90d4..26fbed00a4 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -8305,7 +8305,6 @@ do_pg_backup_start(const char *backupidstr, bool fast, TimeLineID *starttli_p,
 			if (get_dirent_type(fullpath, de, false, ERROR) != PGFILETYPE_LNK)
 				continue;
 
-#if defined(HAVE_READLINK) || defined(WIN32)
 			rllen = readlink(fullpath, linkpath, sizeof(linkpath));
 			if (rllen < 0)
 			{
@@ -8358,17 +8357,6 @@ do_pg_backup_start(const char *backupidstr, bool fast, TimeLineID *starttli_p,
 							 ti->oid, escapedpath.data);
 
 			pfree(escapedpath.data);
-#else
-
-			/*
-			 * If the platform does not have symbolic links, it should not be
-			 * possible to have tablespaces - clearly somebody else created
-			 * them. Warn about it and ignore.
-			 */
-			ereport(WARNING,
-					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-					 errmsg("tablespaces are not supported on this platform")));
-#endif
 		}
 		FreeDir(tblspcdir);
 
diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c
index 570ce3dbd5..526e82e388 100644
--- a/src/backend/commands/tablespace.c
+++ b/src/backend/commands/tablespace.c
@@ -213,7 +213,6 @@ TablespaceCreateDbspace(Oid spcOid, Oid dbOid, bool isRedo)
 Oid
 CreateTableSpace(CreateTableSpaceStmt *stmt)
 {
-#ifdef HAVE_SYMLINK
 	Relation	rel;
 	Datum		values[Natts_pg_tablespace];
 	bool		nulls[Natts_pg_tablespace] = {0};
@@ -391,12 +390,6 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
 	table_close(rel, NoLock);
 
 	return tablespaceoid;
-#else							/* !HAVE_SYMLINK */
-	ereport(ERROR,
-			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-			 errmsg("tablespaces are not supported on this platform")));
-	return InvalidOid;			/* keep compiler quiet */
-#endif							/* HAVE_SYMLINK */
 }
 
 /*
@@ -407,7 +400,6 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
 void
 DropTableSpace(DropTableSpaceStmt *stmt)
 {
-#ifdef HAVE_SYMLINK
 	char	   *tablespacename = stmt->tablespacename;
 	TableScanDesc scandesc;
 	Relation	rel;
@@ -573,11 +565,6 @@ DropTableSpace(DropTableSpaceStmt *stmt)
 
 	/* We keep the lock on pg_tablespace until commit */
 	table_close(rel, NoLock);
-#else							/* !HAVE_SYMLINK */
-	ereport(ERROR,
-			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-			 errmsg("tablespaces are not supported on this platform")));
-#endif							/* HAVE_SYMLINK */
 }
 
 
diff --git a/src/backend/replication/basebackup.c b/src/backend/replication/basebackup.c
index 7f85071229..09f071300d 100644
--- a/src/backend/replication/basebackup.c
+++ b/src/backend/replication/basebackup.c
@@ -1330,7 +1330,6 @@ sendDir(bbsink *sink, const char *path, int basepathlen, bool sizeonly,
 #endif
 			)
 		{
-#if defined(HAVE_READLINK) || defined(WIN32)
 			char		linkpath[MAXPGPATH];
 			int			rllen;
 
@@ -1349,18 +1348,6 @@ sendDir(bbsink *sink, const char *path, int basepathlen, bool sizeonly,
 
 			size += _tarWriteHeader(sink, pathbuf + basepathlen + 1, linkpath,
 									&statbuf, sizeonly);
-#else
-
-			/*
-			 * If the platform does not have symbolic links, it should not be
-			 * possible to have tablespaces - clearly somebody else created
-			 * them. Warn about it and ignore.
-			 */
-			ereport(WARNING,
-					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-					 errmsg("tablespaces are not supported on this platform")));
-			continue;
-#endif							/* HAVE_READLINK */
 		}
 		else if (S_ISDIR(statbuf.st_mode))
 		{
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
index 89690be2ed..af0d924459 100644
--- a/src/backend/utils/adt/misc.c
+++ b/src/backend/utils/adt/misc.c
@@ -302,8 +302,6 @@ pg_tablespace_location(PG_FUNCTION_ARGS)
 		tablespaceOid == GLOBALTABLESPACE_OID)
 		PG_RETURN_TEXT_P(cstring_to_text(""));
 
-#if defined(HAVE_READLINK) || defined(WIN32)
-
 	/*
 	 * Find the location of the tablespace by reading the symbolic link that
 	 * is in pg_tblspc/<oid>.
@@ -349,12 +347,6 @@ pg_tablespace_location(PG_FUNCTION_ARGS)
 	targetpath[rllen] = '\0';
 
 	PG_RETURN_TEXT_P(cstring_to_text(targetpath));
-#else
-	ereport(ERROR,
-			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-			 errmsg("tablespaces are not supported on this platform")));
-	PG_RETURN_NULL();
-#endif
 }
 
 /*
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 89b888eaa5..2c93ffe811 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -2646,13 +2646,9 @@ create_xlog_or_symlink(void)
 				pg_fatal("could not access directory \"%s\": %m", xlog_dir);
 		}
 
-#ifdef HAVE_SYMLINK
 		if (symlink(xlog_dir, subdirloc) != 0)
 			pg_fatal("could not create symbolic link \"%s\": %m",
 					 subdirloc);
-#else
-		pg_fatal("symlinks are not supported on this platform");
-#endif
 	}
 	else
 	{
diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c
index 1a877ba54e..8694b05e68 100644
--- a/src/bin/pg_basebackup/pg_basebackup.c
+++ b/src/bin/pg_basebackup/pg_basebackup.c
@@ -2763,12 +2763,8 @@ main(int argc, char **argv)
 						   PQserverVersion(conn) < MINIMUM_VERSION_FOR_PG_WAL ?
 						   "pg_xlog" : "pg_wal");
 
-#ifdef HAVE_SYMLINK
 		if (symlink(xlog_dir, linkloc) != 0)
 			pg_fatal("could not create symbolic link \"%s\": %m", linkloc);
-#else
-		pg_fatal("symlinks are not supported on this platform");
-#endif
 		free(linkloc);
 	}
 
diff --git a/src/bin/pg_rewind/file_ops.c b/src/bin/pg_rewind/file_ops.c
index 6cb288f099..5e6d8b89c4 100644
--- a/src/bin/pg_rewind/file_ops.c
+++ b/src/bin/pg_rewind/file_ops.c
@@ -437,7 +437,6 @@ recurse_dir(const char *datadir, const char *parentpath,
 		else if (pgwin32_is_junction(fullpath))
 #endif
 		{
-#if defined(HAVE_READLINK) || defined(WIN32)
 			char		link_target[MAXPGPATH];
 			int			len;
 
@@ -460,10 +459,6 @@ recurse_dir(const char *datadir, const char *parentpath,
 			if ((parentpath && strcmp(parentpath, "pg_tblspc") == 0) ||
 				strcmp(path, "pg_wal") == 0)
 				recurse_dir(datadir, path, callback);
-#else
-			pg_fatal("\"%s\" is a symbolic link, but symbolic links are not supported on this platform",
-					 fullpath);
-#endif							/* HAVE_READLINK */
 		}
 	}
 
diff --git a/src/common/exec.c b/src/common/exec.c
index f7d44b0956..c00fe5fba5 100644
--- a/src/common/exec.c
+++ b/src/common/exec.c
@@ -250,6 +250,10 @@ find_my_exec(const char *argv0, char *retpath)
  * Note: we are not particularly tense about producing nice error messages
  * because we are not really expecting error here; we just determined that
  * the symlink does point to a valid executable.
+ *
+ * Here we test HAVE_READLINK, which excludes Windows.  There's no point in
+ * using our junction point-based replacement code for this, which works only
+ * on directories.
  */
 static int
 resolve_symlinks(char *path)
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 120eacfb20..15e01efa06 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -427,9 +427,6 @@
 /* Define to 1 if you have the <readline/readline.h> header file. */
 #undef HAVE_READLINE_READLINE_H
 
-/* Define to 1 if you have the `readlink' function. */
-#undef HAVE_READLINK
-
 /* Define to 1 if you have the `readv' function. */
 #undef HAVE_READV
 
@@ -556,9 +553,6 @@
 /* Define to 1 if `tm_zone' is a member of `struct tm'. */
 #undef HAVE_STRUCT_TM_TM_ZONE
 
-/* Define to 1 if you have the `symlink' function. */
-#undef HAVE_SYMLINK
-
 /* Define to 1 if you have the `syncfs' function. */
 #undef HAVE_SYNCFS
 
diff --git a/src/include/port.h b/src/include/port.h
index 7a1a02f659..daab10ead4 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -522,11 +522,19 @@ extern bool wait_result_is_any_signal(int exit_status, bool include_command_not_
 /*
  * Interfaces that we assume all Unix system have.  We retain individual macros
  * for better documentation.
+ *
+ * For symlink-related functions, there is no need to test these macros,
+ * because we provided basic support on Windows that can work with absolute
+ * paths to directories.  Code that wants to test for complete symlink support
+ * (including relative paths and non-directories) should be conditional on
+ * HAVE_READLINE or HAVE_SYMLINK.
  */
 #ifndef WIN32
 #define HAVE_GETRLIMIT 1
+#define HAVE_READLINK 1
 #define HAVE_SETSID 1
 #define HAVE_SHM_OPEN 1
+#define HAVE_SYMLINK 1
 #endif
 
 #endif							/* PG_PORT_H */
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index a9680dc863..71db5f60f8 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -337,7 +337,6 @@ sub GenerateFiles
 		HAVE_READLINE_H             => undef,
 		HAVE_READLINE_HISTORY_H     => undef,
 		HAVE_READLINE_READLINE_H    => undef,
-		HAVE_READLINK               => undef,
 		HAVE_READV                  => undef,
 		HAVE_RL_COMPLETION_MATCHES  => undef,
 		HAVE_RL_COMPLETION_SUPPRESS_QUOTE        => undef,
@@ -380,7 +379,6 @@ sub GenerateFiles
 		HAVE_STRUCT_SOCKADDR_UN                  => undef,
 		HAVE_STRUCT_TM_TM_ZONE                   => undef,
 		HAVE_SYNC_FILE_RANGE                     => undef,
-		HAVE_SYMLINK                             => 1,
 		HAVE_SYNCFS                              => undef,
 		HAVE_SYSLOG                              => undef,
 		HAVE_SYS_EPOLL_H                         => undef,
-- 
2.37.1

