Cleaning up historical portability baggage

Started by Thomas Munroover 3 years ago108 messages
#1Thomas Munro
thomas.munro@gmail.com
6 attachment(s)

Hello,

I wonder how much dead code for ancient operating systems we could now
drop. Here are some easier cases, I think, and one tricky one that
might take some debate. I think it makes a lot of sense to say that
we expect at least POSIX-1:2001, because that corresponds to C99, with
the thread option because every targeted system has that.

0001-Remove-dead-pg_pread-and-pg_pwrite-replacement-code.patch
0002-Remove-dead-getrusage-replacement-code.patch
0003-Remove-dead-setenv-unsetenv-replacement-code.patch
0004-Remove-dead-handling-for-pre-POSIX-sigwait.patch
0005-Remove-dead-getpwuid_r-replacement-code.patch
0006-Remove-disable-thread-safety.patch

Clearly there is more stuff like this (eg more _r functions, they're
just a touch more complicated), but this is a start. I mention these
now in case it's helpful for the Meson work, and just generally
because I wanted to clean up after the retirement of ancient HP-UX.
The threads patch probably needs more polish and is extracted from
another series I'll propose in a later CF to do some more constructive
work on threads where it'd be helpful not to have to deal with 'no
threads' builds, but I figured it could also pitch this part along
with the other basic POSIX modernisation stuff.

I pulled the configure output from the oldest releases of each
supported target OS, namely:

* hornet, AIX 7.1
* wrasse, Solaris 11.3
* pollock, illumos rolling
* loach, FreeBSD 12.2
* conchuela, DragonflyBSD 6.0
* morepork, OpenBSD 6.9
* sidewinder, NetBSD 9.2
* prairiedog, macOS 10.4 (vintage system most likely to cause problems)
* clam, Linux 3.10/RHEL 7
* fairiewren, Windows/Mingw with configure

I checked for HAVE_PREAD HAVE_PWRITE HAVE_GETRUSAGE HAVE_SETENV
HAVE_UNSETENV HAVE_GETPWUID_R, and the only missing ones were:

HAVE_PREAD is missing on windows
HAVE_PWRITE is missing on windows
HAVE_GETRUSAGE is missing on windows
HAVE_GETPWUID_R is missing on windows

We either have completely separate code paths or replacement functions
for these.

The pwritev/preadv functions are unfortunately not standardised by
POSIX (I dunno why, it's the obvious combination of the p* and *v
functions) despite every OS in the list having them except for Solaris
and old macOS. Oh well.

Attachments:

0001-Remove-dead-pg_pread-and-pg_pwrite-replacement-code.patchtext/x-patch; charset=US-ASCII; name=0001-Remove-dead-pg_pread-and-pg_pwrite-replacement-code.patchDownload
From 9d543f0cf5806625e5d823c18cf8a4d390ec7263 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 9 Jul 2022 21:31:56 +1200
Subject: [PATCH 1/6] Remove dead pg_pread and pg_pwrite replacement code.

pread and pwrite were standardised in POSIX-1:2001.

Previously, we defined pg_pread and pg_pwrite to emulate these function
with lseek() on old Unixen.  The names with a pg_ prefix were a reminder
of a portability hazard: they might change the current file position.

Since the replacement code for Windows doesn't suffer from the position
problem, we might as well start using the POSIX names directly.
---
 .../pg_stat_statements/pg_stat_statements.c   |  4 +-
 src/backend/access/heap/rewriteheap.c         |  2 +-
 src/backend/access/transam/slru.c             |  4 +-
 src/backend/access/transam/xlog.c             |  4 +-
 src/backend/access/transam/xlogreader.c       |  2 +-
 src/backend/access/transam/xlogrecovery.c     |  2 +-
 src/backend/replication/basebackup.c          |  2 +-
 src/backend/replication/walreceiver.c         |  2 +-
 src/backend/storage/file/fd.c                 |  4 +-
 src/backend/utils/init/miscinit.c             |  2 +-
 src/bin/pg_test_fsync/pg_test_fsync.c         | 50 +++++++++----------
 src/include/access/xlogreader.h               |  4 +-
 src/include/port.h                            | 17 +++----
 src/port/pread.c                              | 18 +------
 src/port/preadv.c                             |  4 +-
 src/port/pwrite.c                             | 18 +------
 src/port/pwritev.c                            |  4 +-
 17 files changed, 55 insertions(+), 88 deletions(-)

diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c
index 4acfddcdb8..e8a7666ed9 100644
--- a/contrib/pg_stat_statements/pg_stat_statements.c
+++ b/contrib/pg_stat_statements/pg_stat_statements.c
@@ -2096,9 +2096,9 @@ qtext_store(const char *query, int query_len,
 	if (fd < 0)
 		goto error;
 
-	if (pg_pwrite(fd, query, query_len, off) != query_len)
+	if (pwrite(fd, query, query_len, off) != query_len)
 		goto error;
-	if (pg_pwrite(fd, "\0", 1, off + query_len) != 1)
+	if (pwrite(fd, "\0", 1, off + query_len) != 1)
 		goto error;
 
 	CloseTransientFile(fd);
diff --git a/src/backend/access/heap/rewriteheap.c b/src/backend/access/heap/rewriteheap.c
index 197f06b5ec..9dd885d936 100644
--- a/src/backend/access/heap/rewriteheap.c
+++ b/src/backend/access/heap/rewriteheap.c
@@ -1149,7 +1149,7 @@ heap_xlog_logical_rewrite(XLogReaderState *r)
 	/* write out tail end of mapping file (again) */
 	errno = 0;
 	pgstat_report_wait_start(WAIT_EVENT_LOGICAL_REWRITE_MAPPING_WRITE);
-	if (pg_pwrite(fd, data, len, xlrec->offset) != len)
+	if (pwrite(fd, data, len, xlrec->offset) != len)
 	{
 		/* if write didn't set errno, assume problem is no disk space */
 		if (errno == 0)
diff --git a/src/backend/access/transam/slru.c b/src/backend/access/transam/slru.c
index b65cb49d7f..c9a7b97949 100644
--- a/src/backend/access/transam/slru.c
+++ b/src/backend/access/transam/slru.c
@@ -718,7 +718,7 @@ SlruPhysicalReadPage(SlruCtl ctl, int pageno, int slotno)
 
 	errno = 0;
 	pgstat_report_wait_start(WAIT_EVENT_SLRU_READ);
-	if (pg_pread(fd, shared->page_buffer[slotno], BLCKSZ, offset) != BLCKSZ)
+	if (pread(fd, shared->page_buffer[slotno], BLCKSZ, offset) != BLCKSZ)
 	{
 		pgstat_report_wait_end();
 		slru_errcause = SLRU_READ_FAILED;
@@ -873,7 +873,7 @@ SlruPhysicalWritePage(SlruCtl ctl, int pageno, int slotno, SlruWriteAll fdata)
 
 	errno = 0;
 	pgstat_report_wait_start(WAIT_EVENT_SLRU_WRITE);
-	if (pg_pwrite(fd, shared->page_buffer[slotno], BLCKSZ, offset) != BLCKSZ)
+	if (pwrite(fd, shared->page_buffer[slotno], BLCKSZ, offset) != BLCKSZ)
 	{
 		pgstat_report_wait_end();
 		/* if write didn't set errno, assume problem is no disk space */
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index b809a2152c..80fe2ca5ab 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -2189,7 +2189,7 @@ XLogWrite(XLogwrtRqst WriteRqst, TimeLineID tli, bool flexible)
 					INSTR_TIME_SET_CURRENT(start);
 
 				pgstat_report_wait_start(WAIT_EVENT_WAL_WRITE);
-				written = pg_pwrite(openLogFile, from, nleft, startoffset);
+				written = pwrite(openLogFile, from, nleft, startoffset);
 				pgstat_report_wait_end();
 
 				/*
@@ -3011,7 +3011,7 @@ XLogFileInitInternal(XLogSegNo logsegno, TimeLineID logtli,
 		 * enough.
 		 */
 		errno = 0;
-		if (pg_pwrite(fd, zbuffer.data, 1, wal_segment_size - 1) != 1)
+		if (pwrite(fd, zbuffer.data, 1, wal_segment_size - 1) != 1)
 		{
 			/* if write didn't set errno, assume no disk space */
 			save_errno = errno ? errno : ENOSPC;
diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c
index f3dc4b7797..06e91547dd 100644
--- a/src/backend/access/transam/xlogreader.c
+++ b/src/backend/access/transam/xlogreader.c
@@ -1514,7 +1514,7 @@ WALRead(XLogReaderState *state,
 
 		/* Reset errno first; eases reporting non-errno-affecting errors */
 		errno = 0;
-		readbytes = pg_pread(state->seg.ws_file, p, segbytes, (off_t) startoff);
+		readbytes = pread(state->seg.ws_file, p, segbytes, (off_t) startoff);
 
 #ifndef FRONTEND
 		pgstat_report_wait_end();
diff --git a/src/backend/access/transam/xlogrecovery.c b/src/backend/access/transam/xlogrecovery.c
index 5d6f1b5e46..e25e055c77 100644
--- a/src/backend/access/transam/xlogrecovery.c
+++ b/src/backend/access/transam/xlogrecovery.c
@@ -3210,7 +3210,7 @@ retry:
 	readOff = targetPageOff;
 
 	pgstat_report_wait_start(WAIT_EVENT_WAL_READ);
-	r = pg_pread(readFile, readBuf, XLOG_BLCKSZ, (off_t) readOff);
+	r = pread(readFile, readBuf, XLOG_BLCKSZ, (off_t) readOff);
 	if (r != XLOG_BLCKSZ)
 	{
 		char		fname[MAXFNAMELEN];
diff --git a/src/backend/replication/basebackup.c b/src/backend/replication/basebackup.c
index 95440013c0..c02b583976 100644
--- a/src/backend/replication/basebackup.c
+++ b/src/backend/replication/basebackup.c
@@ -1827,7 +1827,7 @@ basebackup_read_file(int fd, char *buf, size_t nbytes, off_t offset,
 	int			rc;
 
 	pgstat_report_wait_start(WAIT_EVENT_BASEBACKUP_READ);
-	rc = pg_pread(fd, buf, nbytes, offset);
+	rc = pread(fd, buf, nbytes, offset);
 	pgstat_report_wait_end();
 
 	if (rc < 0)
diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c
index 3d37c1fe62..8604fd4bc2 100644
--- a/src/backend/replication/walreceiver.c
+++ b/src/backend/replication/walreceiver.c
@@ -915,7 +915,7 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr, TimeLineID tli)
 		/* OK to write the logs */
 		errno = 0;
 
-		byteswritten = pg_pwrite(recvFile, buf, segbytes, (off_t) startoff);
+		byteswritten = pwrite(recvFile, buf, segbytes, (off_t) startoff);
 		if (byteswritten <= 0)
 		{
 			char		xlogfname[MAXFNAMELEN];
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index f904f60c08..07bd41aaa8 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -2067,7 +2067,7 @@ FileRead(File file, char *buffer, int amount, off_t offset,
 
 retry:
 	pgstat_report_wait_start(wait_event_info);
-	returnCode = pg_pread(vfdP->fd, buffer, amount, offset);
+	returnCode = pread(vfdP->fd, buffer, amount, offset);
 	pgstat_report_wait_end();
 
 	if (returnCode < 0)
@@ -2149,7 +2149,7 @@ FileWrite(File file, char *buffer, int amount, off_t offset,
 retry:
 	errno = 0;
 	pgstat_report_wait_start(wait_event_info);
-	returnCode = pg_pwrite(VfdCache[file].fd, buffer, amount, offset);
+	returnCode = pwrite(VfdCache[file].fd, buffer, amount, offset);
 	pgstat_report_wait_end();
 
 	/* if write didn't set errno, assume problem is no disk space */
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index eb43b2c5e5..bd973ba613 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -1429,7 +1429,7 @@ AddToDataDirLockFile(int target_line, const char *str)
 	len = strlen(destbuffer);
 	errno = 0;
 	pgstat_report_wait_start(WAIT_EVENT_LOCK_FILE_ADDTODATADIR_WRITE);
-	if (pg_pwrite(fd, destbuffer, len, 0) != len)
+	if (pwrite(fd, destbuffer, len, 0) != len)
 	{
 		pgstat_report_wait_end();
 		/* if write didn't set errno, assume problem is no disk space */
diff --git a/src/bin/pg_test_fsync/pg_test_fsync.c b/src/bin/pg_test_fsync/pg_test_fsync.c
index f7bc199a30..be8effe16b 100644
--- a/src/bin/pg_test_fsync/pg_test_fsync.c
+++ b/src/bin/pg_test_fsync/pg_test_fsync.c
@@ -312,10 +312,10 @@ test_sync(int writes_per_op)
 		for (ops = 0; alarm_triggered == false; ops++)
 		{
 			for (writes = 0; writes < writes_per_op; writes++)
-				if (pg_pwrite(tmpfile,
-							  buf,
-							  XLOG_BLCKSZ,
-							  writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
+				if (pwrite(tmpfile,
+						   buf,
+						   XLOG_BLCKSZ,
+						   writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
 					die("write failed");
 		}
 		STOP_TIMER;
@@ -338,10 +338,10 @@ test_sync(int writes_per_op)
 	for (ops = 0; alarm_triggered == false; ops++)
 	{
 		for (writes = 0; writes < writes_per_op; writes++)
-			if (pg_pwrite(tmpfile,
-						  buf,
-						  XLOG_BLCKSZ,
-						  writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
+			if (pwrite(tmpfile,
+					   buf,
+					   XLOG_BLCKSZ,
+					   writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
 				die("write failed");
 		fdatasync(tmpfile);
 	}
@@ -363,10 +363,10 @@ test_sync(int writes_per_op)
 	for (ops = 0; alarm_triggered == false; ops++)
 	{
 		for (writes = 0; writes < writes_per_op; writes++)
-			if (pg_pwrite(tmpfile,
-						  buf,
-						  XLOG_BLCKSZ,
-						  writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
+			if (pwrite(tmpfile,
+					   buf,
+					   XLOG_BLCKSZ,
+					   writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
 				die("write failed");
 		if (fsync(tmpfile) != 0)
 			die("fsync failed");
@@ -387,10 +387,10 @@ test_sync(int writes_per_op)
 	for (ops = 0; alarm_triggered == false; ops++)
 	{
 		for (writes = 0; writes < writes_per_op; writes++)
-			if (pg_pwrite(tmpfile,
-						  buf,
-						  XLOG_BLCKSZ,
-						  writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
+			if (pwrite(tmpfile,
+					   buf,
+					   XLOG_BLCKSZ,
+					   writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
 				die("write failed");
 		if (pg_fsync_writethrough(tmpfile) != 0)
 			die("fsync failed");
@@ -419,10 +419,10 @@ test_sync(int writes_per_op)
 		for (ops = 0; alarm_triggered == false; ops++)
 		{
 			for (writes = 0; writes < writes_per_op; writes++)
-				if (pg_pwrite(tmpfile,
-							  buf,
-							  XLOG_BLCKSZ,
-							  writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
+				if (pwrite(tmpfile,
+						   buf,
+						   XLOG_BLCKSZ,
+						   writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
 
 					/*
 					 * This can generate write failures if the filesystem has
@@ -484,10 +484,10 @@ test_open_sync(const char *msg, int writes_size)
 		for (ops = 0; alarm_triggered == false; ops++)
 		{
 			for (writes = 0; writes < 16 / writes_size; writes++)
-				if (pg_pwrite(tmpfile,
-							  buf,
-							  writes_size * 1024,
-							  writes * writes_size * 1024) !=
+				if (pwrite(tmpfile,
+						   buf,
+						   writes_size * 1024,
+						   writes * writes_size * 1024) !=
 					writes_size * 1024)
 					die("write failed");
 		}
@@ -586,7 +586,7 @@ test_non_sync(void)
 	START_TIMER;
 	for (ops = 0; alarm_triggered == false; ops++)
 	{
-		if (pg_pwrite(tmpfile, buf, XLOG_BLCKSZ, 0) != XLOG_BLCKSZ)
+		if (pwrite(tmpfile, buf, XLOG_BLCKSZ, 0) != XLOG_BLCKSZ)
 			die("write failed");
 	}
 	STOP_TIMER;
diff --git a/src/include/access/xlogreader.h b/src/include/access/xlogreader.h
index 5395f155aa..87ff00feb7 100644
--- a/src/include/access/xlogreader.h
+++ b/src/include/access/xlogreader.h
@@ -375,11 +375,11 @@ extern bool XLogReaderValidatePageHeader(XLogReaderState *state,
 
 /*
  * Error information from WALRead that both backend and frontend caller can
- * process.  Currently only errors from pg_pread can be reported.
+ * process.  Currently only errors from pread can be reported.
  */
 typedef struct WALReadError
 {
-	int			wre_errno;		/* errno set by the last pg_pread() */
+	int			wre_errno;		/* errno set by the last pread() */
 	int			wre_off;		/* Offset we tried to read from. */
 	int			wre_req;		/* Bytes requested to be read. */
 	int			wre_read;		/* Bytes read by the last read(). */
diff --git a/src/include/port.h b/src/include/port.h
index 12c05b5d9f..68101f7b16 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -421,20 +421,15 @@ extern int	inet_aton(const char *cp, struct in_addr *addr);
 #endif
 
 /*
- * Windows and older Unix don't have pread(2) and pwrite(2).  We have
- * replacement functions, but they have slightly different semantics so we'll
- * use a name with a pg_ prefix to avoid confusion.
+ * Windows doesn't have pread(2) and pwrite(2).  We have replacement functions
+ * in src/port/pread.c and src/port/pwrite.c.
  */
-#ifdef HAVE_PREAD
-#define pg_pread pread
-#else
-extern ssize_t pg_pread(int fd, void *buf, size_t nbyte, off_t offset);
+#ifndef HAVE_PREAD
+extern ssize_t pread(int fd, void *buf, size_t nbyte, off_t offset);
 #endif
 
-#ifdef HAVE_PWRITE
-#define pg_pwrite pwrite
-#else
-extern ssize_t pg_pwrite(int fd, const void *buf, size_t nbyte, off_t offset);
+#ifndef HAVE_PWRITE
+extern ssize_t pwrite(int fd, const void *buf, size_t nbyte, off_t offset);
 #endif
 
 /* For pg_pwritev() and pg_preadv(), see port/pg_iovec.h. */
diff --git a/src/port/pread.c b/src/port/pread.c
index 491605926f..bc522d60cd 100644
--- a/src/port/pread.c
+++ b/src/port/pread.c
@@ -1,32 +1,24 @@
 /*-------------------------------------------------------------------------
  *
  * pread.c
- *	  Implementation of pread(2) for platforms that lack one.
+ *	  Implementation of pread(2) for Windows.
  *
  * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
  *	  src/port/pread.c
  *
- * Note that this implementation changes the current file position, unlike
- * the POSIX function, so we use the name pg_pread().
- *
  *-------------------------------------------------------------------------
  */
 
 
 #include "postgres.h"
 
-#ifdef WIN32
 #include <windows.h>
-#else
-#include <unistd.h>
-#endif
 
 ssize_t
-pg_pread(int fd, void *buf, size_t size, off_t offset)
+pread(int fd, void *buf, size_t size, off_t offset)
 {
-#ifdef WIN32
 	OVERLAPPED	overlapped = {0};
 	HANDLE		handle;
 	DWORD		result;
@@ -49,10 +41,4 @@ pg_pread(int fd, void *buf, size_t size, off_t offset)
 	}
 
 	return result;
-#else
-	if (lseek(fd, offset, SEEK_SET) < 0)
-		return -1;
-
-	return read(fd, buf, size);
-#endif
 }
diff --git a/src/port/preadv.c b/src/port/preadv.c
index d12e5a122b..aa7537503f 100644
--- a/src/port/preadv.c
+++ b/src/port/preadv.c
@@ -30,7 +30,7 @@ pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 {
 #ifdef HAVE_READV
 	if (iovcnt == 1)
-		return pg_pread(fd, iov[0].iov_base, iov[0].iov_len, offset);
+		return pread(fd, iov[0].iov_base, iov[0].iov_len, offset);
 	if (lseek(fd, offset, SEEK_SET) < 0)
 		return -1;
 	return readv(fd, iov, iovcnt);
@@ -40,7 +40,7 @@ pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 
 	for (int i = 0; i < iovcnt; ++i)
 	{
-		part = pg_pread(fd, iov[i].iov_base, iov[i].iov_len, offset);
+		part = pread(fd, iov[i].iov_base, iov[i].iov_len, offset);
 		if (part < 0)
 		{
 			if (i == 0)
diff --git a/src/port/pwrite.c b/src/port/pwrite.c
index eeaffacc48..a8f3f69344 100644
--- a/src/port/pwrite.c
+++ b/src/port/pwrite.c
@@ -1,32 +1,24 @@
 /*-------------------------------------------------------------------------
  *
  * pwrite.c
- *	  Implementation of pwrite(2) for platforms that lack one.
+ *	  Implementation of pwrite(2) for Windows.
  *
  * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
  *	  src/port/pwrite.c
  *
- * Note that this implementation changes the current file position, unlike
- * the POSIX function, so we use the name pg_pwrite().
- *
  *-------------------------------------------------------------------------
  */
 
 
 #include "postgres.h"
 
-#ifdef WIN32
 #include <windows.h>
-#else
-#include <unistd.h>
-#endif
 
 ssize_t
-pg_pwrite(int fd, const void *buf, size_t size, off_t offset)
+pwrite(int fd, const void *buf, size_t size, off_t offset)
 {
-#ifdef WIN32
 	OVERLAPPED	overlapped = {0};
 	HANDLE		handle;
 	DWORD		result;
@@ -46,10 +38,4 @@ pg_pwrite(int fd, const void *buf, size_t size, off_t offset)
 	}
 
 	return result;
-#else
-	if (lseek(fd, offset, SEEK_SET) < 0)
-		return -1;
-
-	return write(fd, buf, size);
-#endif
 }
diff --git a/src/port/pwritev.c b/src/port/pwritev.c
index 0bdd69fffc..cb7421381e 100644
--- a/src/port/pwritev.c
+++ b/src/port/pwritev.c
@@ -30,7 +30,7 @@ pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 {
 #ifdef HAVE_WRITEV
 	if (iovcnt == 1)
-		return pg_pwrite(fd, iov[0].iov_base, iov[0].iov_len, offset);
+		return pwrite(fd, iov[0].iov_base, iov[0].iov_len, offset);
 	if (lseek(fd, offset, SEEK_SET) < 0)
 		return -1;
 	return writev(fd, iov, iovcnt);
@@ -40,7 +40,7 @@ pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 
 	for (int i = 0; i < iovcnt; ++i)
 	{
-		part = pg_pwrite(fd, iov[i].iov_base, iov[i].iov_len, offset);
+		part = pwrite(fd, iov[i].iov_base, iov[i].iov_len, offset);
 		if (part < 0)
 		{
 			if (i == 0)
-- 
2.36.1

0002-Remove-dead-getrusage-replacement-code.patchtext/x-patch; charset=US-ASCII; name=0002-Remove-dead-getrusage-replacement-code.patchDownload
From 80b57167c9149aeb60922530b79f7bd40d7130a1 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 9 Jul 2022 22:01:26 +1200
Subject: [PATCH 2/6] Remove dead getrusage replacement code.

getrusage is in POSIX-1:2001.  Note that POSIX only covers ru_utime and
ru_stime and we rely on many more fields unconditionally, but that
doesn't seem to cause a problem on any current system.  If a system were
to appear that has minimal POSIX getrusage, we'd be better off doing a
configure test for the extended fields rather than carrying the ancient
replacement code.

The only supported system we need a replacement for now is Windows.
---
 src/include/rusagestub.h |  3 ---
 src/port/getrusage.c     | 46 ++--------------------------------------
 2 files changed, 2 insertions(+), 47 deletions(-)

diff --git a/src/include/rusagestub.h b/src/include/rusagestub.h
index b887effa3e..be26f849a5 100644
--- a/src/include/rusagestub.h
+++ b/src/include/rusagestub.h
@@ -15,9 +15,6 @@
 #define RUSAGESTUB_H
 
 #include <sys/time.h>			/* for struct timeval */
-#ifndef WIN32
-#include <sys/times.h>			/* for struct tms */
-#endif
 #include <limits.h>				/* for CLK_TCK */
 
 #define RUSAGE_SELF		0
diff --git a/src/port/getrusage.c b/src/port/getrusage.c
index 02665f4032..41b3373953 100644
--- a/src/port/getrusage.c
+++ b/src/port/getrusage.c
@@ -17,11 +17,8 @@
 
 #include "rusagestub.h"
 
-/* This code works on:
- *		solaris_i386
- *		solaris_sparc
- *		win32
- * which currently is all the supported platforms that don't have a
+/*
+ * This code works on Windows, which is the only supported platform without a
  * native version of getrusage().  So, if configure decides to compile
  * this file at all, we just use this version unconditionally.
  */
@@ -29,7 +26,6 @@
 int
 getrusage(int who, struct rusage *rusage)
 {
-#ifdef WIN32
 	FILETIME	starttime;
 	FILETIME	exittime;
 	FILETIME	kerneltime;
@@ -66,44 +62,6 @@ getrusage(int who, struct rusage *rusage)
 	li.QuadPart /= 10L;			/* Convert to microseconds */
 	rusage->ru_utime.tv_sec = li.QuadPart / 1000000L;
 	rusage->ru_utime.tv_usec = li.QuadPart % 1000000L;
-#else							/* all but WIN32 */
-
-	struct tms	tms;
-	int			tick_rate = CLK_TCK;	/* ticks per second */
-	clock_t		u,
-				s;
-
-	if (rusage == (struct rusage *) NULL)
-	{
-		errno = EFAULT;
-		return -1;
-	}
-	if (times(&tms) < 0)
-	{
-		/* errno set by times */
-		return -1;
-	}
-	switch (who)
-	{
-		case RUSAGE_SELF:
-			u = tms.tms_utime;
-			s = tms.tms_stime;
-			break;
-		case RUSAGE_CHILDREN:
-			u = tms.tms_cutime;
-			s = tms.tms_cstime;
-			break;
-		default:
-			errno = EINVAL;
-			return -1;
-	}
-#define TICK_TO_SEC(T, RATE)	((T)/(RATE))
-#define TICK_TO_USEC(T,RATE)	(((T)%(RATE)*1000000)/RATE)
-	rusage->ru_utime.tv_sec = TICK_TO_SEC(u, tick_rate);
-	rusage->ru_utime.tv_usec = TICK_TO_USEC(u, tick_rate);
-	rusage->ru_stime.tv_sec = TICK_TO_SEC(s, tick_rate);
-	rusage->ru_stime.tv_usec = TICK_TO_USEC(u, tick_rate);
-#endif							/* WIN32 */
 
 	return 0;
 }
-- 
2.36.1

0003-Remove-dead-setenv-unsetenv-replacement-code.patchtext/x-patch; charset=US-ASCII; name=0003-Remove-dead-setenv-unsetenv-replacement-code.patchDownload
From a6fd1ddb7d92b2e37cba33022f07981954c6364e Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 9 Jul 2022 23:00:49 +1200
Subject: [PATCH 3/6] Remove dead setenv, unsetenv replacement code.

setenv and unsetenv are in POSIX-1:2001.  We still need special code for
these on Windows, but we don't need replacement code on any supported
Unix.
---
 configure                  | 43 -------------------------
 configure.ac               | 13 --------
 src/include/pg_config.h.in |  6 ----
 src/include/port.h         |  8 -----
 src/port/setenv.c          | 48 ----------------------------
 src/port/unsetenv.c        | 65 --------------------------------------
 src/tools/msvc/Solution.pm |  2 --
 7 files changed, 185 deletions(-)
 delete mode 100644 src/port/setenv.c
 delete mode 100644 src/port/unsetenv.c

diff --git a/configure b/configure
index a90be03821..e4cbd562ce 100755
--- a/configure
+++ b/configure
@@ -16824,49 +16824,6 @@ esac
 $as_echo "$as_me: On $host_os we will use our strtof wrapper." >&6;}
 fi
 
-case $host_os in
-        # Windows uses a specialised env handler
-        mingw*)
-
-$as_echo "#define HAVE_SETENV 1" >>confdefs.h
-
-
-$as_echo "#define HAVE_UNSETENV 1" >>confdefs.h
-
-                ac_cv_func_setenv=yes
-                ac_cv_func_unsetenv=yes
-                ;;
-        *)
-                ac_fn_c_check_func "$LINENO" "setenv" "ac_cv_func_setenv"
-if test "x$ac_cv_func_setenv" = xyes; then :
-  $as_echo "#define HAVE_SETENV 1" >>confdefs.h
-
-else
-  case " $LIBOBJS " in
-  *" setenv.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS setenv.$ac_objext"
- ;;
-esac
-
-fi
-
-ac_fn_c_check_func "$LINENO" "unsetenv" "ac_cv_func_unsetenv"
-if test "x$ac_cv_func_unsetenv" = xyes; then :
-  $as_echo "#define HAVE_UNSETENV 1" >>confdefs.h
-
-else
-  case " $LIBOBJS " in
-  *" unsetenv.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS unsetenv.$ac_objext"
- ;;
-esac
-
-fi
-
-
-                ;;
-esac
-
 # System's version of getaddrinfo(), if any, may be used only if we found
 # a definition for struct addrinfo; see notes in src/include/getaddrinfo.h.
 # We use only our own getaddrinfo.c on Windows, but it's time to revisit that.
diff --git a/configure.ac b/configure.ac
index 7fbfb6795f..1cb5994822 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1928,19 +1928,6 @@ if test "$PORTNAME" = "win32" -o "$PORTNAME" = "cygwin"; then
 	AC_MSG_NOTICE([On $host_os we will use our strtof wrapper.])
 fi
 
-case $host_os in
-        # Windows uses a specialised env handler
-        mingw*)
-                AC_DEFINE(HAVE_SETENV, 1, [Define to 1 because replacement version used.])
-                AC_DEFINE(HAVE_UNSETENV, 1, [Define to 1 because replacement version used.])
-                ac_cv_func_setenv=yes
-                ac_cv_func_unsetenv=yes
-                ;;
-        *)
-                AC_REPLACE_FUNCS([setenv unsetenv])
-                ;;
-esac
-
 # System's version of getaddrinfo(), if any, may be used only if we found
 # a definition for struct addrinfo; see notes in src/include/getaddrinfo.h.
 # We use only our own getaddrinfo.c on Windows, but it's time to revisit that.
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 7133c3dc66..6268da407a 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -490,9 +490,6 @@
 /* Define to 1 if you have the <security/pam_appl.h> header file. */
 #undef HAVE_SECURITY_PAM_APPL_H
 
-/* Define to 1 if you have the `setenv' function. */
-#undef HAVE_SETENV
-
 /* Define to 1 if you have the `setproctitle' function. */
 #undef HAVE_SETPROCTITLE
 
@@ -679,9 +676,6 @@
 /* Define to 1 if you have the <unistd.h> header file. */
 #undef HAVE_UNISTD_H
 
-/* Define to 1 if you have the `unsetenv' function. */
-#undef HAVE_UNSETENV
-
 /* Define to 1 if you have the `uselocale' function. */
 #undef HAVE_USELOCALE
 
diff --git a/src/include/port.h b/src/include/port.h
index 68101f7b16..2dfdd8674e 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -446,14 +446,6 @@ extern size_t strlcpy(char *dst, const char *src, size_t siz);
 extern size_t strnlen(const char *str, size_t maxlen);
 #endif
 
-#ifndef HAVE_SETENV
-extern int	setenv(const char *name, const char *value, int overwrite);
-#endif
-
-#ifndef HAVE_UNSETENV
-extern int	unsetenv(const char *name);
-#endif
-
 #ifndef HAVE_DLOPEN
 extern void *dlopen(const char *file, int mode);
 extern void *dlsym(void *handle, const char *symbol);
diff --git a/src/port/setenv.c b/src/port/setenv.c
deleted file mode 100644
index d13c882467..0000000000
--- a/src/port/setenv.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * setenv.c
- *	  setenv() emulation for machines without it
- *
- * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- *
- * IDENTIFICATION
- *	  src/port/setenv.c
- *
- *-------------------------------------------------------------------------
- */
-
-#include "c.h"
-
-
-int
-setenv(const char *name, const char *value, int overwrite)
-{
-	char	   *envstr;
-
-	/* Error conditions, per POSIX */
-	if (name == NULL || name[0] == '\0' || strchr(name, '=') != NULL ||
-		value == NULL)
-	{
-		errno = EINVAL;
-		return -1;
-	}
-
-	/* No work if variable exists and we're not to replace it */
-	if (overwrite == 0 && getenv(name) != NULL)
-		return 0;
-
-	/*
-	 * Add or replace the value using putenv().  This will leak memory if the
-	 * same variable is repeatedly redefined, but there's little we can do
-	 * about that when sitting atop putenv().
-	 */
-	envstr = (char *) malloc(strlen(name) + strlen(value) + 2);
-	if (!envstr)				/* not much we can do if no memory */
-		return -1;
-
-	sprintf(envstr, "%s=%s", name, value);
-
-	return putenv(envstr);
-}
diff --git a/src/port/unsetenv.c b/src/port/unsetenv.c
deleted file mode 100644
index 62b806d796..0000000000
--- a/src/port/unsetenv.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * unsetenv.c
- *	  unsetenv() emulation for machines without it
- *
- * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- *
- * IDENTIFICATION
- *	  src/port/unsetenv.c
- *
- *-------------------------------------------------------------------------
- */
-
-#include "c.h"
-
-
-int
-unsetenv(const char *name)
-{
-	char	   *envstr;
-
-	/* Error conditions, per POSIX */
-	if (name == NULL || name[0] == '\0' || strchr(name, '=') != NULL)
-	{
-		errno = EINVAL;
-		return -1;
-	}
-
-	if (getenv(name) == NULL)
-		return 0;				/* no work */
-
-	/*
-	 * The technique embodied here works if libc follows the Single Unix Spec
-	 * and actually uses the storage passed to putenv() to hold the environ
-	 * entry.  When we clobber the entry in the second step we are ensuring
-	 * that we zap the actual environ member.  However, there are some libc
-	 * implementations (notably recent BSDs) that do not obey SUS but copy the
-	 * presented string.  This method fails on such platforms.  Hopefully all
-	 * such platforms have unsetenv() and thus won't be using this hack. See:
-	 * http://www.greenend.org.uk/rjk/2008/putenv.html
-	 *
-	 * Note that repeatedly setting and unsetting a var using this code will
-	 * leak memory.
-	 */
-
-	envstr = (char *) malloc(strlen(name) + 2);
-	if (!envstr)				/* not much we can do if no memory */
-		return -1;
-
-	/* Override the existing setting by forcibly defining the var */
-	sprintf(envstr, "%s=", name);
-	if (putenv(envstr))
-		return -1;
-
-	/* Now we can clobber the variable definition this way: */
-	strcpy(envstr, "=");
-
-	/*
-	 * This last putenv cleans up if we have multiple zero-length names as a
-	 * result of unsetting multiple things.
-	 */
-	return putenv(envstr);
-}
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index b8b1728df7..17fe0d95ea 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -356,7 +356,6 @@ sub GenerateFiles
 		HAVE_RL_RESET_SCREEN_SIZE                => undef,
 		HAVE_RL_VARIABLE_BIND                    => undef,
 		HAVE_SECURITY_PAM_APPL_H                 => undef,
-		HAVE_SETENV                              => undef,
 		HAVE_SETPROCTITLE                        => undef,
 		HAVE_SETPROCTITLE_FAST                   => undef,
 		HAVE_SETSID                              => undef,
@@ -419,7 +418,6 @@ sub GenerateFiles
 		HAVE_UINT8                               => undef,
 		HAVE_UNION_SEMUN                         => undef,
 		HAVE_UNISTD_H                            => 1,
-		HAVE_UNSETENV                            => undef,
 		HAVE_USELOCALE                           => undef,
 		HAVE_UUID_BSD                            => undef,
 		HAVE_UUID_E2FS                           => undef,
-- 
2.36.1

0004-Remove-dead-handling-for-pre-POSIX-sigwait.patchtext/x-patch; charset=US-ASCII; name=0004-Remove-dead-handling-for-pre-POSIX-sigwait.patchDownload
From f57341a5ce5a2a53e6c78e0df423d943f00d7561 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 9 Jul 2022 23:26:45 +1200
Subject: [PATCH 4/6] Remove dead handling for pre-POSIX sigwait().

sigwait is in POSIX-1:1996.  It's now safe to assume that every
supported system has a conforming sigwait().  (sigwaitinfo() is another
story...).
---
 configure                  | 64 ++------------------------------------
 configure.ac               | 27 ----------------
 src/bin/psql/command.c     | 10 +++---
 src/bin/psql/startup.c     |  4 +--
 src/include/pg_config.h.in |  7 -----
 src/tools/msvc/Solution.pm |  2 --
 6 files changed, 10 insertions(+), 104 deletions(-)

diff --git a/configure b/configure
index e4cbd562ce..79d644d751 100755
--- a/configure
+++ b/configure
@@ -16242,11 +16242,9 @@ $as_echo "#define HAVE_FSEEKO 1" >>confdefs.h
 fi
 
 
-# Make sure there's a declaration for sigwait(), then make sure
-# that it conforms to the POSIX standard (there seem to still be
-# some platforms out there with pre-POSIX sigwait()).  On Solaris,
-# _POSIX_PTHREAD_SEMANTICS affects the result, but we already
-# added that to CPPFLAGS.
+# posix_fadvise() is a no-op on Solaris, so don't incur function overhead
+# by calling it, 2009-04-02
+# http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libc/port/gen/posix_fadvise.c
 # The Clang compiler raises a warning for an undeclared identifier that matches
 # a compiler builtin function.  All extant Clang versions are affected, as of
 # Clang 3.6.0.  Test a builtin known to every version.  This problem affects the
@@ -16335,62 +16333,6 @@ case $ac_cv_c_decl_report in
   *) ac_c_decl_warn_flag= ;;
 esac
 
-ac_fn_c_check_decl "$LINENO" "sigwait" "ac_cv_have_decl_sigwait" "#include <signal.h>
-"
-if test "x$ac_cv_have_decl_sigwait" = xyes; then :
-  ac_have_decl=1
-else
-  ac_have_decl=0
-fi
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL_SIGWAIT $ac_have_decl
-_ACEOF
-
-if test "x$ac_cv_have_decl_sigwait" = xyes; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for POSIX-conforming sigwait declaration" >&5
-$as_echo_n "checking for POSIX-conforming sigwait declaration... " >&6; }
-if ${pgac_cv_have_posix_decl_sigwait+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-      #include <signal.h>
-      int sigwait(const sigset_t *set, int *sig);
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  pgac_cv_have_posix_decl_sigwait=yes
-else
-  pgac_cv_have_posix_decl_sigwait=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_have_posix_decl_sigwait" >&5
-$as_echo "$pgac_cv_have_posix_decl_sigwait" >&6; }
-fi
-if test "x$pgac_cv_have_posix_decl_sigwait" = xyes; then
-
-$as_echo "#define HAVE_POSIX_DECL_SIGWAIT 1" >>confdefs.h
-
-else
-  # On non-Windows, libpq requires POSIX sigwait() for thread safety.
-  if test "$enable_thread_safety" = yes -a "$PORTNAME" != "win32"; then
-    as_fn_error $? "POSIX-conforming sigwait is required to enable thread safety." "$LINENO" 5
-  fi
-fi
-
-# posix_fadvise() is a no-op on Solaris, so don't incur function overhead
-# by calling it, 2009-04-02
-# http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libc/port/gen/posix_fadvise.c
 if test "$PORTNAME" != "solaris"; then :
 
 for ac_func in posix_fadvise
diff --git a/configure.ac b/configure.ac
index 1cb5994822..59d108121d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1827,33 +1827,6 @@ PGAC_CHECK_BUILTIN_FUNC_PTR([__builtin_frame_address], [0])
 # in case it finds that _LARGEFILE_SOURCE has to be #define'd for that.
 AC_FUNC_FSEEKO
 
-# Make sure there's a declaration for sigwait(), then make sure
-# that it conforms to the POSIX standard (there seem to still be
-# some platforms out there with pre-POSIX sigwait()).  On Solaris,
-# _POSIX_PTHREAD_SEMANTICS affects the result, but we already
-# added that to CPPFLAGS.
-AC_CHECK_DECLS(sigwait, [], [], [#include <signal.h>])
-if test "x$ac_cv_have_decl_sigwait" = xyes; then
-  AC_CACHE_CHECK([for POSIX-conforming sigwait declaration],
-    [pgac_cv_have_posix_decl_sigwait],
-    [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
-      #include <signal.h>
-      int sigwait(const sigset_t *set, int *sig);
-      ],
-      [])],
-      [pgac_cv_have_posix_decl_sigwait=yes],
-      [pgac_cv_have_posix_decl_sigwait=no])])
-fi
-if test "x$pgac_cv_have_posix_decl_sigwait" = xyes; then
-  AC_DEFINE(HAVE_POSIX_DECL_SIGWAIT, 1,
-            [Define to 1 if you have a POSIX-conforming sigwait declaration.])
-else
-  # On non-Windows, libpq requires POSIX sigwait() for thread safety.
-  if test "$enable_thread_safety" = yes -a "$PORTNAME" != "win32"; then
-    AC_MSG_ERROR([POSIX-conforming sigwait is required to enable thread safety.])
-  fi
-fi
-
 # posix_fadvise() is a no-op on Solaris, so don't incur function overhead
 # by calling it, 2009-04-02
 # http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libc/port/gen/posix_fadvise.c
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index c562c04afe..e38f165e4b 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -4953,7 +4953,7 @@ do_watch(PQExpBuffer query_buf, double sleep)
 	FILE	   *pagerpipe = NULL;
 	int			title_len;
 	int			res = 0;
-#ifdef HAVE_POSIX_DECL_SIGWAIT
+#ifndef WIN32
 	sigset_t	sigalrm_sigchld_sigint;
 	sigset_t	sigalrm_sigchld;
 	sigset_t	sigint;
@@ -4967,7 +4967,7 @@ do_watch(PQExpBuffer query_buf, double sleep)
 		return false;
 	}
 
-#ifdef HAVE_POSIX_DECL_SIGWAIT
+#ifndef WIN32
 	sigemptyset(&sigalrm_sigchld_sigint);
 	sigaddset(&sigalrm_sigchld_sigint, SIGCHLD);
 	sigaddset(&sigalrm_sigchld_sigint, SIGALRM);
@@ -5006,7 +5006,7 @@ do_watch(PQExpBuffer query_buf, double sleep)
 	 * PAGER environment variables, because traditional pagers probably won't
 	 * be very useful for showing a stream of results.
 	 */
-#ifdef HAVE_POSIX_DECL_SIGWAIT
+#ifndef WIN32
 	pagerprog = getenv("PSQL_WATCH_PAGER");
 #endif
 	if (pagerprog && myopt.topt.pager)
@@ -5077,7 +5077,7 @@ do_watch(PQExpBuffer query_buf, double sleep)
 		if (pagerpipe && ferror(pagerpipe))
 			break;
 
-#ifndef HAVE_POSIX_DECL_SIGWAIT
+#ifdef WIN32
 
 		/*
 		 * Set up cancellation of 'watch' via SIGINT.  We redo this each time
@@ -5146,7 +5146,7 @@ do_watch(PQExpBuffer query_buf, double sleep)
 		restore_sigpipe_trap();
 	}
 
-#ifdef HAVE_POSIX_DECL_SIGWAIT
+#ifndef WIN32
 	/* Disable the interval timer. */
 	memset(&interval, 0, sizeof(interval));
 	setitimer(ITIMER_REAL, &interval, NULL);
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
index 7c2f555f15..e2e5678e2d 100644
--- a/src/bin/psql/startup.c
+++ b/src/bin/psql/startup.c
@@ -110,7 +110,7 @@ log_locus_callback(const char **filename, uint64 *lineno)
 	}
 }
 
-#ifdef HAVE_POSIX_DECL_SIGWAIT
+#ifndef WIN32
 static void
 empty_signal_handler(SIGNAL_ARGS)
 {
@@ -308,7 +308,7 @@ main(int argc, char *argv[])
 
 	psql_setup_cancel_handler();
 
-#ifdef HAVE_POSIX_DECL_SIGWAIT
+#ifndef WIN32
 
 	/*
 	 * do_watch() needs signal handlers installed (otherwise sigwait() will
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 6268da407a..5b2a9db56d 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -149,10 +149,6 @@
    don't. */
 #undef HAVE_DECL_RTLD_NOW
 
-/* Define to 1 if you have the declaration of `sigwait', and to 0 if you
-   don't. */
-#undef HAVE_DECL_SIGWAIT
-
 /* Define to 1 if you have the declaration of `strlcat', and to 0 if you
    don't. */
 #undef HAVE_DECL_STRLCAT
@@ -412,9 +408,6 @@
 /* Define to 1 if you have the <poll.h> header file. */
 #undef HAVE_POLL_H
 
-/* Define to 1 if you have a POSIX-conforming sigwait declaration. */
-#undef HAVE_POSIX_DECL_SIGWAIT
-
 /* Define to 1 if you have the `posix_fadvise' function. */
 #undef HAVE_POSIX_FADVISE
 
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 17fe0d95ea..9ad22333ee 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -246,7 +246,6 @@ sub GenerateFiles
 		HAVE_DECL_PWRITEV                           => 0,
 		HAVE_DECL_RTLD_GLOBAL                       => 0,
 		HAVE_DECL_RTLD_NOW                          => 0,
-		HAVE_DECL_SIGWAIT                           => 0,
 		HAVE_DECL_STRLCAT                           => 0,
 		HAVE_DECL_STRLCPY                           => 0,
 		HAVE_DECL_STRNLEN                           => 1,
@@ -331,7 +330,6 @@ sub GenerateFiles
 		HAVE_PAM_PAM_APPL_H         => undef,
 		HAVE_POLL                   => undef,
 		HAVE_POLL_H                 => undef,
-		HAVE_POSIX_DECL_SIGWAIT     => undef,
 		HAVE_POSIX_FADVISE          => undef,
 		HAVE_POSIX_FALLOCATE        => undef,
 		HAVE_PPC_LWARX_MUTEX_HINT   => undef,
-- 
2.36.1

0005-Remove-dead-getpwuid_r-replacement-code.patchtext/x-patch; charset=US-ASCII; name=0005-Remove-dead-getpwuid_r-replacement-code.patchDownload
From 8c1c344b298278ada2e4b70ac01218a6227e1616 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sun, 10 Jul 2022 11:31:58 +1200
Subject: [PATCH 5/6] Remove dead getpwuid_r replacement code.

getpwuid_r is from POSIX-1:1996 and is present in all our supported Unix
systems.
---
 configure                  |  2 +-
 configure.ac               |  2 +-
 src/include/pg_config.h.in |  3 --
 src/port/thread.c          | 58 +++-----------------------------------
 src/tools/msvc/Solution.pm |  1 -
 5 files changed, 6 insertions(+), 60 deletions(-)

diff --git a/configure b/configure
index 79d644d751..5d9150fad2 100755
--- a/configure
+++ b/configure
@@ -11599,7 +11599,7 @@ fi
 
 
 
-for ac_func in strerror_r getpwuid_r gethostbyname_r
+for ac_func in strerror_r gethostbyname_r
 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"
diff --git a/configure.ac b/configure.ac
index 59d108121d..6b7ac306a2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1201,7 +1201,7 @@ LIBS="$LIBS $PTHREAD_LIBS"
 AC_CHECK_HEADER(pthread.h, [], [AC_MSG_ERROR([
 pthread.h not found;  use --disable-thread-safety to disable thread safety])])
 
-AC_CHECK_FUNCS([strerror_r getpwuid_r gethostbyname_r])
+AC_CHECK_FUNCS([strerror_r gethostbyname_r])
 
 # Do test here with the proper thread flags
 PGAC_FUNC_STRERROR_R_INT
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 5b2a9db56d..716baf2e91 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -243,9 +243,6 @@
 /* Define to 1 if you have the `getpeerucred' function. */
 #undef HAVE_GETPEERUCRED
 
-/* Define to 1 if you have the `getpwuid_r' function. */
-#undef HAVE_GETPWUID_R
-
 /* Define to 1 if you have the `getrlimit' function. */
 #undef HAVE_GETRLIMIT
 
diff --git a/src/port/thread.c b/src/port/thread.c
index 23c3fbdf86..492e5a3b72 100644
--- a/src/port/thread.c
+++ b/src/port/thread.c
@@ -18,62 +18,12 @@
 
 
 /*
- *	Threading sometimes requires specially-named versions of functions
- *	that return data in static buffers, like strerror_r() instead of
- *	strerror().  Other operating systems use pthread_setspecific()
- *	and pthread_getspecific() internally to allow standard library
- *	functions to return static data to threaded applications. And some
- *	operating systems have neither.
- *
- *	Additional confusion exists because many operating systems that
- *	use pthread_setspecific/pthread_getspecific() also have *_r versions
- *	of standard library functions for compatibility with operating systems
- *	that require them.  However, internally, these *_r functions merely
- *	call the thread-safe standard library functions.
- *
- *	For example, BSD/OS 4.3 uses Bind 8.2.3 for getpwuid().  Internally,
- *	getpwuid() calls pthread_setspecific/pthread_getspecific() to return
- *	static data to the caller in a thread-safe manner.  However, BSD/OS
- *	also has getpwuid_r(), which merely calls getpwuid() and shifts
- *	around the arguments to match the getpwuid_r() function declaration.
- *	Therefore, while BSD/OS has getpwuid_r(), it isn't required.  It also
- *	doesn't have strerror_r(), so we can't fall back to only using *_r
- *	functions for threaded programs.
- *
- *	The current setup is to try threading in this order:
- *
- *		use *_r function names if they exit
- *			(*_THREADSAFE=yes)
- *		use non-*_r functions if they are thread-safe
+ *  Historically, the code in this module had to deal with operating systems
+ *  that lacked getpwuid_r().
  */
 
 #ifndef WIN32
 
-/*
- * Wrapper around getpwuid() or getpwuid_r() to mimic POSIX getpwuid_r()
- * behaviour, if that function is not available or required.
- *
- * Per POSIX, the possible cases are:
- * success: returns zero, *result is non-NULL
- * uid not found: returns zero, *result is NULL
- * error during lookup: returns an errno code, *result is NULL
- * (caller should *not* assume that the errno variable is set)
- */
-static int
-pqGetpwuid(uid_t uid, struct passwd *resultbuf, char *buffer,
-		   size_t buflen, struct passwd **result)
-{
-#if defined(FRONTEND) && defined(ENABLE_THREAD_SAFETY) && defined(HAVE_GETPWUID_R)
-	return getpwuid_r(uid, resultbuf, buffer, buflen, result);
-#else
-	/* no getpwuid_r() available, just use getpwuid() */
-	errno = 0;
-	*result = getpwuid(uid);
-	/* paranoia: ensure we return zero on success */
-	return (*result == NULL) ? errno : 0;
-#endif
-}
-
 /*
  * pg_get_user_name - get the name of the user with the given ID
  *
@@ -89,7 +39,7 @@ pg_get_user_name(uid_t user_id, char *buffer, size_t buflen)
 	struct passwd *pw = NULL;
 	int			pwerr;
 
-	pwerr = pqGetpwuid(user_id, &pwdstr, pwdbuf, sizeof(pwdbuf), &pw);
+	pwerr = getpwuid_r(user_id, &pwdstr, pwdbuf, sizeof(pwdbuf), &pw);
 	if (pw != NULL)
 	{
 		strlcpy(buffer, pw->pw_name, buflen);
@@ -125,7 +75,7 @@ pg_get_user_home_dir(uid_t user_id, char *buffer, size_t buflen)
 	struct passwd *pw = NULL;
 	int			pwerr;
 
-	pwerr = pqGetpwuid(user_id, &pwdstr, pwdbuf, sizeof(pwdbuf), &pw);
+	pwerr = getpwuid_r(user_id, &pwdstr, pwdbuf, sizeof(pwdbuf), &pw);
 	if (pw != NULL)
 	{
 		strlcpy(buffer, pw->pw_dir, buflen);
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 9ad22333ee..1e83583e76 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -275,7 +275,6 @@ sub GenerateFiles
 		HAVE_GETOPT_LONG                            => undef,
 		HAVE_GETPEEREID                             => undef,
 		HAVE_GETPEERUCRED                           => undef,
-		HAVE_GETPWUID_R                             => undef,
 		HAVE_GETRLIMIT                              => undef,
 		HAVE_GETRUSAGE                              => undef,
 		HAVE_GETTIMEOFDAY                           => undef,
-- 
2.36.1

0006-Remove-disable-thread-safety.patchtext/x-patch; charset=US-ASCII; name=0006-Remove-disable-thread-safety.patchDownload
From afe047827118a51996bd97dabdb29a57c5b93ff7 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Fri, 26 Mar 2021 22:58:06 +1300
Subject: [PATCH 6/6] Remove --disable-thread-safety.

All supported operating systems either have the POSIX threads option, or
Windows native threads.  We no longer test --disable-thread-safety
builds, and it is unlikely that anyone makes use of that build option.
Future work to improve our use of threads will be simplified by not
having to cope with a no-threads build option.
---
 configure                                     | 56 ++-------------
 configure.ac                                  | 28 ++------
 doc/src/sgml/installation.sgml                | 13 ----
 doc/src/sgml/libpq.sgml                       |  3 +-
 src/Makefile.global.in                        |  1 -
 src/bin/pgbench/pgbench.c                     | 22 +-----
 src/include/pg_config.h.in                    |  4 --
 src/interfaces/ecpg/ecpglib/connect.c         | 40 -----------
 src/interfaces/ecpg/ecpglib/descriptor.c      |  9 ---
 src/interfaces/ecpg/ecpglib/ecpglib_extern.h  |  2 -
 src/interfaces/ecpg/ecpglib/execute.c         |  2 -
 src/interfaces/ecpg/ecpglib/memory.c          |  7 --
 src/interfaces/ecpg/ecpglib/misc.c            | 47 ------------
 .../ecpg/include/ecpg-pthread-win32.h         |  3 -
 src/interfaces/ecpg/include/ecpg_config.h.in  |  4 --
 src/interfaces/ecpg/include/ecpglib.h         |  2 -
 .../ecpg/test/expected/thread-alloc.c         | 43 +++++------
 .../ecpg/test/expected/thread-alloc_2.stdout  |  1 -
 .../ecpg/test/expected/thread-descriptor.c    | 22 +++---
 .../ecpg/test/expected/thread-prep.c          | 71 ++++++++-----------
 .../ecpg/test/expected/thread-prep.stdout     |  1 -
 .../ecpg/test/expected/thread-prep_2.stdout   |  0
 .../ecpg/test/expected/thread-thread.c        | 63 +++++++---------
 .../ecpg/test/expected/thread-thread.stdout   |  2 +-
 .../ecpg/test/expected/thread-thread_2.stdout |  1 -
 .../test/expected/thread-thread_implicit.c    | 63 +++++++---------
 .../expected/thread-thread_implicit.stdout    |  2 +-
 .../expected/thread-thread_implicit_2.stdout  |  1 -
 src/interfaces/ecpg/test/thread/alloc.pgc     |  9 ---
 .../ecpg/test/thread/descriptor.pgc           |  8 +--
 src/interfaces/ecpg/test/thread/prep.pgc      |  9 ---
 src/interfaces/ecpg/test/thread/thread.pgc    |  9 ---
 .../ecpg/test/thread/thread_implicit.pgc      |  9 ---
 src/interfaces/libpq/Makefile                 |  2 -
 src/interfaces/libpq/fe-auth.c                |  9 ++-
 src/interfaces/libpq/fe-connect.c             |  4 --
 src/interfaces/libpq/fe-exec.c                |  4 --
 src/interfaces/libpq/fe-print.c               | 13 +---
 src/interfaces/libpq/fe-secure-openssl.c      | 17 +----
 src/interfaces/libpq/fe-secure.c              | 26 +------
 src/interfaces/libpq/legacy-pqsignal.c        |  4 --
 src/interfaces/libpq/libpq-int.h              |  9 +--
 src/port/getaddrinfo.c                        |  2 +-
 src/tools/msvc/Solution.pm                    |  3 +-
 src/tools/msvc/ecpg_regression.proj           |  2 +-
 45 files changed, 142 insertions(+), 510 deletions(-)
 delete mode 100644 src/interfaces/ecpg/test/expected/thread-alloc_2.stdout
 delete mode 100644 src/interfaces/ecpg/test/expected/thread-prep_2.stdout
 delete mode 100644 src/interfaces/ecpg/test/expected/thread-thread_2.stdout
 delete mode 100644 src/interfaces/ecpg/test/expected/thread-thread_implicit_2.stdout

diff --git a/configure b/configure
index 5d9150fad2..67bde08cf1 100755
--- a/configure
+++ b/configure
@@ -728,7 +728,6 @@ with_tcl
 ICU_LIBS
 ICU_CFLAGS
 with_icu
-enable_thread_safety
 INCLUDES
 autodepend
 PKG_CONFIG_LIBDIR
@@ -851,7 +850,6 @@ with_CC
 with_llvm
 enable_depend
 enable_cassert
-enable_thread_safety
 with_icu
 with_tcl
 with_tclconfig
@@ -1540,7 +1538,6 @@ Optional Features:
   --enable-tap-tests      enable TAP tests (requires Perl and IPC::Run)
   --enable-depend         turn on automatic dependency tracking
   --enable-cassert        enable assertion checks (for debugging)
-  --disable-thread-safety disable thread-safety in client libraries
   --disable-largefile     omit support for large files
 
 Optional Packages:
@@ -7820,43 +7817,6 @@ $as_echo "$as_me: WARNING: *** Library directory $dir does not exist." >&2;}
 done
 IFS=$ac_save_IFS
 
-#
-# Enable thread-safe client libraries
-#
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking allow thread-safe client libraries" >&5
-$as_echo_n "checking allow thread-safe client libraries... " >&6; }
-
-
-# Check whether --enable-thread-safety was given.
-if test "${enable_thread_safety+set}" = set; then :
-  enableval=$enable_thread_safety;
-  case $enableval in
-    yes)
-      :
-      ;;
-    no)
-      :
-      ;;
-    *)
-      as_fn_error $? "no argument expected for --enable-thread-safety option" "$LINENO" 5
-      ;;
-  esac
-
-else
-  enable_thread_safety=yes
-
-fi
-
-
-if test "$enable_thread_safety" = yes; then
-
-$as_echo "#define ENABLE_THREAD_SAFETY 1" >>confdefs.h
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_thread_safety" >&5
-$as_echo "$enable_thread_safety" >&6; }
-
-
 #
 # ICU
 #
@@ -10935,7 +10895,7 @@ fi
 done
 
 
-if test "$enable_thread_safety" = yes -a "$PORTNAME" != "win32"; then :
+if "$PORTNAME" != "win32"; then :
    # then
 
 
@@ -11594,7 +11554,7 @@ if test "x$ac_cv_header_pthread_h" = xyes; then :
 
 else
   as_fn_error $? "
-pthread.h not found;  use --disable-thread-safety to disable thread safety" "$LINENO" 5
+pthread.h not found" "$LINENO" 5
 fi
 
 
@@ -12335,8 +12295,7 @@ if test "$ac_res" != no; then :
 fi
 
 
-if test "$enable_thread_safety" = yes; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gethostbyname_r" >&5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gethostbyname_r" >&5
 $as_echo_n "checking for library containing gethostbyname_r... " >&6; }
 if ${ac_cv_search_gethostbyname_r+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -12392,7 +12351,7 @@ if test "$ac_res" != no; then :
 
 fi
 
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_barrier_wait" >&5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_barrier_wait" >&5
 $as_echo_n "checking for library containing pthread_barrier_wait... " >&6; }
 if ${ac_cv_search_pthread_barrier_wait+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -12448,7 +12407,6 @@ if test "$ac_res" != no; then :
 
 fi
 
-fi
 
 if test "$with_readline" = yes; then
 
@@ -13321,7 +13279,7 @@ else
   thread_safe_libldap=no
 fi
 
-    if test "$enable_thread_safety" = yes -a "$thread_safe_libldap" = no; then
+    if test "$thread_safe_libldap" = no; then
       # Use ldap_r for FE if available, else assume ldap is thread-safe.
       # On some platforms ldap_r fails to link without PTHREAD_LIBS.
       LIBS="$_LIBS"
@@ -16732,8 +16690,7 @@ fi
 
 
 
-if test "$enable_thread_safety" = yes; then
-  ac_fn_c_check_func "$LINENO" "pthread_barrier_wait" "ac_cv_func_pthread_barrier_wait"
+ac_fn_c_check_func "$LINENO" "pthread_barrier_wait" "ac_cv_func_pthread_barrier_wait"
 if test "x$ac_cv_func_pthread_barrier_wait" = xyes; then :
   $as_echo "#define HAVE_PTHREAD_BARRIER_WAIT 1" >>confdefs.h
 
@@ -16747,7 +16704,6 @@ esac
 fi
 
 
-fi
 
 if test "$PORTNAME" = "win32" -o "$PORTNAME" = "cygwin"; then
 	# Cygwin and (apparently, based on test results) Mingw both
diff --git a/configure.ac b/configure.ac
index 6b7ac306a2..bdf7d9e304 100644
--- a/configure.ac
+++ b/configure.ac
@@ -775,18 +775,6 @@ for dir in $LIBRARY_DIRS $SRCH_LIB; do
 done
 IFS=$ac_save_IFS
 
-#
-# Enable thread-safe client libraries
-#
-AC_MSG_CHECKING([allow thread-safe client libraries])
-PGAC_ARG_BOOL(enable, thread-safety, yes, [disable thread-safety in client libraries])
-if test "$enable_thread_safety" = yes; then
-  AC_DEFINE([ENABLE_THREAD_SAFETY], 1,
-          [Define to 1 to build client libraries as thread-safe code. (--enable-thread-safety)])
-fi
-AC_MSG_RESULT([$enable_thread_safety])
-AC_SUBST(enable_thread_safety)
-
 #
 # ICU
 #
@@ -1184,7 +1172,7 @@ dnl note: We have to use AS_IF here rather than plain if. The AC_CHECK_HEADER
 dnl invocation below is the first one in the script, and autoconf generates
 dnl additional code for that, which must not be inside the if-block. AS_IF
 dnl knows how to do that.
-AS_IF([test "$enable_thread_safety" = yes -a "$PORTNAME" != "win32"],
+AS_IF(["$PORTNAME" != "win32"],
 [ # then
 AX_PTHREAD	# set thread flags
 
@@ -1199,7 +1187,7 @@ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
 LIBS="$LIBS $PTHREAD_LIBS"
 
 AC_CHECK_HEADER(pthread.h, [], [AC_MSG_ERROR([
-pthread.h not found;  use --disable-thread-safety to disable thread safety])])
+pthread.h not found])])
 
 AC_CHECK_FUNCS([strerror_r gethostbyname_r])
 
@@ -1247,10 +1235,8 @@ AC_SEARCH_LIBS(shmget, cygipc)
 # *BSD:
 AC_SEARCH_LIBS(backtrace_symbols, execinfo)
 
-if test "$enable_thread_safety" = yes; then
-  AC_SEARCH_LIBS(gethostbyname_r, nsl)
-  AC_SEARCH_LIBS(pthread_barrier_wait, pthread)
-fi
+AC_SEARCH_LIBS(gethostbyname_r, nsl)
+AC_SEARCH_LIBS(pthread_barrier_wait, pthread)
 
 if test "$with_readline" = yes; then
   PGAC_CHECK_READLINE
@@ -1375,7 +1361,7 @@ if test "$with_ldap" = yes ; then
     AC_CHECK_FUNC([ldap_verify_credentials],
 		  [thread_safe_libldap=yes],
 		  [thread_safe_libldap=no])
-    if test "$enable_thread_safety" = yes -a "$thread_safe_libldap" = no; then
+    if test "$thread_safe_libldap" = no; then
       # Use ldap_r for FE if available, else assume ldap is thread-safe.
       # On some platforms ldap_r fails to link without PTHREAD_LIBS.
       LIBS="$_LIBS"
@@ -1886,9 +1872,7 @@ AC_REPLACE_FUNCS(m4_normalize([
 	strtof
 ]))
 
-if test "$enable_thread_safety" = yes; then
-  AC_REPLACE_FUNCS(pthread_barrier_wait)
-fi
+AC_REPLACE_FUNCS(pthread_barrier_wait)
 
 if test "$PORTNAME" = "win32" -o "$PORTNAME" = "cygwin"; then
 	# Cygwin and (apparently, based on test results) Mingw both
diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml
index 1a1343a008..8b4ca85c8a 100644
--- a/doc/src/sgml/installation.sgml
+++ b/doc/src/sgml/installation.sgml
@@ -1285,19 +1285,6 @@ build-postgresql:
        </listitem>
       </varlistentry>
 
-      <varlistentry>
-       <term><option>--disable-thread-safety</option></term>
-       <listitem>
-        <para>
-         Disable the thread-safety of client libraries.  This prevents
-         concurrent threads in <application>libpq</application> and
-         <application>ECPG</application> programs from safely controlling
-         their private connection handles.  Use this only on platforms
-         with deficient threading support.
-        </para>
-       </listitem>
-      </varlistentry>
-
      </variablelist>
 
    </sect3>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 74456aa69d..655b4db31e 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -8837,7 +8837,8 @@ int PQisthreadsafe();
 
      <para>
       Returns 1 if the <application>libpq</application> is thread-safe
-      and 0 if it is not.
+      and 0 if it is not.  Since <productname>PostgreSQL</productname> version
+      16, this function always returns 1.
      </para>
     </listitem>
    </varlistentry>
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index 138d66ac00..3d2e4ce90d 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -202,7 +202,6 @@ enable_debug	= @enable_debug@
 enable_dtrace	= @enable_dtrace@
 enable_coverage	= @enable_coverage@
 enable_tap_tests	= @enable_tap_tests@
-enable_thread_safety	= @enable_thread_safety@
 
 python_includespec	= @python_includespec@
 python_libdir		= @python_libdir@
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index bcaea8f5ea..dc1915fcfd 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -140,7 +140,7 @@ typedef struct socket_set
 	EnterSynchronizationBarrier((barrier), \
 								SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY)
 #define THREAD_BARRIER_DESTROY(barrier)
-#elif defined(ENABLE_THREAD_SAFETY)
+#else
 /* Use POSIX threads */
 #include "port/pg_pthread.h"
 #define THREAD_T pthread_t
@@ -156,16 +156,6 @@ typedef struct socket_set
 	pthread_barrier_init((barrier), NULL, (n))
 #define THREAD_BARRIER_WAIT(barrier) pthread_barrier_wait((barrier))
 #define THREAD_BARRIER_DESTROY(barrier) pthread_barrier_destroy((barrier))
-#else
-/* No threads implementation, use none (-j 1) */
-#define THREAD_T void *
-#define THREAD_FUNC_RETURN_TYPE void *
-#define THREAD_FUNC_RETURN return NULL
-#define THREAD_FUNC_CC
-#define THREAD_BARRIER_T int
-#define THREAD_BARRIER_INIT(barrier, n) (*(barrier) = 0)
-#define THREAD_BARRIER_WAIT(barrier)
-#define THREAD_BARRIER_DESTROY(barrier)
 #endif
 
 
@@ -6684,10 +6674,6 @@ main(int argc, char **argv)
 				{
 					exit(1);
 				}
-#ifndef ENABLE_THREAD_SAFETY
-				if (nthreads != 1)
-					pg_fatal("threads are not supported on this platform; use -j1");
-#endif							/* !ENABLE_THREAD_SAFETY */
 				break;
 			case 'C':
 				benchmarking_option_set = true;
@@ -7201,7 +7187,6 @@ main(int argc, char **argv)
 	if (errno != 0)
 		pg_fatal("could not initialize barrier: %m");
 
-#ifdef ENABLE_THREAD_SAFETY
 	/* start all threads but thread 0 which is executed directly later */
 	for (i = 1; i < nthreads; i++)
 	{
@@ -7213,9 +7198,6 @@ main(int argc, char **argv)
 		if (errno != 0)
 			pg_fatal("could not create thread: %m");
 	}
-#else
-	Assert(nthreads == 1);
-#endif							/* ENABLE_THREAD_SAFETY */
 
 	/* compute when to stop */
 	threads[0].create_time = pg_time_now();
@@ -7233,10 +7215,8 @@ main(int argc, char **argv)
 	{
 		TState	   *thread = &threads[i];
 
-#ifdef ENABLE_THREAD_SAFETY
 		if (i > 0)
 			THREAD_JOIN(thread->thread);
-#endif							/* ENABLE_THREAD_SAFETY */
 
 		for (int j = 0; j < thread->nstate; j++)
 			if (thread->state[j].state != CSTATE_FINISHED)
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 716baf2e91..ad831ef3d9 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -51,10 +51,6 @@
 /* Define to 1 if you want National Language Support. (--enable-nls) */
 #undef ENABLE_NLS
 
-/* Define to 1 to build client libraries as thread-safe code.
-   (--enable-thread-safety) */
-#undef ENABLE_THREAD_SAFETY
-
 /* Define to 1 if gettimeofday() takes only 1 argument. */
 #undef GETTIMEOFDAY_1ARG
 
diff --git a/src/interfaces/ecpg/ecpglib/connect.c b/src/interfaces/ecpg/ecpglib/connect.c
index db0bae1fe0..8afb1f0a26 100644
--- a/src/interfaces/ecpg/ecpglib/connect.c
+++ b/src/interfaces/ecpg/ecpglib/connect.c
@@ -14,15 +14,12 @@
 locale_t	ecpg_clocale = (locale_t) 0;
 #endif
 
-#ifdef ENABLE_THREAD_SAFETY
 static pthread_mutex_t connections_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_key_t actual_connection_key;
 static pthread_once_t actual_connection_key_once = PTHREAD_ONCE_INIT;
-#endif
 static struct connection *actual_connection = NULL;
 static struct connection *all_connections = NULL;
 
-#ifdef ENABLE_THREAD_SAFETY
 static void
 ecpg_actual_connection_init(void)
 {
@@ -34,7 +31,6 @@ ecpg_pthreads_init(void)
 {
 	pthread_once(&actual_connection_key_once, ecpg_actual_connection_init);
 }
-#endif
 
 static struct connection *
 ecpg_get_connection_nr(const char *connection_name)
@@ -43,7 +39,6 @@ ecpg_get_connection_nr(const char *connection_name)
 
 	if ((connection_name == NULL) || (strcmp(connection_name, "CURRENT") == 0))
 	{
-#ifdef ENABLE_THREAD_SAFETY
 		ecpg_pthreads_init();	/* ensure actual_connection_key is valid */
 
 		ret = pthread_getspecific(actual_connection_key);
@@ -56,9 +51,6 @@ ecpg_get_connection_nr(const char *connection_name)
 		if (ret == NULL)
 			/* no TSD connection, going for global */
 			ret = actual_connection;
-#else
-		ret = actual_connection;
-#endif
 	}
 	else
 	{
@@ -82,7 +74,6 @@ ecpg_get_connection(const char *connection_name)
 
 	if ((connection_name == NULL) || (strcmp(connection_name, "CURRENT") == 0))
 	{
-#ifdef ENABLE_THREAD_SAFETY
 		ecpg_pthreads_init();	/* ensure actual_connection_key is valid */
 
 		ret = pthread_getspecific(actual_connection_key);
@@ -95,21 +86,14 @@ ecpg_get_connection(const char *connection_name)
 		if (ret == NULL)
 			/* no TSD connection here either, using global */
 			ret = actual_connection;
-#else
-		ret = actual_connection;
-#endif
 	}
 	else
 	{
-#ifdef ENABLE_THREAD_SAFETY
 		pthread_mutex_lock(&connections_mutex);
-#endif
 
 		ret = ecpg_get_connection_nr(connection_name);
 
-#ifdef ENABLE_THREAD_SAFETY
 		pthread_mutex_unlock(&connections_mutex);
-#endif
 	}
 
 	return ret;
@@ -143,10 +127,8 @@ ecpg_finish(struct connection *act)
 				con->next = act->next;
 		}
 
-#ifdef ENABLE_THREAD_SAFETY
 		if (pthread_getspecific(actual_connection_key) == act)
 			pthread_setspecific(actual_connection_key, all_connections);
-#endif
 		if (actual_connection == act)
 			actual_connection = all_connections;
 
@@ -212,11 +194,7 @@ ECPGsetconn(int lineno, const char *connection_name)
 	if (!ecpg_init(con, connection_name, lineno))
 		return false;
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_setspecific(actual_connection_key, con);
-#else
-	actual_connection = con;
-#endif
 	return true;
 }
 
@@ -326,9 +304,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
 	if (dbname == NULL && connection_name == NULL)
 		connection_name = "DEFAULT";
 
-#if ENABLE_THREAD_SAFETY
 	ecpg_pthreads_init();
-#endif
 
 	/* check if the identifier is unique */
 	if (ecpg_get_connection(connection_name))
@@ -505,9 +481,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
 	}
 
 	/* add connection to our list */
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_lock(&connections_mutex);
-#endif
 
 	/*
 	 * ... but first, make certain we have created ecpg_clocale.  Rely on
@@ -519,9 +493,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
 		ecpg_clocale = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
 		if (!ecpg_clocale)
 		{
-#ifdef ENABLE_THREAD_SAFETY
 			pthread_mutex_unlock(&connections_mutex);
-#endif
 			ecpg_raise(lineno, ECPG_OUT_OF_MEMORY,
 					   ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
 			if (host)
@@ -558,9 +530,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
 		this->next = all_connections;
 
 	all_connections = this;
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_setspecific(actual_connection_key, all_connections);
-#endif
 	actual_connection = all_connections;
 
 	ecpg_log("ECPGconnect: opening database %s on %s port %s %s%s %s%s\n",
@@ -678,9 +648,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
 		ecpg_log("ECPGconnect: %s", errmsg);
 
 		ecpg_finish(this);
-#ifdef ENABLE_THREAD_SAFETY
 		pthread_mutex_unlock(&connections_mutex);
-#endif
 
 		ecpg_raise(lineno, ECPG_CONNECT, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, db);
 		if (realname)
@@ -692,9 +660,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
 	if (realname)
 		ecpg_free(realname);
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_unlock(&connections_mutex);
-#endif
 
 	this->autocommit = autocommit;
 
@@ -716,9 +682,7 @@ ECPGdisconnect(int lineno, const char *connection_name)
 		return false;
 	}
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_lock(&connections_mutex);
-#endif
 
 	if (strcmp(connection_name, "ALL") == 0)
 	{
@@ -737,18 +701,14 @@ ECPGdisconnect(int lineno, const char *connection_name)
 
 		if (!ecpg_init(con, connection_name, lineno))
 		{
-#ifdef ENABLE_THREAD_SAFETY
 			pthread_mutex_unlock(&connections_mutex);
-#endif
 			return false;
 		}
 		else
 			ecpg_finish(con);
 	}
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_unlock(&connections_mutex);
-#endif
 
 	return true;
 }
diff --git a/src/interfaces/ecpg/ecpglib/descriptor.c b/src/interfaces/ecpg/ecpglib/descriptor.c
index 649a71c286..b47f422d92 100644
--- a/src/interfaces/ecpg/ecpglib/descriptor.c
+++ b/src/interfaces/ecpg/ecpglib/descriptor.c
@@ -19,7 +19,6 @@
 static void descriptor_free(struct descriptor *desc);
 
 /* We manage descriptors separately for each thread. */
-#ifdef ENABLE_THREAD_SAFETY
 static pthread_key_t descriptor_key;
 static pthread_once_t descriptor_once = PTHREAD_ONCE_INIT;
 
@@ -49,12 +48,6 @@ set_descriptors(struct descriptor *value)
 {
 	pthread_setspecific(descriptor_key, value);
 }
-#else
-static struct descriptor *all_descriptors = NULL;
-
-#define get_descriptors()		(all_descriptors)
-#define set_descriptors(value)	do { all_descriptors = (value); } while(0)
-#endif
 
 /* old internal convenience function that might go away later */
 static PGresult *
@@ -782,7 +775,6 @@ ECPGdeallocate_desc(int line, const char *name)
 	return false;
 }
 
-#ifdef ENABLE_THREAD_SAFETY
 
 /* Deallocate all descriptors in the list */
 static void
@@ -796,7 +788,6 @@ descriptor_deallocate_all(struct descriptor *list)
 		list = next;
 	}
 }
-#endif							/* ENABLE_THREAD_SAFETY */
 
 bool
 ECPGallocate_desc(int line, const char *name)
diff --git a/src/interfaces/ecpg/ecpglib/ecpglib_extern.h b/src/interfaces/ecpg/ecpglib/ecpglib_extern.h
index c438cfb820..968f1211b8 100644
--- a/src/interfaces/ecpg/ecpglib/ecpglib_extern.h
+++ b/src/interfaces/ecpg/ecpglib/ecpglib_extern.h
@@ -169,9 +169,7 @@ bool		ecpg_get_data(const PGresult *, int, int, int, enum ECPGttype type,
 						  enum ECPGttype, char *, char *, long, long, long,
 						  enum ARRAY_TYPE, enum COMPAT_MODE, bool);
 
-#ifdef ENABLE_THREAD_SAFETY
 void		ecpg_pthreads_init(void);
-#endif
 struct connection *ecpg_get_connection(const char *);
 char	   *ecpg_alloc(long, int);
 char	   *ecpg_auto_alloc(long, int);
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index bd94bd4e6c..0b2716d921 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1961,9 +1961,7 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator,
 		return false;
 	}
 
-#ifdef ENABLE_THREAD_SAFETY
 	ecpg_pthreads_init();
-#endif
 
 	con = ecpg_get_connection(connection_name);
 
diff --git a/src/interfaces/ecpg/ecpglib/memory.c b/src/interfaces/ecpg/ecpglib/memory.c
index bd81251054..a83637ac75 100644
--- a/src/interfaces/ecpg/ecpglib/memory.c
+++ b/src/interfaces/ecpg/ecpglib/memory.c
@@ -68,7 +68,6 @@ struct auto_mem
 	struct auto_mem *next;
 };
 
-#ifdef ENABLE_THREAD_SAFETY
 static pthread_key_t auto_mem_key;
 static pthread_once_t auto_mem_once = PTHREAD_ONCE_INIT;
 
@@ -97,12 +96,6 @@ set_auto_allocs(struct auto_mem *am)
 {
 	pthread_setspecific(auto_mem_key, am);
 }
-#else
-static struct auto_mem *auto_allocs = NULL;
-
-#define get_auto_allocs()		(auto_allocs)
-#define set_auto_allocs(am)		do { auto_allocs = (am); } while(0)
-#endif
 
 char *
 ecpg_auto_alloc(long size, int lineno)
diff --git a/src/interfaces/ecpg/ecpglib/misc.c b/src/interfaces/ecpg/ecpglib/misc.c
index 1eef1ec044..71f07c4e4f 100644
--- a/src/interfaces/ecpg/ecpglib/misc.c
+++ b/src/interfaces/ecpg/ecpglib/misc.c
@@ -55,42 +55,11 @@ static struct sqlca_t sqlca_init =
 	}
 };
 
-#ifdef ENABLE_THREAD_SAFETY
 static pthread_key_t sqlca_key;
 static pthread_once_t sqlca_key_once = PTHREAD_ONCE_INIT;
-#else
-static struct sqlca_t sqlca =
-{
-	{
-		'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '
-	},
-	sizeof(struct sqlca_t),
-	0,
-	{
-		0,
-		{
-			0
-		}
-	},
-	{
-		'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '
-	},
-	{
-		0, 0, 0, 0, 0, 0
-	},
-	{
-		0, 0, 0, 0, 0, 0, 0, 0
-	},
-	{
-		'0', '0', '0', '0', '0'
-	}
-};
-#endif
 
-#ifdef ENABLE_THREAD_SAFETY
 static pthread_mutex_t debug_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t debug_init_mutex = PTHREAD_MUTEX_INITIALIZER;
-#endif
 static int	simple_debug = 0;
 static FILE *debugstream = NULL;
 
@@ -123,7 +92,6 @@ ecpg_init(const struct connection *con, const char *connection_name, const int l
 	return true;
 }
 
-#ifdef ENABLE_THREAD_SAFETY
 static void
 ecpg_sqlca_key_destructor(void *arg)
 {
@@ -135,12 +103,10 @@ ecpg_sqlca_key_init(void)
 {
 	pthread_key_create(&sqlca_key, ecpg_sqlca_key_destructor);
 }
-#endif
 
 struct sqlca_t *
 ECPGget_sqlca(void)
 {
-#ifdef ENABLE_THREAD_SAFETY
 	struct sqlca_t *sqlca;
 
 	pthread_once(&sqlca_key_once, ecpg_sqlca_key_init);
@@ -155,9 +121,6 @@ ECPGget_sqlca(void)
 		pthread_setspecific(sqlca_key, sqlca);
 	}
 	return sqlca;
-#else
-	return &sqlca;
-#endif
 }
 
 bool
@@ -240,9 +203,7 @@ ECPGtrans(int lineno, const char *connection_name, const char *transaction)
 void
 ECPGdebug(int n, FILE *dbgs)
 {
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_lock(&debug_init_mutex);
-#endif
 
 	if (n > 100)
 	{
@@ -256,9 +217,7 @@ ECPGdebug(int n, FILE *dbgs)
 
 	ecpg_log("ECPGdebug: set to %d\n", simple_debug);
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_unlock(&debug_init_mutex);
-#endif
 }
 
 void
@@ -290,9 +249,7 @@ ecpg_log(const char *format,...)
 	else
 		snprintf(fmt, bufsize, "[%d]: %s", (int) getpid(), intl_format);
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_lock(&debug_mutex);
-#endif
 
 	va_start(ap, format);
 	vfprintf(debugstream, fmt, ap);
@@ -307,9 +264,7 @@ ecpg_log(const char *format,...)
 
 	fflush(debugstream);
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_unlock(&debug_mutex);
-#endif
 
 	free(fmt);
 }
@@ -451,7 +406,6 @@ ECPGis_noind_null(enum ECPGttype type, const void *ptr)
 }
 
 #ifdef WIN32
-#ifdef ENABLE_THREAD_SAFETY
 
 void
 win32_pthread_mutex(volatile pthread_mutex_t *mutex)
@@ -482,7 +436,6 @@ win32_pthread_once(volatile pthread_once_t *once, void (*fn) (void))
 		pthread_mutex_unlock(&win32_pthread_once_lock);
 	}
 }
-#endif							/* ENABLE_THREAD_SAFETY */
 #endif							/* WIN32 */
 
 #ifdef ENABLE_NLS
diff --git a/src/interfaces/ecpg/include/ecpg-pthread-win32.h b/src/interfaces/ecpg/include/ecpg-pthread-win32.h
index 33c897b633..8252a17809 100644
--- a/src/interfaces/ecpg/include/ecpg-pthread-win32.h
+++ b/src/interfaces/ecpg/include/ecpg-pthread-win32.h
@@ -5,8 +5,6 @@
 #ifndef _ECPG_PTHREAD_WIN32_H
 #define _ECPG_PTHREAD_WIN32_H
 
-#ifdef ENABLE_THREAD_SAFETY
-
 #ifndef WIN32
 
 #include <pthread.h>
@@ -53,6 +51,5 @@ void		win32_pthread_once(volatile pthread_once_t *once, void (*fn) (void));
 			win32_pthread_once((once), (fn)); \
 	} while(0)
 #endif							/* WIN32 */
-#endif							/* ENABLE_THREAD_SAFETY */
 
 #endif							/* _ECPG_PTHREAD_WIN32_H */
diff --git a/src/interfaces/ecpg/include/ecpg_config.h.in b/src/interfaces/ecpg/include/ecpg_config.h.in
index cbd24f11a0..6d01608a49 100644
--- a/src/interfaces/ecpg/include/ecpg_config.h.in
+++ b/src/interfaces/ecpg/include/ecpg_config.h.in
@@ -1,7 +1,3 @@
-/* Define to 1 to build client libraries as thread-safe code.
- *    (--enable-thread-safety) */
-#undef ENABLE_THREAD_SAFETY
-
 /* Define to 1 if the system has the type `int64'. */
 #undef HAVE_INT64
 
diff --git a/src/interfaces/ecpg/include/ecpglib.h b/src/interfaces/ecpg/include/ecpglib.h
index 00240109a6..05433726ac 100644
--- a/src/interfaces/ecpg/include/ecpglib.h
+++ b/src/interfaces/ecpg/include/ecpglib.h
@@ -92,9 +92,7 @@ void	   *ECPGget_var(int number);
 /* dynamic result allocation */
 void		ECPGfree_auto_mem(void);
 
-#ifdef ENABLE_THREAD_SAFETY
 void		ecpg_pthreads_init(void);
-#endif
 
 #ifdef __cplusplus
 }
diff --git a/src/interfaces/ecpg/test/expected/thread-alloc.c b/src/interfaces/ecpg/test/expected/thread-alloc.c
index 37ef44ed94..3b31d27fd3 100644
--- a/src/interfaces/ecpg/test/expected/thread-alloc.c
+++ b/src/interfaces/ecpg/test/expected/thread-alloc.c
@@ -11,14 +11,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifdef WIN32
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
@@ -101,7 +93,7 @@ struct sqlca_t *ECPGget_sqlca(void);
 
 #endif
 
-#line 26 "alloc.pgc"
+#line 18 "alloc.pgc"
 
 
 #line 1 "regression.h"
@@ -111,14 +103,14 @@ struct sqlca_t *ECPGget_sqlca(void);
 
 
 
-#line 27 "alloc.pgc"
+#line 19 "alloc.pgc"
 
 
 /* exec sql whenever sqlerror  sqlprint ; */
-#line 29 "alloc.pgc"
+#line 21 "alloc.pgc"
 
 /* exec sql whenever not found  sqlprint ; */
-#line 30 "alloc.pgc"
+#line 22 "alloc.pgc"
 
 
 #ifdef WIN32
@@ -134,54 +126,54 @@ static void* fn(void* arg)
 	 
 	   
 	
-#line 41 "alloc.pgc"
+#line 33 "alloc.pgc"
  int value ;
  
-#line 42 "alloc.pgc"
+#line 34 "alloc.pgc"
  char name [ 100 ] ;
  
-#line 43 "alloc.pgc"
+#line 35 "alloc.pgc"
  char ** r = NULL ;
 /* exec sql end declare section */
-#line 44 "alloc.pgc"
+#line 36 "alloc.pgc"
 
 
 	value = (intptr_t) arg;
 	sprintf(name, "Connection: %d", value);
 
 	{ ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , name, 0); 
-#line 49 "alloc.pgc"
+#line 41 "alloc.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 49 "alloc.pgc"
+#line 41 "alloc.pgc"
 
 	{ ECPGsetcommit(__LINE__, "on", NULL);
-#line 50 "alloc.pgc"
+#line 42 "alloc.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 50 "alloc.pgc"
+#line 42 "alloc.pgc"
 
 	for (i = 1; i <= REPEATS; ++i)
 	{
 		{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select relname from pg_class where relname = 'pg_class'", ECPGt_EOIT, 
 	ECPGt_char,&(r),(long)0,(long)0,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
-#line 53 "alloc.pgc"
+#line 45 "alloc.pgc"
 
 if (sqlca.sqlcode == ECPG_NOT_FOUND) sqlprint();
-#line 53 "alloc.pgc"
+#line 45 "alloc.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 53 "alloc.pgc"
+#line 45 "alloc.pgc"
 
 		free(r);
 		r = NULL;
 	}
 	{ ECPGdisconnect(__LINE__, name);
-#line 57 "alloc.pgc"
+#line 49 "alloc.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 57 "alloc.pgc"
+#line 49 "alloc.pgc"
 
 
 	return 0;
@@ -215,4 +207,3 @@ int main ()
 
 	return 0;
 }
-#endif
diff --git a/src/interfaces/ecpg/test/expected/thread-alloc_2.stdout b/src/interfaces/ecpg/test/expected/thread-alloc_2.stdout
deleted file mode 100644
index 75fe16bb36..0000000000
--- a/src/interfaces/ecpg/test/expected/thread-alloc_2.stdout
+++ /dev/null
@@ -1 +0,0 @@
-No threading enabled.
diff --git a/src/interfaces/ecpg/test/expected/thread-descriptor.c b/src/interfaces/ecpg/test/expected/thread-descriptor.c
index f56cc25ab0..e34f4708d1 100644
--- a/src/interfaces/ecpg/test/expected/thread-descriptor.c
+++ b/src/interfaces/ecpg/test/expected/thread-descriptor.c
@@ -7,7 +7,6 @@
 #define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y))
 
 #line 1 "descriptor.pgc"
-#ifdef ENABLE_THREAD_SAFETY
 #ifdef WIN32
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
@@ -16,7 +15,6 @@
 #else
 #include <pthread.h>
 #endif
-#endif
 #include <stdio.h>
 
 #define THREADS		16
@@ -91,16 +89,16 @@ struct sqlca_t *ECPGget_sqlca(void);
 
 #endif
 
-#line 16 "descriptor.pgc"
+#line 14 "descriptor.pgc"
 
 /* exec sql whenever sqlerror  sqlprint ; */
-#line 17 "descriptor.pgc"
+#line 15 "descriptor.pgc"
 
 /* exec sql whenever not found  sqlprint ; */
-#line 18 "descriptor.pgc"
+#line 16 "descriptor.pgc"
 
 
-#if defined(ENABLE_THREAD_SAFETY) && defined(WIN32)
+#if defined(WIN32)
 static unsigned __stdcall fn(void* arg)
 #else
 static void* fn(void* arg)
@@ -111,16 +109,16 @@ static void* fn(void* arg)
 	for (i = 1; i <= REPEATS; ++i)
 	{
 		ECPGallocate_desc(__LINE__, "mydesc");
-#line 30 "descriptor.pgc"
+#line 28 "descriptor.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();
-#line 30 "descriptor.pgc"
+#line 28 "descriptor.pgc"
 
 		ECPGdeallocate_desc(__LINE__, "mydesc");
-#line 31 "descriptor.pgc"
+#line 29 "descriptor.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();
-#line 31 "descriptor.pgc"
+#line 29 "descriptor.pgc"
 
 	}
 
@@ -129,7 +127,6 @@ if (sqlca.sqlcode < 0) sqlprint();
 
 int main ()
 {
-#ifdef ENABLE_THREAD_SAFETY
 	int i;
 #ifdef WIN32
 	HANDLE threads[THREADS];
@@ -153,9 +150,6 @@ int main ()
 	for (i = 0; i < THREADS; ++i)
 		pthread_join(threads[i], NULL);
 #endif
-#else
-	fn(NULL);
-#endif
 
 	return 0;
 }
diff --git a/src/interfaces/ecpg/test/expected/thread-prep.c b/src/interfaces/ecpg/test/expected/thread-prep.c
index 7cdf2505d3..052e27b634 100644
--- a/src/interfaces/ecpg/test/expected/thread-prep.c
+++ b/src/interfaces/ecpg/test/expected/thread-prep.c
@@ -11,14 +11,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifdef WIN32
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
@@ -101,7 +93,7 @@ struct sqlca_t *ECPGget_sqlca(void);
 
 #endif
 
-#line 26 "prep.pgc"
+#line 18 "prep.pgc"
 
 
 #line 1 "regression.h"
@@ -111,14 +103,14 @@ struct sqlca_t *ECPGget_sqlca(void);
 
 
 
-#line 27 "prep.pgc"
+#line 19 "prep.pgc"
 
 
 /* exec sql whenever sqlerror  sqlprint ; */
-#line 29 "prep.pgc"
+#line 21 "prep.pgc"
 
 /* exec sql whenever not found  sqlprint ; */
-#line 30 "prep.pgc"
+#line 22 "prep.pgc"
 
 
 #ifdef WIN32
@@ -134,64 +126,64 @@ static void* fn(void* arg)
 	 
 	   
 	
-#line 41 "prep.pgc"
+#line 33 "prep.pgc"
  int value ;
  
-#line 42 "prep.pgc"
+#line 34 "prep.pgc"
  char name [ 100 ] ;
  
-#line 43 "prep.pgc"
+#line 35 "prep.pgc"
  char query [ 256 ] = "INSERT INTO T VALUES ( ? )" ;
 /* exec sql end declare section */
-#line 44 "prep.pgc"
+#line 36 "prep.pgc"
 
 
 	value = (intptr_t) arg;
 	sprintf(name, "Connection: %d", value);
 
 	{ ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , name, 0); 
-#line 49 "prep.pgc"
+#line 41 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 49 "prep.pgc"
+#line 41 "prep.pgc"
 
 	{ ECPGsetcommit(__LINE__, "on", NULL);
-#line 50 "prep.pgc"
+#line 42 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 50 "prep.pgc"
+#line 42 "prep.pgc"
 
 	for (i = 1; i <= REPEATS; ++i)
 	{
 		{ ECPGprepare(__LINE__, NULL, 0, "i", query);
-#line 53 "prep.pgc"
+#line 45 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 53 "prep.pgc"
+#line 45 "prep.pgc"
 
 		{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_execute, "i", 
 	ECPGt_int,&(value),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
-#line 54 "prep.pgc"
+#line 46 "prep.pgc"
 
 if (sqlca.sqlcode == ECPG_NOT_FOUND) sqlprint();
-#line 54 "prep.pgc"
+#line 46 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 54 "prep.pgc"
+#line 46 "prep.pgc"
 
 	}
 	{ ECPGdeallocate(__LINE__, 0, NULL, "i");
-#line 56 "prep.pgc"
+#line 48 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 56 "prep.pgc"
+#line 48 "prep.pgc"
 
 	{ ECPGdisconnect(__LINE__, name);
-#line 57 "prep.pgc"
+#line 49 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 57 "prep.pgc"
+#line 49 "prep.pgc"
 
 
 	return 0;
@@ -207,34 +199,34 @@ int main ()
 #endif
 
 	{ ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0); 
-#line 71 "prep.pgc"
+#line 63 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 71 "prep.pgc"
+#line 63 "prep.pgc"
 
 	{ ECPGsetcommit(__LINE__, "on", NULL);
-#line 72 "prep.pgc"
+#line 64 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 72 "prep.pgc"
+#line 64 "prep.pgc"
 
 	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table if exists T", ECPGt_EOIT, ECPGt_EORT);
-#line 73 "prep.pgc"
+#line 65 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 73 "prep.pgc"
+#line 65 "prep.pgc"
 
 	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table T ( i int )", ECPGt_EOIT, ECPGt_EORT);
-#line 74 "prep.pgc"
+#line 66 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 74 "prep.pgc"
+#line 66 "prep.pgc"
 
 	{ ECPGdisconnect(__LINE__, "CURRENT");
-#line 75 "prep.pgc"
+#line 67 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 75 "prep.pgc"
+#line 67 "prep.pgc"
 
 
 #ifdef WIN32
@@ -256,4 +248,3 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	return 0;
 }
-#endif
diff --git a/src/interfaces/ecpg/test/expected/thread-prep.stdout b/src/interfaces/ecpg/test/expected/thread-prep.stdout
index 75fe16bb36..e69de29bb2 100644
--- a/src/interfaces/ecpg/test/expected/thread-prep.stdout
+++ b/src/interfaces/ecpg/test/expected/thread-prep.stdout
@@ -1 +0,0 @@
-No threading enabled.
diff --git a/src/interfaces/ecpg/test/expected/thread-prep_2.stdout b/src/interfaces/ecpg/test/expected/thread-prep_2.stdout
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/src/interfaces/ecpg/test/expected/thread-thread.c b/src/interfaces/ecpg/test/expected/thread-thread.c
index 0e75c47fab..95faa223c2 100644
--- a/src/interfaces/ecpg/test/expected/thread-thread.c
+++ b/src/interfaces/ecpg/test/expected/thread-thread.c
@@ -15,14 +15,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifndef WIN32
 #include <pthread.h>
 #else
@@ -38,7 +30,7 @@ main(void)
 
 
 
-#line 24 "thread.pgc"
+#line 16 "thread.pgc"
 
 
 void *test_thread(void *arg);
@@ -57,10 +49,10 @@ int main()
   /* exec sql begin declare section */
    
   
-#line 40 "thread.pgc"
+#line 32 "thread.pgc"
  int l_rows ;
 /* exec sql end declare section */
-#line 41 "thread.pgc"
+#line 33 "thread.pgc"
 
 
  /* Do not switch on debug output for regression tests. The threads get executed in
@@ -69,22 +61,22 @@ int main()
 
   /* setup test_thread table */
   { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0); }
-#line 48 "thread.pgc"
+#line 40 "thread.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table test_thread", ECPGt_EOIT, ECPGt_EORT);}
-#line 49 "thread.pgc"
+#line 41 "thread.pgc"
  /* DROP might fail */
   { ECPGtrans(__LINE__, NULL, "commit");}
-#line 50 "thread.pgc"
+#line 42 "thread.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table test_thread ( tstamp timestamp not null default cast ( timeofday ( ) as timestamp ) , thread text not null , iteration integer not null , primary key ( thread , iteration ) )", ECPGt_EOIT, ECPGt_EORT);}
-#line 55 "thread.pgc"
+#line 47 "thread.pgc"
 
   { ECPGtrans(__LINE__, NULL, "commit");}
-#line 56 "thread.pgc"
+#line 48 "thread.pgc"
 
   { ECPGdisconnect(__LINE__, "CURRENT");}
-#line 57 "thread.pgc"
+#line 49 "thread.pgc"
 
 
   /* create, and start, threads */
@@ -116,18 +108,18 @@ int main()
 
   /* and check results */
   { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0); }
-#line 87 "thread.pgc"
+#line 79 "thread.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count ( * ) from test_thread", ECPGt_EOIT, 
 	ECPGt_int,&(l_rows),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
-#line 88 "thread.pgc"
+#line 80 "thread.pgc"
 
   { ECPGtrans(__LINE__, NULL, "commit");}
-#line 89 "thread.pgc"
+#line 81 "thread.pgc"
 
   { ECPGdisconnect(__LINE__, "CURRENT");}
-#line 90 "thread.pgc"
+#line 82 "thread.pgc"
 
   if( l_rows == (nthreads * iterations) )
     printf("Success.\n");
@@ -145,13 +137,13 @@ void *test_thread(void *arg)
     
    
   
-#line 104 "thread.pgc"
+#line 96 "thread.pgc"
  int l_i ;
  
-#line 105 "thread.pgc"
+#line 97 "thread.pgc"
  char l_connection [ 128 ] ;
 /* exec sql end declare section */
-#line 106 "thread.pgc"
+#line 98 "thread.pgc"
 
 
   /* build up connection name, and connect to database */
@@ -161,13 +153,13 @@ void *test_thread(void *arg)
   _snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum);
 #endif
   /* exec sql whenever sqlerror  sqlprint ; */
-#line 114 "thread.pgc"
+#line 106 "thread.pgc"
 
   { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , l_connection, 0); 
-#line 115 "thread.pgc"
+#line 107 "thread.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 115 "thread.pgc"
+#line 107 "thread.pgc"
 
   if( sqlca.sqlcode != 0 )
     {
@@ -175,10 +167,10 @@ if (sqlca.sqlcode < 0) sqlprint();}
       return NULL;
     }
   { ECPGtrans(__LINE__, l_connection, "begin");
-#line 121 "thread.pgc"
+#line 113 "thread.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 121 "thread.pgc"
+#line 113 "thread.pgc"
 
 
   /* insert into test_thread table */
@@ -189,10 +181,10 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_int,&(l_i),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
-#line 126 "thread.pgc"
+#line 118 "thread.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 126 "thread.pgc"
+#line 118 "thread.pgc"
 
       if( sqlca.sqlcode != 0 )
 	printf("%s: ERROR: insert failed!\n", l_connection);
@@ -200,17 +192,16 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
   /* all done */
   { ECPGtrans(__LINE__, l_connection, "commit");
-#line 132 "thread.pgc"
+#line 124 "thread.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 132 "thread.pgc"
+#line 124 "thread.pgc"
 
   { ECPGdisconnect(__LINE__, l_connection);
-#line 133 "thread.pgc"
+#line 125 "thread.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 133 "thread.pgc"
+#line 125 "thread.pgc"
 
   return NULL;
 }
-#endif /* ENABLE_THREAD_SAFETY */
diff --git a/src/interfaces/ecpg/test/expected/thread-thread.stdout b/src/interfaces/ecpg/test/expected/thread-thread.stdout
index 75fe16bb36..a9d787cc55 100644
--- a/src/interfaces/ecpg/test/expected/thread-thread.stdout
+++ b/src/interfaces/ecpg/test/expected/thread-thread.stdout
@@ -1 +1 @@
-No threading enabled.
+Success.
diff --git a/src/interfaces/ecpg/test/expected/thread-thread_2.stdout b/src/interfaces/ecpg/test/expected/thread-thread_2.stdout
deleted file mode 100644
index a9d787cc55..0000000000
--- a/src/interfaces/ecpg/test/expected/thread-thread_2.stdout
+++ /dev/null
@@ -1 +0,0 @@
-Success.
diff --git a/src/interfaces/ecpg/test/expected/thread-thread_implicit.c b/src/interfaces/ecpg/test/expected/thread-thread_implicit.c
index 0df2794530..7ac0297a23 100644
--- a/src/interfaces/ecpg/test/expected/thread-thread_implicit.c
+++ b/src/interfaces/ecpg/test/expected/thread-thread_implicit.c
@@ -15,14 +15,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifndef WIN32
 #include <pthread.h>
 #else
@@ -38,7 +30,7 @@ main(void)
 
 
 
-#line 24 "thread_implicit.pgc"
+#line 16 "thread_implicit.pgc"
 
 
 void *test_thread(void *arg);
@@ -57,10 +49,10 @@ int main()
   /* exec sql begin declare section */
    
   
-#line 40 "thread_implicit.pgc"
+#line 32 "thread_implicit.pgc"
  int l_rows ;
 /* exec sql end declare section */
-#line 41 "thread_implicit.pgc"
+#line 33 "thread_implicit.pgc"
 
 
  /* Do not switch on debug output for regression tests. The threads get executed in
@@ -69,22 +61,22 @@ int main()
 
   /* setup test_thread table */
   { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0); }
-#line 48 "thread_implicit.pgc"
+#line 40 "thread_implicit.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table test_thread", ECPGt_EOIT, ECPGt_EORT);}
-#line 49 "thread_implicit.pgc"
+#line 41 "thread_implicit.pgc"
  /* DROP might fail */
   { ECPGtrans(__LINE__, NULL, "commit");}
-#line 50 "thread_implicit.pgc"
+#line 42 "thread_implicit.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table test_thread ( tstamp timestamp not null default cast ( timeofday ( ) as timestamp ) , thread text not null , iteration integer not null , primary key ( thread , iteration ) )", ECPGt_EOIT, ECPGt_EORT);}
-#line 55 "thread_implicit.pgc"
+#line 47 "thread_implicit.pgc"
 
   { ECPGtrans(__LINE__, NULL, "commit");}
-#line 56 "thread_implicit.pgc"
+#line 48 "thread_implicit.pgc"
 
   { ECPGdisconnect(__LINE__, "CURRENT");}
-#line 57 "thread_implicit.pgc"
+#line 49 "thread_implicit.pgc"
 
 
   /* create, and start, threads */
@@ -116,18 +108,18 @@ int main()
 
   /* and check results */
   { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0); }
-#line 87 "thread_implicit.pgc"
+#line 79 "thread_implicit.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count ( * ) from test_thread", ECPGt_EOIT, 
 	ECPGt_int,&(l_rows),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
-#line 88 "thread_implicit.pgc"
+#line 80 "thread_implicit.pgc"
 
   { ECPGtrans(__LINE__, NULL, "commit");}
-#line 89 "thread_implicit.pgc"
+#line 81 "thread_implicit.pgc"
 
   { ECPGdisconnect(__LINE__, "CURRENT");}
-#line 90 "thread_implicit.pgc"
+#line 82 "thread_implicit.pgc"
 
   if( l_rows == (nthreads * iterations) )
     printf("Success.\n");
@@ -145,13 +137,13 @@ void *test_thread(void *arg)
     
    
   
-#line 104 "thread_implicit.pgc"
+#line 96 "thread_implicit.pgc"
  int l_i ;
  
-#line 105 "thread_implicit.pgc"
+#line 97 "thread_implicit.pgc"
  char l_connection [ 128 ] ;
 /* exec sql end declare section */
-#line 106 "thread_implicit.pgc"
+#line 98 "thread_implicit.pgc"
 
 
   /* build up connection name, and connect to database */
@@ -161,13 +153,13 @@ void *test_thread(void *arg)
   _snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum);
 #endif
   /* exec sql whenever sqlerror  sqlprint ; */
-#line 114 "thread_implicit.pgc"
+#line 106 "thread_implicit.pgc"
 
   { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , l_connection, 0); 
-#line 115 "thread_implicit.pgc"
+#line 107 "thread_implicit.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 115 "thread_implicit.pgc"
+#line 107 "thread_implicit.pgc"
 
   if( sqlca.sqlcode != 0 )
     {
@@ -175,10 +167,10 @@ if (sqlca.sqlcode < 0) sqlprint();}
       return NULL;
     }
   { ECPGtrans(__LINE__, NULL, "begin");
-#line 121 "thread_implicit.pgc"
+#line 113 "thread_implicit.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 121 "thread_implicit.pgc"
+#line 113 "thread_implicit.pgc"
 
 
   /* insert into test_thread table */
@@ -189,10 +181,10 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_int,&(l_i),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
-#line 126 "thread_implicit.pgc"
+#line 118 "thread_implicit.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 126 "thread_implicit.pgc"
+#line 118 "thread_implicit.pgc"
 
       if( sqlca.sqlcode != 0 )
 	printf("%s: ERROR: insert failed!\n", l_connection);
@@ -200,17 +192,16 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
   /* all done */
   { ECPGtrans(__LINE__, NULL, "commit");
-#line 132 "thread_implicit.pgc"
+#line 124 "thread_implicit.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 132 "thread_implicit.pgc"
+#line 124 "thread_implicit.pgc"
 
   { ECPGdisconnect(__LINE__, l_connection);
-#line 133 "thread_implicit.pgc"
+#line 125 "thread_implicit.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 133 "thread_implicit.pgc"
+#line 125 "thread_implicit.pgc"
 
   return NULL;
 }
-#endif /* ENABLE_THREAD_SAFETY */
diff --git a/src/interfaces/ecpg/test/expected/thread-thread_implicit.stdout b/src/interfaces/ecpg/test/expected/thread-thread_implicit.stdout
index 75fe16bb36..a9d787cc55 100644
--- a/src/interfaces/ecpg/test/expected/thread-thread_implicit.stdout
+++ b/src/interfaces/ecpg/test/expected/thread-thread_implicit.stdout
@@ -1 +1 @@
-No threading enabled.
+Success.
diff --git a/src/interfaces/ecpg/test/expected/thread-thread_implicit_2.stdout b/src/interfaces/ecpg/test/expected/thread-thread_implicit_2.stdout
deleted file mode 100644
index a9d787cc55..0000000000
--- a/src/interfaces/ecpg/test/expected/thread-thread_implicit_2.stdout
+++ /dev/null
@@ -1 +0,0 @@
-Success.
diff --git a/src/interfaces/ecpg/test/thread/alloc.pgc b/src/interfaces/ecpg/test/thread/alloc.pgc
index c0021a737e..d3d35493bf 100644
--- a/src/interfaces/ecpg/test/thread/alloc.pgc
+++ b/src/interfaces/ecpg/test/thread/alloc.pgc
@@ -2,14 +2,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifdef WIN32
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
@@ -87,4 +79,3 @@ int main ()
 
 	return 0;
 }
-#endif
diff --git a/src/interfaces/ecpg/test/thread/descriptor.pgc b/src/interfaces/ecpg/test/thread/descriptor.pgc
index 76a7a5dff5..30bce7c87b 100644
--- a/src/interfaces/ecpg/test/thread/descriptor.pgc
+++ b/src/interfaces/ecpg/test/thread/descriptor.pgc
@@ -1,4 +1,3 @@
-#ifdef ENABLE_THREAD_SAFETY
 #ifdef WIN32
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
@@ -7,7 +6,6 @@
 #else
 #include <pthread.h>
 #endif
-#endif
 #include <stdio.h>
 
 #define THREADS		16
@@ -17,7 +15,7 @@ EXEC SQL include sqlca;
 EXEC SQL whenever sqlerror sqlprint;
 EXEC SQL whenever not found sqlprint;
 
-#if defined(ENABLE_THREAD_SAFETY) && defined(WIN32)
+#if defined(WIN32)
 static unsigned __stdcall fn(void* arg)
 #else
 static void* fn(void* arg)
@@ -36,7 +34,6 @@ static void* fn(void* arg)
 
 int main ()
 {
-#ifdef ENABLE_THREAD_SAFETY
 	int i;
 #ifdef WIN32
 	HANDLE threads[THREADS];
@@ -60,9 +57,6 @@ int main ()
 	for (i = 0; i < THREADS; ++i)
 		pthread_join(threads[i], NULL);
 #endif
-#else
-	fn(NULL);
-#endif
 
 	return 0;
 }
diff --git a/src/interfaces/ecpg/test/thread/prep.pgc b/src/interfaces/ecpg/test/thread/prep.pgc
index d7ecfd4855..f61b31ce10 100644
--- a/src/interfaces/ecpg/test/thread/prep.pgc
+++ b/src/interfaces/ecpg/test/thread/prep.pgc
@@ -2,14 +2,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifdef WIN32
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
@@ -93,4 +85,3 @@ int main ()
 
 	return 0;
 }
-#endif
diff --git a/src/interfaces/ecpg/test/thread/thread.pgc b/src/interfaces/ecpg/test/thread/thread.pgc
index e7d8c00af6..b9b9ebb441 100644
--- a/src/interfaces/ecpg/test/thread/thread.pgc
+++ b/src/interfaces/ecpg/test/thread/thread.pgc
@@ -6,14 +6,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifndef WIN32
 #include <pthread.h>
 #else
@@ -133,4 +125,3 @@ void *test_thread(void *arg)
   EXEC SQL DISCONNECT :l_connection;
   return NULL;
 }
-#endif /* ENABLE_THREAD_SAFETY */
diff --git a/src/interfaces/ecpg/test/thread/thread_implicit.pgc b/src/interfaces/ecpg/test/thread/thread_implicit.pgc
index b4cae7e1ae..ff9b12a943 100644
--- a/src/interfaces/ecpg/test/thread/thread_implicit.pgc
+++ b/src/interfaces/ecpg/test/thread/thread_implicit.pgc
@@ -6,14 +6,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifndef WIN32
 #include <pthread.h>
 #else
@@ -133,4 +125,3 @@ void *test_thread(void *arg)
   EXEC SQL DISCONNECT :l_connection;
   return NULL;
 }
-#endif /* ENABLE_THREAD_SAFETY */
diff --git a/src/interfaces/libpq/Makefile b/src/interfaces/libpq/Makefile
index b5fd72a4ac..bd43871c69 100644
--- a/src/interfaces/libpq/Makefile
+++ b/src/interfaces/libpq/Makefile
@@ -71,10 +71,8 @@ ifeq ($(PORTNAME), win32)
 OBJS += \
 	win32.o
 
-ifeq ($(enable_thread_safety), yes)
 OBJS += pthread-win32.o
 endif
-endif
 
 
 # Add libraries that libpq depends (or might depend) on into the
diff --git a/src/interfaces/libpq/fe-auth.c b/src/interfaces/libpq/fe-auth.c
index 49a1c626f6..3504ab2c34 100644
--- a/src/interfaces/libpq/fe-auth.c
+++ b/src/interfaces/libpq/fe-auth.c
@@ -1116,11 +1116,10 @@ pg_fe_getusername(uid_t user_id, PQExpBuffer errorMessage)
 #endif
 
 	/*
-	 * Some users are using configure --enable-thread-safety-force, so we
-	 * might as well do the locking within our library to protect getpwuid().
-	 * In fact, application developers can use getpwuid() in their application
-	 * if they use the locking call we provide, or install their own locking
-	 * function using PQregisterThreadLock().
+	 * We do the locking within our library to protect getpwuid().  Application
+	 * developers can use getpwuid() in their application if they use the
+	 * locking call we provide, or install their own locking function using
+	 * PQregisterThreadLock().
 	 */
 	pglock_thread();
 
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index dc49387d6c..7f14026777 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -55,13 +55,11 @@
 #endif
 #endif
 
-#ifdef ENABLE_THREAD_SAFETY
 #ifdef WIN32
 #include "pthread-win32.h"
 #else
 #include <pthread.h>
 #endif
-#endif
 
 #ifdef USE_LDAP
 #ifdef WIN32
@@ -7364,7 +7362,6 @@ pqGetHomeDirectory(char *buf, int bufsize)
 static void
 default_threadlock(int acquire)
 {
-#ifdef ENABLE_THREAD_SAFETY
 #ifndef WIN32
 	static pthread_mutex_t singlethread_lock = PTHREAD_MUTEX_INITIALIZER;
 #else
@@ -7393,7 +7390,6 @@ default_threadlock(int acquire)
 		if (pthread_mutex_unlock(&singlethread_lock))
 			Assert(false);
 	}
-#endif
 }
 
 pgthreadlock_t
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index e20d6177fe..37dc81bf17 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -3923,11 +3923,7 @@ PQisnonblocking(const PGconn *conn)
 int
 PQisthreadsafe(void)
 {
-#ifdef ENABLE_THREAD_SAFETY
 	return true;
-#else
-	return false;
-#endif
 }
 
 
diff --git a/src/interfaces/libpq/fe-print.c b/src/interfaces/libpq/fe-print.c
index 783cd9b756..2dc0f1afb9 100644
--- a/src/interfaces/libpq/fe-print.c
+++ b/src/interfaces/libpq/fe-print.c
@@ -88,14 +88,11 @@ PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
 		bool		usePipe = false;
 		char	   *pagerenv;
 
-#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
+#if !defined(WIN32)
 		sigset_t	osigset;
 		bool		sigpipe_masked = false;
 		bool		sigpipe_pending;
 #endif
-#if !defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
-		pqsigfunc	oldsigpipehandler = NULL;
-#endif
 
 #ifdef TIOCGWINSZ
 		struct winsize screen_size;
@@ -185,12 +182,8 @@ PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
 				{
 					usePipe = true;
 #ifndef WIN32
-#ifdef ENABLE_THREAD_SAFETY
 					if (pq_block_sigpipe(&osigset, &sigpipe_pending) == 0)
 						sigpipe_masked = true;
-#else
-					oldsigpipehandler = pqsignal(SIGPIPE, SIG_IGN);
-#endif							/* ENABLE_THREAD_SAFETY */
 #endif							/* WIN32 */
 				}
 				else
@@ -323,13 +316,9 @@ exit:
 #else
 			pclose(fout);
 
-#ifdef ENABLE_THREAD_SAFETY
 			/* we can't easily verify if EPIPE occurred, so say it did */
 			if (sigpipe_masked)
 				pq_reset_sigpipe(&osigset, sigpipe_pending, true);
-#else
-			pqsignal(SIGPIPE, oldsigpipehandler);
-#endif							/* ENABLE_THREAD_SAFETY */
 #endif							/* WIN32 */
 		}
 	}
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index 8117cbd40f..01b2494bb4 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -46,13 +46,11 @@
 
 #include <sys/stat.h>
 
-#ifdef ENABLE_THREAD_SAFETY
 #ifdef WIN32
 #include "pthread-win32.h"
 #else
 #include <pthread.h>
 #endif
-#endif
 
 /*
  * These SSL-related #includes must come after all system-provided headers.
@@ -93,7 +91,6 @@ static bool pq_init_crypto_lib = true;
 
 static bool ssl_lib_initialized = false;
 
-#ifdef ENABLE_THREAD_SAFETY
 static long crypto_open_connections = 0;
 
 #ifndef WIN32
@@ -102,7 +99,6 @@ static pthread_mutex_t ssl_config_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t ssl_config_mutex = NULL;
 static long win32_ssl_create_mutex = 0;
 #endif
-#endif							/* ENABLE_THREAD_SAFETY */
 
 static PQsslKeyPassHook_OpenSSL_type PQsslKeyPassHook = NULL;
 static int	ssl_protocol_version_to_openssl(const char *protocol);
@@ -114,15 +110,12 @@ static int	ssl_protocol_version_to_openssl(const char *protocol);
 void
 pgtls_init_library(bool do_ssl, int do_crypto)
 {
-#ifdef ENABLE_THREAD_SAFETY
-
 	/*
 	 * Disallow changing the flags while we have open connections, else we'd
 	 * get completely confused.
 	 */
 	if (crypto_open_connections != 0)
 		return;
-#endif
 
 	pq_init_ssl_lib = do_ssl;
 	pq_init_crypto_lib = do_crypto;
@@ -709,7 +702,7 @@ pgtls_verify_peer_name_matches_certificate_guts(PGconn *conn,
 	return rc;
 }
 
-#if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_CRYPTO_LOCK)
+#if defined(HAVE_CRYPTO_LOCK)
 /*
  *	Callback functions for OpenSSL internal locking.  (OpenSSL 1.1.0
  *	does its own locking, and doesn't need these anymore.  The
@@ -750,7 +743,7 @@ pq_lockingcallback(int mode, int n, const char *file, int line)
 			Assert(false);
 	}
 }
-#endif							/* ENABLE_THREAD_SAFETY && HAVE_CRYPTO_LOCK */
+#endif							/* HAVE_CRYPTO_LOCK */
 
 /*
  * Initialize SSL library.
@@ -765,7 +758,6 @@ pq_lockingcallback(int mode, int n, const char *file, int line)
 int
 pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto)
 {
-#ifdef ENABLE_THREAD_SAFETY
 #ifdef WIN32
 	/* Also see similar code in fe-connect.c, default_threadlock() */
 	if (ssl_config_mutex == NULL)
@@ -831,7 +823,6 @@ pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto)
 		}
 	}
 #endif							/* HAVE_CRYPTO_LOCK */
-#endif							/* ENABLE_THREAD_SAFETY */
 
 	if (!ssl_lib_initialized && do_ssl)
 	{
@@ -848,9 +839,7 @@ pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto)
 		ssl_lib_initialized = true;
 	}
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_unlock(&ssl_config_mutex);
-#endif
 	return 0;
 }
 
@@ -869,7 +858,7 @@ pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto)
 static void
 destroy_ssl_system(void)
 {
-#if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_CRYPTO_LOCK)
+#if defined(HAVE_CRYPTO_LOCK)
 	/* Mutex is created in pgtls_init() */
 	if (pthread_mutex_lock(&ssl_config_mutex))
 		return;
diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c
index a1dc7b796d..88607fb65b 100644
--- a/src/interfaces/libpq/fe-secure.c
+++ b/src/interfaces/libpq/fe-secure.c
@@ -37,13 +37,11 @@
 
 #include <sys/stat.h>
 
-#ifdef ENABLE_THREAD_SAFETY
 #ifdef WIN32
 #include "pthread-win32.h"
 #else
 #include <pthread.h>
 #endif
-#endif
 
 #include "fe-auth.h"
 #include "libpq-fe.h"
@@ -58,8 +56,6 @@
 
 #define SIGPIPE_MASKED(conn)	((conn)->sigpipe_so || (conn)->sigpipe_flag)
 
-#ifdef ENABLE_THREAD_SAFETY
-
 struct sigpipe_info
 {
 	sigset_t	oldsigmask;
@@ -92,24 +88,6 @@ struct sigpipe_info
 			pq_reset_sigpipe(&(spinfo).oldsigmask, (spinfo).sigpipe_pending, \
 							 (spinfo).got_epipe); \
 	} while (0)
-#else							/* !ENABLE_THREAD_SAFETY */
-
-#define DECLARE_SIGPIPE_INFO(spinfo) pqsigfunc spinfo = NULL
-
-#define DISABLE_SIGPIPE(conn, spinfo, failaction) \
-	do { \
-		if (!SIGPIPE_MASKED(conn)) \
-			spinfo = pqsignal(SIGPIPE, SIG_IGN); \
-	} while (0)
-
-#define REMEMBER_EPIPE(spinfo, cond)
-
-#define RESTORE_SIGPIPE(conn, spinfo) \
-	do { \
-		if (!SIGPIPE_MASKED(conn)) \
-			pqsignal(SIGPIPE, spinfo); \
-	} while (0)
-#endif							/* ENABLE_THREAD_SAFETY */
 #else							/* WIN32 */
 
 #define DECLARE_SIGPIPE_INFO(spinfo)
@@ -524,7 +502,7 @@ PQgssEncInUse(PGconn *conn)
 #endif							/* ENABLE_GSS */
 
 
-#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
+#if !defined(WIN32)
 
 /*
  *	Block SIGPIPE for this thread.  This prevents send()/write() from exiting
@@ -608,4 +586,4 @@ pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, bool got_epipe)
 	SOCK_ERRNO_SET(save_errno);
 }
 
-#endif							/* ENABLE_THREAD_SAFETY && !WIN32 */
+#endif							/* !WIN32 */
diff --git a/src/interfaces/libpq/legacy-pqsignal.c b/src/interfaces/libpq/legacy-pqsignal.c
index db470df9ea..1b4424eabb 100644
--- a/src/interfaces/libpq/legacy-pqsignal.c
+++ b/src/interfaces/libpq/legacy-pqsignal.c
@@ -27,10 +27,6 @@
  * Because it is only intended for backwards compatibility, we freeze it
  * with the semantics it had in 9.2; in particular, this has different
  * behavior for SIGALRM than the version in src/port/pqsignal.c.
- *
- * libpq itself uses this only for SIGPIPE (and even then, only in
- * non-ENABLE_THREAD_SAFETY builds), so the incompatibility isn't
- * troublesome for internal references.
  */
 pqsigfunc
 pqsignal(int signo, pqsigfunc func)
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index 51ab51f9f9..99c40af8cf 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -28,14 +28,12 @@
 #include <sys/time.h>
 #endif
 
-#ifdef ENABLE_THREAD_SAFETY
 #ifdef WIN32
 #include "pthread-win32.h"
 #else
 #include <pthread.h>
 #endif
 #include <signal.h>
-#endif
 
 /* include stuff common to fe and be */
 #include "getaddrinfo.h"
@@ -649,15 +647,10 @@ extern int	pqPacketSend(PGconn *conn, char pack_type,
 						 const void *buf, size_t buf_len);
 extern bool pqGetHomeDirectory(char *buf, int bufsize);
 
-#ifdef ENABLE_THREAD_SAFETY
 extern pgthreadlock_t pg_g_threadlock;
 
 #define pglock_thread()		pg_g_threadlock(true)
 #define pgunlock_thread()	pg_g_threadlock(false)
-#else
-#define pglock_thread()		((void) 0)
-#define pgunlock_thread()	((void) 0)
-#endif
 
 /* === in fe-exec.c === */
 
@@ -732,7 +725,7 @@ extern ssize_t pqsecure_write(PGconn *, const void *ptr, size_t len);
 extern ssize_t pqsecure_raw_read(PGconn *, void *ptr, size_t len);
 extern ssize_t pqsecure_raw_write(PGconn *, const void *ptr, size_t len);
 
-#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
+#if !defined(WIN32)
 extern int	pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending);
 extern void pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending,
 							 bool got_epipe);
diff --git a/src/port/getaddrinfo.c b/src/port/getaddrinfo.c
index bea7b520f0..8cb3a4db2f 100644
--- a/src/port/getaddrinfo.c
+++ b/src/port/getaddrinfo.c
@@ -414,7 +414,7 @@ pqGethostbyname(const char *name,
 				struct hostent **result,
 				int *herrno)
 {
-#if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_GETHOSTBYNAME_R)
+#if defined(HAVE_GETHOSTBYNAME_R)
 
 	/*
 	 * broken (well early POSIX draft) gethostbyname_r() which returns 'struct
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 1e83583e76..b64720f1c6 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -219,7 +219,6 @@ sub GenerateFiles
 		DLSUFFIX                   => '".dll"',
 		ENABLE_GSS                 => $self->{options}->{gss} ? 1 : undef,
 		ENABLE_NLS                 => $self->{options}->{nls} ? 1 : undef,
-		ENABLE_THREAD_SAFETY       => 1,
 		GETTIMEOFDAY_1ARG          => undef,
 		HAVE_APPEND_HISTORY        => undef,
 		HAVE_ASN1_STRING_GET0_DATA => undef,
@@ -1235,7 +1234,7 @@ sub GetFakeConfigure
 {
 	my $self = shift;
 
-	my $cfg = '--enable-thread-safety';
+	my $cfg = '';
 	$cfg .= ' --enable-cassert'   if ($self->{options}->{asserts});
 	$cfg .= ' --enable-nls'       if ($self->{options}->{nls});
 	$cfg .= ' --enable-tap-tests' if ($self->{options}->{tap_tests});
diff --git a/src/tools/msvc/ecpg_regression.proj b/src/tools/msvc/ecpg_regression.proj
index ec2760b1f6..0ec60a275e 100644
--- a/src/tools/msvc/ecpg_regression.proj
+++ b/src/tools/msvc/ecpg_regression.proj
@@ -54,7 +54,7 @@
 
   <!-- Run ECPG and the Visual C++ compiler on the files. Don't bother with dependency check between the steps -->
   <Exec WorkingDirectory="%(Pgc.RelativeDir)" Command="$(OUTDIR)ecpg\ecpg -I ../../include --regression $(ECPGPARAM) -o %(Pgc.Filename).c %(Pgc.Filename).pgc" />
-  <Exec WorkingDirectory="%(Pgc.RelativeDir)" Command="cl /nologo %(Pgc.FileName).c /TC /MD$(DEBUGLIB) /DENABLE_THREAD_SAFETY /DWIN32 /I. /I..\..\include /I..\..\..\libpq /I..\..\..\..\include /link /defaultlib:$(OUTDIR)libecpg\libecpg.lib /defaultlib:$(OUTDIR)libecpg_compat\libecpg_compat.lib /defaultlib:$(OUTDIR)libpgtypes\libpgtypes.lib" />
+  <Exec WorkingDirectory="%(Pgc.RelativeDir)" Command="cl /nologo %(Pgc.FileName).c /TC /MD$(DEBUGLIB) /DWIN32 /I. /I..\..\include /I..\..\..\libpq /I..\..\..\..\include /link /defaultlib:$(OUTDIR)libecpg\libecpg.lib /defaultlib:$(OUTDIR)libecpg_compat\libecpg_compat.lib /defaultlib:$(OUTDIR)libpgtypes\libpgtypes.lib" />
  </Target>
 
  <!-- Clean up all output files -->
-- 
2.36.1

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Thomas Munro (#1)
Re: Cleaning up historical portability baggage

Thomas Munro <thomas.munro@gmail.com> writes:

I wonder how much dead code for ancient operating systems we could now
drop.

+1, it seems like this is the cycle for some housecleaning.

* prairiedog, macOS 10.4 (vintage system most likely to cause problems)

FWIW, I am expecting to retire prairiedog once the meson stuff drops.
macOS 10.4 is incapable of running ninja (for lack of <spawn.h>).
While I could keep it working for awhile with the autoconf build system,
I'm not sure I see the point. The hardware is still chugging along,
but I think it'd be more useful to run up-to-date NetBSD or the like
on it.

Having said that, I'll be happy to try out this patch series on
that platform and see if it burps.

regards, tom lane

#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tom Lane (#2)
Re: Cleaning up historical portability baggage

I wrote:

Having said that, I'll be happy to try out this patch series on
that platform and see if it burps.

HEAD + patches 0001-0006 seems fine on prairiedog's host.
Builds clean (or as clean as HEAD does anyway), passes make check.
I did not trouble with check-world.

(I haven't actually read the patches, so this isn't a review,
just a quick smoke-test.)

regards, tom lane

#4Greg Stark
stark@mit.edu
In reply to: Thomas Munro (#1)
Re: Cleaning up historical portability baggage

On Sat, 9 Jul 2022 at 21:46, Thomas Munro <thomas.munro@gmail.com> wrote:

Hello,

I wonder how much dead code for ancient operating systems we could now
drop.

0002-Remove-dead-getrusage-replacement-code.patch

I thought the getrusage replacement code was for Windows. Does
getrusage on Windows actually do anything useful?

More generally I think there is a question about whether some of these
things are "supported" in only a minimal way to satisfy standards but
maybe not in a way that we actually want to use. Getrusage might exist
on Windows but not actually report the metrics we need, reentrant
library functions may be implemented by simply locking instead of
actually avoiding static storage, etc.

--
greg

#5Greg Stark
stark@mit.edu
In reply to: Greg Stark (#4)
Re: Cleaning up historical portability baggage

(Reading the patch it seems both those points are already addressed)

#6Robert Haas
robertmhaas@gmail.com
In reply to: Thomas Munro (#1)
Re: Cleaning up historical portability baggage

On Sat, Jul 9, 2022 at 9:46 PM Thomas Munro <thomas.munro@gmail.com> wrote:

The pwritev/preadv functions are unfortunately not standardised by
POSIX (I dunno why, it's the obvious combination of the p* and *v
functions) despite every OS in the list having them except for Solaris
and old macOS. Oh well.

I don't think that 0001 is buying us a whole lot, really. I prefer the
style where we have PG-specific functions that behave differently on
different platforms to the one where we call something that looks like
a native OS function call on all platforms but on some of them it is
secretly invoking a replacement implementation in src/port. The
problem with the latter is it looks like you're using something that's
universally supported and works the same way everywhere, but you're
really not. If it were up to me, we'd have more pg_whatever() that
calls whatever() on non-Windows and something else on Windows, rather
than going in the direction that this patch takes us.

I like all of the other patches. Reducing the number of configure
tests that we need seems like a really good idea.

--
Robert Haas
EDB: http://www.enterprisedb.com

#7Thomas Munro
thomas.munro@gmail.com
In reply to: Robert Haas (#6)
Re: Cleaning up historical portability baggage

On Tue, Jul 12, 2022 at 4:46 AM Robert Haas <robertmhaas@gmail.com> wrote:

I don't think that 0001 is buying us a whole lot, really. I prefer the
style where we have PG-specific functions that behave differently on
different platforms to the one where we call something that looks like
a native OS function call on all platforms but on some of them it is
secretly invoking a replacement implementation in src/port. The
problem with the latter is it looks like you're using something that's
universally supported and works the same way everywhere, but you're
really not. If it were up to me, we'd have more pg_whatever() that
calls whatever() on non-Windows and something else on Windows, rather
than going in the direction that this patch takes us.

Hmm, but that's not what we're doing in general. For example, on
Windows we're redirecting open() to a replacement function of our own,
we're not using "pg_open()" in our code. That's not an example based
on AC_REPLACE_FUNCS, but there are plenty of those too. Isn't this
quite well established?

AFAIK we generally only use pg_whatever() when there's a good reason,
such as an incompatibility, a complication or a different abstraction
that you want to highlight to a reader. The reason here was
temporary: we couldn't implement standard pread/pwrite perfectly on
ancient HP-UX, but we *can* implement it on Windows, so the reason is
gone.

These particular pg_ prefixes have only been in our tree for a few
years and I was hoping to boot them out again before they stick, like
"Size". I like using standard interfaces where possible for the very
basic stuff, to de-weird our stuff.

I like all of the other patches. Reducing the number of configure
tests that we need seems like a really good idea.

Thanks for looking. Yeah, we could also be a little more aggressive
about removing configure tests, in the cases where it's just Windows
vs !Windows. "HAVE_XXX" tests that are always true on POSIX systems
at the level we require would then be unnecessary.

#8Peter Eisentraut
peter.eisentraut@enterprisedb.com
In reply to: Thomas Munro (#7)
Re: Cleaning up historical portability baggage

On 12.07.22 03:10, Thomas Munro wrote:

AFAIK we generally only use pg_whatever() when there's a good reason,
such as an incompatibility, a complication or a different abstraction
that you want to highlight to a reader. The reason here was
temporary: we couldn't implement standard pread/pwrite perfectly on
ancient HP-UX, but we*can* implement it on Windows, so the reason is
gone.

These particular pg_ prefixes have only been in our tree for a few
years and I was hoping to boot them out again before they stick, like
"Size". I like using standard interfaces where possible for the very
basic stuff, to de-weird our stuff.

I agree. That's been the established approach.

#9Robert Haas
robertmhaas@gmail.com
In reply to: Thomas Munro (#7)
Re: Cleaning up historical portability baggage

On Mon, Jul 11, 2022 at 9:11 PM Thomas Munro <thomas.munro@gmail.com> wrote:

Hmm, but that's not what we're doing in general. For example, on
Windows we're redirecting open() to a replacement function of our own,
we're not using "pg_open()" in our code. That's not an example based
on AC_REPLACE_FUNCS, but there are plenty of those too. Isn't this
quite well established?

Yes. I just don't care for it.

Sounds like I'm in the minority, though.

--
Robert Haas
EDB: http://www.enterprisedb.com

#10Tom Lane
tgl@sss.pgh.pa.us
In reply to: Robert Haas (#9)
Re: Cleaning up historical portability baggage

Robert Haas <robertmhaas@gmail.com> writes:

On Mon, Jul 11, 2022 at 9:11 PM Thomas Munro <thomas.munro@gmail.com> wrote:

Hmm, but that's not what we're doing in general. For example, on
Windows we're redirecting open() to a replacement function of our own,
we're not using "pg_open()" in our code. That's not an example based
on AC_REPLACE_FUNCS, but there are plenty of those too. Isn't this
quite well established?

Yes. I just don't care for it.
Sounds like I'm in the minority, though.

I concur with your point that it's not great to use the standard name
for a function that doesn't have exactly the standard semantics.
But if it does, using a nonstandard name is not better. It's just one
more thing that readers of our code have to learn about.

Note that "exactly" only needs to mean "satisfies all the promises
made by POSIX". If some caller is depending on behavior details not
specified in the standard, that's the caller's bug not the wrapper
function's. Otherwise, yeah, we couldn't ever be sure whether a
wrapper function is close enough.

regards, tom lane

#11Andres Freund
andres@anarazel.de
In reply to: Robert Haas (#9)
Re: Cleaning up historical portability baggage

Hi,

On 2022-07-12 08:01:40 -0400, Robert Haas wrote:

On Mon, Jul 11, 2022 at 9:11 PM Thomas Munro <thomas.munro@gmail.com> wrote:

Hmm, but that's not what we're doing in general. For example, on
Windows we're redirecting open() to a replacement function of our own,
we're not using "pg_open()" in our code. That's not an example based
on AC_REPLACE_FUNCS, but there are plenty of those too. Isn't this
quite well established?

Yes. I just don't care for it.

Sounds like I'm in the minority, though.

I agree with you, at least largely.

Redefining functions, be it by linking in something or by redefining function
names via macros, is a mess. There's places where we then have to undefine
some of these things to be able to include external headers etc. Some
functions are only replaced in backends, others in frontend too. It makes it
hard to know what exactly the assumed set of platform primitives is. Etc.

Greetings,

Andres Freund

#12Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andres Freund (#11)
Re: Cleaning up historical portability baggage

Andres Freund <andres@anarazel.de> writes:

Redefining functions, be it by linking in something or by redefining function
names via macros, is a mess. There's places where we then have to undefine
some of these things to be able to include external headers etc. Some
functions are only replaced in backends, others in frontend too. It makes it
hard to know what exactly the assumed set of platform primitives is. Etc.

In the cases at hand, we aren't doing that, are we? The replacement
function is only used on platforms that lack the relevant POSIX function,
so it's hard to argue that we're replacing anything.

regards, tom lane

#13Thomas Munro
thomas.munro@gmail.com
In reply to: Tom Lane (#12)
13 attachment(s)
Re: Cleaning up historical portability baggage

I have committed the first few:

* "Remove dead getrusage replacement code."
* "Remove dead handling for pre-POSIX sigwait()."
* "Remove dead getpwuid_r replacement code."

Here are some more, a couple of which I posted before but I've now
gone a bit further with them in terms of removing configure checks
etc:

* "Remove dlopen configure probe."
* "Remove configure probe and extra tests for getrlimit."
* "Remove configure probe for shm_open."
* "Remove configure probe for setsid."
* "Remove configure probes for readlink, and dead code and docs."
* "Remove configure probe for symlink, and dead code."
* "Remove configure probe for link."
* "Remove dead replacement code for clock_gettime()."
* "Remove configure probes for poll and poll.h."
* "Remove dead setenv, unsetenv replacement code."
* "Remove dead pread and pwrite replacement code."
* "Simplify replacement code for preadv and pwritev."
* "Remove --disable-thread-safety."

Some of these depend on SUSv2 options (not just "base"), but we
already do that (fsync, ...) and they're all features that are by now
ubiquitous, which means the fallback code is untested and the probes
are pointless.

<archeology-mode>I'd guess the last system we ran on that didn't have
symlinks would have been SVr3-based SCO, HP-UX, DG/UX etc from the
1980s, since they were invented in 4.2BSD in 1983 and adopted by SVr4
in 1988. The RLIMIT_OFILE stuff seems to be referring to 1BSD or 2BSD
on a PDP, whereas RLIMIT_NOFILE was already used in 4.3BSD in 1986,
which I'd have guessed would be the oldest OS POSTGRES ever actually
ran on, so that must have been cargo culting from something older?</>

The clock_gettime() one only becomes committable once prairiedog's
host switched to NetBSD, so that'll be committed at the same time as
the fdatasync one from a nearby thread.

The setenv/unsetenv one levels up to SUSv3 (= POSIX issue 6, 2001).
That'd be the first time we don't point at SUSv2 (= POSIX issue 5,
199x) to justify a change like this.

I expect there to be further clean-up after the removal of
--disable-thread-safety.

Attachments:

0001-Remove-dlopen-configure-probe.patchtext/x-patch; charset=US-ASCII; name=0001-Remove-dlopen-configure-probe.patchDownload
From b2701bf5e9421ac6301697c56a45f5248351e063 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Tue, 19 Jul 2022 18:07:51 +1200
Subject: [PATCH 01/13] Remove dlopen configure probe.

dlopen() is in SUSv2 and all targeted Unix systems have it.  We still
need replacement functions for Windows, but we don't need a configure
probe for that.
---
 configure                      | 19 ++++++-------------
 configure.ac                   |  2 +-
 src/backend/utils/fmgr/dfmgr.c |  4 ++--
 src/include/pg_config.h.in     |  3 ---
 src/include/port.h             |  3 ++-
 src/port/dlopen.c              |  6 +-----
 src/tools/msvc/Solution.pm     |  1 -
 7 files changed, 12 insertions(+), 26 deletions(-)

diff --git a/configure b/configure
index c5bc382395..a2706684e3 100755
--- a/configure
+++ b/configure
@@ -16687,19 +16687,6 @@ $as_echo "#define HAVE_PS_STRINGS 1" >>confdefs.h
 
 fi
 
-ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
-if test "x$ac_cv_func_dlopen" = xyes; then :
-  $as_echo "#define HAVE_DLOPEN 1" >>confdefs.h
-
-else
-  case " $LIBOBJS " in
-  *" dlopen.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS dlopen.$ac_objext"
- ;;
-esac
-
-fi
-
 ac_fn_c_check_func "$LINENO" "explicit_bzero" "ac_cv_func_explicit_bzero"
 if test "x$ac_cv_func_explicit_bzero" = xyes; then :
   $as_echo "#define HAVE_EXPLICIT_BZERO 1" >>confdefs.h
@@ -17048,6 +17035,12 @@ fi
  ;;
 esac
 
+  case " $LIBOBJS " in
+  *" dlopen.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS dlopen.$ac_objext"
+ ;;
+esac
+
   case " $LIBOBJS " in
   *" fdatasync.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS fdatasync.$ac_objext"
diff --git a/configure.ac b/configure.ac
index 61d0dd5d58..0861a10ec3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1880,7 +1880,6 @@ if test "$pgac_cv_var_PS_STRINGS" = yes ; then
 fi
 
 AC_REPLACE_FUNCS(m4_normalize([
-	dlopen
 	explicit_bzero
 	getopt
 	getpeereid
@@ -1957,6 +1956,7 @@ if test "$PORTNAME" = "win32"; then
   AC_CHECK_FUNCS(_configthreadlocale)
   AC_REPLACE_FUNCS(gettimeofday)
   AC_LIBOBJ(dirmod)
+  AC_LIBOBJ(dlopen)
   AC_LIBOBJ(fdatasync)
   AC_LIBOBJ(getrusage)
   AC_LIBOBJ(kill)
diff --git a/src/backend/utils/fmgr/dfmgr.c b/src/backend/utils/fmgr/dfmgr.c
index 7f9ea97280..08fd7e1264 100644
--- a/src/backend/utils/fmgr/dfmgr.c
+++ b/src/backend/utils/fmgr/dfmgr.c
@@ -16,7 +16,7 @@
 
 #include <sys/stat.h>
 
-#ifdef HAVE_DLOPEN
+#ifndef WIN32
 #include <dlfcn.h>
 
 /*
@@ -28,7 +28,7 @@
 #undef bool
 #endif
 #endif
-#endif							/* HAVE_DLOPEN */
+#endif							/* !WIN32 */
 
 #include "fmgr.h"
 #include "lib/stringinfo.h"
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index f9618e1986..c213f31273 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -169,9 +169,6 @@
    don't. */
 #undef HAVE_DECL_STRTOULL
 
-/* Define to 1 if you have the `dlopen' function. */
-#undef HAVE_DLOPEN
-
 /* Define to 1 if you have the <editline/history.h> header file. */
 #undef HAVE_EDITLINE_HISTORY_H
 
diff --git a/src/include/port.h b/src/include/port.h
index d39b04141f..4532608bb3 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -455,7 +455,8 @@ extern int	setenv(const char *name, const char *value, int overwrite);
 extern int	unsetenv(const char *name);
 #endif
 
-#ifndef HAVE_DLOPEN
+#ifdef WIN32
+/* src/port/dlopen.c has an implementation of dlopen for Windows */
 extern void *dlopen(const char *file, int mode);
 extern void *dlsym(void *handle, const char *symbol);
 extern int	dlclose(void *handle);
diff --git a/src/port/dlopen.c b/src/port/dlopen.c
index 6ff9f4bf64..48aa37129d 100644
--- a/src/port/dlopen.c
+++ b/src/port/dlopen.c
@@ -1,7 +1,7 @@
 /*-------------------------------------------------------------------------
  *
  * dlopen.c
- *	  dynamic loader for platforms without dlopen()
+ *	  dynamic loader for Windows
  *
  * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
@@ -15,8 +15,6 @@
 
 #include "c.h"
 
-#if defined(WIN32)
-
 static char last_dyn_error[512];
 
 static void
@@ -93,5 +91,3 @@ dlopen(const char *file, int mode)
 	last_dyn_error[0] = 0;
 	return (void *) h;
 }
-
-#endif
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index b09872e018..ce56b23bba 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -251,7 +251,6 @@ sub GenerateFiles
 		HAVE_DECL_STRNLEN                           => 1,
 		HAVE_DECL_STRTOLL                           => 1,
 		HAVE_DECL_STRTOULL                          => 1,
-		HAVE_DLOPEN                                 => undef,
 		HAVE_EDITLINE_HISTORY_H                     => undef,
 		HAVE_EDITLINE_READLINE_H                    => undef,
 		HAVE_EXECINFO_H                             => undef,
-- 
2.30.2

0002-Remove-configure-probe-and-extra-tests-for-getrlimit.patchtext/x-patch; charset=US-ASCII; name=0002-Remove-configure-probe-and-extra-tests-for-getrlimit.patchDownload
From 29e9f6e44be1f9187c4ca661104794af2ee5a380 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 23 Jul 2022 21:34:14 +1200
Subject: [PATCH 02/13] Remove configure probe and extra tests for getrlimit.

getrlimit() is in SUSv2 and all targeted systems have it.

Furthermore, it's not necessary to test for RLIMIT_CORE, RLIMIT_STACK or
RLIMIT_NOFILE macros, since SUSv2 requires those and all targeted
systems have them.

Windows doesn't have getrlimit(), but we can just test WIN32 when doing
Unix-only stuff.
---
 configure                     |  2 +-
 configure.ac                  |  1 -
 src/backend/storage/file/fd.c | 12 ++++--------
 src/backend/tcop/postgres.c   | 10 +++-------
 src/bin/pg_ctl/pg_ctl.c       |  8 ++++----
 src/bin/pgbench/pgbench.c     | 10 +++-------
 src/include/pg_config.h.in    |  3 ---
 src/test/regress/pg_regress.c |  4 ++--
 src/tools/msvc/Solution.pm    |  1 -
 9 files changed, 17 insertions(+), 34 deletions(-)

diff --git a/configure b/configure
index a2706684e3..3abc028412 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 getrlimit inet_pton kqueue mbstowcs_l memset_s poll posix_fallocate ppoll pthread_is_threaded_np readlink readv setproctitle setproctitle_fast setsid shm_open 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 readlink readv setproctitle setproctitle_fast setsid shm_open strchrnul strsignal symlink 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"
diff --git a/configure.ac b/configure.ac
index 0861a10ec3..73242d76a6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1797,7 +1797,6 @@ AC_CHECK_FUNCS(m4_normalize([
 	fdatasync
 	getifaddrs
 	getpeerucred
-	getrlimit
 	inet_pton
 	kqueue
 	mbstowcs_l
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index f904f60c08..28401a8881 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -886,7 +886,7 @@ count_usable_fds(int max_to_probe, int *usable_fds, int *already_open)
 	int			highestfd = 0;
 	int			j;
 
-#ifdef HAVE_GETRLIMIT
+#ifndef WIN32
 	struct rlimit rlim;
 	int			getrlimit_status;
 #endif
@@ -894,22 +894,18 @@ count_usable_fds(int max_to_probe, int *usable_fds, int *already_open)
 	size = 1024;
 	fd = (int *) palloc(size * sizeof(int));
 
-#ifdef HAVE_GETRLIMIT
-#ifdef RLIMIT_NOFILE			/* most platforms use RLIMIT_NOFILE */
+#ifndef WIN32
 	getrlimit_status = getrlimit(RLIMIT_NOFILE, &rlim);
-#else							/* but BSD doesn't ... */
-	getrlimit_status = getrlimit(RLIMIT_OFILE, &rlim);
-#endif							/* RLIMIT_NOFILE */
 	if (getrlimit_status != 0)
 		ereport(WARNING, (errmsg("getrlimit failed: %m")));
-#endif							/* HAVE_GETRLIMIT */
+#endif							/* !WIN32 */
 
 	/* dup until failure or probe limit reached */
 	for (;;)
 	{
 		int			thisfd;
 
-#ifdef HAVE_GETRLIMIT
+#ifndef WIN32
 
 		/*
 		 * don't go beyond RLIMIT_NOFILE; causes irritating kernel logs on
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index bdb11f430f..e4e972cce0 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -4765,12 +4765,12 @@ forbidden_in_wal_sender(char firstchar)
 /*
  * Obtain platform stack depth limit (in bytes)
  *
- * Return -1 if unknown
+ * -1 for error, and errno is set.
  */
 long
 get_stack_depth_rlimit(void)
 {
-#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_STACK)
+#ifndef WIN32
 	static long val = 0;
 
 	/* This won't change after process launch, so check just once */
@@ -4789,13 +4789,9 @@ get_stack_depth_rlimit(void)
 			val = rlim.rlim_cur;
 	}
 	return val;
-#else							/* no getrlimit */
-#if defined(WIN32) || defined(__CYGWIN__)
+#else
 	/* On Windows we set the backend stack size in src/backend/Makefile */
 	return WIN32_STACK_RLIMIT;
-#else							/* not windows ... give up */
-	return -1;
-#endif
 #endif
 }
 
diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
index ef58883a5c..3157d51918 100644
--- a/src/bin/pg_ctl/pg_ctl.c
+++ b/src/bin/pg_ctl/pg_ctl.c
@@ -160,7 +160,7 @@ static bool wait_for_postmaster_stop(void);
 static bool wait_for_postmaster_promote(void);
 static bool postmaster_is_alive(pid_t pid);
 
-#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
+#ifndef WIN32
 static void unlimit_core_size(void);
 #endif
 
@@ -776,7 +776,7 @@ wait_for_postmaster_promote(void)
 }
 
 
-#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
+#ifndef WIN32
 static void
 unlimit_core_size(void)
 {
@@ -949,7 +949,7 @@ do_start(void)
 	if (exec_path == NULL)
 		exec_path = find_other_exec_or_die(argv0, "postgres", PG_BACKEND_VERSIONSTR);
 
-#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
+#ifndef WIN32
 	if (allow_core_files)
 		unlimit_core_size();
 #endif
@@ -2069,7 +2069,7 @@ do_help(void)
 	printf(_("If the -D option is omitted, the environment variable PGDATA is used.\n"));
 
 	printf(_("\nOptions for start or restart:\n"));
-#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
+#ifndef WIN32
 	printf(_("  -c, --core-files       allow postgres to produce core files\n"));
 #else
 	printf(_("  -c, --core-files       not applicable on this platform\n"));
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index bcaea8f5ea..71682a3300 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -6583,7 +6583,7 @@ main(int argc, char **argv)
 	int			i;
 	int			nclients_dealt;
 
-#ifdef HAVE_GETRLIMIT
+#ifndef WIN32
 	struct rlimit rlim;
 #endif
 
@@ -6661,12 +6661,8 @@ main(int argc, char **argv)
 				{
 					exit(1);
 				}
-#ifdef HAVE_GETRLIMIT
-#ifdef RLIMIT_NOFILE			/* most platforms use RLIMIT_NOFILE */
+#ifndef WIN32
 				if (getrlimit(RLIMIT_NOFILE, &rlim) == -1)
-#else							/* but BSD doesn't ... */
-				if (getrlimit(RLIMIT_OFILE, &rlim) == -1)
-#endif							/* RLIMIT_NOFILE */
 					pg_fatal("getrlimit failed: %m");
 				if (rlim.rlim_cur < nclients + 3)
 				{
@@ -6675,7 +6671,7 @@ main(int argc, char **argv)
 					pg_log_error_hint("Reduce number of clients, or use limit/ulimit to increase the system limit.");
 					exit(1);
 				}
-#endif							/* HAVE_GETRLIMIT */
+#endif							/* !WIN32 */
 				break;
 			case 'j':			/* jobs */
 				benchmarking_option_set = true;
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index c213f31273..8e9318904f 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -237,9 +237,6 @@
 /* Define to 1 if you have the `getpeerucred' function. */
 #undef HAVE_GETPEERUCRED
 
-/* Define to 1 if you have the `getrlimit' function. */
-#undef HAVE_GETRLIMIT
-
 /* Define to 1 if you have the `gettimeofday' function. */
 #undef HAVE_GETTIMEOFDAY
 
diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c
index 982801e029..d3505cd13b 100644
--- a/src/test/regress/pg_regress.c
+++ b/src/test/regress/pg_regress.c
@@ -129,7 +129,7 @@ static void psql_end_command(StringInfo buf, const char *database);
 /*
  * allow core files if possible.
  */
-#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
+#ifndef WIN32
 static void
 unlimit_core_size(void)
 {
@@ -2229,7 +2229,7 @@ regression_main(int argc, char *argv[],
 
 	initialize_environment();
 
-#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
+#ifndef WIN32
 	unlimit_core_size();
 #endif
 
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index ce56b23bba..1018b57f00 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -273,7 +273,6 @@ sub GenerateFiles
 		HAVE_GETOPT_LONG                            => undef,
 		HAVE_GETPEEREID                             => undef,
 		HAVE_GETPEERUCRED                           => undef,
-		HAVE_GETRLIMIT                              => undef,
 		HAVE_GETTIMEOFDAY                           => undef,
 		HAVE_GSSAPI_GSSAPI_H                        => undef,
 		HAVE_GSSAPI_H                               => undef,
-- 
2.30.2

0003-Remove-configure-probe-for-shm_open.patchtext/x-patch; charset=US-ASCII; name=0003-Remove-configure-probe-for-shm_open.patchDownload
From f313527fbbb455c11f6853f5f8fa034d4dbb32d2 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 23 Jul 2022 23:49:27 +1200
Subject: [PATCH 03/13] Remove configure probe for shm_open.

shm_open() is in SUSv2 (realtime) and all targeted Unix systems have it.
---
 configure                      | 2 +-
 configure.ac                   | 1 -
 src/bin/initdb/initdb.c        | 4 ++--
 src/include/pg_config.h.in     | 3 ---
 src/include/storage/dsm_impl.h | 5 -----
 src/tools/msvc/Solution.pm     | 1 -
 6 files changed, 3 insertions(+), 13 deletions(-)

diff --git a/configure b/configure
index 3abc028412..276fcb647c 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 setsid shm_open 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 readlink readv setproctitle setproctitle_fast setsid strchrnul strsignal symlink 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"
diff --git a/configure.ac b/configure.ac
index 73242d76a6..7ec30a7486 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1810,7 +1810,6 @@ AC_CHECK_FUNCS(m4_normalize([
 	setproctitle
 	setproctitle_fast
 	setsid
-	shm_open
 	strchrnul
 	strsignal
 	symlink
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 89b888eaa5..85fc95503a 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -55,7 +55,7 @@
 #include <signal.h>
 #include <time.h>
 
-#ifdef HAVE_SHM_OPEN
+#ifndef WIN32
 #include "sys/mman.h"
 #endif
 
@@ -849,7 +849,7 @@ set_null_conf(void)
 static const char *
 choose_dsm_implementation(void)
 {
-#if defined(HAVE_SHM_OPEN) && !defined(__sun__)
+#if !defined(WIN32) && !defined(__sun__)
 	int			ntries = 10;
 	pg_prng_state prng_state;
 
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 8e9318904f..922756568e 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -480,9 +480,6 @@
 /* Define to 1 if you have the `setsid' function. */
 #undef HAVE_SETSID
 
-/* Define to 1 if you have the `shm_open' function. */
-#undef HAVE_SHM_OPEN
-
 /* Define to 1 if the system has the type `socklen_t'. */
 #undef HAVE_SOCKLEN_T
 
diff --git a/src/include/storage/dsm_impl.h b/src/include/storage/dsm_impl.h
index c51584dc6a..223d4d05bc 100644
--- a/src/include/storage/dsm_impl.h
+++ b/src/include/storage/dsm_impl.h
@@ -27,14 +27,9 @@
 #define USE_DSM_WINDOWS
 #define DEFAULT_DYNAMIC_SHARED_MEMORY_TYPE		DSM_IMPL_WINDOWS
 #else
-#ifdef HAVE_SHM_OPEN
 #define USE_DSM_POSIX
 #define DEFAULT_DYNAMIC_SHARED_MEMORY_TYPE		DSM_IMPL_POSIX
-#endif
 #define USE_DSM_SYSV
-#ifndef DEFAULT_DYNAMIC_SHARED_MEMORY_TYPE
-#define DEFAULT_DYNAMIC_SHARED_MEMORY_TYPE		DSM_IMPL_SYSV
-#endif
 #define USE_DSM_MMAP
 #endif
 
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 1018b57f00..893feb6eaf 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -353,7 +353,6 @@ sub GenerateFiles
 		HAVE_SETPROCTITLE                        => undef,
 		HAVE_SETPROCTITLE_FAST                   => undef,
 		HAVE_SETSID                              => undef,
-		HAVE_SHM_OPEN                            => undef,
 		HAVE_SOCKLEN_T                           => 1,
 		HAVE_SPINLOCKS                           => 1,
 		HAVE_STDBOOL_H                           => 1,
-- 
2.30.2

0004-Remove-configure-probe-for-setsid.patchtext/x-patch; charset=US-ASCII; name=0004-Remove-configure-probe-for-setsid.patchDownload
From 57de5d03ef3b610d68783b975bab3f3c4f979020 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sun, 24 Jul 2022 00:54:07 +1200
Subject: [PATCH 04/13] Remove configure probe for setsid.

setsid() is in SUSv2 and all targeted Unix systems have it.  This can be
replaced with a test that we're not on Windows.
---
 configure                             | 2 +-
 configure.ac                          | 1 -
 src/backend/postmaster/postmaster.c   | 4 ++--
 src/backend/storage/ipc/procarray.c   | 2 +-
 src/backend/storage/ipc/signalfuncs.c | 2 +-
 src/backend/utils/init/miscinit.c     | 2 +-
 src/backend/utils/init/postinit.c     | 4 ++--
 src/bin/pg_ctl/pg_ctl.c               | 2 +-
 src/include/pg_config.h.in            | 3 ---
 src/tools/msvc/Solution.pm            | 1 -
 10 files changed, 9 insertions(+), 14 deletions(-)

diff --git a/configure b/configure
index 276fcb647c..62ff8250d4 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 setsid 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 readlink readv setproctitle setproctitle_fast strchrnul strsignal symlink 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"
diff --git a/configure.ac b/configure.ac
index 7ec30a7486..eb29046398 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1809,7 +1809,6 @@ AC_CHECK_FUNCS(m4_normalize([
 	readv
 	setproctitle
 	setproctitle_fast
-	setsid
 	strchrnul
 	strsignal
 	symlink
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 1c25457526..b67e82a969 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -4024,7 +4024,7 @@ PostmasterStateMachine(void)
 /*
  * Send a signal to a postmaster child process
  *
- * On systems that have setsid(), each child process sets itself up as a
+ * On Unix systems, each child process uses setsid() to set itself up as a
  * process group leader.  For signals that are generally interpreted in the
  * appropriate fashion, we signal the entire process group not just the
  * direct child process.  This allows us to, for example, SIGQUIT a blocked
@@ -4042,7 +4042,7 @@ signal_child(pid_t pid, int signal)
 {
 	if (kill(pid, signal) < 0)
 		elog(DEBUG3, "kill(%ld,%d) failed: %m", (long) pid, signal);
-#ifdef HAVE_SETSID
+#ifndef WIN32
 	switch (signal)
 	{
 		case SIGINT:
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index dadaa958a8..b680c14748 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -3869,7 +3869,7 @@ TerminateOtherDBBackends(Oid databaseId)
 				 * If we have setsid(), signal the backend's whole process
 				 * group
 				 */
-#ifdef HAVE_SETSID
+#ifndef WIN32
 				(void) kill(-pid, SIGTERM);
 #else
 				(void) kill(pid, SIGTERM);
diff --git a/src/backend/storage/ipc/signalfuncs.c b/src/backend/storage/ipc/signalfuncs.c
index 6e310b14eb..e2dfb4ff00 100644
--- a/src/backend/storage/ipc/signalfuncs.c
+++ b/src/backend/storage/ipc/signalfuncs.c
@@ -93,7 +93,7 @@ pg_signal_backend(int pid, int sig)
 	 */
 
 	/* If we have setsid(), signal the backend's whole process group */
-#ifdef HAVE_SETSID
+#ifndef WIN32
 	if (kill(-pid, sig))
 #else
 	if (kill(pid, sig))
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index eb43b2c5e5..70018ca5d0 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -145,7 +145,7 @@ InitPostmasterChild(void)
 	 * children, but for consistency we make all postmaster child processes do
 	 * this.
 	 */
-#ifdef HAVE_SETSID
+#ifndef WIN32
 	if (setsid() < 0)
 		elog(FATAL, "setsid() failed: %m");
 #endif
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index a5c208a20a..3c77b1aa60 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -1249,7 +1249,7 @@ StatementTimeoutHandler(void)
 	if (ClientAuthInProgress)
 		sig = SIGTERM;
 
-#ifdef HAVE_SETSID
+#ifndef WIN32
 	/* try to signal whole process group */
 	kill(-MyProcPid, sig);
 #endif
@@ -1262,7 +1262,7 @@ StatementTimeoutHandler(void)
 static void
 LockTimeoutHandler(void)
 {
-#ifdef HAVE_SETSID
+#ifndef WIN32
 	/* try to signal whole process group */
 	kill(-MyProcPid, SIGINT);
 #endif
diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
index 3157d51918..bb46723e3b 100644
--- a/src/bin/pg_ctl/pg_ctl.c
+++ b/src/bin/pg_ctl/pg_ctl.c
@@ -478,7 +478,7 @@ start_postmaster(void)
 	 * group and make it a group leader, so that it doesn't get signaled along
 	 * with the current group that launched it.
 	 */
-#ifdef HAVE_SETSID
+#ifndef WIN32
 	if (setsid() < 0)
 	{
 		write_stderr(_("%s: could not start server due to setsid() failure: %s\n"),
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 922756568e..9a3372f7de 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -477,9 +477,6 @@
 /* Define to 1 if you have the `setproctitle_fast' function. */
 #undef HAVE_SETPROCTITLE_FAST
 
-/* Define to 1 if you have the `setsid' function. */
-#undef HAVE_SETSID
-
 /* Define to 1 if the system has the type `socklen_t'. */
 #undef HAVE_SOCKLEN_T
 
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 893feb6eaf..e3b60a773a 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -352,7 +352,6 @@ sub GenerateFiles
 		HAVE_SETENV                              => undef,
 		HAVE_SETPROCTITLE                        => undef,
 		HAVE_SETPROCTITLE_FAST                   => undef,
-		HAVE_SETSID                              => undef,
 		HAVE_SOCKLEN_T                           => 1,
 		HAVE_SPINLOCKS                           => 1,
 		HAVE_STDBOOL_H                           => 1,
-- 
2.30.2

0005-Remove-configure-probes-for-readlink-and-dead-code-a.patchtext/x-patch; charset=US-ASCII; name=0005-Remove-configure-probes-for-readlink-and-dead-code-a.patchDownload
From 20df3fb6b0f2ab7f0391738a99958da91a22a114 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sun, 24 Jul 2022 01:03:11 +1200
Subject: [PATCH 05/13] Remove configure probes for readlink, and dead code and
 docs.

readlink() is in SUSv2 and all targeted Unix systems have it.
---
 configure                               |  2 +-
 configure.ac                            |  1 -
 doc/src/sgml/ref/create_tablespace.sgml |  4 ----
 src/backend/access/transam/xlog.c       | 12 ------------
 src/backend/replication/basebackup.c    | 13 -------------
 src/backend/utils/adt/misc.c            |  8 --------
 src/bin/initdb/findtimezone.c           |  2 +-
 src/bin/pg_rewind/file_ops.c            |  5 -----
 src/common/exec.c                       |  4 ++--
 src/include/pg_config.h.in              |  3 ---
 src/tools/msvc/Solution.pm              |  1 -
 11 files changed, 4 insertions(+), 51 deletions(-)

diff --git a/configure b/configure
index 62ff8250d4..6e10773263 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 symlink 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"
diff --git a/configure.ac b/configure.ac
index eb29046398..b4015aebb4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1805,7 +1805,6 @@ AC_CHECK_FUNCS(m4_normalize([
 	posix_fallocate
 	ppoll
 	pthread_is_threaded_np
-	readlink
 	readv
 	setproctitle
 	setproctitle_fast
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/replication/basebackup.c b/src/backend/replication/basebackup.c
index 637c0ce459..1a569e2582 100644
--- a/src/backend/replication/basebackup.c
+++ b/src/backend/replication/basebackup.c
@@ -1328,7 +1328,6 @@ sendDir(bbsink *sink, const char *path, int basepathlen, bool sizeonly,
 #endif
 			)
 		{
-#if defined(HAVE_READLINK) || defined(WIN32)
 			char		linkpath[MAXPGPATH];
 			int			rllen;
 
@@ -1347,18 +1346,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/findtimezone.c b/src/bin/initdb/findtimezone.c
index ddb65e6489..dc1d4e9a49 100644
--- a/src/bin/initdb/findtimezone.c
+++ b/src/bin/initdb/findtimezone.c
@@ -544,7 +544,7 @@ static bool
 check_system_link_file(const char *linkname, struct tztry *tt,
 					   char *bestzonename)
 {
-#ifdef HAVE_READLINK
+#ifndef WIN32
 	char		link_target[MAXPGPATH];
 	int			len;
 	const char *cur_name;
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..2a398f1eb1 100644
--- a/src/common/exec.c
+++ b/src/common/exec.c
@@ -254,7 +254,7 @@ find_my_exec(const char *argv0, char *retpath)
 static int
 resolve_symlinks(char *path)
 {
-#ifdef HAVE_READLINK
+#ifndef WIN32
 	struct stat buf;
 	char		orig_wd[MAXPGPATH],
 				link_buf[MAXPGPATH];
@@ -333,7 +333,7 @@ resolve_symlinks(char *path)
 				  _("could not change directory to \"%s\": %m"), orig_wd);
 		return -1;
 	}
-#endif							/* HAVE_READLINK */
+#endif							/* !WIN32 */
 
 	return 0;
 }
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 9a3372f7de..9fc0298f7d 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -435,9 +435,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
 
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index e3b60a773a..f9aec9494e 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -339,7 +339,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,
-- 
2.30.2

0006-Remove-configure-probe-for-symlink-and-dead-code.patchtext/x-patch; charset=US-ASCII; name=0006-Remove-configure-probe-for-symlink-and-dead-code.patchDownload
From 1c5a70717e6d20139d77fe1cba1f6c82da4d079e Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sun, 24 Jul 2022 01:12:31 +1200
Subject: [PATCH 06/13] Remove configure probe for symlink, and dead code.

symlink() is in SUSv2 and all targeted Unix systems have it.  Windows
doesn't have it, but we have replacement code that doesn't need a
configure probe.
---
 configure                             |  5 +----
 configure.ac                          |  3 ---
 src/backend/commands/tablespace.c     | 13 -------------
 src/bin/initdb/initdb.c               |  4 ----
 src/bin/pg_basebackup/pg_basebackup.c |  4 ----
 src/include/pg_config.h.in            |  3 ---
 src/timezone/zic.c                    | 10 ----------
 src/tools/msvc/Solution.pm            |  1 -
 8 files changed, 1 insertion(+), 42 deletions(-)

diff --git a/configure b/configure
index 6e10773263..b18198bf5f 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 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"
@@ -17107,9 +17107,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 b4015aebb4..a89992caf6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1810,7 +1810,6 @@ AC_CHECK_FUNCS(m4_normalize([
 	setproctitle_fast
 	strchrnul
 	strsignal
-	symlink
 	syncfs
 	sync_file_range
 	uselocale
@@ -1964,8 +1963,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/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c
index cb7d46089a..7ab6ec6d68 100644
--- a/src/backend/commands/tablespace.c
+++ b/src/backend/commands/tablespace.c
@@ -235,7 +235,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};
@@ -413,12 +412,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 */
 }
 
 /*
@@ -429,7 +422,6 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
 void
 DropTableSpace(DropTableSpaceStmt *stmt)
 {
-#ifdef HAVE_SYMLINK
 	char	   *tablespacename = stmt->tablespacename;
 	TableScanDesc scandesc;
 	Relation	rel;
@@ -595,11 +587,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/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 85fc95503a..3e607b824f 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/include/pg_config.h.in b/src/include/pg_config.h.in
index 9fc0298f7d..61634347d5 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -561,9 +561,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/timezone/zic.c b/src/timezone/zic.c
index 0ea6ead2db..2c55a009a8 100644
--- a/src/timezone/zic.c
+++ b/src/timezone/zic.c
@@ -944,7 +944,6 @@ namecheck(const char *name)
  * is relative to the global variable DIRECTORY.  TO can be either
  * relative or absolute.
  */
-#ifdef HAVE_SYMLINK
 static char *
 relname(char const *target, char const *linkname)
 {
@@ -986,7 +985,6 @@ relname(char const *target, char const *linkname)
 	}
 	return result;
 }
-#endif							/* HAVE_SYMLINK */
 
 /* Hard link FROM to TO, following any symbolic links.
    Return 0 if successful, an error number otherwise.  */
@@ -1038,7 +1036,6 @@ dolink(char const *target, char const *linkname, bool staysymlink)
 	}
 	if (link_errno != 0)
 	{
-#ifdef HAVE_SYMLINK
 		bool		absolute = *target == '/';
 		char	   *linkalloc = absolute ? NULL : relname(target, linkname);
 		char const *contents = absolute ? target : linkalloc;
@@ -1059,7 +1056,6 @@ dolink(char const *target, char const *linkname, bool staysymlink)
 						strerror(link_errno));
 		}
 		else
-#endif							/* HAVE_SYMLINK */
 		{
 			FILE	   *fp,
 					   *tp;
@@ -1090,11 +1086,9 @@ dolink(char const *target, char const *linkname, bool staysymlink)
 			if (link_errno != ENOTSUP)
 				warning(_("copy used because hard link failed: %s"),
 						strerror(link_errno));
-#ifdef HAVE_SYMLINK
 			else if (symlink_errno != ENOTSUP)
 				warning(_("copy used because symbolic link failed: %s"),
 						strerror(symlink_errno));
-#endif
 		}
 	}
 }
@@ -1128,13 +1122,9 @@ itsdir(char const *name)
 static bool
 itssymlink(char const *name)
 {
-#ifdef HAVE_SYMLINK
 	char		c;
 
 	return 0 <= readlink(name, &c, 1);
-#else
-	return false;
-#endif
 }
 
 /*
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index f9aec9494e..5030f63e9a 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -381,7 +381,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.30.2

0007-Remove-configure-probe-for-link.patchtext/x-patch; charset=US-ASCII; name=0007-Remove-configure-probe-for-link.patchDownload
From 66dc6f1601da55342702b604fc0e90adbdc99d83 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sun, 24 Jul 2022 01:19:05 +1200
Subject: [PATCH 07/13] Remove configure probe for link.

link() is in SUSv2 and all targeted Unix systems have it.  We have
replacement code for Windows that doesn't require a configure probe.
---
 configure                  | 19 ++++++-------------
 configure.ac               |  2 +-
 src/include/pg_config.h.in |  3 ---
 src/include/port.h         |  3 ++-
 src/port/link.c            |  4 ----
 src/tools/msvc/Solution.pm |  1 -
 6 files changed, 9 insertions(+), 23 deletions(-)

diff --git a/configure b/configure
index b18198bf5f..85efc8984d 100755
--- a/configure
+++ b/configure
@@ -16739,19 +16739,6 @@ esac
 
 fi
 
-ac_fn_c_check_func "$LINENO" "link" "ac_cv_func_link"
-if test "x$ac_cv_func_link" = xyes; then :
-  $as_echo "#define HAVE_LINK 1" >>confdefs.h
-
-else
-  case " $LIBOBJS " in
-  *" link.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS link.$ac_objext"
- ;;
-esac
-
-fi
-
 ac_fn_c_check_func "$LINENO" "mkdtemp" "ac_cv_func_mkdtemp"
 if test "x$ac_cv_func_mkdtemp" = xyes; then :
   $as_echo "#define HAVE_MKDTEMP 1" >>confdefs.h
@@ -17059,6 +17046,12 @@ esac
  ;;
 esac
 
+  case " $LIBOBJS " in
+  *" link.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS link.$ac_objext"
+ ;;
+esac
+
   case " $LIBOBJS " in
   *" open.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS open.$ac_objext"
diff --git a/configure.ac b/configure.ac
index a89992caf6..0fb7396669 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1879,7 +1879,6 @@ AC_REPLACE_FUNCS(m4_normalize([
 	getopt
 	getpeereid
 	inet_aton
-	link
 	mkdtemp
 	pread
 	pwrite
@@ -1955,6 +1954,7 @@ if test "$PORTNAME" = "win32"; then
   AC_LIBOBJ(fdatasync)
   AC_LIBOBJ(getrusage)
   AC_LIBOBJ(kill)
+  AC_LIBOBJ(link)
   AC_LIBOBJ(open)
   AC_LIBOBJ(system)
   AC_LIBOBJ(win32env)
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 61634347d5..ba9d702101 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -342,9 +342,6 @@
 /* Define to 1 if you have the `zstd' library (-lzstd). */
 #undef HAVE_LIBZSTD
 
-/* Define to 1 if you have the `link' function. */
-#undef HAVE_LINK
-
 /* Define to 1 if the system has the type `locale_t'. */
 #undef HAVE_LOCALE_T
 
diff --git a/src/include/port.h b/src/include/port.h
index 4532608bb3..666f6b04f9 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -402,7 +402,8 @@ extern float pg_strtof(const char *nptr, char **endptr);
 #define strtof(a,b) (pg_strtof((a),(b)))
 #endif
 
-#ifndef HAVE_LINK
+#ifdef WIN32
+/* replacement in src/port/link.c */
 extern int	link(const char *src, const char *dst);
 #endif
 
diff --git a/src/port/link.c b/src/port/link.c
index 1e0ccd4648..45517280db 100644
--- a/src/port/link.c
+++ b/src/port/link.c
@@ -14,8 +14,6 @@
 
 #include "c.h"
 
-#ifdef WIN32
-
 int
 link(const char *src, const char *dst)
 {
@@ -31,5 +29,3 @@ link(const char *src, const char *dst)
 	else
 		return 0;
 }
-
-#endif
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 5030f63e9a..d904f42d53 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -308,7 +308,6 @@ sub GenerateFiles
 		HAVE_LIBXSLT                                => undef,
 		HAVE_LIBZ                   => $self->{options}->{zlib} ? 1 : undef,
 		HAVE_LIBZSTD                => undef,
-		HAVE_LINK                   => undef,
 		HAVE_LOCALE_T               => 1,
 		HAVE_LONG_INT_64            => undef,
 		HAVE_LONG_LONG_INT_64       => 1,
-- 
2.30.2

0008-Remove-dead-replacement-code-for-clock_gettime.patchtext/x-patch; charset=US-ASCII; name=0008-Remove-dead-replacement-code-for-clock_gettime.patchDownload
From 7b15e84052c24baaa31404320058c4978fd566f2 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sun, 24 Jul 2022 00:12:37 +1200
Subject: [PATCH 08/13] Remove dead replacement code for clock_gettime().

clock_gettime() is in SUSv2 (realtime) and all targeted Unix systems
have it.  Fallback code for old Unix is no longer reachable on modern
systems, though we still need Windows-specific code.

XXX This will only be true once prairedog is decommissioned!
---
 configure                            |  2 +-
 configure.ac                         |  1 -
 src/include/pg_config.h.in           |  3 --
 src/include/portability/instr_time.h | 68 ----------------------------
 src/tools/msvc/Solution.pm           |  1 -
 5 files changed, 1 insertion(+), 74 deletions(-)

diff --git a/configure b/configure
index 85efc8984d..b6094c1a62 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 readv setproctitle setproctitle_fast strchrnul strsignal syncfs sync_file_range uselocale wcstombs_l writev
+for ac_func in backtrace_symbols 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"
diff --git a/configure.ac b/configure.ac
index 0fb7396669..27552e949e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1792,7 +1792,6 @@ LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'`
 
 AC_CHECK_FUNCS(m4_normalize([
 	backtrace_symbols
-	clock_gettime
 	copyfile
 	fdatasync
 	getifaddrs
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index ba9d702101..9c426ca8a0 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -83,9 +83,6 @@
 /* Define to 1 if you have the `BIO_meth_new' function. */
 #undef HAVE_BIO_METH_NEW
 
-/* Define to 1 if you have the `clock_gettime' function. */
-#undef HAVE_CLOCK_GETTIME
-
 /* Define to 1 if your compiler handles computed gotos. */
 #undef HAVE_COMPUTED_GOTO
 
diff --git a/src/include/portability/instr_time.h b/src/include/portability/instr_time.h
index ca09a1608f..8faeca8b49 100644
--- a/src/include/portability/instr_time.h
+++ b/src/include/portability/instr_time.h
@@ -57,8 +57,6 @@
 
 #ifndef WIN32
 
-#ifdef HAVE_CLOCK_GETTIME
-
 /* Use clock_gettime() */
 
 #include <time.h>
@@ -141,72 +139,6 @@ typedef struct timespec instr_time;
 #define INSTR_TIME_GET_MICROSEC(t) \
 	(((uint64) (t).tv_sec * (uint64) 1000000) + (uint64) ((t).tv_nsec / 1000))
 
-#else							/* !HAVE_CLOCK_GETTIME */
-
-/* Use gettimeofday() */
-
-#include <sys/time.h>
-
-typedef struct timeval instr_time;
-
-#define INSTR_TIME_IS_ZERO(t)	((t).tv_usec == 0 && (t).tv_sec == 0)
-
-#define INSTR_TIME_SET_ZERO(t)	((t).tv_sec = 0, (t).tv_usec = 0)
-
-#define INSTR_TIME_SET_CURRENT(t)	gettimeofday(&(t), NULL)
-
-#define INSTR_TIME_ADD(x,y) \
-	do { \
-		(x).tv_sec += (y).tv_sec; \
-		(x).tv_usec += (y).tv_usec; \
-		/* Normalize */ \
-		while ((x).tv_usec >= 1000000) \
-		{ \
-			(x).tv_usec -= 1000000; \
-			(x).tv_sec++; \
-		} \
-	} while (0)
-
-#define INSTR_TIME_SUBTRACT(x,y) \
-	do { \
-		(x).tv_sec -= (y).tv_sec; \
-		(x).tv_usec -= (y).tv_usec; \
-		/* Normalize */ \
-		while ((x).tv_usec < 0) \
-		{ \
-			(x).tv_usec += 1000000; \
-			(x).tv_sec--; \
-		} \
-	} while (0)
-
-#define INSTR_TIME_ACCUM_DIFF(x,y,z) \
-	do { \
-		(x).tv_sec += (y).tv_sec - (z).tv_sec; \
-		(x).tv_usec += (y).tv_usec - (z).tv_usec; \
-		/* Normalize after each add to avoid overflow/underflow of tv_usec */ \
-		while ((x).tv_usec < 0) \
-		{ \
-			(x).tv_usec += 1000000; \
-			(x).tv_sec--; \
-		} \
-		while ((x).tv_usec >= 1000000) \
-		{ \
-			(x).tv_usec -= 1000000; \
-			(x).tv_sec++; \
-		} \
-	} while (0)
-
-#define INSTR_TIME_GET_DOUBLE(t) \
-	(((double) (t).tv_sec) + ((double) (t).tv_usec) / 1000000.0)
-
-#define INSTR_TIME_GET_MILLISEC(t) \
-	(((double) (t).tv_sec * 1000.0) + ((double) (t).tv_usec) / 1000.0)
-
-#define INSTR_TIME_GET_MICROSEC(t) \
-	(((uint64) (t).tv_sec * (uint64) 1000000) + (uint64) (t).tv_usec)
-
-#endif							/* HAVE_CLOCK_GETTIME */
-
 #else							/* WIN32 */
 
 /* Use QueryPerformanceCounter() */
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index d904f42d53..8ccd9d6ab0 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -228,7 +228,6 @@ sub GenerateFiles
 		HAVE_BACKTRACE_SYMBOLS     => undef,
 		HAVE_BIO_GET_DATA          => undef,
 		HAVE_BIO_METH_NEW          => undef,
-		HAVE_CLOCK_GETTIME         => undef,
 		HAVE_COMPUTED_GOTO         => undef,
 		HAVE_COPYFILE              => undef,
 		HAVE_COPYFILE_H            => undef,
-- 
2.30.2

0009-Remove-configure-probes-for-poll-and-poll.h.patchtext/x-patch; charset=US-ASCII; name=0009-Remove-configure-probes-for-poll-and-poll.h.patchDownload
From 195cde040271967c6566d327cef1e01f9f4d178c Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sun, 24 Jul 2022 00:03:41 +1200
Subject: [PATCH 09/13] Remove configure probes for poll and poll.h.

poll() and <poll.h> are in SUSv2 (XSI) and all targeted Unix systems
have them.  Wherever we test HAVE_POLL or HAVE_POLL_H, we really mean
'not Windows' and alternative paths are not being tested on Unix.
---
 configure                       | 4 ++--
 configure.ac                    | 2 --
 src/backend/libpq/pqcomm.c      | 2 +-
 src/backend/storage/ipc/latch.c | 8 +++-----
 src/backend/utils/misc/guc.c    | 2 +-
 src/bin/pgbench/pgbench.c       | 2 --
 src/include/pg_config.h.in      | 6 ------
 src/interfaces/libpq/fe-misc.c  | 8 ++++----
 src/tools/msvc/Solution.pm      | 2 --
 9 files changed, 11 insertions(+), 25 deletions(-)

diff --git a/configure b/configure
index b6094c1a62..98affa21dd 100755
--- a/configure
+++ b/configure
@@ -13875,7 +13875,7 @@ $as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h
 fi
 
 
-for ac_header in atomic.h copyfile.h execinfo.h getopt.h ifaddrs.h langinfo.h mbarrier.h poll.h sys/epoll.h sys/event.h sys/ipc.h sys/personality.h sys/prctl.h sys/procctl.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/signalfd.h sys/sockio.h sys/uio.h sys/un.h termios.h ucred.h
+for ac_header in atomic.h copyfile.h execinfo.h getopt.h ifaddrs.h langinfo.h mbarrier.h sys/epoll.h sys/event.h sys/ipc.h sys/personality.h sys/prctl.h sys/procctl.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/signalfd.h sys/sockio.h sys/uio.h sys/un.h termios.h ucred.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@@ -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 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
+for ac_func in backtrace_symbols copyfile fdatasync getifaddrs getpeerucred inet_pton kqueue mbstowcs_l memset_s 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"
diff --git a/configure.ac b/configure.ac
index 27552e949e..18233608da 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1452,7 +1452,6 @@ AC_CHECK_HEADERS(m4_normalize([
 	ifaddrs.h
 	langinfo.h
 	mbarrier.h
-	poll.h
 	sys/epoll.h
 	sys/event.h
 	sys/ipc.h
@@ -1800,7 +1799,6 @@ AC_CHECK_FUNCS(m4_normalize([
 	kqueue
 	mbstowcs_l
 	memset_s
-	poll
 	posix_fallocate
 	ppoll
 	pthread_is_threaded_np
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 75392a8bb7..74ceb7e5f5 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -54,7 +54,7 @@
  */
 #include "postgres.h"
 
-#ifdef HAVE_POLL_H
+#ifndef WIN32
 #include <poll.h>
 #endif
 #include <signal.h>
diff --git a/src/backend/storage/ipc/latch.c b/src/backend/storage/ipc/latch.c
index eb3a569aae..d0e05eefb6 100644
--- a/src/backend/storage/ipc/latch.c
+++ b/src/backend/storage/ipc/latch.c
@@ -46,7 +46,7 @@
 #ifdef HAVE_SYS_SIGNALFD_H
 #include <sys/signalfd.h>
 #endif
-#ifdef HAVE_POLL_H
+#ifndef WIN32
 #include <poll.h>
 #endif
 
@@ -76,12 +76,10 @@
 #define WAIT_USE_EPOLL
 #elif defined(HAVE_KQUEUE)
 #define WAIT_USE_KQUEUE
-#elif defined(HAVE_POLL)
-#define WAIT_USE_POLL
-#elif WIN32
+#elif defined(WIN32)
 #define WAIT_USE_WIN32
 #else
-#error "no wait set implementation available"
+#define WAIT_USE_POLL
 #endif
 
 /*
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index af4a1c3068..7c42c74ed8 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -20,7 +20,7 @@
 #include <float.h>
 #include <math.h>
 #include <limits.h>
-#ifdef HAVE_POLL_H
+#ifndef WIN32
 #include <poll.h>
 #endif
 #ifndef WIN32
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 71682a3300..e48d4f5053 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -47,9 +47,7 @@
 /* For testing, PGBENCH_USE_SELECT can be defined to force use of that code */
 #if defined(HAVE_PPOLL) && !defined(PGBENCH_USE_SELECT)
 #define POLL_USING_PPOLL
-#ifdef HAVE_POLL_H
 #include <poll.h>
-#endif
 #else							/* no ppoll(), so use select() */
 #define POLL_USING_SELECT
 #ifdef HAVE_SYS_SELECT_H
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 9c426ca8a0..be96c292be 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -381,12 +381,6 @@
 /* Define to 1 if you have the <pam/pam_appl.h> header file. */
 #undef HAVE_PAM_PAM_APPL_H
 
-/* Define to 1 if you have the `poll' function. */
-#undef HAVE_POLL
-
-/* Define to 1 if you have the <poll.h> header file. */
-#undef HAVE_POLL_H
-
 /* Define to 1 if you have the `posix_fadvise' function. */
 #undef HAVE_POSIX_FADVISE
 
diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c
index d76bb3957a..86a36cb60c 100644
--- a/src/interfaces/libpq/fe-misc.c
+++ b/src/interfaces/libpq/fe-misc.c
@@ -40,7 +40,7 @@
 #include <sys/time.h>
 #endif
 
-#ifdef HAVE_POLL_H
+#ifndef WIN32
 #include <poll.h>
 #endif
 #ifdef HAVE_SYS_SELECT_H
@@ -1095,7 +1095,7 @@ static int
 pqSocketPoll(int sock, int forRead, int forWrite, time_t end_time)
 {
 	/* We use poll(2) if available, otherwise select(2) */
-#ifdef HAVE_POLL
+#ifndef WIN32
 	struct pollfd input_fd;
 	int			timeout_ms;
 
@@ -1125,7 +1125,7 @@ pqSocketPoll(int sock, int forRead, int forWrite, time_t end_time)
 	}
 
 	return poll(&input_fd, 1, timeout_ms);
-#else							/* !HAVE_POLL */
+#else							/* WIN32 */
 
 	fd_set		input_mask;
 	fd_set		output_mask;
@@ -1163,7 +1163,7 @@ pqSocketPoll(int sock, int forRead, int forWrite, time_t end_time)
 
 	return select(sock + 1, &input_mask, &output_mask,
 				  &except_mask, ptr_timeout);
-#endif							/* HAVE_POLL */
+#endif							/* WIN32 */
 }
 
 
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 8ccd9d6ab0..6e6c7126d4 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -321,8 +321,6 @@ sub GenerateFiles
 		HAVE_OPENSSL_INIT_SSL       => undef,
 		HAVE_OSSP_UUID_H            => undef,
 		HAVE_PAM_PAM_APPL_H         => undef,
-		HAVE_POLL                   => undef,
-		HAVE_POLL_H                 => undef,
 		HAVE_POSIX_FADVISE          => undef,
 		HAVE_POSIX_FALLOCATE        => undef,
 		HAVE_PPC_LWARX_MUTEX_HINT   => undef,
-- 
2.30.2

0010-Remove-dead-setenv-unsetenv-replacement-code.patchtext/x-patch; charset=US-ASCII; name=0010-Remove-dead-setenv-unsetenv-replacement-code.patchDownload
From 1b99146ceff694ad4422388a90639ace08d774ea Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 9 Jul 2022 23:00:49 +1200
Subject: [PATCH 10/13] Remove dead setenv, unsetenv replacement code.

setenv() and unsetenv() are in SUSv3 and targeted Unix systems have
them.  We still need special code for these on Windows, but that doesn't
require a configure probe.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Greg Stark <stark@mit.edu>
Reviewed-by: Robert Haas <robertmhaas@gmail.com>
Discussion: https://postgr.es/m/CA+hUKGJ3LHeP9w5Fgzdr4G8AnEtJ=z=p6hGDEm4qYGEUX5B6fQ@mail.gmail.com
---
 configure                  | 43 -------------------------
 configure.ac               | 13 --------
 src/include/pg_config.h.in |  6 ----
 src/include/port.h         |  6 ++--
 src/port/setenv.c          | 48 ----------------------------
 src/port/unsetenv.c        | 65 --------------------------------------
 src/tools/msvc/Solution.pm |  2 --
 7 files changed, 2 insertions(+), 181 deletions(-)
 delete mode 100644 src/port/setenv.c
 delete mode 100644 src/port/unsetenv.c

diff --git a/configure b/configure
index 98affa21dd..82443d3edb 100755
--- a/configure
+++ b/configure
@@ -16865,49 +16865,6 @@ esac
 $as_echo "$as_me: On $host_os we will use our strtof wrapper." >&6;}
 fi
 
-case $host_os in
-        # Windows uses a specialised env handler
-        mingw*)
-
-$as_echo "#define HAVE_SETENV 1" >>confdefs.h
-
-
-$as_echo "#define HAVE_UNSETENV 1" >>confdefs.h
-
-                ac_cv_func_setenv=yes
-                ac_cv_func_unsetenv=yes
-                ;;
-        *)
-                ac_fn_c_check_func "$LINENO" "setenv" "ac_cv_func_setenv"
-if test "x$ac_cv_func_setenv" = xyes; then :
-  $as_echo "#define HAVE_SETENV 1" >>confdefs.h
-
-else
-  case " $LIBOBJS " in
-  *" setenv.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS setenv.$ac_objext"
- ;;
-esac
-
-fi
-
-ac_fn_c_check_func "$LINENO" "unsetenv" "ac_cv_func_unsetenv"
-if test "x$ac_cv_func_unsetenv" = xyes; then :
-  $as_echo "#define HAVE_UNSETENV 1" >>confdefs.h
-
-else
-  case " $LIBOBJS " in
-  *" unsetenv.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS unsetenv.$ac_objext"
- ;;
-esac
-
-fi
-
-
-                ;;
-esac
-
 # System's version of getaddrinfo(), if any, may be used only if we found
 # a definition for struct addrinfo; see notes in src/include/getaddrinfo.h.
 # We use only our own getaddrinfo.c on Windows, but it's time to revisit that.
diff --git a/configure.ac b/configure.ac
index 18233608da..c1a93dff20 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1899,19 +1899,6 @@ if test "$PORTNAME" = "win32" -o "$PORTNAME" = "cygwin"; then
 	AC_MSG_NOTICE([On $host_os we will use our strtof wrapper.])
 fi
 
-case $host_os in
-        # Windows uses a specialised env handler
-        mingw*)
-                AC_DEFINE(HAVE_SETENV, 1, [Define to 1 because replacement version used.])
-                AC_DEFINE(HAVE_UNSETENV, 1, [Define to 1 because replacement version used.])
-                ac_cv_func_setenv=yes
-                ac_cv_func_unsetenv=yes
-                ;;
-        *)
-                AC_REPLACE_FUNCS([setenv unsetenv])
-                ;;
-esac
-
 # System's version of getaddrinfo(), if any, may be used only if we found
 # a definition for struct addrinfo; see notes in src/include/getaddrinfo.h.
 # We use only our own getaddrinfo.c on Windows, but it's time to revisit that.
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index be96c292be..6ea38998f8 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -453,9 +453,6 @@
 /* Define to 1 if you have the <security/pam_appl.h> header file. */
 #undef HAVE_SECURITY_PAM_APPL_H
 
-/* Define to 1 if you have the `setenv' function. */
-#undef HAVE_SETENV
-
 /* Define to 1 if you have the `setproctitle' function. */
 #undef HAVE_SETPROCTITLE
 
@@ -630,9 +627,6 @@
 /* Define to 1 if you have the <unistd.h> header file. */
 #undef HAVE_UNISTD_H
 
-/* Define to 1 if you have the `unsetenv' function. */
-#undef HAVE_UNSETENV
-
 /* Define to 1 if you have the `uselocale' function. */
 #undef HAVE_USELOCALE
 
diff --git a/src/include/port.h b/src/include/port.h
index 666f6b04f9..a8d9a64799 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -448,11 +448,9 @@ extern size_t strlcpy(char *dst, const char *src, size_t siz);
 extern size_t strnlen(const char *str, size_t maxlen);
 #endif
 
-#ifndef HAVE_SETENV
+#ifdef WIN32
+/* src/port/win32env.c has these for Windows */
 extern int	setenv(const char *name, const char *value, int overwrite);
-#endif
-
-#ifndef HAVE_UNSETENV
 extern int	unsetenv(const char *name);
 #endif
 
diff --git a/src/port/setenv.c b/src/port/setenv.c
deleted file mode 100644
index d13c882467..0000000000
--- a/src/port/setenv.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * setenv.c
- *	  setenv() emulation for machines without it
- *
- * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- *
- * IDENTIFICATION
- *	  src/port/setenv.c
- *
- *-------------------------------------------------------------------------
- */
-
-#include "c.h"
-
-
-int
-setenv(const char *name, const char *value, int overwrite)
-{
-	char	   *envstr;
-
-	/* Error conditions, per POSIX */
-	if (name == NULL || name[0] == '\0' || strchr(name, '=') != NULL ||
-		value == NULL)
-	{
-		errno = EINVAL;
-		return -1;
-	}
-
-	/* No work if variable exists and we're not to replace it */
-	if (overwrite == 0 && getenv(name) != NULL)
-		return 0;
-
-	/*
-	 * Add or replace the value using putenv().  This will leak memory if the
-	 * same variable is repeatedly redefined, but there's little we can do
-	 * about that when sitting atop putenv().
-	 */
-	envstr = (char *) malloc(strlen(name) + strlen(value) + 2);
-	if (!envstr)				/* not much we can do if no memory */
-		return -1;
-
-	sprintf(envstr, "%s=%s", name, value);
-
-	return putenv(envstr);
-}
diff --git a/src/port/unsetenv.c b/src/port/unsetenv.c
deleted file mode 100644
index 62b806d796..0000000000
--- a/src/port/unsetenv.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * unsetenv.c
- *	  unsetenv() emulation for machines without it
- *
- * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- *
- * IDENTIFICATION
- *	  src/port/unsetenv.c
- *
- *-------------------------------------------------------------------------
- */
-
-#include "c.h"
-
-
-int
-unsetenv(const char *name)
-{
-	char	   *envstr;
-
-	/* Error conditions, per POSIX */
-	if (name == NULL || name[0] == '\0' || strchr(name, '=') != NULL)
-	{
-		errno = EINVAL;
-		return -1;
-	}
-
-	if (getenv(name) == NULL)
-		return 0;				/* no work */
-
-	/*
-	 * The technique embodied here works if libc follows the Single Unix Spec
-	 * and actually uses the storage passed to putenv() to hold the environ
-	 * entry.  When we clobber the entry in the second step we are ensuring
-	 * that we zap the actual environ member.  However, there are some libc
-	 * implementations (notably recent BSDs) that do not obey SUS but copy the
-	 * presented string.  This method fails on such platforms.  Hopefully all
-	 * such platforms have unsetenv() and thus won't be using this hack. See:
-	 * http://www.greenend.org.uk/rjk/2008/putenv.html
-	 *
-	 * Note that repeatedly setting and unsetting a var using this code will
-	 * leak memory.
-	 */
-
-	envstr = (char *) malloc(strlen(name) + 2);
-	if (!envstr)				/* not much we can do if no memory */
-		return -1;
-
-	/* Override the existing setting by forcibly defining the var */
-	sprintf(envstr, "%s=", name);
-	if (putenv(envstr))
-		return -1;
-
-	/* Now we can clobber the variable definition this way: */
-	strcpy(envstr, "=");
-
-	/*
-	 * This last putenv cleans up if we have multiple zero-length names as a
-	 * result of unsetting multiple things.
-	 */
-	return putenv(envstr);
-}
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 6e6c7126d4..0d4ca94e7f 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -344,7 +344,6 @@ sub GenerateFiles
 		HAVE_RL_RESET_SCREEN_SIZE                => undef,
 		HAVE_RL_VARIABLE_BIND                    => undef,
 		HAVE_SECURITY_PAM_APPL_H                 => undef,
-		HAVE_SETENV                              => undef,
 		HAVE_SETPROCTITLE                        => undef,
 		HAVE_SETPROCTITLE_FAST                   => undef,
 		HAVE_SOCKLEN_T                           => 1,
@@ -403,7 +402,6 @@ sub GenerateFiles
 		HAVE_UINT8                               => undef,
 		HAVE_UNION_SEMUN                         => undef,
 		HAVE_UNISTD_H                            => 1,
-		HAVE_UNSETENV                            => undef,
 		HAVE_USELOCALE                           => undef,
 		HAVE_UUID_BSD                            => undef,
 		HAVE_UUID_E2FS                           => undef,
-- 
2.30.2

0011-Remove-dead-pread-and-pwrite-replacement-code.patchtext/x-patch; charset=US-ASCII; name=0011-Remove-dead-pread-and-pwrite-replacement-code.patchDownload
From 057674c17f6db4591da1cdf7a4a5cde3c6f98ec1 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 9 Jul 2022 21:31:56 +1200
Subject: [PATCH 11/13] Remove dead pread and pwrite replacement code.

pread() and pwrite() are in SUSv2 (XSI option) and SUSv4 (base), and all
targeted Unix systems have them.

Previously, we defined pg_pread and pg_pwrite to emulate these function
with lseek() on old Unixen.  The names with a pg_ prefix were a reminder
of a portability hazard: they might change the current file position.
That hazard is gone, so we can drop the prefixes.

We still have replacement code for Windows, but the configure probes are
no longer needed.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Greg Stark <stark@mit.edu>
Reviewed-by: Robert Haas <robertmhaas@gmail.com>
Discussion: https://postgr.es/m/CA+hUKGJ3LHeP9w5Fgzdr4G8AnEtJ=z=p6hGDEm4qYGEUX5B6fQ@mail.gmail.com
---
 configure                                     | 38 +++++---------
 configure.ac                                  |  4 +-
 .../pg_stat_statements/pg_stat_statements.c   |  4 +-
 src/backend/access/heap/rewriteheap.c         |  2 +-
 src/backend/access/transam/slru.c             |  4 +-
 src/backend/access/transam/xlog.c             |  4 +-
 src/backend/access/transam/xlogreader.c       |  2 +-
 src/backend/access/transam/xlogrecovery.c     |  2 +-
 src/backend/replication/basebackup.c          |  2 +-
 src/backend/replication/walreceiver.c         |  2 +-
 src/backend/storage/file/fd.c                 |  4 +-
 src/backend/utils/init/miscinit.c             |  2 +-
 src/bin/pg_test_fsync/pg_test_fsync.c         | 50 +++++++++----------
 src/include/access/xlogreader.h               |  4 +-
 src/include/pg_config.h.in                    |  6 ---
 src/include/port.h                            | 18 ++-----
 src/port/pread.c                              | 18 +------
 src/port/preadv.c                             |  4 +-
 src/port/pwrite.c                             | 18 +------
 src/port/pwritev.c                            |  4 +-
 src/tools/msvc/Solution.pm                    |  2 -
 21 files changed, 68 insertions(+), 126 deletions(-)

diff --git a/configure b/configure
index 82443d3edb..3c7ae744ca 100755
--- a/configure
+++ b/configure
@@ -16752,32 +16752,6 @@ esac
 
 fi
 
-ac_fn_c_check_func "$LINENO" "pread" "ac_cv_func_pread"
-if test "x$ac_cv_func_pread" = xyes; then :
-  $as_echo "#define HAVE_PREAD 1" >>confdefs.h
-
-else
-  case " $LIBOBJS " in
-  *" pread.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS pread.$ac_objext"
- ;;
-esac
-
-fi
-
-ac_fn_c_check_func "$LINENO" "pwrite" "ac_cv_func_pwrite"
-if test "x$ac_cv_func_pwrite" = xyes; then :
-  $as_echo "#define HAVE_PWRITE 1" >>confdefs.h
-
-else
-  case " $LIBOBJS " in
-  *" pwrite.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS pwrite.$ac_objext"
- ;;
-esac
-
-fi
-
 ac_fn_c_check_func "$LINENO" "strlcat" "ac_cv_func_strlcat"
 if test "x$ac_cv_func_strlcat" = xyes; then :
   $as_echo "#define HAVE_STRLCAT 1" >>confdefs.h
@@ -17015,6 +16989,18 @@ esac
  ;;
 esac
 
+  case " $LIBOBJS " in
+  *" pread.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS pread.$ac_objext"
+ ;;
+esac
+
+  case " $LIBOBJS " in
+  *" pwrite.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS pwrite.$ac_objext"
+ ;;
+esac
+
   case " $LIBOBJS " in
   *" system.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS system.$ac_objext"
diff --git a/configure.ac b/configure.ac
index c1a93dff20..bc8534717d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1877,8 +1877,6 @@ AC_REPLACE_FUNCS(m4_normalize([
 	getpeereid
 	inet_aton
 	mkdtemp
-	pread
-	pwrite
 	strlcat
 	strlcpy
 	strnlen
@@ -1940,6 +1938,8 @@ if test "$PORTNAME" = "win32"; then
   AC_LIBOBJ(kill)
   AC_LIBOBJ(link)
   AC_LIBOBJ(open)
+  AC_LIBOBJ(pread)
+  AC_LIBOBJ(pwrite)
   AC_LIBOBJ(system)
   AC_LIBOBJ(win32env)
   AC_LIBOBJ(win32error)
diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c
index 049da9fe6d..0d72ea212e 100644
--- a/contrib/pg_stat_statements/pg_stat_statements.c
+++ b/contrib/pg_stat_statements/pg_stat_statements.c
@@ -2091,9 +2091,9 @@ qtext_store(const char *query, int query_len,
 	if (fd < 0)
 		goto error;
 
-	if (pg_pwrite(fd, query, query_len, off) != query_len)
+	if (pwrite(fd, query, query_len, off) != query_len)
 		goto error;
-	if (pg_pwrite(fd, "\0", 1, off + query_len) != 1)
+	if (pwrite(fd, "\0", 1, off + query_len) != 1)
 		goto error;
 
 	CloseTransientFile(fd);
diff --git a/src/backend/access/heap/rewriteheap.c b/src/backend/access/heap/rewriteheap.c
index 197f06b5ec..9dd885d936 100644
--- a/src/backend/access/heap/rewriteheap.c
+++ b/src/backend/access/heap/rewriteheap.c
@@ -1149,7 +1149,7 @@ heap_xlog_logical_rewrite(XLogReaderState *r)
 	/* write out tail end of mapping file (again) */
 	errno = 0;
 	pgstat_report_wait_start(WAIT_EVENT_LOGICAL_REWRITE_MAPPING_WRITE);
-	if (pg_pwrite(fd, data, len, xlrec->offset) != len)
+	if (pwrite(fd, data, len, xlrec->offset) != len)
 	{
 		/* if write didn't set errno, assume problem is no disk space */
 		if (errno == 0)
diff --git a/src/backend/access/transam/slru.c b/src/backend/access/transam/slru.c
index b65cb49d7f..c9a7b97949 100644
--- a/src/backend/access/transam/slru.c
+++ b/src/backend/access/transam/slru.c
@@ -718,7 +718,7 @@ SlruPhysicalReadPage(SlruCtl ctl, int pageno, int slotno)
 
 	errno = 0;
 	pgstat_report_wait_start(WAIT_EVENT_SLRU_READ);
-	if (pg_pread(fd, shared->page_buffer[slotno], BLCKSZ, offset) != BLCKSZ)
+	if (pread(fd, shared->page_buffer[slotno], BLCKSZ, offset) != BLCKSZ)
 	{
 		pgstat_report_wait_end();
 		slru_errcause = SLRU_READ_FAILED;
@@ -873,7 +873,7 @@ SlruPhysicalWritePage(SlruCtl ctl, int pageno, int slotno, SlruWriteAll fdata)
 
 	errno = 0;
 	pgstat_report_wait_start(WAIT_EVENT_SLRU_WRITE);
-	if (pg_pwrite(fd, shared->page_buffer[slotno], BLCKSZ, offset) != BLCKSZ)
+	if (pwrite(fd, shared->page_buffer[slotno], BLCKSZ, offset) != BLCKSZ)
 	{
 		pgstat_report_wait_end();
 		/* if write didn't set errno, assume problem is no disk space */
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 26fbed00a4..eb5115fd5a 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -2189,7 +2189,7 @@ XLogWrite(XLogwrtRqst WriteRqst, TimeLineID tli, bool flexible)
 					INSTR_TIME_SET_CURRENT(start);
 
 				pgstat_report_wait_start(WAIT_EVENT_WAL_WRITE);
-				written = pg_pwrite(openLogFile, from, nleft, startoffset);
+				written = pwrite(openLogFile, from, nleft, startoffset);
 				pgstat_report_wait_end();
 
 				/*
@@ -3011,7 +3011,7 @@ XLogFileInitInternal(XLogSegNo logsegno, TimeLineID logtli,
 		 * enough.
 		 */
 		errno = 0;
-		if (pg_pwrite(fd, zbuffer.data, 1, wal_segment_size - 1) != 1)
+		if (pwrite(fd, zbuffer.data, 1, wal_segment_size - 1) != 1)
 		{
 			/* if write didn't set errno, assume no disk space */
 			save_errno = errno ? errno : ENOSPC;
diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c
index f3dc4b7797..06e91547dd 100644
--- a/src/backend/access/transam/xlogreader.c
+++ b/src/backend/access/transam/xlogreader.c
@@ -1514,7 +1514,7 @@ WALRead(XLogReaderState *state,
 
 		/* Reset errno first; eases reporting non-errno-affecting errors */
 		errno = 0;
-		readbytes = pg_pread(state->seg.ws_file, p, segbytes, (off_t) startoff);
+		readbytes = pread(state->seg.ws_file, p, segbytes, (off_t) startoff);
 
 #ifndef FRONTEND
 		pgstat_report_wait_end();
diff --git a/src/backend/access/transam/xlogrecovery.c b/src/backend/access/transam/xlogrecovery.c
index 5d6f1b5e46..e25e055c77 100644
--- a/src/backend/access/transam/xlogrecovery.c
+++ b/src/backend/access/transam/xlogrecovery.c
@@ -3210,7 +3210,7 @@ retry:
 	readOff = targetPageOff;
 
 	pgstat_report_wait_start(WAIT_EVENT_WAL_READ);
-	r = pg_pread(readFile, readBuf, XLOG_BLCKSZ, (off_t) readOff);
+	r = pread(readFile, readBuf, XLOG_BLCKSZ, (off_t) readOff);
 	if (r != XLOG_BLCKSZ)
 	{
 		char		fname[MAXFNAMELEN];
diff --git a/src/backend/replication/basebackup.c b/src/backend/replication/basebackup.c
index 1a569e2582..3c375b131f 100644
--- a/src/backend/replication/basebackup.c
+++ b/src/backend/replication/basebackup.c
@@ -1820,7 +1820,7 @@ basebackup_read_file(int fd, char *buf, size_t nbytes, off_t offset,
 	int			rc;
 
 	pgstat_report_wait_start(WAIT_EVENT_BASEBACKUP_READ);
-	rc = pg_pread(fd, buf, nbytes, offset);
+	rc = pread(fd, buf, nbytes, offset);
 	pgstat_report_wait_end();
 
 	if (rc < 0)
diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c
index 3d37c1fe62..8604fd4bc2 100644
--- a/src/backend/replication/walreceiver.c
+++ b/src/backend/replication/walreceiver.c
@@ -915,7 +915,7 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr, TimeLineID tli)
 		/* OK to write the logs */
 		errno = 0;
 
-		byteswritten = pg_pwrite(recvFile, buf, segbytes, (off_t) startoff);
+		byteswritten = pwrite(recvFile, buf, segbytes, (off_t) startoff);
 		if (byteswritten <= 0)
 		{
 			char		xlogfname[MAXFNAMELEN];
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index 28401a8881..71e7f2e143 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -2063,7 +2063,7 @@ FileRead(File file, char *buffer, int amount, off_t offset,
 
 retry:
 	pgstat_report_wait_start(wait_event_info);
-	returnCode = pg_pread(vfdP->fd, buffer, amount, offset);
+	returnCode = pread(vfdP->fd, buffer, amount, offset);
 	pgstat_report_wait_end();
 
 	if (returnCode < 0)
@@ -2145,7 +2145,7 @@ FileWrite(File file, char *buffer, int amount, off_t offset,
 retry:
 	errno = 0;
 	pgstat_report_wait_start(wait_event_info);
-	returnCode = pg_pwrite(VfdCache[file].fd, buffer, amount, offset);
+	returnCode = pwrite(VfdCache[file].fd, buffer, amount, offset);
 	pgstat_report_wait_end();
 
 	/* if write didn't set errno, assume problem is no disk space */
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index 70018ca5d0..c65b596d1b 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -1429,7 +1429,7 @@ AddToDataDirLockFile(int target_line, const char *str)
 	len = strlen(destbuffer);
 	errno = 0;
 	pgstat_report_wait_start(WAIT_EVENT_LOCK_FILE_ADDTODATADIR_WRITE);
-	if (pg_pwrite(fd, destbuffer, len, 0) != len)
+	if (pwrite(fd, destbuffer, len, 0) != len)
 	{
 		pgstat_report_wait_end();
 		/* if write didn't set errno, assume problem is no disk space */
diff --git a/src/bin/pg_test_fsync/pg_test_fsync.c b/src/bin/pg_test_fsync/pg_test_fsync.c
index 6739214eb8..8f0ef8e66b 100644
--- a/src/bin/pg_test_fsync/pg_test_fsync.c
+++ b/src/bin/pg_test_fsync/pg_test_fsync.c
@@ -312,10 +312,10 @@ test_sync(int writes_per_op)
 		for (ops = 0; alarm_triggered == false; ops++)
 		{
 			for (writes = 0; writes < writes_per_op; writes++)
-				if (pg_pwrite(tmpfile,
-							  buf,
-							  XLOG_BLCKSZ,
-							  writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
+				if (pwrite(tmpfile,
+						   buf,
+						   XLOG_BLCKSZ,
+						   writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
 					die("write failed");
 		}
 		STOP_TIMER;
@@ -338,10 +338,10 @@ test_sync(int writes_per_op)
 	for (ops = 0; alarm_triggered == false; ops++)
 	{
 		for (writes = 0; writes < writes_per_op; writes++)
-			if (pg_pwrite(tmpfile,
-						  buf,
-						  XLOG_BLCKSZ,
-						  writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
+			if (pwrite(tmpfile,
+					   buf,
+					   XLOG_BLCKSZ,
+					   writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
 				die("write failed");
 		fdatasync(tmpfile);
 	}
@@ -363,10 +363,10 @@ test_sync(int writes_per_op)
 	for (ops = 0; alarm_triggered == false; ops++)
 	{
 		for (writes = 0; writes < writes_per_op; writes++)
-			if (pg_pwrite(tmpfile,
-						  buf,
-						  XLOG_BLCKSZ,
-						  writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
+			if (pwrite(tmpfile,
+					   buf,
+					   XLOG_BLCKSZ,
+					   writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
 				die("write failed");
 		if (fsync(tmpfile) != 0)
 			die("fsync failed");
@@ -387,10 +387,10 @@ test_sync(int writes_per_op)
 	for (ops = 0; alarm_triggered == false; ops++)
 	{
 		for (writes = 0; writes < writes_per_op; writes++)
-			if (pg_pwrite(tmpfile,
-						  buf,
-						  XLOG_BLCKSZ,
-						  writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
+			if (pwrite(tmpfile,
+					   buf,
+					   XLOG_BLCKSZ,
+					   writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
 				die("write failed");
 		if (pg_fsync_writethrough(tmpfile) != 0)
 			die("fsync failed");
@@ -419,10 +419,10 @@ test_sync(int writes_per_op)
 		for (ops = 0; alarm_triggered == false; ops++)
 		{
 			for (writes = 0; writes < writes_per_op; writes++)
-				if (pg_pwrite(tmpfile,
-							  buf,
-							  XLOG_BLCKSZ,
-							  writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
+				if (pwrite(tmpfile,
+						   buf,
+						   XLOG_BLCKSZ,
+						   writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
 
 					/*
 					 * This can generate write failures if the filesystem has
@@ -484,10 +484,10 @@ test_open_sync(const char *msg, int writes_size)
 		for (ops = 0; alarm_triggered == false; ops++)
 		{
 			for (writes = 0; writes < 16 / writes_size; writes++)
-				if (pg_pwrite(tmpfile,
-							  buf,
-							  writes_size * 1024,
-							  writes * writes_size * 1024) !=
+				if (pwrite(tmpfile,
+						   buf,
+						   writes_size * 1024,
+						   writes * writes_size * 1024) !=
 					writes_size * 1024)
 					die("write failed");
 		}
@@ -586,7 +586,7 @@ test_non_sync(void)
 	START_TIMER;
 	for (ops = 0; alarm_triggered == false; ops++)
 	{
-		if (pg_pwrite(tmpfile, buf, XLOG_BLCKSZ, 0) != XLOG_BLCKSZ)
+		if (pwrite(tmpfile, buf, XLOG_BLCKSZ, 0) != XLOG_BLCKSZ)
 			die("write failed");
 	}
 	STOP_TIMER;
diff --git a/src/include/access/xlogreader.h b/src/include/access/xlogreader.h
index 5395f155aa..87ff00feb7 100644
--- a/src/include/access/xlogreader.h
+++ b/src/include/access/xlogreader.h
@@ -375,11 +375,11 @@ extern bool XLogReaderValidatePageHeader(XLogReaderState *state,
 
 /*
  * Error information from WALRead that both backend and frontend caller can
- * process.  Currently only errors from pg_pread can be reported.
+ * process.  Currently only errors from pread can be reported.
  */
 typedef struct WALReadError
 {
-	int			wre_errno;		/* errno set by the last pg_pread() */
+	int			wre_errno;		/* errno set by the last pread() */
 	int			wre_off;		/* Offset we tried to read from. */
 	int			wre_req;		/* Bytes requested to be read. */
 	int			wre_read;		/* Bytes read by the last read(). */
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 6ea38998f8..e8633878d2 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -393,9 +393,6 @@
 /* Define to 1 if you have the `ppoll' function. */
 #undef HAVE_PPOLL
 
-/* Define to 1 if you have the `pread' function. */
-#undef HAVE_PREAD
-
 /* Define to 1 if the PS_STRINGS thing exists. */
 #undef HAVE_PS_STRINGS
 
@@ -411,9 +408,6 @@
 /* Have PTHREAD_PRIO_INHERIT. */
 #undef HAVE_PTHREAD_PRIO_INHERIT
 
-/* Define to 1 if you have the `pwrite' function. */
-#undef HAVE_PWRITE
-
 /* Define to 1 if you have the <readline.h> header file. */
 #undef HAVE_READLINE_H
 
diff --git a/src/include/port.h b/src/include/port.h
index a8d9a64799..21c441136b 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -418,20 +418,12 @@ extern int	inet_aton(const char *cp, struct in_addr *addr);
 #endif
 
 /*
- * Windows and older Unix don't have pread(2) and pwrite(2).  We have
- * replacement functions, but they have slightly different semantics so we'll
- * use a name with a pg_ prefix to avoid confusion.
+ * Windows doesn't have pread(2) and pwrite(2).  We have replacement functions
+ * in src/port/pread.c and src/port/pwrite.c.
  */
-#ifdef HAVE_PREAD
-#define pg_pread pread
-#else
-extern ssize_t pg_pread(int fd, void *buf, size_t nbyte, off_t offset);
-#endif
-
-#ifdef HAVE_PWRITE
-#define pg_pwrite pwrite
-#else
-extern ssize_t pg_pwrite(int fd, const void *buf, size_t nbyte, off_t offset);
+#ifdef WIN32
+extern ssize_t pread(int fd, void *buf, size_t nbyte, off_t offset);
+extern ssize_t pwrite(int fd, const void *buf, size_t nbyte, off_t offset);
 #endif
 
 /* For pg_pwritev() and pg_preadv(), see port/pg_iovec.h. */
diff --git a/src/port/pread.c b/src/port/pread.c
index 491605926f..bc522d60cd 100644
--- a/src/port/pread.c
+++ b/src/port/pread.c
@@ -1,32 +1,24 @@
 /*-------------------------------------------------------------------------
  *
  * pread.c
- *	  Implementation of pread(2) for platforms that lack one.
+ *	  Implementation of pread(2) for Windows.
  *
  * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
  *	  src/port/pread.c
  *
- * Note that this implementation changes the current file position, unlike
- * the POSIX function, so we use the name pg_pread().
- *
  *-------------------------------------------------------------------------
  */
 
 
 #include "postgres.h"
 
-#ifdef WIN32
 #include <windows.h>
-#else
-#include <unistd.h>
-#endif
 
 ssize_t
-pg_pread(int fd, void *buf, size_t size, off_t offset)
+pread(int fd, void *buf, size_t size, off_t offset)
 {
-#ifdef WIN32
 	OVERLAPPED	overlapped = {0};
 	HANDLE		handle;
 	DWORD		result;
@@ -49,10 +41,4 @@ pg_pread(int fd, void *buf, size_t size, off_t offset)
 	}
 
 	return result;
-#else
-	if (lseek(fd, offset, SEEK_SET) < 0)
-		return -1;
-
-	return read(fd, buf, size);
-#endif
 }
diff --git a/src/port/preadv.c b/src/port/preadv.c
index d12e5a122b..aa7537503f 100644
--- a/src/port/preadv.c
+++ b/src/port/preadv.c
@@ -30,7 +30,7 @@ pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 {
 #ifdef HAVE_READV
 	if (iovcnt == 1)
-		return pg_pread(fd, iov[0].iov_base, iov[0].iov_len, offset);
+		return pread(fd, iov[0].iov_base, iov[0].iov_len, offset);
 	if (lseek(fd, offset, SEEK_SET) < 0)
 		return -1;
 	return readv(fd, iov, iovcnt);
@@ -40,7 +40,7 @@ pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 
 	for (int i = 0; i < iovcnt; ++i)
 	{
-		part = pg_pread(fd, iov[i].iov_base, iov[i].iov_len, offset);
+		part = pread(fd, iov[i].iov_base, iov[i].iov_len, offset);
 		if (part < 0)
 		{
 			if (i == 0)
diff --git a/src/port/pwrite.c b/src/port/pwrite.c
index eeaffacc48..a8f3f69344 100644
--- a/src/port/pwrite.c
+++ b/src/port/pwrite.c
@@ -1,32 +1,24 @@
 /*-------------------------------------------------------------------------
  *
  * pwrite.c
- *	  Implementation of pwrite(2) for platforms that lack one.
+ *	  Implementation of pwrite(2) for Windows.
  *
  * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
  *	  src/port/pwrite.c
  *
- * Note that this implementation changes the current file position, unlike
- * the POSIX function, so we use the name pg_pwrite().
- *
  *-------------------------------------------------------------------------
  */
 
 
 #include "postgres.h"
 
-#ifdef WIN32
 #include <windows.h>
-#else
-#include <unistd.h>
-#endif
 
 ssize_t
-pg_pwrite(int fd, const void *buf, size_t size, off_t offset)
+pwrite(int fd, const void *buf, size_t size, off_t offset)
 {
-#ifdef WIN32
 	OVERLAPPED	overlapped = {0};
 	HANDLE		handle;
 	DWORD		result;
@@ -46,10 +38,4 @@ pg_pwrite(int fd, const void *buf, size_t size, off_t offset)
 	}
 
 	return result;
-#else
-	if (lseek(fd, offset, SEEK_SET) < 0)
-		return -1;
-
-	return write(fd, buf, size);
-#endif
 }
diff --git a/src/port/pwritev.c b/src/port/pwritev.c
index 0bdd69fffc..cb7421381e 100644
--- a/src/port/pwritev.c
+++ b/src/port/pwritev.c
@@ -30,7 +30,7 @@ pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 {
 #ifdef HAVE_WRITEV
 	if (iovcnt == 1)
-		return pg_pwrite(fd, iov[0].iov_base, iov[0].iov_len, offset);
+		return pwrite(fd, iov[0].iov_base, iov[0].iov_len, offset);
 	if (lseek(fd, offset, SEEK_SET) < 0)
 		return -1;
 	return writev(fd, iov, iovcnt);
@@ -40,7 +40,7 @@ pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 
 	for (int i = 0; i < iovcnt; ++i)
 	{
-		part = pg_pwrite(fd, iov[i].iov_base, iov[i].iov_len, offset);
+		part = pwrite(fd, iov[i].iov_base, iov[i].iov_len, offset);
 		if (part < 0)
 		{
 			if (i == 0)
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 0d4ca94e7f..811cfe1ff3 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -325,13 +325,11 @@ sub GenerateFiles
 		HAVE_POSIX_FALLOCATE        => undef,
 		HAVE_PPC_LWARX_MUTEX_HINT   => undef,
 		HAVE_PPOLL                  => undef,
-		HAVE_PREAD                  => undef,
 		HAVE_PS_STRINGS             => undef,
 		HAVE_PTHREAD                => undef,
 		HAVE_PTHREAD_BARRIER_WAIT   => undef,
 		HAVE_PTHREAD_IS_THREADED_NP => undef,
 		HAVE_PTHREAD_PRIO_INHERIT   => undef,
-		HAVE_PWRITE                 => undef,
 		HAVE_READLINE_H             => undef,
 		HAVE_READLINE_HISTORY_H     => undef,
 		HAVE_READLINE_READLINE_H    => undef,
-- 
2.30.2

0012-Simplify-replacement-code-for-preadv-and-pwritev.patchtext/x-patch; charset=US-ASCII; name=0012-Simplify-replacement-code-for-preadv-and-pwritev.patchDownload
From 887ce3b4b7f0457dc70f85fa16c64ee22a494d52 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 23 Jul 2022 23:24:14 +1200
Subject: [PATCH 12/13] Simplify replacement code for preadv and pwritev.

preadv and pwritev are not standardized by POSIX, but all targeted Unix
systems have them except for Solaris (illumos has them since 2015).  We
had two replacement implementations, one based on lseek() +
readv()/writev() and another based on a simple loop.  The former was
used by Solaris only, and the latter by Windows only.

Supporting the extra path only for Solaris, at the cost of having a
pg_preadv/pg_pwritev that could never be used in a multi-threaded
program accessing the same file descriptor from two threads does not
sound like a good trade.

Drop the readv()/writev() variant, and also the pg_ prefix, now that the
file position portability hazard is gone.
---
 configure                     |  2 +-
 configure.ac                  |  2 --
 src/backend/storage/file/fd.c |  4 ++--
 src/include/pg_config.h.in    |  6 ------
 src/include/port/pg_iovec.h   | 12 ++++--------
 src/port/preadv.c             | 13 +------------
 src/port/pwritev.c            | 13 +------------
 src/tools/msvc/Solution.pm    |  2 --
 8 files changed, 9 insertions(+), 45 deletions(-)

diff --git a/configure b/configure
index 3c7ae744ca..531161182a 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 copyfile fdatasync getifaddrs getpeerucred inet_pton kqueue mbstowcs_l memset_s posix_fallocate ppoll pthread_is_threaded_np readv setproctitle setproctitle_fast strchrnul strsignal syncfs sync_file_range uselocale wcstombs_l writev
+for ac_func in backtrace_symbols copyfile fdatasync getifaddrs getpeerucred inet_pton kqueue mbstowcs_l memset_s posix_fallocate ppoll pthread_is_threaded_np setproctitle setproctitle_fast strchrnul strsignal syncfs sync_file_range uselocale wcstombs_l
 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"
diff --git a/configure.ac b/configure.ac
index bc8534717d..56ec5a0b08 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1802,7 +1802,6 @@ AC_CHECK_FUNCS(m4_normalize([
 	posix_fallocate
 	ppoll
 	pthread_is_threaded_np
-	readv
 	setproctitle
 	setproctitle_fast
 	strchrnul
@@ -1811,7 +1810,6 @@ AC_CHECK_FUNCS(m4_normalize([
 	sync_file_range
 	uselocale
 	wcstombs_l
-	writev
 ]))
 
 # These typically are compiler builtins, for which AC_CHECK_FUNCS fails.
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index 71e7f2e143..7d72b842c3 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -3762,7 +3762,7 @@ data_sync_elevel(int elevel)
 }
 
 /*
- * A convenience wrapper for pg_pwritev() that retries on partial write.  If an
+ * A convenience wrapper for pwritev() that retries on partial write.  If an
  * error is returned, it is unspecified how much has been written.
  */
 ssize_t
@@ -3782,7 +3782,7 @@ pg_pwritev_with_retry(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 	for (;;)
 	{
 		/* Write as much as we can. */
-		part = pg_pwritev(fd, iov, iovcnt, offset);
+		part = pwritev(fd, iov, iovcnt, offset);
 		if (part < 0)
 			return -1;
 
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index e8633878d2..f7a7b8116c 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -417,9 +417,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 `readv' function. */
-#undef HAVE_READV
-
 /* Define to 1 if you have the `rl_completion_matches' function. */
 #undef HAVE_RL_COMPLETION_MATCHES
 
@@ -648,9 +645,6 @@
 /* Define to 1 if you have the <winldap.h> header file. */
 #undef HAVE_WINLDAP_H
 
-/* Define to 1 if you have the `writev' function. */
-#undef HAVE_WRITEV
-
 /* Define to 1 if you have the `X509_get_signature_nid' function. */
 #undef HAVE_X509_GET_SIGNATURE_NID
 
diff --git a/src/include/port/pg_iovec.h b/src/include/port/pg_iovec.h
index f0b1a71bcb..f0a50c0e01 100644
--- a/src/include/port/pg_iovec.h
+++ b/src/include/port/pg_iovec.h
@@ -39,16 +39,12 @@ struct iovec
 /* Define a reasonable maximum that is safe to use on the stack. */
 #define PG_IOV_MAX Min(IOV_MAX, 32)
 
-#if HAVE_DECL_PREADV
-#define pg_preadv preadv
-#else
-extern ssize_t pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset);
+#if !HAVE_DECL_PREADV
+extern ssize_t preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset);
 #endif
 
-#if HAVE_DECL_PWRITEV
-#define pg_pwritev pwritev
-#else
-extern ssize_t pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset);
+#if !HAVE_DECL_PWRITEV
+extern ssize_t pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset);
 #endif
 
 #endif							/* PG_IOVEC_H */
diff --git a/src/port/preadv.c b/src/port/preadv.c
index aa7537503f..0aaf99222f 100644
--- a/src/port/preadv.c
+++ b/src/port/preadv.c
@@ -8,9 +8,6 @@
  * IDENTIFICATION
  *	  src/port/preadv.c
  *
- * Note that this implementation changes the current file position, unlike
- * the POSIX-like function, so we use the name pg_preadv().
- *
  *-------------------------------------------------------------------------
  */
 
@@ -26,15 +23,8 @@
 #include "port/pg_iovec.h"
 
 ssize_t
-pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
+preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 {
-#ifdef HAVE_READV
-	if (iovcnt == 1)
-		return pread(fd, iov[0].iov_base, iov[0].iov_len, offset);
-	if (lseek(fd, offset, SEEK_SET) < 0)
-		return -1;
-	return readv(fd, iov, iovcnt);
-#else
 	ssize_t		sum = 0;
 	ssize_t		part;
 
@@ -54,5 +44,4 @@ pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 			return sum;
 	}
 	return sum;
-#endif
 }
diff --git a/src/port/pwritev.c b/src/port/pwritev.c
index cb7421381e..a0fa4b8edd 100644
--- a/src/port/pwritev.c
+++ b/src/port/pwritev.c
@@ -8,9 +8,6 @@
  * IDENTIFICATION
  *	  src/port/pwritev.c
  *
- * Note that this implementation changes the current file position, unlike
- * the POSIX-like function, so we use the name pg_pwritev().
- *
  *-------------------------------------------------------------------------
  */
 
@@ -26,15 +23,8 @@
 #include "port/pg_iovec.h"
 
 ssize_t
-pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
+pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 {
-#ifdef HAVE_WRITEV
-	if (iovcnt == 1)
-		return pwrite(fd, iov[0].iov_base, iov[0].iov_len, offset);
-	if (lseek(fd, offset, SEEK_SET) < 0)
-		return -1;
-	return writev(fd, iov, iovcnt);
-#else
 	ssize_t		sum = 0;
 	ssize_t		part;
 
@@ -54,5 +44,4 @@ pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 			return sum;
 	}
 	return sum;
-#endif
 }
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 811cfe1ff3..a4cebdcf96 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -333,7 +333,6 @@ sub GenerateFiles
 		HAVE_READLINE_H             => undef,
 		HAVE_READLINE_HISTORY_H     => undef,
 		HAVE_READLINE_READLINE_H    => undef,
-		HAVE_READV                  => undef,
 		HAVE_RL_COMPLETION_MATCHES  => undef,
 		HAVE_RL_COMPLETION_SUPPRESS_QUOTE        => undef,
 		HAVE_RL_FILENAME_COMPLETION_FUNCTION     => undef,
@@ -409,7 +408,6 @@ sub GenerateFiles
 		HAVE_WINLDAP_H                           => undef,
 		HAVE_WCSTOMBS_L                          => 1,
 		HAVE_VISIBILITY_ATTRIBUTE                => undef,
-		HAVE_WRITEV                              => undef,
 		HAVE_X509_GET_SIGNATURE_NID              => 1,
 		HAVE_X86_64_POPCNTQ                      => undef,
 		HAVE__BOOL                               => undef,
-- 
2.30.2

0013-Remove-disable-thread-safety.patchtext/x-patch; charset=US-ASCII; name=0013-Remove-disable-thread-safety.patchDownload
From fb697af651fb4a5c8b74deefdce360a2334ac791 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Fri, 26 Mar 2021 22:58:06 +1300
Subject: [PATCH 13/13] Remove --disable-thread-safety.

Threads are in SUSv2 and all targeted Unix systems have the option.
There are no known Unix systems that don't choose to implement the
threading option, and we're no longer testing such builds.

Future work to improve our use of threads will be simplified by not
having to cope with a no-threads build option.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Greg Stark <stark@mit.edu>
Reviewed-by: Robert Haas <robertmhaas@gmail.com>
Discussion: https://postgr.es/m/CA+hUKGJ3LHeP9w5Fgzdr4G8AnEtJ=z=p6hGDEm4qYGEUX5B6fQ@mail.gmail.com
---
 configure                                     | 56 ++-------------
 configure.ac                                  | 28 ++------
 doc/src/sgml/installation.sgml                | 13 ----
 doc/src/sgml/libpq.sgml                       |  3 +-
 src/Makefile.global.in                        |  1 -
 src/bin/pgbench/pgbench.c                     | 22 +-----
 src/include/pg_config.h.in                    |  4 --
 src/interfaces/ecpg/ecpglib/connect.c         | 40 -----------
 src/interfaces/ecpg/ecpglib/descriptor.c      |  9 ---
 src/interfaces/ecpg/ecpglib/ecpglib_extern.h  |  2 -
 src/interfaces/ecpg/ecpglib/execute.c         |  2 -
 src/interfaces/ecpg/ecpglib/memory.c          |  7 --
 src/interfaces/ecpg/ecpglib/misc.c            | 47 ------------
 .../ecpg/include/ecpg-pthread-win32.h         |  3 -
 src/interfaces/ecpg/include/ecpg_config.h.in  |  4 --
 src/interfaces/ecpg/include/ecpglib.h         |  2 -
 .../ecpg/test/expected/thread-alloc.c         | 43 +++++------
 .../ecpg/test/expected/thread-alloc_2.stdout  |  1 -
 .../ecpg/test/expected/thread-descriptor.c    | 22 +++---
 .../ecpg/test/expected/thread-prep.c          | 71 ++++++++-----------
 .../ecpg/test/expected/thread-prep.stdout     |  1 -
 .../ecpg/test/expected/thread-prep_2.stdout   |  0
 .../ecpg/test/expected/thread-thread.c        | 63 +++++++---------
 .../ecpg/test/expected/thread-thread.stdout   |  2 +-
 .../ecpg/test/expected/thread-thread_2.stdout |  1 -
 .../test/expected/thread-thread_implicit.c    | 63 +++++++---------
 .../expected/thread-thread_implicit.stdout    |  2 +-
 .../expected/thread-thread_implicit_2.stdout  |  1 -
 src/interfaces/ecpg/test/thread/alloc.pgc     |  9 ---
 .../ecpg/test/thread/descriptor.pgc           |  8 +--
 src/interfaces/ecpg/test/thread/prep.pgc      |  9 ---
 src/interfaces/ecpg/test/thread/thread.pgc    |  9 ---
 .../ecpg/test/thread/thread_implicit.pgc      |  9 ---
 src/interfaces/libpq/Makefile                 |  2 -
 src/interfaces/libpq/fe-auth.c                |  9 ++-
 src/interfaces/libpq/fe-connect.c             |  4 --
 src/interfaces/libpq/fe-exec.c                |  4 --
 src/interfaces/libpq/fe-print.c               | 13 +---
 src/interfaces/libpq/fe-secure-openssl.c      | 17 +----
 src/interfaces/libpq/fe-secure.c              | 26 +------
 src/interfaces/libpq/legacy-pqsignal.c        |  4 --
 src/interfaces/libpq/libpq-int.h              |  9 +--
 src/port/getaddrinfo.c                        |  2 +-
 src/tools/msvc/Solution.pm                    |  3 +-
 src/tools/msvc/ecpg_regression.proj           |  2 +-
 45 files changed, 142 insertions(+), 510 deletions(-)
 delete mode 100644 src/interfaces/ecpg/test/expected/thread-alloc_2.stdout
 delete mode 100644 src/interfaces/ecpg/test/expected/thread-prep_2.stdout
 delete mode 100644 src/interfaces/ecpg/test/expected/thread-thread_2.stdout
 delete mode 100644 src/interfaces/ecpg/test/expected/thread-thread_implicit_2.stdout

diff --git a/configure b/configure
index 531161182a..53dd6bb6e4 100755
--- a/configure
+++ b/configure
@@ -728,7 +728,6 @@ with_tcl
 ICU_LIBS
 ICU_CFLAGS
 with_icu
-enable_thread_safety
 INCLUDES
 autodepend
 PKG_CONFIG_LIBDIR
@@ -853,7 +852,6 @@ with_CC
 with_llvm
 enable_depend
 enable_cassert
-enable_thread_safety
 with_icu
 with_tcl
 with_tclconfig
@@ -1542,7 +1540,6 @@ Optional Features:
   --enable-tap-tests      enable TAP tests (requires Perl and IPC::Run)
   --enable-depend         turn on automatic dependency tracking
   --enable-cassert        enable assertion checks (for debugging)
-  --disable-thread-safety disable thread-safety in client libraries
   --disable-largefile     omit support for large files
 
 Optional Packages:
@@ -7972,43 +7969,6 @@ $as_echo "$as_me: WARNING: *** Library directory $dir does not exist." >&2;}
 done
 IFS=$ac_save_IFS
 
-#
-# Enable thread-safe client libraries
-#
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking allow thread-safe client libraries" >&5
-$as_echo_n "checking allow thread-safe client libraries... " >&6; }
-
-
-# Check whether --enable-thread-safety was given.
-if test "${enable_thread_safety+set}" = set; then :
-  enableval=$enable_thread_safety;
-  case $enableval in
-    yes)
-      :
-      ;;
-    no)
-      :
-      ;;
-    *)
-      as_fn_error $? "no argument expected for --enable-thread-safety option" "$LINENO" 5
-      ;;
-  esac
-
-else
-  enable_thread_safety=yes
-
-fi
-
-
-if test "$enable_thread_safety" = yes; then
-
-$as_echo "#define ENABLE_THREAD_SAFETY 1" >>confdefs.h
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_thread_safety" >&5
-$as_echo "$enable_thread_safety" >&6; }
-
-
 #
 # ICU
 #
@@ -11087,7 +11047,7 @@ fi
 done
 
 
-if test "$enable_thread_safety" = yes -a "$PORTNAME" != "win32"; then :
+if "$PORTNAME" != "win32"; then :
    # then
 
 
@@ -11746,7 +11706,7 @@ if test "x$ac_cv_header_pthread_h" = xyes; then :
 
 else
   as_fn_error $? "
-pthread.h not found;  use --disable-thread-safety to disable thread safety" "$LINENO" 5
+pthread.h not found" "$LINENO" 5
 fi
 
 
@@ -12487,8 +12447,7 @@ if test "$ac_res" != no; then :
 fi
 
 
-if test "$enable_thread_safety" = yes; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gethostbyname_r" >&5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gethostbyname_r" >&5
 $as_echo_n "checking for library containing gethostbyname_r... " >&6; }
 if ${ac_cv_search_gethostbyname_r+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -12544,7 +12503,7 @@ if test "$ac_res" != no; then :
 
 fi
 
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_barrier_wait" >&5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_barrier_wait" >&5
 $as_echo_n "checking for library containing pthread_barrier_wait... " >&6; }
 if ${ac_cv_search_pthread_barrier_wait+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -12600,7 +12559,6 @@ if test "$ac_res" != no; then :
 
 fi
 
-fi
 
 if test "$with_readline" = yes; then
 
@@ -13473,7 +13431,7 @@ else
   thread_safe_libldap=no
 fi
 
-    if test "$enable_thread_safety" = yes -a "$thread_safe_libldap" = no; then
+    if test "$thread_safe_libldap" = no; then
       # Use ldap_r for FE if available, else assume ldap is thread-safe.
       # On some platforms ldap_r fails to link without PTHREAD_LIBS.
       LIBS="$_LIBS"
@@ -16806,8 +16764,7 @@ fi
 
 
 
-if test "$enable_thread_safety" = yes; then
-  ac_fn_c_check_func "$LINENO" "pthread_barrier_wait" "ac_cv_func_pthread_barrier_wait"
+ac_fn_c_check_func "$LINENO" "pthread_barrier_wait" "ac_cv_func_pthread_barrier_wait"
 if test "x$ac_cv_func_pthread_barrier_wait" = xyes; then :
   $as_echo "#define HAVE_PTHREAD_BARRIER_WAIT 1" >>confdefs.h
 
@@ -16821,7 +16778,6 @@ esac
 fi
 
 
-fi
 
 if test "$PORTNAME" = "win32" -o "$PORTNAME" = "cygwin"; then
 	# Cygwin and (apparently, based on test results) Mingw both
diff --git a/configure.ac b/configure.ac
index 56ec5a0b08..bfbe13c9a8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -788,18 +788,6 @@ for dir in $LIBRARY_DIRS $SRCH_LIB; do
 done
 IFS=$ac_save_IFS
 
-#
-# Enable thread-safe client libraries
-#
-AC_MSG_CHECKING([allow thread-safe client libraries])
-PGAC_ARG_BOOL(enable, thread-safety, yes, [disable thread-safety in client libraries])
-if test "$enable_thread_safety" = yes; then
-  AC_DEFINE([ENABLE_THREAD_SAFETY], 1,
-          [Define to 1 to build client libraries as thread-safe code. (--enable-thread-safety)])
-fi
-AC_MSG_RESULT([$enable_thread_safety])
-AC_SUBST(enable_thread_safety)
-
 #
 # ICU
 #
@@ -1197,7 +1185,7 @@ dnl note: We have to use AS_IF here rather than plain if. The AC_CHECK_HEADER
 dnl invocation below is the first one in the script, and autoconf generates
 dnl additional code for that, which must not be inside the if-block. AS_IF
 dnl knows how to do that.
-AS_IF([test "$enable_thread_safety" = yes -a "$PORTNAME" != "win32"],
+AS_IF(["$PORTNAME" != "win32"],
 [ # then
 AX_PTHREAD	# set thread flags
 
@@ -1212,7 +1200,7 @@ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
 LIBS="$LIBS $PTHREAD_LIBS"
 
 AC_CHECK_HEADER(pthread.h, [], [AC_MSG_ERROR([
-pthread.h not found;  use --disable-thread-safety to disable thread safety])])
+pthread.h not found])])
 
 AC_CHECK_FUNCS([strerror_r gethostbyname_r])
 
@@ -1260,10 +1248,8 @@ AC_SEARCH_LIBS(shmget, cygipc)
 # *BSD:
 AC_SEARCH_LIBS(backtrace_symbols, execinfo)
 
-if test "$enable_thread_safety" = yes; then
-  AC_SEARCH_LIBS(gethostbyname_r, nsl)
-  AC_SEARCH_LIBS(pthread_barrier_wait, pthread)
-fi
+AC_SEARCH_LIBS(gethostbyname_r, nsl)
+AC_SEARCH_LIBS(pthread_barrier_wait, pthread)
 
 if test "$with_readline" = yes; then
   PGAC_CHECK_READLINE
@@ -1388,7 +1374,7 @@ if test "$with_ldap" = yes ; then
     AC_CHECK_FUNC([ldap_verify_credentials],
 		  [thread_safe_libldap=yes],
 		  [thread_safe_libldap=no])
-    if test "$enable_thread_safety" = yes -a "$thread_safe_libldap" = no; then
+    if test "$thread_safe_libldap" = no; then
       # Use ldap_r for FE if available, else assume ldap is thread-safe.
       # On some platforms ldap_r fails to link without PTHREAD_LIBS.
       LIBS="$_LIBS"
@@ -1881,9 +1867,7 @@ AC_REPLACE_FUNCS(m4_normalize([
 	strtof
 ]))
 
-if test "$enable_thread_safety" = yes; then
-  AC_REPLACE_FUNCS(pthread_barrier_wait)
-fi
+AC_REPLACE_FUNCS(pthread_barrier_wait)
 
 if test "$PORTNAME" = "win32" -o "$PORTNAME" = "cygwin"; then
 	# Cygwin and (apparently, based on test results) Mingw both
diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml
index 70d188e2bc..f31e1f9160 100644
--- a/doc/src/sgml/installation.sgml
+++ b/doc/src/sgml/installation.sgml
@@ -1285,19 +1285,6 @@ build-postgresql:
        </listitem>
       </varlistentry>
 
-      <varlistentry>
-       <term><option>--disable-thread-safety</option></term>
-       <listitem>
-        <para>
-         Disable the thread-safety of client libraries.  This prevents
-         concurrent threads in <application>libpq</application> and
-         <application>ECPG</application> programs from safely controlling
-         their private connection handles.  Use this only on platforms
-         with deficient threading support.
-        </para>
-       </listitem>
-      </varlistentry>
-
      </variablelist>
 
    </sect3>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 74456aa69d..655b4db31e 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -8837,7 +8837,8 @@ int PQisthreadsafe();
 
      <para>
       Returns 1 if the <application>libpq</application> is thread-safe
-      and 0 if it is not.
+      and 0 if it is not.  Since <productname>PostgreSQL</productname> version
+      16, this function always returns 1.
      </para>
     </listitem>
    </varlistentry>
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index 14fdd4ef7b..cb35cd9eba 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -202,7 +202,6 @@ enable_debug	= @enable_debug@
 enable_dtrace	= @enable_dtrace@
 enable_coverage	= @enable_coverage@
 enable_tap_tests	= @enable_tap_tests@
-enable_thread_safety	= @enable_thread_safety@
 
 python_includespec	= @python_includespec@
 python_libdir		= @python_libdir@
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index e48d4f5053..bd46a83463 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -138,7 +138,7 @@ typedef struct socket_set
 	EnterSynchronizationBarrier((barrier), \
 								SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY)
 #define THREAD_BARRIER_DESTROY(barrier)
-#elif defined(ENABLE_THREAD_SAFETY)
+#else
 /* Use POSIX threads */
 #include "port/pg_pthread.h"
 #define THREAD_T pthread_t
@@ -154,16 +154,6 @@ typedef struct socket_set
 	pthread_barrier_init((barrier), NULL, (n))
 #define THREAD_BARRIER_WAIT(barrier) pthread_barrier_wait((barrier))
 #define THREAD_BARRIER_DESTROY(barrier) pthread_barrier_destroy((barrier))
-#else
-/* No threads implementation, use none (-j 1) */
-#define THREAD_T void *
-#define THREAD_FUNC_RETURN_TYPE void *
-#define THREAD_FUNC_RETURN return NULL
-#define THREAD_FUNC_CC
-#define THREAD_BARRIER_T int
-#define THREAD_BARRIER_INIT(barrier, n) (*(barrier) = 0)
-#define THREAD_BARRIER_WAIT(barrier)
-#define THREAD_BARRIER_DESTROY(barrier)
 #endif
 
 
@@ -6678,10 +6668,6 @@ main(int argc, char **argv)
 				{
 					exit(1);
 				}
-#ifndef ENABLE_THREAD_SAFETY
-				if (nthreads != 1)
-					pg_fatal("threads are not supported on this platform; use -j1");
-#endif							/* !ENABLE_THREAD_SAFETY */
 				break;
 			case 'C':
 				benchmarking_option_set = true;
@@ -7195,7 +7181,6 @@ main(int argc, char **argv)
 	if (errno != 0)
 		pg_fatal("could not initialize barrier: %m");
 
-#ifdef ENABLE_THREAD_SAFETY
 	/* start all threads but thread 0 which is executed directly later */
 	for (i = 1; i < nthreads; i++)
 	{
@@ -7207,9 +7192,6 @@ main(int argc, char **argv)
 		if (errno != 0)
 			pg_fatal("could not create thread: %m");
 	}
-#else
-	Assert(nthreads == 1);
-#endif							/* ENABLE_THREAD_SAFETY */
 
 	/* compute when to stop */
 	threads[0].create_time = pg_time_now();
@@ -7227,10 +7209,8 @@ main(int argc, char **argv)
 	{
 		TState	   *thread = &threads[i];
 
-#ifdef ENABLE_THREAD_SAFETY
 		if (i > 0)
 			THREAD_JOIN(thread->thread);
-#endif							/* ENABLE_THREAD_SAFETY */
 
 		for (int j = 0; j < thread->nstate; j++)
 			if (thread->state[j].state != CSTATE_FINISHED)
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index f7a7b8116c..a9f7ebd8ad 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -51,10 +51,6 @@
 /* Define to 1 if you want National Language Support. (--enable-nls) */
 #undef ENABLE_NLS
 
-/* Define to 1 to build client libraries as thread-safe code.
-   (--enable-thread-safety) */
-#undef ENABLE_THREAD_SAFETY
-
 /* Define to 1 if gettimeofday() takes only 1 argument. */
 #undef GETTIMEOFDAY_1ARG
 
diff --git a/src/interfaces/ecpg/ecpglib/connect.c b/src/interfaces/ecpg/ecpglib/connect.c
index db0bae1fe0..8afb1f0a26 100644
--- a/src/interfaces/ecpg/ecpglib/connect.c
+++ b/src/interfaces/ecpg/ecpglib/connect.c
@@ -14,15 +14,12 @@
 locale_t	ecpg_clocale = (locale_t) 0;
 #endif
 
-#ifdef ENABLE_THREAD_SAFETY
 static pthread_mutex_t connections_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_key_t actual_connection_key;
 static pthread_once_t actual_connection_key_once = PTHREAD_ONCE_INIT;
-#endif
 static struct connection *actual_connection = NULL;
 static struct connection *all_connections = NULL;
 
-#ifdef ENABLE_THREAD_SAFETY
 static void
 ecpg_actual_connection_init(void)
 {
@@ -34,7 +31,6 @@ ecpg_pthreads_init(void)
 {
 	pthread_once(&actual_connection_key_once, ecpg_actual_connection_init);
 }
-#endif
 
 static struct connection *
 ecpg_get_connection_nr(const char *connection_name)
@@ -43,7 +39,6 @@ ecpg_get_connection_nr(const char *connection_name)
 
 	if ((connection_name == NULL) || (strcmp(connection_name, "CURRENT") == 0))
 	{
-#ifdef ENABLE_THREAD_SAFETY
 		ecpg_pthreads_init();	/* ensure actual_connection_key is valid */
 
 		ret = pthread_getspecific(actual_connection_key);
@@ -56,9 +51,6 @@ ecpg_get_connection_nr(const char *connection_name)
 		if (ret == NULL)
 			/* no TSD connection, going for global */
 			ret = actual_connection;
-#else
-		ret = actual_connection;
-#endif
 	}
 	else
 	{
@@ -82,7 +74,6 @@ ecpg_get_connection(const char *connection_name)
 
 	if ((connection_name == NULL) || (strcmp(connection_name, "CURRENT") == 0))
 	{
-#ifdef ENABLE_THREAD_SAFETY
 		ecpg_pthreads_init();	/* ensure actual_connection_key is valid */
 
 		ret = pthread_getspecific(actual_connection_key);
@@ -95,21 +86,14 @@ ecpg_get_connection(const char *connection_name)
 		if (ret == NULL)
 			/* no TSD connection here either, using global */
 			ret = actual_connection;
-#else
-		ret = actual_connection;
-#endif
 	}
 	else
 	{
-#ifdef ENABLE_THREAD_SAFETY
 		pthread_mutex_lock(&connections_mutex);
-#endif
 
 		ret = ecpg_get_connection_nr(connection_name);
 
-#ifdef ENABLE_THREAD_SAFETY
 		pthread_mutex_unlock(&connections_mutex);
-#endif
 	}
 
 	return ret;
@@ -143,10 +127,8 @@ ecpg_finish(struct connection *act)
 				con->next = act->next;
 		}
 
-#ifdef ENABLE_THREAD_SAFETY
 		if (pthread_getspecific(actual_connection_key) == act)
 			pthread_setspecific(actual_connection_key, all_connections);
-#endif
 		if (actual_connection == act)
 			actual_connection = all_connections;
 
@@ -212,11 +194,7 @@ ECPGsetconn(int lineno, const char *connection_name)
 	if (!ecpg_init(con, connection_name, lineno))
 		return false;
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_setspecific(actual_connection_key, con);
-#else
-	actual_connection = con;
-#endif
 	return true;
 }
 
@@ -326,9 +304,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
 	if (dbname == NULL && connection_name == NULL)
 		connection_name = "DEFAULT";
 
-#if ENABLE_THREAD_SAFETY
 	ecpg_pthreads_init();
-#endif
 
 	/* check if the identifier is unique */
 	if (ecpg_get_connection(connection_name))
@@ -505,9 +481,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
 	}
 
 	/* add connection to our list */
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_lock(&connections_mutex);
-#endif
 
 	/*
 	 * ... but first, make certain we have created ecpg_clocale.  Rely on
@@ -519,9 +493,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
 		ecpg_clocale = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
 		if (!ecpg_clocale)
 		{
-#ifdef ENABLE_THREAD_SAFETY
 			pthread_mutex_unlock(&connections_mutex);
-#endif
 			ecpg_raise(lineno, ECPG_OUT_OF_MEMORY,
 					   ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
 			if (host)
@@ -558,9 +530,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
 		this->next = all_connections;
 
 	all_connections = this;
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_setspecific(actual_connection_key, all_connections);
-#endif
 	actual_connection = all_connections;
 
 	ecpg_log("ECPGconnect: opening database %s on %s port %s %s%s %s%s\n",
@@ -678,9 +648,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
 		ecpg_log("ECPGconnect: %s", errmsg);
 
 		ecpg_finish(this);
-#ifdef ENABLE_THREAD_SAFETY
 		pthread_mutex_unlock(&connections_mutex);
-#endif
 
 		ecpg_raise(lineno, ECPG_CONNECT, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, db);
 		if (realname)
@@ -692,9 +660,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
 	if (realname)
 		ecpg_free(realname);
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_unlock(&connections_mutex);
-#endif
 
 	this->autocommit = autocommit;
 
@@ -716,9 +682,7 @@ ECPGdisconnect(int lineno, const char *connection_name)
 		return false;
 	}
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_lock(&connections_mutex);
-#endif
 
 	if (strcmp(connection_name, "ALL") == 0)
 	{
@@ -737,18 +701,14 @@ ECPGdisconnect(int lineno, const char *connection_name)
 
 		if (!ecpg_init(con, connection_name, lineno))
 		{
-#ifdef ENABLE_THREAD_SAFETY
 			pthread_mutex_unlock(&connections_mutex);
-#endif
 			return false;
 		}
 		else
 			ecpg_finish(con);
 	}
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_unlock(&connections_mutex);
-#endif
 
 	return true;
 }
diff --git a/src/interfaces/ecpg/ecpglib/descriptor.c b/src/interfaces/ecpg/ecpglib/descriptor.c
index 649a71c286..b47f422d92 100644
--- a/src/interfaces/ecpg/ecpglib/descriptor.c
+++ b/src/interfaces/ecpg/ecpglib/descriptor.c
@@ -19,7 +19,6 @@
 static void descriptor_free(struct descriptor *desc);
 
 /* We manage descriptors separately for each thread. */
-#ifdef ENABLE_THREAD_SAFETY
 static pthread_key_t descriptor_key;
 static pthread_once_t descriptor_once = PTHREAD_ONCE_INIT;
 
@@ -49,12 +48,6 @@ set_descriptors(struct descriptor *value)
 {
 	pthread_setspecific(descriptor_key, value);
 }
-#else
-static struct descriptor *all_descriptors = NULL;
-
-#define get_descriptors()		(all_descriptors)
-#define set_descriptors(value)	do { all_descriptors = (value); } while(0)
-#endif
 
 /* old internal convenience function that might go away later */
 static PGresult *
@@ -782,7 +775,6 @@ ECPGdeallocate_desc(int line, const char *name)
 	return false;
 }
 
-#ifdef ENABLE_THREAD_SAFETY
 
 /* Deallocate all descriptors in the list */
 static void
@@ -796,7 +788,6 @@ descriptor_deallocate_all(struct descriptor *list)
 		list = next;
 	}
 }
-#endif							/* ENABLE_THREAD_SAFETY */
 
 bool
 ECPGallocate_desc(int line, const char *name)
diff --git a/src/interfaces/ecpg/ecpglib/ecpglib_extern.h b/src/interfaces/ecpg/ecpglib/ecpglib_extern.h
index c438cfb820..968f1211b8 100644
--- a/src/interfaces/ecpg/ecpglib/ecpglib_extern.h
+++ b/src/interfaces/ecpg/ecpglib/ecpglib_extern.h
@@ -169,9 +169,7 @@ bool		ecpg_get_data(const PGresult *, int, int, int, enum ECPGttype type,
 						  enum ECPGttype, char *, char *, long, long, long,
 						  enum ARRAY_TYPE, enum COMPAT_MODE, bool);
 
-#ifdef ENABLE_THREAD_SAFETY
 void		ecpg_pthreads_init(void);
-#endif
 struct connection *ecpg_get_connection(const char *);
 char	   *ecpg_alloc(long, int);
 char	   *ecpg_auto_alloc(long, int);
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index bd94bd4e6c..0b2716d921 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1961,9 +1961,7 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator,
 		return false;
 	}
 
-#ifdef ENABLE_THREAD_SAFETY
 	ecpg_pthreads_init();
-#endif
 
 	con = ecpg_get_connection(connection_name);
 
diff --git a/src/interfaces/ecpg/ecpglib/memory.c b/src/interfaces/ecpg/ecpglib/memory.c
index bd81251054..a83637ac75 100644
--- a/src/interfaces/ecpg/ecpglib/memory.c
+++ b/src/interfaces/ecpg/ecpglib/memory.c
@@ -68,7 +68,6 @@ struct auto_mem
 	struct auto_mem *next;
 };
 
-#ifdef ENABLE_THREAD_SAFETY
 static pthread_key_t auto_mem_key;
 static pthread_once_t auto_mem_once = PTHREAD_ONCE_INIT;
 
@@ -97,12 +96,6 @@ set_auto_allocs(struct auto_mem *am)
 {
 	pthread_setspecific(auto_mem_key, am);
 }
-#else
-static struct auto_mem *auto_allocs = NULL;
-
-#define get_auto_allocs()		(auto_allocs)
-#define set_auto_allocs(am)		do { auto_allocs = (am); } while(0)
-#endif
 
 char *
 ecpg_auto_alloc(long size, int lineno)
diff --git a/src/interfaces/ecpg/ecpglib/misc.c b/src/interfaces/ecpg/ecpglib/misc.c
index 1eef1ec044..71f07c4e4f 100644
--- a/src/interfaces/ecpg/ecpglib/misc.c
+++ b/src/interfaces/ecpg/ecpglib/misc.c
@@ -55,42 +55,11 @@ static struct sqlca_t sqlca_init =
 	}
 };
 
-#ifdef ENABLE_THREAD_SAFETY
 static pthread_key_t sqlca_key;
 static pthread_once_t sqlca_key_once = PTHREAD_ONCE_INIT;
-#else
-static struct sqlca_t sqlca =
-{
-	{
-		'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '
-	},
-	sizeof(struct sqlca_t),
-	0,
-	{
-		0,
-		{
-			0
-		}
-	},
-	{
-		'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '
-	},
-	{
-		0, 0, 0, 0, 0, 0
-	},
-	{
-		0, 0, 0, 0, 0, 0, 0, 0
-	},
-	{
-		'0', '0', '0', '0', '0'
-	}
-};
-#endif
 
-#ifdef ENABLE_THREAD_SAFETY
 static pthread_mutex_t debug_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t debug_init_mutex = PTHREAD_MUTEX_INITIALIZER;
-#endif
 static int	simple_debug = 0;
 static FILE *debugstream = NULL;
 
@@ -123,7 +92,6 @@ ecpg_init(const struct connection *con, const char *connection_name, const int l
 	return true;
 }
 
-#ifdef ENABLE_THREAD_SAFETY
 static void
 ecpg_sqlca_key_destructor(void *arg)
 {
@@ -135,12 +103,10 @@ ecpg_sqlca_key_init(void)
 {
 	pthread_key_create(&sqlca_key, ecpg_sqlca_key_destructor);
 }
-#endif
 
 struct sqlca_t *
 ECPGget_sqlca(void)
 {
-#ifdef ENABLE_THREAD_SAFETY
 	struct sqlca_t *sqlca;
 
 	pthread_once(&sqlca_key_once, ecpg_sqlca_key_init);
@@ -155,9 +121,6 @@ ECPGget_sqlca(void)
 		pthread_setspecific(sqlca_key, sqlca);
 	}
 	return sqlca;
-#else
-	return &sqlca;
-#endif
 }
 
 bool
@@ -240,9 +203,7 @@ ECPGtrans(int lineno, const char *connection_name, const char *transaction)
 void
 ECPGdebug(int n, FILE *dbgs)
 {
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_lock(&debug_init_mutex);
-#endif
 
 	if (n > 100)
 	{
@@ -256,9 +217,7 @@ ECPGdebug(int n, FILE *dbgs)
 
 	ecpg_log("ECPGdebug: set to %d\n", simple_debug);
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_unlock(&debug_init_mutex);
-#endif
 }
 
 void
@@ -290,9 +249,7 @@ ecpg_log(const char *format,...)
 	else
 		snprintf(fmt, bufsize, "[%d]: %s", (int) getpid(), intl_format);
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_lock(&debug_mutex);
-#endif
 
 	va_start(ap, format);
 	vfprintf(debugstream, fmt, ap);
@@ -307,9 +264,7 @@ ecpg_log(const char *format,...)
 
 	fflush(debugstream);
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_unlock(&debug_mutex);
-#endif
 
 	free(fmt);
 }
@@ -451,7 +406,6 @@ ECPGis_noind_null(enum ECPGttype type, const void *ptr)
 }
 
 #ifdef WIN32
-#ifdef ENABLE_THREAD_SAFETY
 
 void
 win32_pthread_mutex(volatile pthread_mutex_t *mutex)
@@ -482,7 +436,6 @@ win32_pthread_once(volatile pthread_once_t *once, void (*fn) (void))
 		pthread_mutex_unlock(&win32_pthread_once_lock);
 	}
 }
-#endif							/* ENABLE_THREAD_SAFETY */
 #endif							/* WIN32 */
 
 #ifdef ENABLE_NLS
diff --git a/src/interfaces/ecpg/include/ecpg-pthread-win32.h b/src/interfaces/ecpg/include/ecpg-pthread-win32.h
index 33c897b633..8252a17809 100644
--- a/src/interfaces/ecpg/include/ecpg-pthread-win32.h
+++ b/src/interfaces/ecpg/include/ecpg-pthread-win32.h
@@ -5,8 +5,6 @@
 #ifndef _ECPG_PTHREAD_WIN32_H
 #define _ECPG_PTHREAD_WIN32_H
 
-#ifdef ENABLE_THREAD_SAFETY
-
 #ifndef WIN32
 
 #include <pthread.h>
@@ -53,6 +51,5 @@ void		win32_pthread_once(volatile pthread_once_t *once, void (*fn) (void));
 			win32_pthread_once((once), (fn)); \
 	} while(0)
 #endif							/* WIN32 */
-#endif							/* ENABLE_THREAD_SAFETY */
 
 #endif							/* _ECPG_PTHREAD_WIN32_H */
diff --git a/src/interfaces/ecpg/include/ecpg_config.h.in b/src/interfaces/ecpg/include/ecpg_config.h.in
index cbd24f11a0..6d01608a49 100644
--- a/src/interfaces/ecpg/include/ecpg_config.h.in
+++ b/src/interfaces/ecpg/include/ecpg_config.h.in
@@ -1,7 +1,3 @@
-/* Define to 1 to build client libraries as thread-safe code.
- *    (--enable-thread-safety) */
-#undef ENABLE_THREAD_SAFETY
-
 /* Define to 1 if the system has the type `int64'. */
 #undef HAVE_INT64
 
diff --git a/src/interfaces/ecpg/include/ecpglib.h b/src/interfaces/ecpg/include/ecpglib.h
index 00240109a6..05433726ac 100644
--- a/src/interfaces/ecpg/include/ecpglib.h
+++ b/src/interfaces/ecpg/include/ecpglib.h
@@ -92,9 +92,7 @@ void	   *ECPGget_var(int number);
 /* dynamic result allocation */
 void		ECPGfree_auto_mem(void);
 
-#ifdef ENABLE_THREAD_SAFETY
 void		ecpg_pthreads_init(void);
-#endif
 
 #ifdef __cplusplus
 }
diff --git a/src/interfaces/ecpg/test/expected/thread-alloc.c b/src/interfaces/ecpg/test/expected/thread-alloc.c
index 37ef44ed94..3b31d27fd3 100644
--- a/src/interfaces/ecpg/test/expected/thread-alloc.c
+++ b/src/interfaces/ecpg/test/expected/thread-alloc.c
@@ -11,14 +11,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifdef WIN32
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
@@ -101,7 +93,7 @@ struct sqlca_t *ECPGget_sqlca(void);
 
 #endif
 
-#line 26 "alloc.pgc"
+#line 18 "alloc.pgc"
 
 
 #line 1 "regression.h"
@@ -111,14 +103,14 @@ struct sqlca_t *ECPGget_sqlca(void);
 
 
 
-#line 27 "alloc.pgc"
+#line 19 "alloc.pgc"
 
 
 /* exec sql whenever sqlerror  sqlprint ; */
-#line 29 "alloc.pgc"
+#line 21 "alloc.pgc"
 
 /* exec sql whenever not found  sqlprint ; */
-#line 30 "alloc.pgc"
+#line 22 "alloc.pgc"
 
 
 #ifdef WIN32
@@ -134,54 +126,54 @@ static void* fn(void* arg)
 	 
 	   
 	
-#line 41 "alloc.pgc"
+#line 33 "alloc.pgc"
  int value ;
  
-#line 42 "alloc.pgc"
+#line 34 "alloc.pgc"
  char name [ 100 ] ;
  
-#line 43 "alloc.pgc"
+#line 35 "alloc.pgc"
  char ** r = NULL ;
 /* exec sql end declare section */
-#line 44 "alloc.pgc"
+#line 36 "alloc.pgc"
 
 
 	value = (intptr_t) arg;
 	sprintf(name, "Connection: %d", value);
 
 	{ ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , name, 0); 
-#line 49 "alloc.pgc"
+#line 41 "alloc.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 49 "alloc.pgc"
+#line 41 "alloc.pgc"
 
 	{ ECPGsetcommit(__LINE__, "on", NULL);
-#line 50 "alloc.pgc"
+#line 42 "alloc.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 50 "alloc.pgc"
+#line 42 "alloc.pgc"
 
 	for (i = 1; i <= REPEATS; ++i)
 	{
 		{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select relname from pg_class where relname = 'pg_class'", ECPGt_EOIT, 
 	ECPGt_char,&(r),(long)0,(long)0,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
-#line 53 "alloc.pgc"
+#line 45 "alloc.pgc"
 
 if (sqlca.sqlcode == ECPG_NOT_FOUND) sqlprint();
-#line 53 "alloc.pgc"
+#line 45 "alloc.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 53 "alloc.pgc"
+#line 45 "alloc.pgc"
 
 		free(r);
 		r = NULL;
 	}
 	{ ECPGdisconnect(__LINE__, name);
-#line 57 "alloc.pgc"
+#line 49 "alloc.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 57 "alloc.pgc"
+#line 49 "alloc.pgc"
 
 
 	return 0;
@@ -215,4 +207,3 @@ int main ()
 
 	return 0;
 }
-#endif
diff --git a/src/interfaces/ecpg/test/expected/thread-alloc_2.stdout b/src/interfaces/ecpg/test/expected/thread-alloc_2.stdout
deleted file mode 100644
index 75fe16bb36..0000000000
--- a/src/interfaces/ecpg/test/expected/thread-alloc_2.stdout
+++ /dev/null
@@ -1 +0,0 @@
-No threading enabled.
diff --git a/src/interfaces/ecpg/test/expected/thread-descriptor.c b/src/interfaces/ecpg/test/expected/thread-descriptor.c
index f56cc25ab0..e34f4708d1 100644
--- a/src/interfaces/ecpg/test/expected/thread-descriptor.c
+++ b/src/interfaces/ecpg/test/expected/thread-descriptor.c
@@ -7,7 +7,6 @@
 #define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y))
 
 #line 1 "descriptor.pgc"
-#ifdef ENABLE_THREAD_SAFETY
 #ifdef WIN32
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
@@ -16,7 +15,6 @@
 #else
 #include <pthread.h>
 #endif
-#endif
 #include <stdio.h>
 
 #define THREADS		16
@@ -91,16 +89,16 @@ struct sqlca_t *ECPGget_sqlca(void);
 
 #endif
 
-#line 16 "descriptor.pgc"
+#line 14 "descriptor.pgc"
 
 /* exec sql whenever sqlerror  sqlprint ; */
-#line 17 "descriptor.pgc"
+#line 15 "descriptor.pgc"
 
 /* exec sql whenever not found  sqlprint ; */
-#line 18 "descriptor.pgc"
+#line 16 "descriptor.pgc"
 
 
-#if defined(ENABLE_THREAD_SAFETY) && defined(WIN32)
+#if defined(WIN32)
 static unsigned __stdcall fn(void* arg)
 #else
 static void* fn(void* arg)
@@ -111,16 +109,16 @@ static void* fn(void* arg)
 	for (i = 1; i <= REPEATS; ++i)
 	{
 		ECPGallocate_desc(__LINE__, "mydesc");
-#line 30 "descriptor.pgc"
+#line 28 "descriptor.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();
-#line 30 "descriptor.pgc"
+#line 28 "descriptor.pgc"
 
 		ECPGdeallocate_desc(__LINE__, "mydesc");
-#line 31 "descriptor.pgc"
+#line 29 "descriptor.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();
-#line 31 "descriptor.pgc"
+#line 29 "descriptor.pgc"
 
 	}
 
@@ -129,7 +127,6 @@ if (sqlca.sqlcode < 0) sqlprint();
 
 int main ()
 {
-#ifdef ENABLE_THREAD_SAFETY
 	int i;
 #ifdef WIN32
 	HANDLE threads[THREADS];
@@ -153,9 +150,6 @@ int main ()
 	for (i = 0; i < THREADS; ++i)
 		pthread_join(threads[i], NULL);
 #endif
-#else
-	fn(NULL);
-#endif
 
 	return 0;
 }
diff --git a/src/interfaces/ecpg/test/expected/thread-prep.c b/src/interfaces/ecpg/test/expected/thread-prep.c
index 7cdf2505d3..052e27b634 100644
--- a/src/interfaces/ecpg/test/expected/thread-prep.c
+++ b/src/interfaces/ecpg/test/expected/thread-prep.c
@@ -11,14 +11,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifdef WIN32
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
@@ -101,7 +93,7 @@ struct sqlca_t *ECPGget_sqlca(void);
 
 #endif
 
-#line 26 "prep.pgc"
+#line 18 "prep.pgc"
 
 
 #line 1 "regression.h"
@@ -111,14 +103,14 @@ struct sqlca_t *ECPGget_sqlca(void);
 
 
 
-#line 27 "prep.pgc"
+#line 19 "prep.pgc"
 
 
 /* exec sql whenever sqlerror  sqlprint ; */
-#line 29 "prep.pgc"
+#line 21 "prep.pgc"
 
 /* exec sql whenever not found  sqlprint ; */
-#line 30 "prep.pgc"
+#line 22 "prep.pgc"
 
 
 #ifdef WIN32
@@ -134,64 +126,64 @@ static void* fn(void* arg)
 	 
 	   
 	
-#line 41 "prep.pgc"
+#line 33 "prep.pgc"
  int value ;
  
-#line 42 "prep.pgc"
+#line 34 "prep.pgc"
  char name [ 100 ] ;
  
-#line 43 "prep.pgc"
+#line 35 "prep.pgc"
  char query [ 256 ] = "INSERT INTO T VALUES ( ? )" ;
 /* exec sql end declare section */
-#line 44 "prep.pgc"
+#line 36 "prep.pgc"
 
 
 	value = (intptr_t) arg;
 	sprintf(name, "Connection: %d", value);
 
 	{ ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , name, 0); 
-#line 49 "prep.pgc"
+#line 41 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 49 "prep.pgc"
+#line 41 "prep.pgc"
 
 	{ ECPGsetcommit(__LINE__, "on", NULL);
-#line 50 "prep.pgc"
+#line 42 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 50 "prep.pgc"
+#line 42 "prep.pgc"
 
 	for (i = 1; i <= REPEATS; ++i)
 	{
 		{ ECPGprepare(__LINE__, NULL, 0, "i", query);
-#line 53 "prep.pgc"
+#line 45 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 53 "prep.pgc"
+#line 45 "prep.pgc"
 
 		{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_execute, "i", 
 	ECPGt_int,&(value),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
-#line 54 "prep.pgc"
+#line 46 "prep.pgc"
 
 if (sqlca.sqlcode == ECPG_NOT_FOUND) sqlprint();
-#line 54 "prep.pgc"
+#line 46 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 54 "prep.pgc"
+#line 46 "prep.pgc"
 
 	}
 	{ ECPGdeallocate(__LINE__, 0, NULL, "i");
-#line 56 "prep.pgc"
+#line 48 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 56 "prep.pgc"
+#line 48 "prep.pgc"
 
 	{ ECPGdisconnect(__LINE__, name);
-#line 57 "prep.pgc"
+#line 49 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 57 "prep.pgc"
+#line 49 "prep.pgc"
 
 
 	return 0;
@@ -207,34 +199,34 @@ int main ()
 #endif
 
 	{ ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0); 
-#line 71 "prep.pgc"
+#line 63 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 71 "prep.pgc"
+#line 63 "prep.pgc"
 
 	{ ECPGsetcommit(__LINE__, "on", NULL);
-#line 72 "prep.pgc"
+#line 64 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 72 "prep.pgc"
+#line 64 "prep.pgc"
 
 	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table if exists T", ECPGt_EOIT, ECPGt_EORT);
-#line 73 "prep.pgc"
+#line 65 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 73 "prep.pgc"
+#line 65 "prep.pgc"
 
 	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table T ( i int )", ECPGt_EOIT, ECPGt_EORT);
-#line 74 "prep.pgc"
+#line 66 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 74 "prep.pgc"
+#line 66 "prep.pgc"
 
 	{ ECPGdisconnect(__LINE__, "CURRENT");
-#line 75 "prep.pgc"
+#line 67 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 75 "prep.pgc"
+#line 67 "prep.pgc"
 
 
 #ifdef WIN32
@@ -256,4 +248,3 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	return 0;
 }
-#endif
diff --git a/src/interfaces/ecpg/test/expected/thread-prep.stdout b/src/interfaces/ecpg/test/expected/thread-prep.stdout
index 75fe16bb36..e69de29bb2 100644
--- a/src/interfaces/ecpg/test/expected/thread-prep.stdout
+++ b/src/interfaces/ecpg/test/expected/thread-prep.stdout
@@ -1 +0,0 @@
-No threading enabled.
diff --git a/src/interfaces/ecpg/test/expected/thread-prep_2.stdout b/src/interfaces/ecpg/test/expected/thread-prep_2.stdout
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/src/interfaces/ecpg/test/expected/thread-thread.c b/src/interfaces/ecpg/test/expected/thread-thread.c
index 0e75c47fab..95faa223c2 100644
--- a/src/interfaces/ecpg/test/expected/thread-thread.c
+++ b/src/interfaces/ecpg/test/expected/thread-thread.c
@@ -15,14 +15,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifndef WIN32
 #include <pthread.h>
 #else
@@ -38,7 +30,7 @@ main(void)
 
 
 
-#line 24 "thread.pgc"
+#line 16 "thread.pgc"
 
 
 void *test_thread(void *arg);
@@ -57,10 +49,10 @@ int main()
   /* exec sql begin declare section */
    
   
-#line 40 "thread.pgc"
+#line 32 "thread.pgc"
  int l_rows ;
 /* exec sql end declare section */
-#line 41 "thread.pgc"
+#line 33 "thread.pgc"
 
 
  /* Do not switch on debug output for regression tests. The threads get executed in
@@ -69,22 +61,22 @@ int main()
 
   /* setup test_thread table */
   { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0); }
-#line 48 "thread.pgc"
+#line 40 "thread.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table test_thread", ECPGt_EOIT, ECPGt_EORT);}
-#line 49 "thread.pgc"
+#line 41 "thread.pgc"
  /* DROP might fail */
   { ECPGtrans(__LINE__, NULL, "commit");}
-#line 50 "thread.pgc"
+#line 42 "thread.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table test_thread ( tstamp timestamp not null default cast ( timeofday ( ) as timestamp ) , thread text not null , iteration integer not null , primary key ( thread , iteration ) )", ECPGt_EOIT, ECPGt_EORT);}
-#line 55 "thread.pgc"
+#line 47 "thread.pgc"
 
   { ECPGtrans(__LINE__, NULL, "commit");}
-#line 56 "thread.pgc"
+#line 48 "thread.pgc"
 
   { ECPGdisconnect(__LINE__, "CURRENT");}
-#line 57 "thread.pgc"
+#line 49 "thread.pgc"
 
 
   /* create, and start, threads */
@@ -116,18 +108,18 @@ int main()
 
   /* and check results */
   { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0); }
-#line 87 "thread.pgc"
+#line 79 "thread.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count ( * ) from test_thread", ECPGt_EOIT, 
 	ECPGt_int,&(l_rows),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
-#line 88 "thread.pgc"
+#line 80 "thread.pgc"
 
   { ECPGtrans(__LINE__, NULL, "commit");}
-#line 89 "thread.pgc"
+#line 81 "thread.pgc"
 
   { ECPGdisconnect(__LINE__, "CURRENT");}
-#line 90 "thread.pgc"
+#line 82 "thread.pgc"
 
   if( l_rows == (nthreads * iterations) )
     printf("Success.\n");
@@ -145,13 +137,13 @@ void *test_thread(void *arg)
     
    
   
-#line 104 "thread.pgc"
+#line 96 "thread.pgc"
  int l_i ;
  
-#line 105 "thread.pgc"
+#line 97 "thread.pgc"
  char l_connection [ 128 ] ;
 /* exec sql end declare section */
-#line 106 "thread.pgc"
+#line 98 "thread.pgc"
 
 
   /* build up connection name, and connect to database */
@@ -161,13 +153,13 @@ void *test_thread(void *arg)
   _snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum);
 #endif
   /* exec sql whenever sqlerror  sqlprint ; */
-#line 114 "thread.pgc"
+#line 106 "thread.pgc"
 
   { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , l_connection, 0); 
-#line 115 "thread.pgc"
+#line 107 "thread.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 115 "thread.pgc"
+#line 107 "thread.pgc"
 
   if( sqlca.sqlcode != 0 )
     {
@@ -175,10 +167,10 @@ if (sqlca.sqlcode < 0) sqlprint();}
       return NULL;
     }
   { ECPGtrans(__LINE__, l_connection, "begin");
-#line 121 "thread.pgc"
+#line 113 "thread.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 121 "thread.pgc"
+#line 113 "thread.pgc"
 
 
   /* insert into test_thread table */
@@ -189,10 +181,10 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_int,&(l_i),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
-#line 126 "thread.pgc"
+#line 118 "thread.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 126 "thread.pgc"
+#line 118 "thread.pgc"
 
       if( sqlca.sqlcode != 0 )
 	printf("%s: ERROR: insert failed!\n", l_connection);
@@ -200,17 +192,16 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
   /* all done */
   { ECPGtrans(__LINE__, l_connection, "commit");
-#line 132 "thread.pgc"
+#line 124 "thread.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 132 "thread.pgc"
+#line 124 "thread.pgc"
 
   { ECPGdisconnect(__LINE__, l_connection);
-#line 133 "thread.pgc"
+#line 125 "thread.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 133 "thread.pgc"
+#line 125 "thread.pgc"
 
   return NULL;
 }
-#endif /* ENABLE_THREAD_SAFETY */
diff --git a/src/interfaces/ecpg/test/expected/thread-thread.stdout b/src/interfaces/ecpg/test/expected/thread-thread.stdout
index 75fe16bb36..a9d787cc55 100644
--- a/src/interfaces/ecpg/test/expected/thread-thread.stdout
+++ b/src/interfaces/ecpg/test/expected/thread-thread.stdout
@@ -1 +1 @@
-No threading enabled.
+Success.
diff --git a/src/interfaces/ecpg/test/expected/thread-thread_2.stdout b/src/interfaces/ecpg/test/expected/thread-thread_2.stdout
deleted file mode 100644
index a9d787cc55..0000000000
--- a/src/interfaces/ecpg/test/expected/thread-thread_2.stdout
+++ /dev/null
@@ -1 +0,0 @@
-Success.
diff --git a/src/interfaces/ecpg/test/expected/thread-thread_implicit.c b/src/interfaces/ecpg/test/expected/thread-thread_implicit.c
index 0df2794530..7ac0297a23 100644
--- a/src/interfaces/ecpg/test/expected/thread-thread_implicit.c
+++ b/src/interfaces/ecpg/test/expected/thread-thread_implicit.c
@@ -15,14 +15,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifndef WIN32
 #include <pthread.h>
 #else
@@ -38,7 +30,7 @@ main(void)
 
 
 
-#line 24 "thread_implicit.pgc"
+#line 16 "thread_implicit.pgc"
 
 
 void *test_thread(void *arg);
@@ -57,10 +49,10 @@ int main()
   /* exec sql begin declare section */
    
   
-#line 40 "thread_implicit.pgc"
+#line 32 "thread_implicit.pgc"
  int l_rows ;
 /* exec sql end declare section */
-#line 41 "thread_implicit.pgc"
+#line 33 "thread_implicit.pgc"
 
 
  /* Do not switch on debug output for regression tests. The threads get executed in
@@ -69,22 +61,22 @@ int main()
 
   /* setup test_thread table */
   { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0); }
-#line 48 "thread_implicit.pgc"
+#line 40 "thread_implicit.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table test_thread", ECPGt_EOIT, ECPGt_EORT);}
-#line 49 "thread_implicit.pgc"
+#line 41 "thread_implicit.pgc"
  /* DROP might fail */
   { ECPGtrans(__LINE__, NULL, "commit");}
-#line 50 "thread_implicit.pgc"
+#line 42 "thread_implicit.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table test_thread ( tstamp timestamp not null default cast ( timeofday ( ) as timestamp ) , thread text not null , iteration integer not null , primary key ( thread , iteration ) )", ECPGt_EOIT, ECPGt_EORT);}
-#line 55 "thread_implicit.pgc"
+#line 47 "thread_implicit.pgc"
 
   { ECPGtrans(__LINE__, NULL, "commit");}
-#line 56 "thread_implicit.pgc"
+#line 48 "thread_implicit.pgc"
 
   { ECPGdisconnect(__LINE__, "CURRENT");}
-#line 57 "thread_implicit.pgc"
+#line 49 "thread_implicit.pgc"
 
 
   /* create, and start, threads */
@@ -116,18 +108,18 @@ int main()
 
   /* and check results */
   { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0); }
-#line 87 "thread_implicit.pgc"
+#line 79 "thread_implicit.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count ( * ) from test_thread", ECPGt_EOIT, 
 	ECPGt_int,&(l_rows),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
-#line 88 "thread_implicit.pgc"
+#line 80 "thread_implicit.pgc"
 
   { ECPGtrans(__LINE__, NULL, "commit");}
-#line 89 "thread_implicit.pgc"
+#line 81 "thread_implicit.pgc"
 
   { ECPGdisconnect(__LINE__, "CURRENT");}
-#line 90 "thread_implicit.pgc"
+#line 82 "thread_implicit.pgc"
 
   if( l_rows == (nthreads * iterations) )
     printf("Success.\n");
@@ -145,13 +137,13 @@ void *test_thread(void *arg)
     
    
   
-#line 104 "thread_implicit.pgc"
+#line 96 "thread_implicit.pgc"
  int l_i ;
  
-#line 105 "thread_implicit.pgc"
+#line 97 "thread_implicit.pgc"
  char l_connection [ 128 ] ;
 /* exec sql end declare section */
-#line 106 "thread_implicit.pgc"
+#line 98 "thread_implicit.pgc"
 
 
   /* build up connection name, and connect to database */
@@ -161,13 +153,13 @@ void *test_thread(void *arg)
   _snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum);
 #endif
   /* exec sql whenever sqlerror  sqlprint ; */
-#line 114 "thread_implicit.pgc"
+#line 106 "thread_implicit.pgc"
 
   { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , l_connection, 0); 
-#line 115 "thread_implicit.pgc"
+#line 107 "thread_implicit.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 115 "thread_implicit.pgc"
+#line 107 "thread_implicit.pgc"
 
   if( sqlca.sqlcode != 0 )
     {
@@ -175,10 +167,10 @@ if (sqlca.sqlcode < 0) sqlprint();}
       return NULL;
     }
   { ECPGtrans(__LINE__, NULL, "begin");
-#line 121 "thread_implicit.pgc"
+#line 113 "thread_implicit.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 121 "thread_implicit.pgc"
+#line 113 "thread_implicit.pgc"
 
 
   /* insert into test_thread table */
@@ -189,10 +181,10 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_int,&(l_i),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
-#line 126 "thread_implicit.pgc"
+#line 118 "thread_implicit.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 126 "thread_implicit.pgc"
+#line 118 "thread_implicit.pgc"
 
       if( sqlca.sqlcode != 0 )
 	printf("%s: ERROR: insert failed!\n", l_connection);
@@ -200,17 +192,16 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
   /* all done */
   { ECPGtrans(__LINE__, NULL, "commit");
-#line 132 "thread_implicit.pgc"
+#line 124 "thread_implicit.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 132 "thread_implicit.pgc"
+#line 124 "thread_implicit.pgc"
 
   { ECPGdisconnect(__LINE__, l_connection);
-#line 133 "thread_implicit.pgc"
+#line 125 "thread_implicit.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 133 "thread_implicit.pgc"
+#line 125 "thread_implicit.pgc"
 
   return NULL;
 }
-#endif /* ENABLE_THREAD_SAFETY */
diff --git a/src/interfaces/ecpg/test/expected/thread-thread_implicit.stdout b/src/interfaces/ecpg/test/expected/thread-thread_implicit.stdout
index 75fe16bb36..a9d787cc55 100644
--- a/src/interfaces/ecpg/test/expected/thread-thread_implicit.stdout
+++ b/src/interfaces/ecpg/test/expected/thread-thread_implicit.stdout
@@ -1 +1 @@
-No threading enabled.
+Success.
diff --git a/src/interfaces/ecpg/test/expected/thread-thread_implicit_2.stdout b/src/interfaces/ecpg/test/expected/thread-thread_implicit_2.stdout
deleted file mode 100644
index a9d787cc55..0000000000
--- a/src/interfaces/ecpg/test/expected/thread-thread_implicit_2.stdout
+++ /dev/null
@@ -1 +0,0 @@
-Success.
diff --git a/src/interfaces/ecpg/test/thread/alloc.pgc b/src/interfaces/ecpg/test/thread/alloc.pgc
index c0021a737e..d3d35493bf 100644
--- a/src/interfaces/ecpg/test/thread/alloc.pgc
+++ b/src/interfaces/ecpg/test/thread/alloc.pgc
@@ -2,14 +2,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifdef WIN32
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
@@ -87,4 +79,3 @@ int main ()
 
 	return 0;
 }
-#endif
diff --git a/src/interfaces/ecpg/test/thread/descriptor.pgc b/src/interfaces/ecpg/test/thread/descriptor.pgc
index 76a7a5dff5..30bce7c87b 100644
--- a/src/interfaces/ecpg/test/thread/descriptor.pgc
+++ b/src/interfaces/ecpg/test/thread/descriptor.pgc
@@ -1,4 +1,3 @@
-#ifdef ENABLE_THREAD_SAFETY
 #ifdef WIN32
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
@@ -7,7 +6,6 @@
 #else
 #include <pthread.h>
 #endif
-#endif
 #include <stdio.h>
 
 #define THREADS		16
@@ -17,7 +15,7 @@ EXEC SQL include sqlca;
 EXEC SQL whenever sqlerror sqlprint;
 EXEC SQL whenever not found sqlprint;
 
-#if defined(ENABLE_THREAD_SAFETY) && defined(WIN32)
+#if defined(WIN32)
 static unsigned __stdcall fn(void* arg)
 #else
 static void* fn(void* arg)
@@ -36,7 +34,6 @@ static void* fn(void* arg)
 
 int main ()
 {
-#ifdef ENABLE_THREAD_SAFETY
 	int i;
 #ifdef WIN32
 	HANDLE threads[THREADS];
@@ -60,9 +57,6 @@ int main ()
 	for (i = 0; i < THREADS; ++i)
 		pthread_join(threads[i], NULL);
 #endif
-#else
-	fn(NULL);
-#endif
 
 	return 0;
 }
diff --git a/src/interfaces/ecpg/test/thread/prep.pgc b/src/interfaces/ecpg/test/thread/prep.pgc
index d7ecfd4855..f61b31ce10 100644
--- a/src/interfaces/ecpg/test/thread/prep.pgc
+++ b/src/interfaces/ecpg/test/thread/prep.pgc
@@ -2,14 +2,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifdef WIN32
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
@@ -93,4 +85,3 @@ int main ()
 
 	return 0;
 }
-#endif
diff --git a/src/interfaces/ecpg/test/thread/thread.pgc b/src/interfaces/ecpg/test/thread/thread.pgc
index e7d8c00af6..b9b9ebb441 100644
--- a/src/interfaces/ecpg/test/thread/thread.pgc
+++ b/src/interfaces/ecpg/test/thread/thread.pgc
@@ -6,14 +6,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifndef WIN32
 #include <pthread.h>
 #else
@@ -133,4 +125,3 @@ void *test_thread(void *arg)
   EXEC SQL DISCONNECT :l_connection;
   return NULL;
 }
-#endif /* ENABLE_THREAD_SAFETY */
diff --git a/src/interfaces/ecpg/test/thread/thread_implicit.pgc b/src/interfaces/ecpg/test/thread/thread_implicit.pgc
index b4cae7e1ae..ff9b12a943 100644
--- a/src/interfaces/ecpg/test/thread/thread_implicit.pgc
+++ b/src/interfaces/ecpg/test/thread/thread_implicit.pgc
@@ -6,14 +6,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifndef WIN32
 #include <pthread.h>
 #else
@@ -133,4 +125,3 @@ void *test_thread(void *arg)
   EXEC SQL DISCONNECT :l_connection;
   return NULL;
 }
-#endif /* ENABLE_THREAD_SAFETY */
diff --git a/src/interfaces/libpq/Makefile b/src/interfaces/libpq/Makefile
index 8abdb092c2..6af1dbfe8e 100644
--- a/src/interfaces/libpq/Makefile
+++ b/src/interfaces/libpq/Makefile
@@ -71,10 +71,8 @@ ifeq ($(PORTNAME), win32)
 OBJS += \
 	win32.o
 
-ifeq ($(enable_thread_safety), yes)
 OBJS += pthread-win32.o
 endif
-endif
 
 
 # Add libraries that libpq depends (or might depend) on into the
diff --git a/src/interfaces/libpq/fe-auth.c b/src/interfaces/libpq/fe-auth.c
index 49a1c626f6..3504ab2c34 100644
--- a/src/interfaces/libpq/fe-auth.c
+++ b/src/interfaces/libpq/fe-auth.c
@@ -1116,11 +1116,10 @@ pg_fe_getusername(uid_t user_id, PQExpBuffer errorMessage)
 #endif
 
 	/*
-	 * Some users are using configure --enable-thread-safety-force, so we
-	 * might as well do the locking within our library to protect getpwuid().
-	 * In fact, application developers can use getpwuid() in their application
-	 * if they use the locking call we provide, or install their own locking
-	 * function using PQregisterThreadLock().
+	 * We do the locking within our library to protect getpwuid().  Application
+	 * developers can use getpwuid() in their application if they use the
+	 * locking call we provide, or install their own locking function using
+	 * PQregisterThreadLock().
 	 */
 	pglock_thread();
 
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index dc49387d6c..7f14026777 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -55,13 +55,11 @@
 #endif
 #endif
 
-#ifdef ENABLE_THREAD_SAFETY
 #ifdef WIN32
 #include "pthread-win32.h"
 #else
 #include <pthread.h>
 #endif
-#endif
 
 #ifdef USE_LDAP
 #ifdef WIN32
@@ -7364,7 +7362,6 @@ pqGetHomeDirectory(char *buf, int bufsize)
 static void
 default_threadlock(int acquire)
 {
-#ifdef ENABLE_THREAD_SAFETY
 #ifndef WIN32
 	static pthread_mutex_t singlethread_lock = PTHREAD_MUTEX_INITIALIZER;
 #else
@@ -7393,7 +7390,6 @@ default_threadlock(int acquire)
 		if (pthread_mutex_unlock(&singlethread_lock))
 			Assert(false);
 	}
-#endif
 }
 
 pgthreadlock_t
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index a36f5eb310..41861e6a11 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -3924,11 +3924,7 @@ PQisnonblocking(const PGconn *conn)
 int
 PQisthreadsafe(void)
 {
-#ifdef ENABLE_THREAD_SAFETY
 	return true;
-#else
-	return false;
-#endif
 }
 
 
diff --git a/src/interfaces/libpq/fe-print.c b/src/interfaces/libpq/fe-print.c
index 783cd9b756..2dc0f1afb9 100644
--- a/src/interfaces/libpq/fe-print.c
+++ b/src/interfaces/libpq/fe-print.c
@@ -88,14 +88,11 @@ PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
 		bool		usePipe = false;
 		char	   *pagerenv;
 
-#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
+#if !defined(WIN32)
 		sigset_t	osigset;
 		bool		sigpipe_masked = false;
 		bool		sigpipe_pending;
 #endif
-#if !defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
-		pqsigfunc	oldsigpipehandler = NULL;
-#endif
 
 #ifdef TIOCGWINSZ
 		struct winsize screen_size;
@@ -185,12 +182,8 @@ PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
 				{
 					usePipe = true;
 #ifndef WIN32
-#ifdef ENABLE_THREAD_SAFETY
 					if (pq_block_sigpipe(&osigset, &sigpipe_pending) == 0)
 						sigpipe_masked = true;
-#else
-					oldsigpipehandler = pqsignal(SIGPIPE, SIG_IGN);
-#endif							/* ENABLE_THREAD_SAFETY */
 #endif							/* WIN32 */
 				}
 				else
@@ -323,13 +316,9 @@ exit:
 #else
 			pclose(fout);
 
-#ifdef ENABLE_THREAD_SAFETY
 			/* we can't easily verify if EPIPE occurred, so say it did */
 			if (sigpipe_masked)
 				pq_reset_sigpipe(&osigset, sigpipe_pending, true);
-#else
-			pqsignal(SIGPIPE, oldsigpipehandler);
-#endif							/* ENABLE_THREAD_SAFETY */
 #endif							/* WIN32 */
 		}
 	}
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index 8117cbd40f..01b2494bb4 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -46,13 +46,11 @@
 
 #include <sys/stat.h>
 
-#ifdef ENABLE_THREAD_SAFETY
 #ifdef WIN32
 #include "pthread-win32.h"
 #else
 #include <pthread.h>
 #endif
-#endif
 
 /*
  * These SSL-related #includes must come after all system-provided headers.
@@ -93,7 +91,6 @@ static bool pq_init_crypto_lib = true;
 
 static bool ssl_lib_initialized = false;
 
-#ifdef ENABLE_THREAD_SAFETY
 static long crypto_open_connections = 0;
 
 #ifndef WIN32
@@ -102,7 +99,6 @@ static pthread_mutex_t ssl_config_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t ssl_config_mutex = NULL;
 static long win32_ssl_create_mutex = 0;
 #endif
-#endif							/* ENABLE_THREAD_SAFETY */
 
 static PQsslKeyPassHook_OpenSSL_type PQsslKeyPassHook = NULL;
 static int	ssl_protocol_version_to_openssl(const char *protocol);
@@ -114,15 +110,12 @@ static int	ssl_protocol_version_to_openssl(const char *protocol);
 void
 pgtls_init_library(bool do_ssl, int do_crypto)
 {
-#ifdef ENABLE_THREAD_SAFETY
-
 	/*
 	 * Disallow changing the flags while we have open connections, else we'd
 	 * get completely confused.
 	 */
 	if (crypto_open_connections != 0)
 		return;
-#endif
 
 	pq_init_ssl_lib = do_ssl;
 	pq_init_crypto_lib = do_crypto;
@@ -709,7 +702,7 @@ pgtls_verify_peer_name_matches_certificate_guts(PGconn *conn,
 	return rc;
 }
 
-#if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_CRYPTO_LOCK)
+#if defined(HAVE_CRYPTO_LOCK)
 /*
  *	Callback functions for OpenSSL internal locking.  (OpenSSL 1.1.0
  *	does its own locking, and doesn't need these anymore.  The
@@ -750,7 +743,7 @@ pq_lockingcallback(int mode, int n, const char *file, int line)
 			Assert(false);
 	}
 }
-#endif							/* ENABLE_THREAD_SAFETY && HAVE_CRYPTO_LOCK */
+#endif							/* HAVE_CRYPTO_LOCK */
 
 /*
  * Initialize SSL library.
@@ -765,7 +758,6 @@ pq_lockingcallback(int mode, int n, const char *file, int line)
 int
 pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto)
 {
-#ifdef ENABLE_THREAD_SAFETY
 #ifdef WIN32
 	/* Also see similar code in fe-connect.c, default_threadlock() */
 	if (ssl_config_mutex == NULL)
@@ -831,7 +823,6 @@ pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto)
 		}
 	}
 #endif							/* HAVE_CRYPTO_LOCK */
-#endif							/* ENABLE_THREAD_SAFETY */
 
 	if (!ssl_lib_initialized && do_ssl)
 	{
@@ -848,9 +839,7 @@ pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto)
 		ssl_lib_initialized = true;
 	}
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_unlock(&ssl_config_mutex);
-#endif
 	return 0;
 }
 
@@ -869,7 +858,7 @@ pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto)
 static void
 destroy_ssl_system(void)
 {
-#if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_CRYPTO_LOCK)
+#if defined(HAVE_CRYPTO_LOCK)
 	/* Mutex is created in pgtls_init() */
 	if (pthread_mutex_lock(&ssl_config_mutex))
 		return;
diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c
index a1dc7b796d..88607fb65b 100644
--- a/src/interfaces/libpq/fe-secure.c
+++ b/src/interfaces/libpq/fe-secure.c
@@ -37,13 +37,11 @@
 
 #include <sys/stat.h>
 
-#ifdef ENABLE_THREAD_SAFETY
 #ifdef WIN32
 #include "pthread-win32.h"
 #else
 #include <pthread.h>
 #endif
-#endif
 
 #include "fe-auth.h"
 #include "libpq-fe.h"
@@ -58,8 +56,6 @@
 
 #define SIGPIPE_MASKED(conn)	((conn)->sigpipe_so || (conn)->sigpipe_flag)
 
-#ifdef ENABLE_THREAD_SAFETY
-
 struct sigpipe_info
 {
 	sigset_t	oldsigmask;
@@ -92,24 +88,6 @@ struct sigpipe_info
 			pq_reset_sigpipe(&(spinfo).oldsigmask, (spinfo).sigpipe_pending, \
 							 (spinfo).got_epipe); \
 	} while (0)
-#else							/* !ENABLE_THREAD_SAFETY */
-
-#define DECLARE_SIGPIPE_INFO(spinfo) pqsigfunc spinfo = NULL
-
-#define DISABLE_SIGPIPE(conn, spinfo, failaction) \
-	do { \
-		if (!SIGPIPE_MASKED(conn)) \
-			spinfo = pqsignal(SIGPIPE, SIG_IGN); \
-	} while (0)
-
-#define REMEMBER_EPIPE(spinfo, cond)
-
-#define RESTORE_SIGPIPE(conn, spinfo) \
-	do { \
-		if (!SIGPIPE_MASKED(conn)) \
-			pqsignal(SIGPIPE, spinfo); \
-	} while (0)
-#endif							/* ENABLE_THREAD_SAFETY */
 #else							/* WIN32 */
 
 #define DECLARE_SIGPIPE_INFO(spinfo)
@@ -524,7 +502,7 @@ PQgssEncInUse(PGconn *conn)
 #endif							/* ENABLE_GSS */
 
 
-#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
+#if !defined(WIN32)
 
 /*
  *	Block SIGPIPE for this thread.  This prevents send()/write() from exiting
@@ -608,4 +586,4 @@ pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, bool got_epipe)
 	SOCK_ERRNO_SET(save_errno);
 }
 
-#endif							/* ENABLE_THREAD_SAFETY && !WIN32 */
+#endif							/* !WIN32 */
diff --git a/src/interfaces/libpq/legacy-pqsignal.c b/src/interfaces/libpq/legacy-pqsignal.c
index db470df9ea..1b4424eabb 100644
--- a/src/interfaces/libpq/legacy-pqsignal.c
+++ b/src/interfaces/libpq/legacy-pqsignal.c
@@ -27,10 +27,6 @@
  * Because it is only intended for backwards compatibility, we freeze it
  * with the semantics it had in 9.2; in particular, this has different
  * behavior for SIGALRM than the version in src/port/pqsignal.c.
- *
- * libpq itself uses this only for SIGPIPE (and even then, only in
- * non-ENABLE_THREAD_SAFETY builds), so the incompatibility isn't
- * troublesome for internal references.
  */
 pqsigfunc
 pqsignal(int signo, pqsigfunc func)
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index 51ab51f9f9..99c40af8cf 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -28,14 +28,12 @@
 #include <sys/time.h>
 #endif
 
-#ifdef ENABLE_THREAD_SAFETY
 #ifdef WIN32
 #include "pthread-win32.h"
 #else
 #include <pthread.h>
 #endif
 #include <signal.h>
-#endif
 
 /* include stuff common to fe and be */
 #include "getaddrinfo.h"
@@ -649,15 +647,10 @@ extern int	pqPacketSend(PGconn *conn, char pack_type,
 						 const void *buf, size_t buf_len);
 extern bool pqGetHomeDirectory(char *buf, int bufsize);
 
-#ifdef ENABLE_THREAD_SAFETY
 extern pgthreadlock_t pg_g_threadlock;
 
 #define pglock_thread()		pg_g_threadlock(true)
 #define pgunlock_thread()	pg_g_threadlock(false)
-#else
-#define pglock_thread()		((void) 0)
-#define pgunlock_thread()	((void) 0)
-#endif
 
 /* === in fe-exec.c === */
 
@@ -732,7 +725,7 @@ extern ssize_t pqsecure_write(PGconn *, const void *ptr, size_t len);
 extern ssize_t pqsecure_raw_read(PGconn *, void *ptr, size_t len);
 extern ssize_t pqsecure_raw_write(PGconn *, const void *ptr, size_t len);
 
-#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
+#if !defined(WIN32)
 extern int	pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending);
 extern void pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending,
 							 bool got_epipe);
diff --git a/src/port/getaddrinfo.c b/src/port/getaddrinfo.c
index bea7b520f0..8cb3a4db2f 100644
--- a/src/port/getaddrinfo.c
+++ b/src/port/getaddrinfo.c
@@ -414,7 +414,7 @@ pqGethostbyname(const char *name,
 				struct hostent **result,
 				int *herrno)
 {
-#if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_GETHOSTBYNAME_R)
+#if defined(HAVE_GETHOSTBYNAME_R)
 
 	/*
 	 * broken (well early POSIX draft) gethostbyname_r() which returns 'struct
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index a4cebdcf96..22ee155cd1 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -219,7 +219,6 @@ sub GenerateFiles
 		DLSUFFIX                   => '".dll"',
 		ENABLE_GSS                 => $self->{options}->{gss} ? 1 : undef,
 		ENABLE_NLS                 => $self->{options}->{nls} ? 1 : undef,
-		ENABLE_THREAD_SAFETY       => 1,
 		GETTIMEOFDAY_1ARG          => undef,
 		HAVE_APPEND_HISTORY        => undef,
 		HAVE_ASN1_STRING_GET0_DATA => undef,
@@ -1211,7 +1210,7 @@ sub GetFakeConfigure
 {
 	my $self = shift;
 
-	my $cfg = '--enable-thread-safety';
+	my $cfg = '';
 	$cfg .= ' --enable-cassert'   if ($self->{options}->{asserts});
 	$cfg .= ' --enable-nls'       if ($self->{options}->{nls});
 	$cfg .= ' --enable-tap-tests' if ($self->{options}->{tap_tests});
diff --git a/src/tools/msvc/ecpg_regression.proj b/src/tools/msvc/ecpg_regression.proj
index ec2760b1f6..0ec60a275e 100644
--- a/src/tools/msvc/ecpg_regression.proj
+++ b/src/tools/msvc/ecpg_regression.proj
@@ -54,7 +54,7 @@
 
   <!-- Run ECPG and the Visual C++ compiler on the files. Don't bother with dependency check between the steps -->
   <Exec WorkingDirectory="%(Pgc.RelativeDir)" Command="$(OUTDIR)ecpg\ecpg -I ../../include --regression $(ECPGPARAM) -o %(Pgc.Filename).c %(Pgc.Filename).pgc" />
-  <Exec WorkingDirectory="%(Pgc.RelativeDir)" Command="cl /nologo %(Pgc.FileName).c /TC /MD$(DEBUGLIB) /DENABLE_THREAD_SAFETY /DWIN32 /I. /I..\..\include /I..\..\..\libpq /I..\..\..\..\include /link /defaultlib:$(OUTDIR)libecpg\libecpg.lib /defaultlib:$(OUTDIR)libecpg_compat\libecpg_compat.lib /defaultlib:$(OUTDIR)libpgtypes\libpgtypes.lib" />
+  <Exec WorkingDirectory="%(Pgc.RelativeDir)" Command="cl /nologo %(Pgc.FileName).c /TC /MD$(DEBUGLIB) /DWIN32 /I. /I..\..\include /I..\..\..\libpq /I..\..\..\..\include /link /defaultlib:$(OUTDIR)libecpg\libecpg.lib /defaultlib:$(OUTDIR)libecpg_compat\libecpg_compat.lib /defaultlib:$(OUTDIR)libpgtypes\libpgtypes.lib" />
  </Target>
 
  <!-- Clean up all output files -->
-- 
2.30.2

#14Tom Lane
tgl@sss.pgh.pa.us
In reply to: Thomas Munro (#13)
Re: Cleaning up historical portability baggage

Thomas Munro <thomas.munro@gmail.com> writes:

Some of these depend on SUSv2 options (not just "base"), but we
already do that (fsync, ...) and they're all features that are by now
ubiquitous, which means the fallback code is untested and the probes
are pointless.

Reading this, it occurred to me that it'd be interesting to scrape
all of the latest configure results from the buildfarm, and see which
tests actually produce more than one answer among the set of tested
platforms. Those that don't could be targets for further simplification,
or else an indicator that we'd better go find some more animals.

Before I go off and do that, though, I wonder if you already did.

regards, tom lane

#15Thomas Munro
thomas.munro@gmail.com
In reply to: Tom Lane (#14)
1 attachment(s)
Re: Cleaning up historical portability baggage

On Sun, Jul 24, 2022 at 11:11 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Thomas Munro <thomas.munro@gmail.com> writes:

Some of these depend on SUSv2 options (not just "base"), but we
already do that (fsync, ...) and they're all features that are by now
ubiquitous, which means the fallback code is untested and the probes
are pointless.

Reading this, it occurred to me that it'd be interesting to scrape
all of the latest configure results from the buildfarm, and see which
tests actually produce more than one answer among the set of tested
platforms. Those that don't could be targets for further simplification,
or else an indicator that we'd better go find some more animals.

Before I go off and do that, though, I wonder if you already did.

Yeah, here are the macros I scraped yesterday, considering the latest
results from machines that did something in the past week.

Attachments:

scrape.sql.gzapplication/gzip; name=scrape.sql.gzDownload
����bscrape.sql�]yo������B�}�"[�GA�+���]CQ�,@P%qL�q�>�V���.:��y�<�UU������3���f�1�x:�?����+;r��p������Mc�J��Fn�7���'�znw{Z�x���F��sp�����$q�S��1ey��Q����\��C���u�����ZYx��L��������q�4GW�����n�u�o��V��W�������d�_�"�`w9q*��~;�;\����O�5N����E����{��M�l�+�����2������4��
��YX��K�|�C&�����{��n��f��~�vt�l�����W�����}Jq-{��0F�6 �w��Gv��������ym?6��#�n������v���c��������w�~#>$~�24���e���S���M��As#v~����I�������y3��A<:�:e�Y>���^�W�3��O�����qSE3�n{����3uu���j���mv�f`^����A�i6�wloo����\����Wnp���c�??_%���������|��w�����m�\�<�3C��-f�G�����L�?6��N��i��7;���_[����h��yI:o� �+�=�1s-����~�����A�'������HC�>�{W�^
���]pH���8l�H^��~�}�s��~t��}���K=�����~�

����8n��Z/�Tou�@�NT�7�B�TL
��O{m��+���&����4d�w�`����R+E�j/����v<;:+H������*j������L:�\_q�R����V
|m7t�M�S�RD��w��'a���%j��������7�!p#��T�G���>���������8p�������W���tP[!��S�����1T�[�b�9����MB�Y)�O�}�'�3�������j�w��K����W4S�����i��o���*Z��������:QL�l�W,w��F��������P#����+�<=��wU+��PUE�RNy�
�Aw�^�dj� x�"�8vX��$�G�]�4Q�	����*�c'�z�[7R���.r���.��+w�wU�+S"�����(<$���������;�>;jiX���#�
��#�"���x� t�A���B
Y�_��
�������Q��J���o�[�G��V-"s5����a�/P�� k�K���[�FOuP��� _��v�x�a2SB����l��o��r�]9*�i?+_��I�!�`vA��ve2%��pI����
	�S>HN�0x�Y,��A���(�UA�D�T�g�'�U"�V�/J=T5�~����D��������o���W�8~���M���������C�	�!W�x9M���+9��B7R��3%�AAj�b�=�QdGv�S��JQM�@��P�9T���\��.� �k��O����#\�������/�f��p����*V^�������]�[��Y)����
��t����r1�)!=�B��mB{�_�55�G��7Nt~<����RT74�����s�D�2-Sq���X���*!��p���5P�82%��@���X��=X+R��L�=�v{�����)��&����rB�DP���R�B���.z�Al�_�xU��/�x�9=���ZQ�z���N+*lTiY��T��PSw�<��8�,7�^[*"���[�[�Q��2%�]��dw�2�*�+������T�8�1HT�F���JA���R�����1SB��=�8$��SAB�-���E�/�B^:?���m�O�+g��L�����/Xn������6����c����\p� t*�eR%��&�(zt����
}���8��h�z�_')�P���xk�G;Vu�T5`���W����p��r=��B(�+�z�w��������WEz*���;�mW��K=�}�]+q����R.��Y�w�4�K�m���58��|�17���z�mm����8p�^�r����C�
P�@�p<)�Q���#w'�;��3������J49����^�fZ(�Pq����]C��Z��Z����Kov��B+����A%��r��)!cq[���>?��2�U����n����W�(	���V�!�,T�R;.�j����!�R�OBf��~��`������H��O������a�Z%���S�
j�^G��=�����5��@�O v�������S���}b��L	�y��=���`G���?��m�?���!s-d�����{B�@s5d
qI���=�����
=5E�T�>���SN��jP�] i��]1�I����*��mD������(wN5�
�C�`A���x�A��S������*@�i�)b�/��V���H5�V��+H�'���}���5�����K�������{�E��+�:r'�c��)�bR-��������V������,}������$���o���������������yE��4?n5k:�h'o��bs`d2��H2_4c���'o��`�,�0
}z�����^��|f�0�k��]�?��:���1>y[����>����l:�o��f
������i�y�"����>88����a�g�e�0��;mps��Q|��}r�}��;a������������[�s^��^g����x�l���j��O����Z��5�sfp'P�����I����S�����gz����mzBl�2����[�+��?/��\�?t
��������i'�n������g������������n>X��zi���$���h����=��rtm���2��Jk1i�C����qm-�/`����O/����6�z*���aa�sma���90e�y3��	2s�<�&3��FZU��5�1o�'��S8y�����g��N3t��������������~C1�f�����;5�Il��>�d�7<��>���}`�&�S���l,o�J[��kC}:�IX�l.��>������[R�|6�GeV��r������pg�A�3$���FC[���P��;}���5��w5t��7�-�1���;)}*�M���3y���[H��f��Pd����\>��d�gFX/q���B
���q�k�'\,�x+�-���'���������b��5�Rg#���������l2
,*��$!I�05j%�S����H�����X�3s&�%��9a?�f�/�a���~���/��?`�e������
&����g��Q�����Z*r�.�:>�����u�Y/p�� ���+�uui]� 2��S����R�ld�F#����1
p�(���=,S�h��\C�e�!����l�C��EY����7b���A2b�����0��D�9�S�Mi_X@�H��s����3�O���� ���]J}�fs�����1]�y�����&�,�����c:�F:X�I��9�M
!�kxE�G_/����������^m@��\��Z3��r�����%�i�E���}�.{�
�,�|�UMj6?��2�l��O��!����k�P���%���C�o�!
!�"���x�N��0����k�x+�t�;��6��1�0��|�u�������������p1���_��7�6�ynNT�����LPM)����0t�����M��,�$�^���:t<�k�T;���� �;�
)Z���D.��x�b��
�`7E���E�<e�<
y8J���c���	�^sx��X2������YuE�Z��20���x�O��mM���v����X'�?�����f���F�����.�b<�����Gc���d�eW�����_D�O��$B�;e�w����d��Ii
7�%��J�dp�O�+�W�lC���lG,�>a}H�jQd�<ZY��J�� xbK/@K��
���pL5���e-���9�5�/�"-�Zt�ngh}��;��US�lm�Y^N����n[�9�*o�����8���Y#���g(p�`ny������+�Bi/Gn�5��#�G��u�s��Gn2���pt���g�[���8+����Y�����=������j�[��c��o����U�)��H�}K,A6.�����/�.����]�g��,����7b���ftt}��Ny�w��?%�x�<i��tE���7<��%�}l�p���.�z���x��g�]�8x�������(��.'�����x�=����#D�Q�6!I��'�������S��{��s�� 	���j�5c���~��{��jI]������sM{7�b��>���������h�v���m4�~������>8�cq�	��������8��o�J�$r6���3�F��o2G�C'��(r����6M�wc���9!���|�M��~�fx��a���n6�t�D�9�l2���r~Fu�k�E��g��r�[F���4�2D�����gq�1+U|K��]��%��F��j���L�FzAfi%k:eiIO�K�V�g���K����9��x^��f0G�!�A�Q�������h������dLc������Zl�K���/r*�K@�s!O-�x����z
@�����#@����������������b1����w?OZ?�PY����C�a�v.1t`��E�CZ���%��.�H1}
�[B�5�1S��o�cM���7XL�����-R��d��yO)(y#C��?��&�|�C�E�)��]32�����"�M:��s�-��c���`�*�M8DF����^ /��k������J\Fb	��x*d��Mjwu���:#3�2��g�t��t��%4#`4���f�X�P��%	3^9�������~��$�G�	����[?��^B~hQ��ED�G���N�#
p������(Q@� ���&�B�t
�)x5(5b	���@e�"A�����"����lD�A� 4H�p��u�aN	�YV���e��D6��
I�/����H��!|�%2�%4�����K	IT#����h����]�2  ���3�V�3�yJD`�H��'�"���$���D�� �����E$/�+�9���#b�d$�E�����F��g�����r'	7"�@*���WD\��������E%|�=�:�@"/eA��(��D���tD���E�5^#Iy���������HK���X��,h�����[,g����P*�b��I\��,�oq��x'���x��A�^XFi������8�����7��F��P��#_\1AA_����(-�_��)�/D/�/D�����0L�0L�QRb`C����Q0�R��DW�p�	{Qd����E,�%!Z������a��x���������A�F�	��}�=k5/~���1bP��Y�!C2rW	���!����G���P�����
p�8�Da�J�D�%Lx	a�l���P�&{c���5�V^����+�PU���@��3�P�W�,W�X*f�1
KN�Q����;
W�*�I��s$p��5�J1	Z��4�".+"7CQ�
�An��)�S
L���nND��p��"�K4�'s`�,-�*@!h�	����kpBD�W���A����A$A�ox>��<�z"��-A��`	�g�O��Jx!)��(�,'�X��2%!Y9H�9H�����	�
�TPE_��>�s�v����8����F���aF<2"X�~`��j9,����%(�9&"��
�Y�~WC���,��>��<"T���9(�$���@)�� ��H0�d��'H��t��qa�
�Ct��PRR9H	��E0�����p|� ����*x�R�A�s ��+l#'S�E��A6��J`C�"�_��5������=��S3,{�x��b���TB�@��mD0���uvQD�@�(1q~�C�D��������_���@��d%���%�!�	1���D��;� =��7��]��	p������8�$[�~���25@�HQ�LfB"��CR��c�hE�Haxq��/�o��2#���ZYh��g���&|yDFfFxF�����!��mH��
�#���r
oh�=d����;��u| Z���J�����*�nb�$G���e�q:���~(�q����P)E�=�b(�7[��i���
_��R@/ ���"��ci��BLm����.0�7nAgA����E	d!������E��E�q��"��IpE~F+��hX��U���8u�����
TUp
s#��s�F)��A�h.x�Q�y$`�54>Q��'�a:�1��M�	���D�c���py.���z���2/��W}�� ����
�E������������W'�v���w?]\�r��3�t����a�����������b��tv;��}j����h���;'�IR���^�����>B����D"�e6���?�vs{���������������p���`.`�}��tv;��"�������d���_����`1X��^|�|�.{���������e�8/�>�7Z��\��<aD�n�(��gH�#
��!�3��T�N�h�8|�"�p�F|w������n,�4�Y���V@x�k(��

o��Js�R�%w��T����(%�#q��5�b� B���C"B}����j�G�2�H�a&�PHq	:
d�.�M���	]��� �T.F��q�h,��I�����l����H�������s��Z��	
��GTT9����(
)��i$E�����gDE�G����y��*a����<iA���qR�.�k��zy��r�S
J����h@�B�bG=��z��|��!fB-��pKR>"�)'�.+z���qY,��`��@�������Y�o��z�C��g�^�?�v��)V8�h[�%�u�.4P\�Yx�/Bl��mFExiFCIIe��Zu�
gH0@#�F�4Bk����Q��l��
�P��^�i�1��w�N��������W]����iu�J|P����JNw�1Vr��B A�<��L.@B71'@�t��.��.#%�`2�"*v�T"Fz����J�dH��!-�F���$?M&���*e�T�,�P8b$��J�2%?
i���6�g]#N�,e�w)��II$P���S(��#QS�@���&)�%�P��Y���O�)QB*����gx��qU�5!�j�����������nb�	_YJ�@h	i�ZB�k�+�=�9�
e��r'���������^�kM�����������kk�@�w��d^�h�{�
�kv�����{�g��~|����~�_��-Jn�nln<������������������O��b	���i��0{��rq�i�ee�
�Xc��_Ts5��[D�Y6�����c����������ydj?^�g��7�����r��~��zv2��������������;R7~�n��oK
6"��g������]���|��f>t�U���A���l?]�{�j�Y�kR���]�<���K��*��x76�**,l]�^���������������O��^��On/�_�{y�qv��H���������~rw}v������'��������?_���/����x�������k�O�~�������1���v��un|*6��MF&�A����%��XR)�J����Y�4���I��/!��MH��!n4�p]���d�����,�F�������Sq�y\zbv��p��=���'j=Ii��<e��<��w��3�	JB;��l��N��d
H'8��V�9Y|#Z�('H9M�`�|��8Y��S�	~�o��M�:�����Mp���m��gd���j/������
BF����s��F���ZM���j��P��W��C�Tl��8+!���'Vz*$�����S!t����S����\��T���*�X)�����)(����)���R��q)v0Z��g|������]��e�I����M=t���L���O^.��7�O������&�@�#b\�m���0�A��90��)"\�B��OL�����.���������E\n���[S�55������)]��$P8'(�s,�d��*�,v ���
����X�����eE���#�By��O��h7�7�QX����~�����G���X|T\���]�1��5�U�b��5Sy�\�b/���@Te�[��x�:�*>�q�5U������%�h�lt���#���cD�(F����P$�*��:RU��"���Tz�b�^��6���C���W�"MW9����q�D��-��S����U����T$wX4���2U�a�3&�&	�d�	��M��C�0iP���A���"kd�4ai��HiK�H)k�����C�=��F�0��uv\1/��a�(e��!�����SC��I����-_}:H*SD��2
$�}[�GV��:������w�}:�����C;y;�8�8��up$�HI^L���"��>(���0�:�([���
����_���������j�U^���n}k���&XKL8[������������?�]�.���bh�����������s�
G��?="�T����I�7�W���vN5mD+����i����;�,�f��r-����\_,��j����(`f��e����LkN$���V�I#��G��EF��������#��pf<�����T�I���43�Lx���Z� �D�a�(8��J���I��.��($S:�6��R��$��za�dt���7�6.�b���'�%�QKRFd�)��nYF �,:`	������2���`%]��$����1�v�Q�Ij

9F%G��8��s�Z�q#��
9�t��YA�(<id-�F��3*�(S�����,W�(�c!x����"	/FU��L|<\��DlQtk�4���u��T�t��8�zL0�
H0��D0:!�G�@�p8P��4��b0p%��e	����a$�	��51����
��
�	��R��h��K��f0���LB����;lA��� I
b[�
rlF$���R�����N��ts�#��?�G�����9b?]��A���&	��z;<��/�D�<M����%H��OV����TOZ��(��}�|������i�0#�0������'"��F�c}�{P��e
	pOM#e��hO��=g��4�]B�PkT����A�������(6���q"D�'����,q�y�hi0O������N,K!����_I����}gX	��'�o��&���`b�.��_-�$'��8K����?ml���I\���=
5��H#
�63rFF�H������.#F��	#T3��>�S>�
�^I]a��&���Xp��X���v75~����`l}���������������|Tv��f��qz��e=$yD'N��G�;��}�#�������g�b�
h�z�������m	V8U]����>+l+�=��bvu���������ow<K�G0��u���g����[����p�X!����95���U�_P��4�^�n-�[U=H�6A��D��
�"ao�%�U�&op��@!��x���C��z0U`��1A_����%������b��
��#e�_:p2<t�d��(Y�'�L���"J d� r�chsx�7�*��`l��'���1F<�)^��i��SM�Xp$��B���1 ����02��V�0^G3�� �d,�����H��
���r,��c�86*���p�K�����#)0T���v�O3��/R+�b����|���`w��{�� ��i�b�!����['�V(LP+v|dZ�V���G��kZ�%����8�D����Y�ddY]CY����
�$^�����]a��%K�A��PA��&0a��&,�Yx~9_��*�p���hl�
�����F�(�
�U�UG�����IeV�j���-n(�F� t��4�E����<�Q�n+����VG���� XI�9���+�9|��^�>Y�U���i���W=����V�6P+�&"�${6 +��@�X��*�G^���b�C5�V����+Uq\�qE�?�T����J�R��W7�1*�K
F�D�1���O�r�S8��=7���������������P�E�����N4����$�c��V������L�{#<`/`�Z���}�;hM*ip�
�v��a��U2��]\����s�����K#1�"�N�I��NUV#:��tB�����q����i(g{s{{sk����s6���F�����^-��\�1;�t�?>�n�������G�?�^��~g�h��������oc@�����dv�[|�g������>��N��R���[$=�d'�5W��..��K�2���G_��.>�x���v-]��xV�����|�v�\o?����#�~�0��_����|>�{�h��*�p*�
�NHE���B�?fs]'���a=r(&A)�B������0��C��vQ�sDBaWG�Wu�`�����S��4�C����7;���|�����6x��
�\��`z�u���[��X'���l���N"�eH���r���I*��@&^J%�:������4<ZC�+��1w�e�������%i�y������e"�KS.44S�^l��x��D��yP�����!���q��K�+x����w������EJ������
S�5���.Xc7��$D"������������V.����-��1�AjKJ.�%uLl�T�Z��V�,���p���-)��!'������)����RM�(�}:*������d�Co�dZ6��dN(Ws6��*�1]��8��2�Pv9b�]�]
 -�&���������4>[���!?mZ.Gu
QS@�)�[�XLI�
).j�9�bJ%F��Q���P����G1b:�c6�����j)v���������,�{�4�v�Y���~��eF�C�X:>���`q�����s�����!��*�U���Y���BR����>�]|�eg�r*�_�kz1�������;;�]���>����/�s~r�������_���R%�?�]\���/{/�
'�2~��U8�R'��>�Q|:��
�Ai���
/��{���Hx1v2��w�������7�'�k���v|�u}x�����b������B�&�D�[���_��D�n�
�g��&����p>���"��T��8����
���:E�b�2`:�=�wF���8|y
�5�#��oi'@2/PL�(�%uH��K-���K��R�%!�#ZR�=(��J����n��f�bx�T���)z���0�WN��F����P���S&�W���
T��� ��:�U/_i�wyK5��t�Rh�T�G������D��(�D���-��ZxITt������^�F��E����BU8����Q�������<�����Q�
���r�iG���*��:�����_*E��,Qr��
)�]����J���1�^G���q�D~��+
&���5��V��|k�r��W��R���x��K���r�I��*���%sW�	���K�R���R����NN����[���7���s���*+�),&,>��zc����i��w���^]b{{��m	i���f|��<���eV%�V����J���*�F{�Uh��V��GI���J�/������JO��>ce�]v��G`�<���$��Tv� �AL@����W�Wr�7]�1Vr��B��<0�L.�{��l������IH���l�2�)K�d�T�0�
^��U���kOG�d����/��z�5Y?����J����t#O����_�M~5#f�����Q���<K��zvRQ
=�z��O�L���^�4��������w|{�������/�
_��gXq>�^v��`�h5L�RCU,�7w���JH#�B^[�SNcFEW�9���Y�^��r'�������s�^�_M�������X��.�U�7��}�x+��?������tmw������������w���t���v����~j�K7�Q��������������%�$���L
�[�v���]��i���������p��C�Xx�x���f�Y���������W��1�WBb�>+(���X�|���D'p,(������AW$:a��Q7e���M�2ua�)��������QR�l��L*#�3�h�i��3!@SbCh,:�����@�lSEi,:��b��R�����XPM������5)8�&�7����j�-h�M�A6�������x����ms���9�$y��=����Cy���By�
"��	US1f��OM'���x ����_����
�V{.(Fle:�L��j�`����#L"�Q�����>���j�J�8=1d�1C5�b�����a���C�?�&���	���C�)����#�!�#���;~�&�#�D�(%�(�SL��Tq�������,��\nS���AT�08$�1mEc�"R.B���{/~x{��;?,F��������bo9�Z�w�T�z���B*��\�J�!V�A�@�|z��rC��Z��W" �Tw4+���_��\��a��� �T�T����
ej)�L����L�x����iN9�������|����6;nv�o�Q'K@/�������H+��G0�����;s�����c�gv{&N|��F�)��?E��t��7��i~$+%M��^$��`�Tt���|��2T�7�1�<��T���`u�#;M_z*g�#?���FP��N�2��&-�$U<��,U�����SE~�����0���3��o�����"������z��9�W�� ���S\-�&�
�*��X%�$D�R���zu60TF���2��G`<+��=7�h���W�kX5��v�S�9��X>�}����}\��r�PX�Rq�x[5��{�����e~}u�h�|�~w����/]*�r�������k�o�_q�z��������>_�v=����lq����om��6e�t���R�\���i�GBZvcx�>=<���a�\z�ZEeO�n�zsuvq~y�S�f����2��nn�O�pwwv��|��k���]��/n,���������]�����=A���D�,�|������w�Xn]���vY������"F;i���	RZh;�3������~{<�!���d�~;����px*W��H7����cI�|���r��=�6���&�6ix�%���)�n4���G�+x���*4��p�5�����'�����`-	����/�HC�la����!"b���'�qP
�ed#�FT���8(	��^���A��5@��Px7[�f�
[
d�0A�����Y)-�Sx
~�\�`k�:f���kpZ��U�!f���L��B�AY��@l*B����4HIs��<�����FO�q�T�,��AO�ZHH��KC�B�Y�9��R=J����Y��+hV��R<b��eP\f%�e�5V��<S�F@Yux���t�O'83�B�Gf��/�(����9���)Re�B��O(����`�.I���a��C�E\����cS65����
����)Vd�$P�&��s�z�(8/v��8"����]����OeE������By-:T��h7���\����}������Gh���[����e�Xm�cG�W�Mc�����Tg3$���+�;�V��V�1����Og��M���&j�s�u�h�*�����5�y+��b�C=	�����T��H�'#���U���_���r��7�����*�T�o#(��q�)������t$��y���:;��L��.��}N��=H:�
��"��	�����N�4�
���P��y&9�������� 2P�`5JJ���Liv�������iU
w�����N��)'c�8S�7'��'��TNk������S�V[|�;�*V���Z�;����7�������\�i��LyXG/��gg�g���|)�$�~��S�`
�� LQ|�a�B
b�������t~S�~^�������o-��?(r����BZ��w�*I �]^����u���-�p3���B������ng�]X�US��]��6�)0m����6���;��Z�W�L��C���"R)�%����0g����6��������n~[t��(���C���5���������w/ba�$�4�\X*R.�6�E�q.��B��.]J�$�.��
�����3^�bV�r�Bo�uX��*av�J�oT��L��e9ef��6�%���?f
����>q��7�����P�=�A�A��^$��3��"��Q-������
���z�"�c)y���C)(9�"���&jA]�����"4q����x�r�#�����g{��	��� �B�=b�zdB#h���CD�\����;V58Z��q�����=0�G�1�4Y`����E��8�Z��?��sP4��	�I���
E���{��!+Ch�
jq���Z\��LK}������p�o��������|���h��o�~��Q��������,3��P;V��%�V������������p���Q�5U�G�C5�
����>�A( W�P����:pc/��7��-)�#kh��<�����f_Zm~��;��>B��e�4\G�A��^������8���c0�t�H���9}���1j�[����ED��?�S)B�d^������C�^3���C�=;;q��BR�?�i{�8L�8snj�3~Z�����JN^Ie72'`V^HcZ^ymq3�Rr�A��}�u6�4��}�Y:@��7C'���\}Y����j�j�]�rv�xckk�F�	g���<����Ez�
���������������k�.N6��<������O����=f�u{]�����������r��i�����R��|��4�NK�"����
_4< ��=���i�zeW����9�^���\:������a�F�b�Y>��d�.nF�fn%���K1[s�Z�f��e<i�,�>.��Rg��a�+��V�W�u|���!�/F�:��r� Y���o���6���!�L��y�(�,s�%�I���Q
�i�`9E�K���.=M�n�KMG���>������4)cn9���M������E��N9Y\�`mE"��axYV�.HYX�v���cz�������=�����JXRA����a���>����a��d>����V���Z
���R� ��j��x�)OS���`�&��r,����K�G�%�II����~�����h�����<�:"�d>
\W�f�q(����oH�&>q]DtB@�������lL��],���_H��.y��R�MP��&&�uy��[������n:�n���|G;FfZ?A��|�qb�t$X<���MQ�r�$�L>�������M��Q�\j�����jZ������L������d��j	6��07u�}�5���[)�s����X'�E�C�ZHDGd�Y+�fH��.����}�����$X����-�7�U�t�����a]�p�� s���@�C9��SS�"���#�%����_o-�O�^�����? a�E�1�#�8b�_N�K����c��*-�/�J�]����T��$>D���r��n�;���1�k��^���w.��!o�^�@�j]9���VyJ�gjQC����$p�%
8�i+PhP(���		#� sVO[��^���W2P����Z����e}��)���@��5]/�+GE���0!V�x��&M����|���Ox4,O�z�����w[������>�|����+��8t:�xyv3??�w`�p�8H�q�]8���p�����+�7��]?9�]|��l��UW|dw` 
|���H�^1x0H���`��#N��J���!gP�����6��,��E��
��2 ^b�0���$��Z1����m'j�a�Rn"��K
9����.�[��hIEO(9��R��7�^CP(%D�P�Q@�0;%�7��G�f@�)HJ�A)��p�L��@S�pJ�O�%H��J��`p����*����
��Q!\�5-*FQCV�h%zs�V4l���ztE��*��jXJC�%}�Rj�X2^���Q�=�hg)�
��v,%�PsX%����n�^oQ�#�%���*X�
$�\t}+��!�]�w� �W�]���K<�x��C^I����{���WR�e��g�r��[NNXr���(�iF�s��Y^a�p�'&�\��SU1�l��h��T�x�bc�nCc��"��������)������`�Lt�����`���u
�)!"3�S;hF��JB��d�����fD����PM����Ch�B4�����Lw������c������ry�j�\��nb6N����&]"^�]F�F�dDlT�0���1=YNBZ%q2������o�q�q��������������@�D(���T�|.�-R����N=���g)���mY�OJ"���G��	���rfG�����o�������]�}�����	7�w<7�/N��s�������x��HK���T(���	i$zB�kkT�i����1�u3��A��^��������W�r�KP�	?U_N������:E�����/��?��
tc��������q!�������{�F?��z���bv�����p���F�t�<����������_pL$�]�<���B�����/���d~q{y���DvU6T������#q���k��pU��ZDo���Xp�@���l���m0q,�k����
���3#�����EJZ;TM�����`*9�����NPY��9�d�jl����/0��p������Y3�E�"���qW�#�2�B�`�|+o�%�j����8���!cs�6f�����O�Y�s (�2�h�]�C��Lw�>&��_�(�z�)O��
��^���kK�:�;5fG�A&4���p@6z�n`�:f���4?��i���������=�1�g1�1�I	������:��&���[\&��.VC,��w��p�iu�L��r�)!T2Iq��(T
�I�;t2��	��������V	A%#$t$�#.>$\�������!2	��?L���u	����Lk��u�Q�28b�Ea
�����h}
�!gs�"�p�l���#>���hH�&<�O��2�b�;*��;�=u���r�&S^e��B&��zXCfC��dJw�*�����PA)#O`�f��%��"@��Ev*`�b�f�������8�[�F��t#.���O�-��"_T���OL���P������B���5�&K%wc������|����S������|��&�sO����8��7-��g�wIx��$��e�=xP��O0B��>�e�}U��?�-u���5����l�+��&6Y����Y���9��x�Ld��`��p��x���u�L58��w��tR�M�e����oA��������|������������w���b��tv;��ww}:��2�'����Dv�e;xpj1��,vp�O;��a��b)����-~W��k����5�V��_�n�����(�����?��]��������'Ww��O�}S)n��w�8�]�����`��6}r{�|�z0���`���`V�����M���	aV�kcR�^��n�)�?��f��e�&�g�I�tv��l�3[2�[.��.���x�����yl3�4��,69`[,�m���f�`�V�������&��e��j���6�����u���f3��ks�y���,mP�����_��~k����6�&iB�h	k��|u�c5]����V�V�d��55%��Ab���h�D5�-O�!M
����()�Si�)�(�5X�����fu�i3��t0���):7-t��v��2����i"/m�(-�:)f���Ii��{9i���B�i7|!!�������T&f�s����>!M�.7���e���5B�����4��:���tz|������F��p�	hT��uH?����q!ZZ�9�[����R�1\���
��K;G���5j���,�nnK9k�8�wDGn��h��f7/q�fk�Q]�5g��vG�$*b�I�W����B�,��H5�l&�!cW��-�5N��GCzY	Cv����Fp_��26+d�A��e%�ye7����s=�N���q��2��=�4,�����[:9�3��-��w�%��>&��/a��d��<r���i�h[Z}HQ������7f�]t�'��c/�;B�������IY�8k���u;t�8���qp������q}��������z��l��nYeolIeo,I���)�`3�����|�`�t�;u�&��8����%+���s}���0�"��z�:�,r�;Id�B�����S�����2�7�7��������?���<�8�����<?�qvv�����������?\�����?�]�>[�T��������bg����������������[��oKI���]�����������4;�]��Ol��N�L�p��.�\|�]�����]�����*�]���]��.~������WMx���2	s����!�����������
�����7u��_c�"�L��s�o-u�����?��������?��wqv��9?�}�������
�����
���?�Y����a>��������g�	M��L�.�	-�_f���*[f�}U'��R�����S��|=�����;�C���=Xt
-��C�a_k3��M��M2����8<��}�]s#;�j�&�tqh�l�iB�����pVc���/���un�
���m����N�$�N$���,�[�������A��i��p��M����
b���E��Qw�f�����7��~Wn�����L�����]�Y+�k��Rt��B��������$��B?��T*�oM��t��%*�F)4����aT���G���G�mlZ�:�7�]�q��]���a�sum�s��j��\h��O�@J����x��M��Q�=�h�)��s����vN�����9���7:��'�^���3��7:�:"Kr(�0A��
�'��mu��
�3���u�I��>��`�}��������N�Nn'��<�N����'{����$�Y���v�����9>�?z�hw����w������p�&`%fO[�R�+�3��h����x@���Y�����ngt���f�\���������em�s����7
�m�Nq�(i]�cJ�����~/u|����(c�����&7��A�P�kq_�L���g>�/;v��/;�����+9Q��X��7
����2��$��l���M�N�����K���I���&�>���IHk{�����CZ2�����q�_��w;������d��"���1��l��V���yZ[6r�:��]����~����'%i�v�/�S���_����-���q���J�`��wC�~%����/{�������'_�8�������4�p������?�����P>8~�)EP�~1'h���	�~�S�@���DO4��KqM�!�f�����'}�t��x'K�\:���F*���FC��L�.�QQ7�Q
���N��Ny�O{5�)�=��K�R\���a���`w�����?{���bL-g�c��t�+V�����������u�M�~u���[�m;���q?����$��v����������J�EbR�b�B.=DJ���Tx��"z��6�i����E<�����gvqz=�e���V�|����**���9�,?�W_a�L��.������b�-NV	�}�\��d��Q����=%�n��n���4skrB����\-��3����fv�1�3�7��
��E�3UB?�2:~eeQp�,
�����(R��R[dtX��7|l���b@��'p��,RF��)��ncE�X,:������*�
#��]���#�Lv��$u�����FuoG����)A7����j%F��#���%e��T�����x�r,�w���N�!!����UB���:>t��L���t4�2pY*����2�o�1�O�1�	Q�X1��0�,!L���J~��.����KXib^�Qv�@���������z�z��0
�k���Xh��P�%�O8
#��e)�MXx�=�"00�{�p	)
�`@<�-���aMM'C�HG�a����rd����9@8��������6����++��������3r�9G'`�ac���Z�,R�C8D��9�F��/���5�	����1�<��bO�9�K�}����A,�_v�����������B��'�Q"Dl!��Z�<mD��h�BJ��}�" ;���,�bym9��G��a���A��b��;�	y�4L �n���7����?�P����4$O��p��(
�1�P�@3#_ a�d��id�)��21U�Z�)�(VD!s�<���?��r��G���WRW�MZ�!D��xp d�v54�w�^������]d��67�=P�qt�����y�
��$��I[p�Qp����D���>��/�:;�s\�����oJ:�����_\\.W�<�0����z�~������&����N���\��a�hj�m����7�'�F<��:_#��]�M����wf���*qqg�x���M��(� ��������+�{g���+j���,Z�S�/�������|{�����������_n����}�����~���q������www�������on��z���������\���� >2qw�Q���jy���U���v�iww������E�g�/���������������/������.��=�8[���z�^�����:Y��z>[��nP�n�����wk�(������������?vj���������{��o�j����^=U=6v�W?}h������.�d�o��[��/�\��G����������������������o�>z�\;�C��7������uZ�����LL�}XOWl�-�6��G�������[1	\W�u�q�[�j���}���R�
�u,�2��Z��o_�|�n�l#k(F`v��H�Pi�.F����:ov��������Q+����7'�����������^�z;~���*�L�����`���+�	��i��#����y���>�E
���
<Ck���*FI�KC�i0-���X����p�L����2����?�����~Lf����A.ov��pyM�-���V�u1:g���O^����7�O���@Jt��1_q�p�*�*�����������}�K���]�;����R=CR+x ����e�1��u���\&0�n\���U��+w5�FD�1��g��S�~�
�e�����S<��'xB92���0J���k�O8��&��
)��s$��qR�;��u���g�P)�h���K�M�5��x#����e��I����
-
�O�t�c0�:aE^p�iH��F�#�	�~$4��Pt��"%N���1V�
��=c���	7Z�	��a!.~C.j2
��HU��V�#j���S0�5�Bm��p��p�R�|��\{���
|$����x1c#�����x+*.�D���{�)RTAC���a�hn�#��(F`�u
m4o��so�� ����E�c���8����������^$"�������}\���������%�� I,@�#:|����������E"�����09�$P�i����'3��Mg��+M���dX��7�^>
���w�R�b�u�C�������2�*���5�t��z���CV�Yq�!��J��3��(��M��j���bkNL�6�N��Ic*�o�K3���%�m5�J�1a�����#�`YkYX�,�B��F��bU	u�������l\N6
IVV:�6Zf6J!7Kdg�^��dt�X��p�\66*��m���,��dI3����e��Xz`��n��r��"z���D,K/����1]��=f;�j�1mY���0|h�)$
-����0��u5;��Z���0rj��C�AG�YmV��`��}���Q���J<��������\��B9�O�G�������$�4zTu"=���t�K��/����3������aj��u+��.rM�'�b��$�
9��'�:�N�����:���ec���b)���B�_�p#���o�J�71Yu"��V��D(��������4;��{xH�/x�-��>tm����mOHj�l���9n#��A��`�5w���l$�nk[xBJ�a�d�������K .��v2�m�J�a�'b�J�yn�U��WQ� ���JeQ�xB���E&�B�%S��;&�
��+�C���,`�����A��P<%*�QbOE	9�b@��?����+oP��W��,#��������%��#4�?�g%B�#��R? ���9�H��"C���;!y�4
!C�	qNb<���D�.�H����4v�B�'(���HPH
��z���0I���KD�V^"U����������O�-�G,�zq]9�	.��G��������{�����b���$��2�k?���u��767�l����������w�������@������G�����{x�{�6�W�����]^�������{�-�����;�k_x_p�}����b��������''���Pm�9~qU3�2~oj�Mrx��m��&��/R���6�Km��R��}iP��/��
��:D�l����
���l�N���wZ��\�d�z���v��m�-e��	��o'	���mof�
�3�6�����O<V���m��~�f���Gl�����6�����7�n�
~xo����oV�
��6�
��������q{3���7��v+�
�?@�>�\��6�o-{��oZ�(����Y�6����m����m��ax�5m��0,{�>Xi���6�������m���>���
|��6��z��
|��m���o��q��$�������������LS���b�
�uR���P��u��6��7g�����������������2�
|*�m��|�6���w��{���_�V�K!��b����O���8��6��s��w6�xx�p��7Ano�����7����m���
�k��>�K0�6��
���>_�����7����\��[mx�����
|0�6�6/���[8l;���u��'��vGw=��M"�J�
<��
�u��
|3�>��&d��{�qB�=����
<	ush�E�����"l/��
�
��
��R��m��n�����#�������mx?��*�6�4q�m��h/;��_����$�n��4e�hm���C�"mOw�=�M��[t���;v��Oqx��A��7)�>i��^�#����m��m��a��4���/5�
<=��=�mxg�m���n��4�6��X���&U���_Z�6�v�bx_�����^�a�T�����{��6��G���
|�{���*�6��eO��/���
�wc"��WGk7v76��������hcswck��QX��h���nwh����]|��m�[9@.2�L^��#�^.����O���9�V��~���~������8�~��Q��/���^nN�xcg�h�%����UD�gg����������������?�ca@1�L��"��.���u�a4���������h`M����hq��O��mXs"�hv�8���s���W{�U��#*��x��=�����9�f,��h���G@2D�B�$Qp�D�P����_�	\.C'QH��tRm4���RH���	|�'�,�������[��KT�4����5C��N�9�1�-���
���a;�j����*��5�x����N��`��D�x�)O3������8GDHT$���$>�����D��`��>l��I���	�/d(p}+G�^�c)�o��'>���(�]����LP�.FQV�$e���D�zn.���HM�ibBl �h6��i>c��h����X
=�=���T���c���a<���U��qFd52��E
��kTJf#5�����{$���F]�M$�j�>��dz;�Hl&�@�<F����$�j�{U^�eT�X�����}��������h�X��t��t�v�C�;���x`D����a�xO����8�T$"���$r��� %4DD�^������EzF:��~!�#�����c|CE��"�:��;�,��Bo�s!��#�/&DIQ�pR�\)���X��Z"'�K8����Ofj�@MI���	' 
9���
53�'FE����9��0���X
#uE�^Q�`��V+s�$���?��h��T���u�t+����p�n�����?�g�l���q?mu,������������C��
Nb�c����
���H����v)�?�`����C���n�+fz0���Z *�b������O�x�W��{����es�'���2������3z��_�|�vL,{��{���rso-����,��65��\T#��`�_�Q��kw������;}a��F��%�XTs��w<W��;���w�����!K5��V�`,�+n�/���m�x��&����gq��8�m��~�ooO@���s;�{%n
@� �����w�
�����ux1O�����A(�g{kD���������6�cg�f���eK;�����ct{!�����v���o����]�m��#� ����(��vhk?H�{��8w[��v�O3!��j���c��M�����v�8���^L6�.a���mh�w^o��3��-�C����%l�����/\������bn���
~�pQv
�y���Wp����~7�p��.��.7/Z�G�8�m^�q	��_������W/��G�������b&����9�����x�q�����F�����������n�p��l�m�����M����zI�2<X���p�m�pl��9�T[xeI�/���C\m{����v
��q�WBiF���K��.h���������s���p�S��i�B�h��Z�e��$�(�	���18��/�����a��]�C�C50������'b�+n/�p����	F�������M��zC�(�w�_9�{z��l���\eGo����7�
GC�����������v���������u�_S�W�W�����p;ugmJ6�w�O7��6�q^�8o������l���C�%z"^�)H�d:�Yin��M���T�V�
<T��.�'����{k�\�'\l7lrQkw�tMq[��������,�	������O����/8{���rc��*�'�wg������7��~:���k;�e�m>����������C
�Eb��,*���9��P�it��(v�kTB����f{H����E��_���n��g�qm��������������d����zv2�]9=�L������b�/���!Yt��s������������-Z8i��������]^��{0��/;�z�T"B�L���-���U->��S����������X"b����^���8����xJ�)��������N~Z���v~r{y�����������?�����_�.�������o�����J�?�����|=?��\+\\���������~��5_/������v��}��V�,��_����8�Z)N��x���iV$9B�(����4��9M#����)��kN�9xV�l�nKL���q���'T�|�k/��`[<%?J�x��`	��~I�TD�1�����b����H��PhL(

�����+��e`(
	�N������I@��^�"�
����"j�	FD�k����Ds�%��-N�lq����N9��$z�'�X�8	��p]��\0�a�V;���N$������|�I5�K��a��NF���2���A�<*��V����Vi+���G�e�`&��3%e��T����J��r,�����Y9#!�3�O��bv��xx}������w/�wr1���u�bO���i��?�{h.VOl��9�Q���(����7���'������y����1:Y6B���Q�����%\�����&(�����6Vg�����������<��G�`rp��A�v|�B�a9�������/���@���c���+�������Hi����lQ� �#��x����Jp��o��z;<?|/�A�<#����%����V����T[��(��}�|$�����i��'�0������'"��F�A`D~P�P��8�T�'"���0r��{.�5�G�^����M�(*��F�q"D(g����qD��PiP�����^*K!�_^	f���p6��m��
g
�����Z��t��'�vq	N�����fF�F�������&�^�����P��.z��q��r}��)����`r]/�+_�\:�-V����&����Ze'���_�t��=Z.�Y�z�����w[����W�>�|��������/���g���w'?�>>'�������,���~�N���Ct��
��s��I�{�(�����a������9���=V\a���+�(���Kc�C������E�~��_sb�y��=����]}����2'�5��o|��I����z���e�Cp��/�A�G����B&���%�����R����l_$#�}��5�.j��d�\����2����2��g�P��T��%�v�+C5~�L���2t��'v��2!�����)C�}��IS_+���	�|Y���e�)��3���F|)rD��r��#��[k�Z���)�G|�D��y�F���N$F�}�
�@�T/�����cE����7���o*t���q8%":�N�I9~cNW��9�u��=��$���H'�c������?M���:�����!�F]�>SG]�8�$����{��ux�|
C�����;�������cf�|����v�yI ��������wS^��w+��/�%���~�+���9M~����W��4�&�
:�D��/��YX�=Vr�.�������%�&���j����o���������%+�?r����c�O����v':C#SJ���q�?����T"��y���=.����@�������S$��<���2~G/����R'�����A=T��y�����>�'��Ww��'�r}��^��o��v�#?��O ~qO��G�r���=
8��{T�0�?<_&~_�������}*��O�������l��o�Q_�~���D�n�}�/�����Q�|����q�����_.���r���zN�����'��6_6*���q?z�L|�O�w?�7��_�����?���}��j�s�6&_�E�G��}������q�%���\���
|�'��@��K�����9��(��I@�t*lT�����t�7�D���XD����+|�o�m7�j�tS�p�5v>^�H�/�;��#��U����������F�.>]�|��`�L�>�����N~<�mo.��p�!Ep�M��� ��/c��w�#.��b�K������[�y��~����a�����y�/�-'>������O�*N�����t���s&Xl���I`=�+&���B�����P�����U��x�����h���n�lc����S�t���`L.���fG�������7ov����&\�]�����Z��R�
���4o7�V�����GD��)/�N�K}�+v�����m�Ds�B_h����{T�P�l�
��x �L�=8PR� �#�!�qT��k���#m��=�A������ow(���s8^��Fzxlca��U|5DTBOE�.B�(�o����DzDpF)0�{�K��H�(!I����
^��T	���H1+�Q����5���G��Cf�����gn$#�c�x z�%EA��z���B�4�B#�};0T�	GPE	6��{D��h$�g�`o�"�#��F-��E��8VBa�!�m�"�w�i*��(�8�!%"��"t����w�I#	T��C60hi`J*Yhn������#���Gz����0�xr%�E�.�8\��eT �l1io,����_����2����i��~1-�~�;�9~��-�OgA����Uw%0��l?���~�r��'����e��3�d}���o�������O��@���*��2��L|�p�$|4��{4�Ly1b��c�����f/v�����u�������r�����{�}���&�?���z���������s'���T	�z�t.�n�
i�_�9�����{wwq{7f��w����������]����]J}!]}���-�!�V'/�]�K/�N��I�S���z+�%����������f������Zjz�^������Ry�L����s.�������u!��z�}��E^�i�Yo�����5'f��]����1������_H�y�-��G[���uLm63�����Yy�Z^$����r�Qp�yUB?d���5G���B���N�����R��������=]���7�6����e��}"wO�k�{R�\{4���&��DX���[����r�^��%���0��2�)���0���h�-Q��<
�RD%p
���T��s�Z�i��J%8�t��,XAj!<�`-���](�(S���',W�!�c!x�G2��X	�fDU����
�K�
Et�`�@!�8��C�jV �C��D�E��E��z�Gd��G�.HV��D�p�(���I��PHT"��`IS��A6���a���$�SxV	n�	t|�-��m����O��FP8|#R�e)GRXx�]��0O����
)��`�=�-j\��������5����+=��G��E�C�"gIDGZd-�Y+m�f�)����bHE���K>���d��^�X���a���Q�
F8D
�9���Hb���l
�p���ED�=a�4��\�
k�����
����`(*��F�q"D#'���p�1�Pi8F������^*K!����3��C3}g�3����`KM�\��������!'58=�-���#���9�M�p^�v1B�mc�B������02g�����C�8Ma�cM����������O�(�G���5d_�~��/���_��0v�5���s3�������;���|����������\������^��\~Q�������v5R
�8fv~~v����[k���~�HW��~]D#K����V�5���$6�������pzf���"�C[�����O�|��}��~�w�'�u���*v�����D�V����`���@�n���p�n����������-��_�>���.�[J-�Z��� �������^ww7������q�YXo�>\�/���z>Z>����]|X����t�����lv~���������o�/�v�b���p�x��>8x�����~���rf����7��w���_0���?�����?�������H����9	8�>SQ)b� 9V����:���V�[P����<<33��	$/�	�SW��U4��$��7'�~Ts�$��J���]�D�
J���!D�CI������R
,���bV6mX���a
6�K��#�vL=�3p��H!��(��*�������M�r�'Yv�2�S�R6�h���c-�����%{!��c�K��LvE����T�F�C���U��E3�(C�(2�d����#��'��~�Q������*�s��:L946�e���QR�Qi�/�<��������i5��35�T�=Re�sU�F��.	a�8�*:-��d`e��ML�X�kc6+F0Zq��U��j;"��8�eO"��!��V�y��� w������#�M�����k�U���a��%�z�S����������B
,��
�n�<X�8���C��a�Vg��~�e
�b�����X���N���F���X��
(���Q�^C�Z�,��������a'�9�<�����x�����g"�����7��b�4"�2��C����sr�U�&�7�����s��M�wF2��d"�N��f��
���pmQ�0��0���G����h��F�<~82.z\�(0F.�Y~����ID�2<."�qO���X�]�
(,]?�
�'g�=�<��R^� �x�M�vY����K s�"������t������B�KO"�jb�<N
�B��$�S��hqY������Rm�,�ZVJF���T��Z�Z#�A_\]^����3U��o�������+9�O�����Z�j��������^.��7bwH^3�>��-�,�mm
;�=����Vy��vo|���_]^�{��|�����K�Mr��KTx���V���b����s4�m���xws�>�����'�w����#����<(�p����[/%����E��&M�0pr>��Q��g�-������7�����?���,]���X�w#��3����3��rg�����U~j�=�nF���F�)C\N�5'��f��O�u(>�j5���z����w��be��D[�d9Q4���& ���E��Z�� ZF�Q�(8��J���L��9
G!���I��hq�(v���zX��a2:&L�n�#�Q1������/)#����F7�z�`^��SN�n�����F5~(38#�t�
�e;��j����F;�����;
��x�+Wz��[h�g�0�*���r��@^iY	\UD*C�J<����������yx*�c!xdGK��@�8��r�/~U�NOME�fE9�����������P�'�Zd�p%+����#��o���O��a�C��%=��?��$	����F��w1���_��+�3��{=7���gD�	�s61����
��#
��=�#�D;F]��4���z�KIlP(7fIR���#�Q���w���G0J���,����U��v���Wb�5>	fC�t�v�Pz$�Y!���g�pa�����s���u�SA����@`���[��D���~�|�y��%�����s�g�T�t\��H�p��.s����A�C��	��I��Ysp��@�3O�D�SD�2Cr�e�o��hp������^7\�6���4b8|�'BDsr^���F �O����4P}�"V;���,�P�|������?dj��.�itDI��vi�F�H�p^����1(�t���x	�T�B�q/
�jf�]$����Y=
o5��\&�ZT+�,s
ee.�b�}��|e>[u����j�j�*����)!����y��������u	$���>��"�o��^>3�k?��o���6767���H��;�����t~��������R���������}��(>
�\����%%�g�q
p��+������]�k�+VW���'g��'�t�LW���9?�}�h��l�����������'e
���^�������~E��mU�.Yf�w��h�}���C������q�^yx0���`���{.��pZ*dnw���9x�����9����.������#*�v����A����� �c�qUi����Y��y�V`'�c��	@��EF��F�H4N�R#u(9V�K��^'ZR�J����P��M������	Vx�G�x��8�P��v:����<�L�<q�F��6�+R�������=%;�G� �{�|/����iO\�B��B�*F��z�$�E
��g��\�
[G���������O����Z)��p��i�0�H����
�|�kO;�_u�*5����<9D��C�=R`����<{��0����z-��CE�zI,N,��D���'����;0��+REtC�(jD�����|$�SN�W�1)����3��9IQ=''�/9z#��C��'k��������9yHG�����B)�����B!6^��6b������#)���^�^VI!	�
E�hk��H"����um����E�;I����4���������y�;TsZ�����d��`��wE�(y��q%'[h(���So�:�\!fr�[���8���p�t�@3w�&�jR��d���s�$�U�)C��i��6�I'�U�X�0�
l|2���R��ER�9N��)���T�)��*����Jy�2�;��u��$�I�/sS���_����-���q���J�`��wC�%����/{�������'_�8�f1�~����.�up|�b����������:��������7���o��Py��j�t)��<FM�?�����T�Le�`P' P��T����������c�*�f�J�B�����)��i�F����~i}�:q5�
:+�jE^�}��5��?b!`������9����r�[mv����"a+y1=!�h%��`V*<
Y[���������oY�3�h?z������E���������w7��a���Z[V2JRq����_?�����q����
��
�Q��`�����^[�v����S�K���g��n�xh�Vtf�^����A�W'
��Nl����(�g��~���PNkNd���	'�4��P|\�����x�`���O��F6�:b�h�35��x��9Yk�$C�(4��7U	u��6��l�4��jJ'�F�Q
8�$�����R�X�@N2:�I�n���Q1���h���&)#���jF7�4�M��SN`f����d�Ag�.H��l��[�0~�$aLb�0hd2*�KR��T��c��(O$a�T����V�VY$+�%(�3�(�W��x�)OS��#��]��SE�U6�G�A�zD*XcT�z���sF��
�A�E�BWGzW���d-�a��a��atBfHO
"���x�,ia��X�J~��\b��N����\r����&(����;�����f9\�V5*i�������pcS�'�������������6��r�����F�f���A���e�0��jq��S?�K2�_�#�U�.K9N��(�����h�K1:+��N�d
o���&F�#yBf����������� t�
�����+�������X����9bT
� �jn@��!��a�0�G�Ee&��&���Q[�����@{�T���H ��S�Q@���g7<����Q5/��2"A�i'B$�r�_8!�GJ���1B)����EHv�OY
�!D��F���������$R<���0�������������">���^�~�������^���$R>�g�
?Qh~�P6�lf�{$�l��Y=q�O�P��S���hU�.s�����?����������]�V�s���b�
����`�w������������������������^bM��������>�������������Z��
K�6���py�a},�������w�}�ng������!�N�q���u��Y����< �=����B�i�7������0�]||p������R�����_o�uV��&��m}g���Ds�e�n��=|��=�5b=��������l����3KdV��;����MD�S��p������4�yi@�����������q��_�'�p_������3�/����E�'/�����_w� ��_�)K3�>�{�T��x�\�����\������J.�`�ne��8�r	���������i�=�UV6����D�>9z���G�z=��x�����O��W�S)q6��f��P��`A�	F�3�C�� 0�`'�9X�gg�/�CGt9�4��'���qe�*U6����:$��}�����1�`��`0i�E(�
H:��Hol ��B�'+��p�
��t4c��b���23�r].Z���A�`[�`�Y
$�	��o1XG�f��K�Fh�l��
��6�)���x�������+�Y�������\9X����
G��TY+��1=�2��Uft�*�2EC(�{��q]�!������������,~�?�;v���1��F����S�zU4�{MK	����q�����u�)DL�lpi�'��i����:�{������a(i0*L4	Br�v1>��{�������a�!�>�����c�s'y�,�����Ws�����.��������'fe71���

����u���8���p�0������_��������5/������;�q����~�&^%��2BE$��A�1f���rB6�5N��?�,%��X8��Q��M���W�8�7�F��\�7^'y����Z9	��=�4���[H���D�0����Or�k�a=�?[��2��dd16N�;�Z��y���W}�{�!w��f��L�0C�nC�/_��b�L&�P�x)NJ�/b�|m�>����L�
�q���*Q��(6L0XyeP���q�SE%{z���JD`�&,K8�8�����q���>d���KB�z�����W�����N���}\�����������X�����>]{<n�U��x�K?�����I�G]f��������G��$�c�������is,����YV�������(��SI6���*;em��^Y�s�c�X���Z�[�R�Z)�t����mZ6XB�v4a��>g;j>
;ZD�v(m;��'�F�>�DniP��Z=��
���\+8&s�����vu������r�����1q�l�������u�#�wAh	^o�o�����/��C�7��y���y�5I����R��r����z�!����to��|o�@]���-�;'r��-��c��������E�
+E@q�D��%kD�,QJYb��2���K*�~HU�V����h�/�9�f�b'o�kgKGb��F�r�F|[|����QokE@�	r0�U" ��9���r$�O������]b>F�O�;���;�K�c�mHt�w'���r��w�
��r���Y�
Q��w[���+X��������1�j�C��;L���NK?��R�\*��;�%���BV~5�1����K}\2�w���V�|�$3�Gr+;Xl�:���3W��1A�!vR�~4g�<��G����	��~���i���#�[�?�v,���mE��E��qvUyDu� �"�;J��pc���D��6����0���VkDs#!q�={���o��i?���vO}���#����LqB�!|����3P���4`�Sz2�`	�T��U+�#� A�v$P�DB�#��Cd���{>-����Vi��Oe�(���1l��8��j�"S�y���[� �?��1��D���ce�����e�F���$\I�@�^j�ya�u�C�g�GB�R��n����+�q���/�������'Q�E��xr����Q�������h��H��4�S�6�R_�E��8���(�������}%.X�'�Fb�h9P����cp��i��
�	�X���E���QP�a����}���E���%���-1���W�P�6��"�^����Xd{c��!������G�!7:��QW����YH��$R��Yvp�1)p�����T����vyw�O�P
-w@�':b��aS������TgG�E� G�����)���J{������'�SlH|���O=�)&}�B������P����y�Us�x�z�:��`�������T��1]��s��G��J:A0��
�x�c:��G
T�Z��7;���	�.�.C;^l�;^-L������H���)�	��i0�#����x������O�@��5t�j��~�/�jM�A�i���2��Z�I����yj�Y�&8�R����N?��]~P	`�F������ib�;��X�
����	��;������9��i�"=<M	=�p
uQg�X���U	��J�n�����+�3���J�V �\	��+�\�+=�++x�"�]�'�aC"���G�("���G}zG��1���G�_��%E7�-�:���B�4�B#�}�80��	EPE	)��oz�
�h�nY�
`o�!��#����
�f7a��(E�5/-���\���� :f�������:R���*��F��m&�<P���h��Z�J(����9����&BArDZE�#���b���)�HP���p!��1�p����Q	��4��~wn��2���3F�#q���`F52��
:�YP�t�@uGQ�B��<��2�=WH��K���b�������Y{t�U\0g>o��/�������q���������\���	y0�y0�ZN��9).g��>N��������'�{�}��T'����`=C�������,�s��������[��vV���f�'?�T|���-	�|cgckm{s����[�kz�px:���[?��<7�%�O�g?�;�����|t��h�{���y��|,9���;��?l��?z!�����@kU�����cvqz=�����&�����WU���pAW����#��n���������vU�^J5So"'�������M!K����5I���V�3��E��G�2��y�kI��?��C�1�1�.�����K��f���8�����1��l�������w��zZ���-?�-=��.;O�t������yi,3��Ib�=�E��w����vH�;���������Z���l���8����h��h�������XZ�TXZ�[Z�O-YZ�\`i�R��
����Y2F?v����f�!����5{s�8A�i���(�o����W�� *!3�!�1FH9������h�����8�����@�(�$���G�3���A�~��=�z��$D�;5+ ����c��!���p �xb^vh�KE2��
L;.��.5�o�Q�������0>RC�a�k!�D"��`��XA|�{T�������X����0A�7JZf�(Zx�� �k��x���x����B�;��72�|@q\���
V���@��l��G��:"�����<�����
���A�tK�c�Sz��He�B)Yhj����q���TG����!	J��L��@M�c��(���2�����������/x���/L���1&��H=V����yfI������������z�|.k/��c����~�?z��O���*����C�,�xK�'m�9���R��3�a"��������(��*���~� ��~���~����h��~����h��[Z4sV�_N���8����J�K�g�;�]���G���]T-�U�����������
U���&��o����,�R�[[�Cn{kk{s�r�������S\j�?g�u�^�i}��	T��R���>	}_n:�������|:�������������u��������;>)]���P�U��{Qt�	���_��6�n�R�I���"��4S�}i�J�n���K�~��&��4�����	�z��V��11��@
��KL�sK�������R������	Is��2o6�0o�$]�:��R����
i�&�$�������M8�K�7�%��������%��qL7K�o"%�4H��K���$����p��Dx�����X���d=�������S-q��!m��{MZ[Gu)k;�OX[��Y�0�������Qli�`I�8�-E
�#a|��>9������h�i�ftI�fs)io	�&�t4�>m��R�%�f_�i%)�l]�vjZ�u�^R��BJ���Pn:��}�d��.��%b"9U-�<�����~�������2�K{�<�#���LL��6v&f(e��r>alaT����A��z�K���e�bomib�K�����I������:���6����miIaol)ah���-,1l�	�
��T3�<�,
�h;��6�(��>|�����%Y�������mH��M�������U�g!�+�C���%���I^hPH�F-&x�6�wm@��]s<�nM�]�k���I�8f�`�b��t��3���T�]xA[�f�����{L���:�b��[%y��c�6������=��Q���{�����Z��K��~���I4&jm���i�&[�V�A�h��J�z���!������R�KI$f9����{��������������Xo���"
�D���iX;_N��j8kCB%`��������[�4�"��9p
!�����r����k�L�[���������V������rw��R����������*8��*�pvz�Up�O~�N�XK���e=�_�/N����O�0�����uxW��7����?��V�������>�5��������]�]���o�?/_'�����MJ�v������
��_��q/`���������w���_\�_~<�]=�8_��\D�������������^����������.?��p}�����Q6�����g77��-Ne~~�~vqv{6;?��b�-�v3[�����������
�������b�~9�9���������c/o��/��X����O���[4���W��?�r/�rY~��_���-p��2�
o-����j�����71
q������1�/�V�O���E!$P��c/���f����~�}Dv55p�����e�x]��xb�qF�L�l�2:7��1![�@|�@��DCDs#��`{�Q���V*.��	oN��p�v��B� ��jA`r��7��,���E�N�8L�`����"�$(��d��XF8�gx R*P�
�p�m�5�j�w����^��J����x{@#��*	����"�HB��<��A�TX�v�%�7d�J�&{��t��O�'((V�B�c2{�����x�*`L�k�HOVB!�B]���2��������_��L��e���\&������H�h�2x�	�#5�\�5=�5+xd#�]�/�w7��M�|#��Nxd �����q�5G�90G�@'<N�	��N��.K!���������K&=A%�A�k���q��
�����!�D+Bc�@!�8bj%rD��|�*��!���
I��!�#!
]�B"o��f��x�;����FZ���
�������(�$iydIa��8)��CP�gi"\T�D�b���_�����ci��,n@�M� '/#a
��X�#{���`6(��
B�YP�tdIuGQ�T�}&�=,�s2~!�
?x>���!��=�R��U���*NM<��	�"VE�J���������hn�*��*FdX`1u

f;��pAiA}L��`S`K;x�����{4>Eru|d=ua5���;��W��W�g{���#���������%[w_���:
�nv�nvs;??�}�_yI�9c��zdL�����������[���������=��Y��!���`�n[����#r��w.kX��
��-X��}�ZA��C%!��8<�=<�/�"	�����So���DL�8�����Ev�%
P��@�"\Fr[�lBI����%�9]�%�KQ��/a����9!����\��RTs*M!�!����%�6�Bj�,J�B.�(��.J~#[���a�4Ab���Q�H*HI�y
:C>�h��8
_���#�\/����u�
����*��1J�s���-�kd���wT/�����=�^O{xLV�#C�A_��G�H��S�@R,HWB�~���D���G�DZ<���E$:fD�GJ��4B��<G��H0IT�������������g{��`��UO|�� B&��4����M�{`N�[O���I=+	A���PY
FMz�Z�5`���Kr72@�5��������W��_�RBA����yL��T�����������Ib�J��_�����mG��.YY���Zv���X1��:C�]Jl�K������}I%0�s;
���J@�@c<l�gGN����C9SF����NH���WdF
`�����e�Lf5����������$�LG@��i�>�u|F��go\�0�����t�*���o/�}��76�})�-�(��B�
m�.�u�NE��q:�����_-����H��s�!=}����(]:*�������g}���&����lD��9��f��FMU��2A1%�`&_�z���M��b�`��1Z�~^Av�� *�SaC�^d���������"��;^�1N�����(�v�q�Q�8L����E����o��%���BE������
��f���_���}\m���K��������/���|s�����������;��w�����������������M�2�<�������*p�}�U+�>���_���d������F���Oo����'x������y9��-��e������B��k����+���������W� �my��{-��\\�]������'�c3��do��+��5�%�(�.l�.u�4�e�u�mu�6�I��MqKu����:�~{u�M�3���n�u����J�����n�������6�M�Iu[�{mj�vux��]�ecu��-��U`Kvn���$!��	���P�%
m����hu�y���P5cF���'��M�}�-=�qsz����<��F����]=���5�qz��^��������������ml�8���]5lu/]���Z=ND�4YuP�EG5��&{h����`S�O"���!��&N
z���Q�p�1��S���8��A������9�9�|��^�t�uD�9�f�se�;�R~wd�Z�;��`fpH�g��F<�d2"O���AO9���S<��]��6~7s��1�)��>�9����D@�)|���j���l��
�����J�AP��8J[�0��"�zB���m�#C�SN;z�%`h/F�y8������/�b@T"�������f�39��n�\��0����������6��F���S��=����4�QQ�0�DH�yz$+#M��^$��`�Tt���x�2T�7���<A�T���`u�#.M ^*��#0���FL��N�2y�&-��T<���T�q��N�|$���{�N����i����2��JG��j���)N�@
>��v�O��	ec�JlU�z	1�G�*�^����Q����R�����
���<M���_�����O�IO]�w)R%�S�*T�wUSU��VX���^.�v�t�t����q������Gk�q=��l���N�=��|�p����|�d�p~�ps�������=|������G����m�5k�_zy��f	w{�?�G/�$7�0�|�?��^�>��
�>[�d�Ga�����70�*�"�z����'�������g�4�����e63-�JX������Y�r�&�b�&
q2[�im���M�N/����E��P�`���,�������-�$sY�����2^Xv��-��-�D�\F�/�Ted#�RKjD[h��2*�"K�%[�XF-.�$
WF�����~a%�oD���(�%�M�ZPI����$�����/��~j!e��e���E�p�����(�.���-��+S�N����
4�G�MF����F�-��R\.I��-��a��JB�BIWm$������H�D$��-�d1.�!�-�T�Q*=���(���$RH�J	�!��CF�/�$%.��r�2q
� ���H���}�B��-p���7�@�.nL�����	6F/Z�H�'^�.~I�,
�>n9�J�q1�,�WB@wp�"�(65[�(�lKmQ����iF�.�cL-\�.�����Q���E�l�"��-W�����Tt9�L������%�`w�F��D�lq"�#�.[��vX�3T�(v[/�� ���#�j1b���"&�_����"D��m	b���B��V�q�
�V���3\v����C��j�u�h�����q�������GYh��,3�B�z(�C5����-/�jOF*=~��B�%���-*���o�-(��Cq9!���`��q��BB9���irY������S������[������X8H��e�}o\4?(i� �V��N�-���,�r� y�BA�p�e�~�#	6�D0y�A�`��@Tlq *u%_���@R��@��U���&��p��r@�X,�a,�f>a!`�i����	'���&j�YU��-�����v����������nN~~��~w����/J������������E?-�Z������M��O��!��ow��U���'���CK��>P����IK�1�t:��	�������V�����^i��E�O��S�I8U�QSQtxii@�m)-����4@Z�������-M��@P������P=DI�?+��1���j��O07�cVC>��`O�9�~p��v�a*�i6�s�-9�C+�4k�6�
��I������7���4�!��i������?4K�^���.M�����$��9\a{�*�P��XPJ0YO�&7>F��&����
�4c�$��T@b���;��"�G+�C�@�+	F�Ql�#�����P�����2z���4��8�<�hF0���o��	W��A��bB�SUK��������!��T�:l=�[�,G��t
>�b0��,�B�P�r	(�]�n����Mq��=Ax�l</����{/~x{��t?,:�q���{�bo���� gr��0��z�`�[������4��{��!��!����k
����	*0�!#���\�:�c�������`\��[�������l����q������v��g���_j��Y 7��Z
>V�We������x���.�z$��A!���p��j�5&����uK���YS�qd����^n	r�38�nIq?����D8��!������Qt������YIu�I�������ck1.��4���4��~���R��$�mr��j�}'�������m��i����^���{x�Tty�$�R�g�a1���-��l-��l%7��`���������-��4r"���S��N��Pic���q*�w�����Hg��<%\�N2�U������	�r�WH�^]�2��:y�{>�J��o���Kmm�����/���+p��+p��o�(�	��������O�NBX8�������p�e���}����t�����:6�h�t��!g�����-Zx�8��������l~q�~ry:__t��[�WBy�zk.�.|�R�0������^s���������!����o��O;;�Qvf��v*���6D�$%�3�N�	j���f�1]/��Z������.������1��Hs�U��n���7���f���Qr�p]J�$��EKjz%�%G)I�'n���:G1d���t�(�taviu��Q�tIv�,������8l��mLW�����Q�����Jv�y�I�� U��%c�������BI�+�FzU8h�
e���f���j������PK=��X9��U]���!3�>
(5H
$h�(��v4O�C�R;��G�9���B
u�#R/O%����3?�����N/��2�oj#�i�[g�U��!����D%<X{�#�y��+�tC
"��C��1��|D#SNFHV��$)��h�;�8I!''%9zc)���nr�����{����A����|yxB�W�P��J������1b`E���p�
����4#t!���C0Jz-�P2$�}���5J���(i]c6J���f����s�f��(c<�����@���A�PM�����C>������Gw������c������ry F�\�nb6N#���$]"T�]F�D�dDLT�0���C����V��i{:�%��hu���mcW"�$7�����3-
G�E!�8�"�J~|�%&�#�R�����Y����V����������c��������oeDf�+8!g��2��k��h���i�
�O�<\�&����@m��#7��5��R�o,���qB�����s�:�x�D���h�+|�;y�7��?�����ho�/�o�n�?�'�������v�o�������[���T6��A�Z�A�5&�7{Z���{f����Ddq�>]{��pcs\�pkw�O/Og��}}ksck	��q������������P�KrB���Ey�H���*T��Y�/�;a���j~q��a��vv�~��A������W%����c��Pz 0b�@���a��D=���xS��*+<�������;|����7/�\������W����\^��	^��������W�C�g�������>>����?�C|�Y9�����c��������b��Y�������W����'��6�8Tn�.N��?�:��g����h�.b���z���^&~���.n&4tx�$\54:�U�����L�V���V�h�J'722W����xX*]�S��h*��S��x*i�&������S�*i���P��/i�qURXU*�Ur)hU�[U��ZGWI4���	����G�HJ�X�S0V��*uGY�R$�����z�8v���kU���x�WI��Q"�J.5��FX��$��zy�<�Y��z��c��S��r��RD���_�r�:�aM�����'z�*=*e����<g%��V�iUZ@����<{��5w����"�V=HP� �T	�Th�R�rW�*i������n���U�D$��N�f5D�:�ePuU�@U�B.k������6�zBV�4��Md�a���D�'��fb����UV�D@Xy9���(�X�� �h�QV�H�v�����u�Uj�e��������4����[E�?�����T"q���C�����,E]'|v�4I`�Nt<�3f����k�����}e��WM:�j^FV�aV���Q �}@��^^��t�MN `X�9l�g�pF��aL,6�Qg���X������������
��(���e�_�@eU��+���\�`6��R���0�hV>'��g�����"+�|V;,�g���_����.���q:
�%J�b��wHX��������������:���W/�y�\]���.�up|�b���l_��r���# �?�"���	+�	&�� �3O�{a�x�w�7dE�+f�
�
�1_�L���J��R:6��E&�|�����rQ���������
n��j7�����jKt 0U�(p������8�����Z����>�����orp�}?\��\^t�/8H�>����x��>x�N��R�Z�#�{,]�1�/��\/	�����������*}���0x:���O�Wz����]T�Rk�\:����i����p�'����"z�XLK��d��.���8�f��3Fu$�v�4\t�+\�[*R���@�?��Qi�0F��ACov�������Q+ �f��9�����e0����������?P�`{��v#}�:��0���}Y��R=�$�������0^8���y�wR*��
Cvp����5�j�cq���jM�B�nP�����VQ\6���yz�k8�R�7�#l#�q6Tb��ct��#m��=NC��4����3ow���5sf^�����d��!�.��\�%$:7��p�*������g�_�#�/����>���;�%�E��s0���W`[�����6�U��T)�X�h
am��~�����W�^�����F�V�� �*�xP��Q��
x*td����jP
���b�Eap%���;��5v�
���8�������R�G��)�1��0Ss$)������Q.��3[P#Oq��HJI	Q�zy#�6��y��I�l4���@~�T7G�_@=��@yH��G�#�	�w�:��P��j0"TJCa�#�B�e���I���*�qC0���� #\	#�X�#n��BZ`B5B����YP@tPD�8QYJ���un��[��s��m��
����%�������x��l��d#N>'��=�j4�Q\jX�(F�4�����������6#�0�����pl
D0���c�a���v�������h\�<d��`=C������]x��;��yIdP/���+W���?~�_�������^�{1������<����l���#�[��������7n=�����H�Q |����nfwf� �$H~��N=� ��D�i��
��pa��\>�/?H�c
�8��!�+�q�Z�
�EJ@�vC[?_X����>����V�!�+�������pvDR�X�9x���O8�����)g�n/|s#��jb��A��#���]
8��5:<�1���J;�}L�:�^�H>����F@Xj%GBt)��@DDK*A���:����%A1�!-A�BL��Q��Q�t�5#(N��(����md(�D���	��p�7�!LC�
p(��OUx(Z&9����>�i�@-��y*��Q���C��w�p�U+QB����R������r�iG��D9T`"�c)yp���'(9�"�QP� %��0�z:s��G9`@��/X!r�a�NT����cR��dR��e(��O�3��MR>b�)'C5+z\��qy3��m�����|��!?I������l���c���.���KZ���a!6���6����X�<���(��3��`�G���{������u
�(!���:D����O���������$���C5�4���>���{WL�� �Wr2"$���So>��!erA���8�����t�X)w��/Q��d���!=�MBZeQ2������o�R�q�_��O�����������D(���M������]��������1,y�2�;(�u��$2-����:`u�J�mqP���6h��\$�}�'�{Lo����C������_�}�����	7�}<s��/N�:&�!�1����x��1���0�TV9!��F(���F�����./^u��%
n� �N�"Ny�O{5
(�Q��S��F�@�.��$��Vj���*�qv}�����M����o�ll-Q���������}}k�}�R7�����/g����G�Er�|�t�����
l������N2HX���(��Pq�����_�&���01�K%z���#Hlf��B	���6���Md���!�f�����		*��'R����p�p��4����hl����q4;"�x���h�4�Q1<OU����

F����d`Pz��:,�HIC(*$�G�$�-�@0J�6a
�!��T`]��,0��V�k����Y��'+��
[ejYoG���tepdW{��,�8���Q`RZ��F�q�(ELI��QJ�RB���� $�����%K�'���I#����I����\
d��&�t���%���dT<�$%2�('H2q
D:I8c�#����)+`	��X$\��"q4vId�Ad�2z���SHp�R���qr%�H e�����cS$\ljF��
>6Y.!s�3@�(P�f0I���%���$���0 <�g�c����;"�e%	������V!��H�;I��H$I"1x�v�d;PH��z	A�!�$~8���� �Pv(f��������#�������x��8�(��Og�!u��:j�"+��d4 qT���Qxo�<
n�@Qh#:�C�Y����H�H��T{2R���0#���� #�}�1�_�D)����8S/���.���E~^[g�"�G���r��10����K������*�5�����	9���-kT@r5�"���1ZIf:�b:�R�����5�k�Uu���u���qf'�FJkdO��uv�a��I���h��,�	����?�dlK8)T�u������G����'�����r<�~������O���}���6m�l�Cd��W�.�� 2�����-�O���}��FdV��i?�ag'w����������-�����g��t������[~����������c
��}��]��\�����&`��[��~���<Mb���GL�.>>h�x	�.n������vg{��"����bg�z{��]���^[w�Z������7~�����.f�Nh��X�?tk����t������nt��n������#\���	��������_�lm�l��cZ[�������_n}F�b��\�et`v�^�	����.������A�U�K�]���?�&DT�U��"��<��N�e��_��F�'4��h\<C?�����cI��}���4�������'"O!6���OR��OYF6"OnD%�x��x��O�%[j��@<Y�	�x��O��:�	�O&�'�O�F����1vX��\��j/�P���@��pH����W��X��h��
 �"w�
��;�����oe�bD��
��Q�4�(�U�1�(��Tz�K �������t��Arl�Y	ld�3'���[�3�lQ
&a_>���X'�#�B�G#�G�5<�(����9���)�G��C�]x��#x��1���c���K�b_1�h����&�Q��G�%xts�I�`O��'-<���#��8 �g��G�x�xeE�����By��O�h7�����G�x��~������G���P��P�Q?<v=v�TH��4��	$��Lu�1sA�����G�T�o�����t���T�c��%[�����<*�S�<b��#:�C��E�*XT�hOF"=>
,b/�?�X���oH��OI��F|H?Q3%�E�[��E���`Q<�XTg�"�c�I���,*���Y�O��M;���2�������m����g���c���R��X*�K�����N�4K�����T�bK
������b�41l���FII)h��HIY))������G��&1%���(i��)���~�$��
S��{-�����o+�$�����tH����V������p���/6���6��}����`0�)[� ������bv�������neJO�
��4e��0MY�4����/���ovu��������j��=�&��
$��O
��<*#�a�2�I
r�D�h,�x���N�,�C�L���&Ft4M���A��|F^�^#3jF����/���� ��������0%6���`Y��M��6U��Cb,&T,u��nl�������}
$���dR���h���6����6���XJ���X1�N�hP;�u���$K�Vv�B���E+$Pk"$TM��Q#$�>5,G_���'{E�b�;
(Z�A����w0�W"�U���W��Zh0��F3������zL�]*L��D�P�U�YthP�����?�E�$L���+��� �' �>q�+�S����:���u�"�cGd�1J�Ox9��!���q��}
LK�|��7���_pH�`��FE�\�����^���hqw~X��c}e��=���r��B���4�D!�('�2�g����Cj��Q��2�(���9v���D@���hV�!H-��]��H!�����H�6"�.GiK��RD��������T	S'���r���4A*{�PO��Wv��x!���K��Kf]wE7����Vt��`@�=��f���e���`��4�L�"��9�|S�q���� ���?
��&Ar/�i|0.*�W�#��Q���i�[L*��CE�:�������
2�3����gl��Y'OG@���F�*T}�(���t@�"7�tQ��O���c��ScFYF�F���Q�`=j����&j�_E�<���M5�l_FUb�6���L��|R�#��R���!��$R\R�R�<+U6{n�mN�����Vn&~��Nz�:slJnr�U*xo���xoW@�W�����N����8jA������7g��[;������������]�����rv�a��IT��hJ8���p�;����+�O�������?�������I�]�pr���w~,u��+y��?�������{��k�W�
L\�C�S����Z��I�s����eu*1V�
�5!��a��:E�U��V�c$��k�
�/����
��O�</P��Jm,�D#�,5�������nI ��%�����)J	;M�t{��������G!���x�P��v:V���R�LpRq�FI�6�@RB������Q%;6J� !��\4���iLT\�BD�B�*F�X(z���E���(�������u�Z��'��J7UH:���|*
���i�S��y�xi�S�G����y��*�����<�D�1N��R���k��zy�I����
 |���'/����'������[���������n@�<F{�3�8+����t��aN�q�3)����=�L���#uC�NR���	�L������E��
�n�b��q#=l�.������`�Q�
2r�
1���4#^$���C�Jz�:Q��$T��!E�5��1�(i]��J�(���$R��D'
"�.;jb#b����a*;t�� 8��]�!
@uw\��H�<�JN�Q�0�P���"�&f��nz��%���e��LF4H���JXP�y��V��i{:�%��` u��Wi�"�$7�A��'2 @
G�G!�8�"�K~R�'��#�S�����Y���x]����������}��������]�|�6�|��2��k�|���{�
���<��&����z��#B=��5��Rz,���yBQ����sC<�x��D�������w��gwS^��^��I/A�&�T}9�������wO��xW u7;_l��~��cg�����?�\4j�p������������w���cpYw=�8�q�z�������nnm�oCx�ma����EwdpH�>��,8��;��-tEWY�8�������a%t����?89?�_���\���_����/�K���������������J�U�MU����DX�8�x5#��:�A�k�\�8(b��`B^�^ql�T��E��:��u]b�`���v��������%[]}4i)�]	\����	~��7�%�f�
���
�Qmi����B3��	��������@�Mm�),�lOXhv�0p�N.	�q���.v3cg�9��&���(��~���~�CK������������*�h
#�Z��bM����"tu������/tA[���RX��Z���!a+�b8H[���.t�"/*��_�����?M�q�]m����W��=��3sXU�����l%���k�\�����/lR'v�	����u���Z:wem�0��s��F	\3g.�Z.<+�:9��rT���~U����#������~
�`�+�)]�FGs+��3������������w�\���1P��ia����\���7-Fs=9,b	��/@�[z������K&^h�TQ",.���4���2g�K���t����-���H��-�F\,�fxa�����VG�h�4,�w��.����r��4Z&���K����u=[�eFZ���f�����z'��@���T�q����`sT��E[�DX�2.�Rr]��o]������p�&��-��p���B�/����l�C�-�
�Y����~>���^��)7����P���-�
��l*�~�`
���eX���Q���Q.�N-�
���P�+-�r��x��E�.}���/z����;o��)��'?5����@/kT��I�\\��'n�7��K��
F^��u�R0������&��%���r$7��B$�� ��}�D<����G�3d���'9������vw;:��]�dU��G�=������u�3�_�t����(��mmol�{�mo>�~�������"��|��a�8��}�������d���br�qr��������3�hs���0��9�.qg����#�Yh������f��S�&�N�s:��_��o���^�Mr�F���RX�����rj�����^�z�xS����W�P3��T8�:wu}�����;_<���Z7;?����>z���y�z�c���S��2/����XK����j�g����V�er{��^$hs��J�������h�[�z���fJ(�m���<OkF���F�)n{�I6gM�t.T�|/:���!/�t�<���U0G�43��x1"�c�:���� ]�S%�����WX����;���h�.J���.�����;����^T�5����5�G����9Ey�M���8�E������%b�zax��R(�a8V;���N,�Pc2�FC�yQ	D�zgez0����y�#��;!��=V��	�F�X�OD5�|J<�����Y���	�X���/c~Qp������<y���_����%��[s����s��{p%+�K~�H������/���/:!��G�>�p�O�����b�o%���d	�\�{o��	��51a��������M�"D;�W��4C�T�B�=��
��IjD�jL�c�0"]�rl��h4>f#�t�#$�QB��G�E��9�B�`:Z��X���Ia^Q�XL���X&pL������[�L57@2�1Y�0�2��#*�"���.S�!9�*2�iO�'���A��?8<�^.oPh�7 4�#-�R�A��S�F���qm8M��2���N,K!Vjo�����l��s;�%�S�u�%����$�x�(�x��G^,����|��:��V����%s���p���

��P�[3#�#a�wd��i�)���21��Z��PW /s�(���?��0��@�����^�V�z���b�
����p���?����l|���fO�������_����P;i��~"�N]����Bz\|�g��/��T�]�������2��'�6��vWGO>��bE���Gq$��Q$��%GJ�F���`I��;�#O2�'J;�7�T������!�!3+�d*�%�<[2������k.��X� Ltq�1�G�L��'�	��d���X�Kz��Mp��8	����:�d�	$O�d)��H��%�?��	H��n���C�I������(6{���N��@sT��).��52�Z!4 �t
�$TB��
/AF��9U&WR�cU|�*�

��pl��~dV����<��[������p�zz�-
�
G]�T"$t�F��FK��jdY*^:�%��\{����j)�XJ�l���H�n���#M�2�����1�RC���lX�.LD��7�E��K�2���2/ _�F��lL����/]���c`�yF
����(�G�L����������17a&F
�o�b<{
d���a�A:�#�c~@8B��12j��d�	!�D��#)�i��^�^��
��q�0j��q3��GI���	�N�=?�'@�HY�qo>w]v��F����C5��7�3�����[����{�  a��q%'G�1Vr��B���<�D��K61'�%e�#�T.�&S�'1�<������R�{���0�
i{:�%���J�8�/S�`�h�2�����Ca��b�S	���YQ�%Ok��:C��,e��,2��IIB�J������iO43�I��/�AM�]MX1g`���d�)��%o�41�0����<���?�9i�g��$C�$UHi�N�
�d!����i{����������S��^��^�-����}���BM\��=
UK��sD����V<�om�����������������O�G�� �8��0��G�A�Q�a�= 
����Pt������x���N��q���5�D��h��S�L�7
�i�B<�2�31�t�~����#�E�����+
A�b�W��j#"�+V���)"~������i��W���Rq���|1f�'*
���Z47�����75�48j�h���7'�L�p��y! 3���^�f-�TAh`r��7�N�����Y�N�28LCe`��7���;��-���]����&���\�q4XV=&���$����B�9�&��3���Sh��K�[Vz�c��#��C�xKG��4�/n�3n��;d?&��:a�/�phu����s�;^��-����;LL�z�3��X�{���I�'tf�;�2W���H�t�G�9a��	���gzfV�
PF��|O��c�Ya�"%F�����l%Zc�"��P�S��XJ�e�QBgt�[|�O��yp�b�,5��nH&�W�D�$�������5v�JT��h
��FR��(J��G����X��rL���|�
��C�!�EuH�a�#�=��
oj�}��@4�+.$"��cAR��B)�RH�:����G���H�����Dx�#Fu%4��xT��n4!�P1Qo��m�����H��5�B����i�dAL"U���H0�7� ��[w�):B�z�(�`!����������+|z0L�1���,����e�����>x�O�&��4�'�m&��EI~}c�?�<Zr?�[b?�K�1��1�F]CK�;'����=����0U�^;��}�c�����!���'�-�;Yt�f'R��.�����U6E��]����]��\����n�7����	nml�d:�%�oN.o���D:8�D:�pNz�tp�O"�N'�K��D�@_���D�D�5�>^O�H��F%��V�N�D��i���b�D:�}"��>-^L"�^J����DzmDL��N��S�DzT�D�]0�Hw�+�Co��t����b�D�?��HG�%��`��hn�tov�t����D:�&���%��9I�n�%��� @"��%a&�0�
��%�����:�0����9����7�	s���+Z�T�h
��Zc���eH�{�����������8����e�C�|f<�����u�*5g�v\iAz[e�J���(�l;KG��4��(�|;��������2���2�`�u���������C(�N]�9�n���Y�uRf=�z���Z3�q��2��3d��G���(�u���<"�.�.���{��2�+x����w��p�-�^�*�^�$�.��2���3��C e����3�^R��pK!�:��TB`��;-��g�u��d�<zPE	�GG�k��5���G�[���`oy��D+�*4�aB�R�!r�����z��|`�����8�����\�]��z]����2��m&l��;���XA��a���J*����/��&��=�1o��1o�����b���<F�������A!K���)��-5�U\��nW�9 �d����0���bfZ��0����[�����K��'J`N=��~N\{9��+���%��{1���g`9��=:��*�.�S��S�g���U�����%���%�������`�`�5��y�s�<�-'��>p{���k�/�y��=Z��<D�������r��y?�W���n�����U�;_l��~����.<��7�mon=�|��c�����]�	7�e�g?_��{[������'7���Q��d���tF�����O'�WM���^=O�w��;��ty��h-z�'vT�\k5o�T����v��7/6�����������$��E��y�a)���F��y���y<E��Gu����ysw��%��n,F�����YrTZ�<�%���%�f�%go>j���Qk���]����,�p�vY��!Kd��Z��`rYrP�`{\���-K^�Yr8L���}�h{c�%�N��K^�/.����N1������,I�|a�
������=Z�`*���d����������S��a�<|h�����\��8|R�����yx�[����8byx����ib�yxk���d�yxowyxovyx0�<��t^z�<|�!���GC/�����z���Y��f�c��e��g��K��Y�.�Y�XM������(3�=����2����>����z1��y����8Z���������v���(�q�v�^������{��.�q��� ��{l���1��	��A%\����G��{0Z��gK�����c�;�hiw4��{�a��{�5�*G���sy��"���!N� �.%�v�:��C��iwo��:w�I��S���h��������JJ����/����!�NrL�kyL���;�����0��<O�D��9y
{.����|����F���`7����/��Cx����4�������<����<�������h����;���A����^N��
9���s��I�����r�Y{tN�UN\0'�&>'o��/������s�����������t/FL��yL��Q������i�pA8m��{�a����v�y���~�����C��;>����"����I��*Ur��3����}pf�O/MY;\:|����C�f<�����/������N��C/�����C��<~)�_����^~����W��;�������zj�~�8�_��z�U�^k5{�T����v���/6����g���s��$��E��}��'���F��}���}<E������zWuy��[j�lc��!w�O2��Qi�� X�>�[���]�����!wG��{ov�{oNr����e�{/��}���1_�d�������������[��X'��p��������4k��D�����G�e��)&Y{�Y{)�������n�X>.L���5�j��s����^�1���x{`�5+C�1��"�����~�w7�R�C&���e�Y:������_��w����>���.���.�O��/�@�������K���.��*�����o7����
E)�:'&��5�����{�}���#&��`��>rJ���c9Y?82���K��c���`)��B�E�1��u���\�&�&���0A�� �� Bx� D���5�L�0��!<~D} B5.m
�� 
"��D�����w��Q'&as����#,�4/����
��������b@<
�, ���A�X@.��sZ��q�,@J�HY@�A�x#����,���|�&;d>����� ���Q}������'9���<���8����P�d���4K�,88xq@c���{<��H1�����@Kq?���w�A��	�����4Gh ���Lk��4B�n� EPTw%�'����=W��'B��(�p,		��hH�H���{z+PTAd�� ���F�����	�GF]C#�� \&P�0r���<��-sO�t|d=�a5���s8$B���*�����z�������_.������G_�����W/��V�[��a/n>��'?�}���g@.���n��G��><�
O�V�_�k9��f��6�NN~���+T[qB����i���b
�Z�B��+x��=[hV�B�|���4�`M#���!�%���IC�k��'���q�����B���<g�UA�1U��@#���<��F$@2&�B�Qp\B�P�l��_�D��BB(��j�Q�(NA�2�z!dt���7�6�-�b���'���R��}4�#�	��b��8�rB2���D,4#/�tA
�`;�j�1=��^D�&�h44���0�wV���qh�'0r*��r��*�`W5������CDT3"���Ly�*~�����X��D��(8FBB`!Q�4$��<��y�:�'C��DM`P 7��Y�	�;I|=I|"?�NHP�1C<+�e#-��/Y�/Y�%����h��ML8�<j#������?�=Z\�����������[�&&�2@�cd&PB��J�'`	t$�%0`\����!�4��6��/�����*�8
���U`fC&�Y�ZRN�}$[�Vd�9�����#1�kz>	)Fcz;<�D&�l�<�*����$Hf��V6�_T[��c��Wp�G����a��P
�}X�jn�9�!���a$:F�E�`k��#Le4"���#������[�54��hF��CQiD.0��!�9A/<���#���Jc2��D�uE�RY
D���r����3�1��~�%��w.�m�virC�j�9!��i�G<~�� O��Iw=8�i��{P(�����0"2g�4��?p��P�`�*���x�����i�F�������8��J�X�B>v�4���j�su�������������������q�������}q���hX~�����[���8������������MI7���'���[
���C��iD�����?�?�CPI����Q�x�yTD>��e�s0�C��Qp��'�`QP�P����������0������k�D�h�H*c�:H���D�����l I�
&���RV2kSK�M.���	dJ��lb9')tb���������6;�����M�(y���:��R0��N�*�� ��$	�bO�U��hh����+���P~"�IM9z�b5)�{+����)�Z����J���	��*�"�J���z�VI$5p�9���]�C,�RAV�'�Z�:���[Rp�=4���y�%�'�.|���GdK�4�[��V���i�ru���E���H�������r�+�#��i7#`+�
��rI=���Q���P�����'"���������?!/9���K<9��
��Y.q/�3����P�:�a�A����OZ��1-����b2!*�=��2�6d�GiK:�R�gb���x�T2��W����v��H �^=�f@k��:^�������%�hY�]��xZr���#�[�a@p�C�@Yc��8.;������zN#�Ai�s��a:�i�U6!O�d�yI����d������dn�O���7�����'��T��#F���*�O��G����&g�<e��LZ��xP���,������_�H	�/��N����~;51�e5��H�4��C��)�|E�<�"IT�F����
�E)�tQJ�:e*�FqI�6�#0qBQ���'��~���5j��	
9���3,L�j���H^r�
`��!&v����e�t����w��C��*�GrJvc�>=B�����\z�MZ���k�����3Xh6�x���r��+�l�w��x����[��e*Wv\��[�43�J�xXi�g�f��Db�&
q1��M�N���$�=rIr�d���H�C�50`����#�0;�I�,M
�qI�J���$(G�2�Dr#*��!HP���dK�<��#k���G�:����B�A2�h�a�C6���H����E�T<)
��D<�&���L-1�>c�|e
@��*��Z�5��#�G�n�^[Y#K���2���Q����X����,*�����
��z�JOs�sD�W���c�x|�c��8p�J�� kd�9y^��`�����b��P��!��xQ+4�A�#��s���Sd������MD	��!B]:��	���92����vc��(�gjB��
���W�a@�^&�&e�@A��!��<3�G������Hr����	Yk��Zl�P<$�� �'Y�QA����@���H K
R0?��jP�#��Y�C��&<��;b#p_��@_�:��� ��^\����������:u�U|:�h^�(/Q���KF<�����Gdw���0P����H�N�hu���NE�=���5@��D��lh�c��a
�%�m��q|�F��L� N�F(�'�#��������H��Y��u9dn��7����	o@m�#9��L [����u���Pl����D�S�0�QH�O������4RF#��.�#@ce�glO�j��$�fx���q���p+V��xP6��?��p�r|��&j���E�����r�LS�p����z���767���t;�p���������7��?���jL6������O����u��H�E^�������>��
O��V�>�
�?��~�~��5d��7�vv�~���|������z��{�������2�"��E�2����3��r��������V�=�jFA��F�)�9|}��5��iY#�
2���@��g���qV8���ppE[�[d���t+^��Xkl$C[(4��T	u������jE�A�($LK:�6��RZ$��z�Ydt4��7�6���b(��'H��,RF��)��nq3��}��aXTs�Fl�QP�8�,��Q�k��:aFQ	��:E�E��-��yX�� ���"V	���X�H�DJ<�������	�X�E���(8:DB�CQ�l(��h��!8����^,��b�,8�����J�V�����`� =�+^��;J|FH|"9���������a#Y6R���A���3�%\n
���&(�����6\d��Hu��q���<���":p��@�vyf���sHj4�j0���0"�]�r ���"@�f�8t[�!�1�G�E���9��9~A�����o������	�n�t��3 7���M���:k�6�DFu�\����Wp�G�Lx�K�_5L�y�5������j2���@A
9���0��H�T!�@{*��i��������y���?��P�	��K�Hf�l���'�\��9
���Q�q��e)D2B]�<�}��8��W���dD,�������
)���>~�q�i��������'�_��<[���|�.�up|�W	�-~q|�o��xp�*-3��������@��3��(g��w.���vi�D�
<�r'�
z���a�:5]@��)�N�rB�'
%jf�M$����Y=
65�Y\&FMT+�&K
4e.�3�}��|>2u���!������������M�O�&�e�5���j���O~t����T-��r1��������7?��^��������h_��q�I5�C����/g����r��N4��H��S6���p_8Y����"��������A���;fR�rqr~w:����������><(�p '/��5_W��������������B�����O�>������/���?��?�l���V�{���k�>��t]fQ����O��u1�9�r��;_|��m��P[��-8t�^nf'�����!43+�f*�7�<|3��L���k.�X�@ptq��*��'�6�EB�b�D�������^�ov��\_�wB5���Cx$��c<YJ�$�<nI�y y�R���n��z F��"�=�j�o����t�~l����7�<���?S� � k���c@p�����)�-h�K��hC?X���eMZ-�Q��B�B��P
M��3*�5��e�yL��KJ|��i�����x��n�S��!���
�
-�LV���Q�=�h���L�i�J;�R���y�	���`��_ZI�>AO�g��'�'���T
@�(AA��oo~�9����-U���P�O
������;����(��'(CQ��XT�0:����j���^����
��}���C�&I�jr�_��
��3?��g0�hI�gsZ�R��q�j�7"��1�)?z�e��-��Q[�����|�Zr���}���B�K�������Dz-����/�������Qp�;�!`��S�(i��B-&_��e�.a�v]v�lK��4��8��L��7�!��=�A^����������+9�b�=����}e����W6=�_��7u)��I�X�0nFy����r��"���h�u(;M���p0�����w=������	H�X�1&���<�(��� e�x4����eA>S<<NFRR����s�����==���'t�`F��A;����K�'��E��p�������Y9"�i_�������F\�&��L���d����t�>MS_#�$�&��e�S�TH5ymF�M�/� �\�`��$�N�������2�����������:q���b�\���l�����p�W�Vh����w7�_ll����?]��]�����|��I_��
(����Yc�a���C]��a�Ptd=�'�J��A�{I�})�$�~wy���w�f��;;�r��>@t�2��E;o��������ng��Y5���l�/�.,1������r}��?Wg���"=&�oG���b���O����k�O����2������:zv��,���D�bZ2L������WoGtt���������a������������N?��z�&�J3*�TE���%&�`��y#/L�2� �6R�<6���o����!�AL�q�
nU����}����-�����n�9;l�F��V-���8���x���]3���|T@����s�e�(��)�%n���&�-����h@6��
�lI��f�6T��_���P��5�.�#sf����_�u(��x������&F���1��)=����h�}�37����ib��-J�e�c2G�f�����T�xZ(,����	��� P
�qJ�����^��2�r�@���}�%<p	�[~� �
qE@���3���B�\����F�\��G\�^��V������^��_.>x�5��es��`��FQS�AJ5���1�#���L�
����H�<���&Y������O��C� 8�����,�;���b�y���O�����e�e-F�1�����5�?�U��YU� �E�h{$�V�H��#����T&��@�(�qBJH�?	����������I�+H�e#K�d��B� AI�1;���G���x��
z\�C�O��SXw��6�#{�G�����[&f���q%�����j;h�v�-�Q+�H`hF��K�dU����.$q��S�����(����<o��c��>�����Ix�x�	�����A��w{0���.���.���-5>9��5����X�*��.�J���T2�uc�HW1��{��=\�<d�<��zp�WTT�DJ|��?Kz�{p��\���e�tv��������e6�����:|<pkgc����������h�5������~Q5����N�f'����;k��p�%3���sy���W��I����Yr_�w��:�_�/N��.��k��9��49����B��/���
*Ku��K����>����&��to�����a������On<������vM���]���y��jv���W��,������h- �_��f���������GN��G?f��h^�t`��� ��C��g��]�/1��[����C+�	��qY��PA\&$�e\��@s:�q��+fP��a�
�T�:H��V�?�A��H�%�	LB5��	�� -A�_�j��b�TXmF.�`(��J~#[���F5�4��L�-,S�����tiy��e�����V���H���#�/�������0S���$)������Dk���fR�kl����T/�0���#R�^��xLV6%C�A_��J���L��>�)���tp5���G�iO������i�Xk�����i��)-�0�[O��b��y$�]����A�J�Q��x�!D�K]I��=������E�F~H����;9�������q�U]\�
�d$w�b^Sx��	�Z�0?0q�W��EZ&$����Y��g�X��;p2A������1�6>&Zo�L>N�Wo�KV�0���]��0V�����o)�3���6�yJ%~��������r�<i����S$��:��P������Cp�r8�����-���y�/}����c�������zALI;�h/9��L��wx;>���pFR��aL_Mf�Y��Q���$�e���"����pC�*
e7����:,�RQs����s-����K��j�<�G��l�Q��~b8l����,rG��[�����]����]=������ry�(FK���z�f���Z�8AiUD�b��y-����.������o�,�1\�5�+��b��HWi#�UJ��Fx�����#�^U=_�#��v�<��t�_���[�&H��c^cXD���VQa��wB�r���M�p���K��N��#������!���W�w�~���3 ��1c��/��������6���p���=R����o|64��������.��+�~�7;{�U2\���0|��a���oq�{�Pg"V��eF�N��v@�������W=U�#�j(�J�1��f5
�3���q]��[��#����i���9�/2~�.��H��K4���Z�T�+)%I�PF��$��vG%��8t��x�J"��Q�`O���3��@Q��B��H#Jo�U�0��b5O�E<T��(��,XS��I:PD�A�������Pk���c��C��Z"���f����a�k*�A��A��f��q�9F���`1�Q�8���I@���8 �/c�B;J���������p�v����8_�;�������W�i���)�/Ar�����Ba�y��#����r<0=��]��.���v�!f�S%#��z�[�-0:U�%��
76W�
�U-ar������K$m`��H�
g����� k�U�}�e�1�MC��4h�Q4
�lCzeU�Q3����_hY�)���(
��A�<Rmid�����9�#b1�VT������CyA���rH�8 _Zs�K; ��}���`�%:����+�z�#+@�m ZR+�C�I�l�X���`��U���*��Z��j8��9W*����'��F���W�����nH#Q�WP(�D#e�c�X�#yR��B�p�6'zn4��g��A"�SU�K,��������)7��@�:���^��C����J ��>����_"Y��cB�:�a+m��W��>�>H�`�����5)�UeA���(�,��5��F��^�S�"�B�H���T��U�V�k��
�dJc�"T���S]��	����E������t������dL�6i���������������������O��������r_�mp�������e�6���M��	yp��&p�i�������8�?qS�����O/�g��o��Nz4QeH��\���R`Hk�9����i'P���	��#�"z�SL�xP�!-a?���&?��Du\�fL�w�� ��Jy�6&���?��xPi�'x���ovx������Q+��f�v�9!;���e\���T�����1P�`{��v:�:�s�0
��}d����$X�����HN8��x�8R*�
�8p���5�j�cq���j�GB�n������V9M6��yJz%18�R�"�#�!�T���cx��#m��=�A������ow\���s�2^�PFzx&z-��.��0�%:7��p�*����b�g�0�#b���>A��;#�E�s0��W0�����6�R�
�)�/�h���(�	���������������x���w��������s�5�NB90��$'<m�	�8N��.5
�(
������L&$8��s	�o���Q�7�h�:Ac7`o�&�#��n��M��9lBnM��0`�&�w�I/���B�8I`#%�k���&t�Jk�Pw�I1T��C6��hi�4J*P����/0nb@4$GB�����;���~(����pQ���=b|�	7[��iX��
���W�d ���%�ci�@F�w��9��c0�7CgA��!�E	$1!������D��D���p"�J�D~�&��h2�
L�r�8��X�&�JU@	s#����$���h.,��G�y�`�54Q��"�a�1��M���9D�c����y���z���2/��W}����:��W��C��9�=Y9\]�2��:y�{>_	;,�����;i��bs{{g�O/Og��}}�}-��������y<Yb����� ��Cp�p�q���/�>����S]����b��J�x�i��t�b0z�0H;���:��&���(a�i��O1��F�P/�F�0%iiW|,c�s0:���� �6pf�����0@O<V��X���3&���-��A00���`ph ���68,`V��m	���1In���@&�����`��P@����'[�����B��14�(�oZM\���R�f
	��{j��u{��w���~��k:?���^����)~P[�?�Cz"�%�Q8R������Q�I}���'�����ft��`�|St"_�>���;%���5�D��Q��uRL��+TS��K���/${�����)��)a�T���21Y������	�z�v�
w-I?U~�=���]��o����e�6�(���>��������	�u�3].1�>��s���6YN=�>0`>�i��r���:���Gw&���;�r���2�>Z��[�<�b��Mx\�����.�������������o�U"�\�P1S�:R���	���&dK�C�����W��g��e��!'��
qc>\�c6�
�1�\��S�64�k�n��v��f�-�� ]�������`Lm�Ax,�1�M����S�1�cp�sC�)��d5w,����|��vp���sG�l���v��$����r��:�|U>;8`6�?�}.�>hU&{�D[���������������}L���1wL�l�[V�Z�S��u��3�n��|��}�:��{z�0�.�����#|�i0������Ib[u*�=���������=���C��g���n~��)�Uyp�)�G�ey�����Pv���K����������w^�`�;��+U���/n��v�z�����s��y-����,^�75����b�7��^�/jx#���K�E����0D��5��x����������Q.����K��w��/�zS{���
�b����%��Q�7���^��v{����K��/_��C������X������G���[���r=(�v�����`������Z�����{�������C�K� �w��5��{�5.�G�N�^i���w���t5����c|�����L�V�b����p�������w�C������w�q��R{�z���
w��+�
�;��%��L�����s'����Mw/�W�������������Kx�=t~��:��v�	�u����}�p���q�t�x���Ei����x�/�C8������]����{���������Y0�l��{��������.�h���8�����
/��y��f�xx�����&���_����������	[�^���6z>�Q���������������a���`���`{��bo��^��3�^|��}h,�����C�n��W�4������_���~|���yo���3M{�W���i�t��k�Z��WZ}O��${6�*�
����/�k��-xy]>8T�������^����'"�a���p���{3�����n����/�C�)���]����Ys}A&w�
y|2�+�t6C����/�2��|����o�E��/�)~����^M���O��,��)y[�����C���IPxa�����"�W�e�w���^��v{k>��K��J�����8��{u����pm���P�x{>E�������\�'\��wrQ��w����K������H�F_oM����?�Ez�!bs}��l=�����Z����������{��?��|���bv�_���9Nqryq����|�!�#Y�qR�}z����C,��4��2��Z��#��:�s��h����]bl���������w7��/Of��-T����������**iw���P������g����������c]��;U,��w)�����Df+A�
��W���E)������Yg1�H�In3!=0����:��%A+���B#�	W_�8�1
��h�<f���f7������F�
��f���p@qG��� �QQ(�����%[jH�uX��oQ����N������Q���;���&����FT����Xb��B�n��z���`�E���qP��+Sp�pxW�x�c��Y�P��<��) -��j�HvX������Dt����o	���o�+�r`X*(���Q*=����|&/�gYJ:V��Y 9��cZ�@���2�X@^ k��9y��]������>�Z* �C!^���h��@X��I�ax!��1~�.�
��;^����l����j����^dLkN��u�\r��9St35�r���G/�Y��i
���W��	H�p$��PO�<�3�����8�jq>ohD��a�d�#��~B�c��;:'Cw ����;�N4bq���]��[q�JH��`=�"D��\��>{Y~�,���(
���n����1���+uZD��E��
/��#=��t�=/�`��B��(����;bN'�b����b�:��� [��S�"������Du�U|:�;����\<5�6��%���lt`��#R��c���F����h�eJr���8Pc��K<�d����&� ���QL�#�} ���}&�'��s�+S"�?�
����A�c��P�
0.9w�xq�3K��R%�[���#7y�vt��d�S���%[��c������'��7�b�3X�=!����i`�2f/��4S��8Ln86���m��4�n����I)����Y12���J6�a2^1��\1e�k
)�>*O8�O:5��Z��e���o����������@�;�t��������z������o�6�y]������x2�|}���^{1?��n��v[��^��6�,�������J���\$s&/&e��#��|�L��ys+�?��x����?]�{(��9;?[��rqR���������v���t������������
�Vh\/�J����@o�V�t��^���y��<�m�'��(o���6e�	���D������I#�E}$��Bj`;n�L��D[%�d	O3���'�Z���U�(4N�iU	u�i����F�!�($�V:�6��R��$��z!�dt��7�6�_�b���'�+��WRF��)y�n�F��,:�
��P���5s
���+]��\@,�a�V;��N�5�5�N������J���V��B�<g�U1+G���V!++��Px�U��+��X%e��T�K	Y��U(�B��5*�F��W]������g��������by'cg�P���W����X��+D�p�+y�����o���O���	�+=�������l��}��+��*K��$�#�MP\��	��GmT�c5m.�&�1��	�����z�J��fP�7TIR#��V����"�����,����@0
���` )�b4>�-j�
�����D���$��a�a�'f!���������� t������b+�������$X���D-(���<A���C�����!�4���F,P�3e��O�=���4�]B��k�����A
������(h�`�q"D`''����4r�u��i�N������N,K!�����R���R}g�R�{��L�T�\I���D���"��{����d�>��xS�����f4;��
@���>�hE����t{����%.��/�*����s�������_��(�>Ye'&�F]��`\G����X($��D���9�F���q
�*�gPt�<�rG��:�P���Om��U>�	��^��=i=����xX������>�O��q�Ch{gs{L����p�����(L���GU��no.n�[��Ar'���{rh1'r��DEW��T�o�Mg������Or��XY�FT+1c+�T@�,��W�������O{��4}����S����i�������G���z2���O������?���u��������=x�`xHC���y����Qp�����Nb�=~��?���e��H�}���;8�������d�ZFlF����a'��l�u��X��r��I@��8���f�d�/���j!`3��x
/���#Z��P�5[�1�n-���m��'#�3{���X)�����\��5f���Y���Y3-�f���9 e����R2+##��U#��c����2f���%�
*F�)L��#����Y'A��L,�%C��f}��I)10�A*��O��������hu���9�J���-k�E�-�-�6lA�,�����w��P�@�����^`+����SA�����Y`��������-��v�����+2������k���EV�B�rM�W�([�a(h����e�����'�'�����0z�A��'�
v�:�*rZ����75x�6%�BII
@�8[�L�r`��'�������K4�p	^-��&�-��ip�P�����~(���L�@%Hb�[n"��"$z� ���#�E-
:b#�#��l�g��GWd�����H(G<�"T$%�����^�D�H��7�������t�z�!-
XHI�9����K@�Wp��iyDA�yG�G��8��cb���
�~����x��K�>���(�G�T"�C��Hu�;�H3�1uM���[#����@wn�4�F5GQ����Z���3-�Z�U�W���U�Bre�p�~=��D3"���������:�P(��1NX
Bs�?hN�&��y?d�G(�'�=��������
�h�zZm��f���<
y<IX�����Th'?3
v���DXg��e7�����l?�<�YQ�?�9���?68�������8��1K�F8��?�� ����f���nvuV
����'���%`��������_��0�����;���n}!��G��f0��c2��o�7&g�w7&��7������|1��iP7����������_���;������lr;�G����_\O�^4]�F��|��__t�2�<����w������b���;Dw��\�\�mL��kb��XV�1y��o������SBG9��?��j��k7O9s��$i�����>�P��2I��IE��	�H��P���9�8��R>�%B�E �Qpi4����#-���1+qDE�&iRTO���������O�m���<�p��W�Z��� �h#�d�<�������$��d��%9_wB Ix������X��=\�*D2v`Hh'�d�D��b
��&s�GX:�2�'����jd��s��CA���Q�!�a�b��}Z�mP�<���<�����B<H������K�3m�����:�|�VK:���c5���9����(9lcp��"w���
�Ta�0���-������{@Oha��C9 �0�<p�r����x�R<z���wxwT�������h�������#9�����9�#�������(�q��K���X��A���5�x�FQ�0����7h��o��g�am�k��+X��j��w��_��i�Q�
;J�8����g���NKb_r�8z)�#��%3��-,�c#L��*�B
>�*=h��0�2������h��/\��^���B�#��sD���w	.�t��[�(��F�*��O�O���~�ox�bJN���K��^Y�U��fB8[I��Tp�y�3�A�9�������'��Z{����'�'��E� �|eA]4:@g��=�-�D�����VdaXP#(r� ��B����hc���)�M/@a4{�`���	x0OlwR0A��%4����	��:
`���E��
�`�BzL!�g���d|�=���l#=p�4�`�a��0��l��"����A��	��cX�+�'�"����A;N�;�V���DT0:Rs<t��r��A`�X9y�l��"��s1� u�\��(����ku0Z]�:`��1k������:r
�M�E��������b��4��N{��I�1jJ��V%��!^���C�(��5
A�Z:�:��5J�v�QOqlg4�l���u3mTjL��W��p�+�"�2�@s�2���t��^4�#����Ek$1����U�I��H��Sw�v����!�s���Pv�Zg���A��Y�@='�?�6�L��@Ax��5�
bT�dA����,T,b�r�B9�e
����!N�@�C��|,z�����h�`����O_u}���'���z%�(���/�"�Fg���E$_��r	tb4��@�N���,2��K�k���%LT��F�EPT����g-��N��O���WG)���
zQ	VA��p5m�uCw�N*���Z���������^x�G�d�<�=��4�R�����F�mx3�
�`�Acs�v��r�����D��AG~~H�#
�<�|Pc����7T[��Rq�5\��D8$"���W�m����.����$r	
#&�"G��9X���r��D@�j����j�Z!(nX��p�#�P��FnB�I  S����U��p$+��S���*1*Z��,���~i1��_Q���B�<��
����k����
��Wt��pc%2�d��B!,$ZQ��;�0"g��S�GQ<������;�' ���\,i���)C� ���������������q� ���x(>�c���>�5���v�85���A������3����������
�����z{	����%��:K(z��<���Z#q���������R��>�����E�����M�7�j�������E~{�����<I���������}{o��{o���}�I����T���b��[S���������� ����~Po����b������>��'��+|P_�����jd?�/v������E,�[|Po�wT�������qy�S���1�nl�_C�4�������h�]6B��1L������V�����L_��T���-���u���kS��C�8���5?����(���A����g���I9��g��_��V��G�	[�k�b�������V���>cUW�5m�k~l���#�e\n�_(>��
��_ob���t������>���1���c~;<�����s)��?�������c~v��.�����V��~���������4�:�����w�W�_�����+���7F��������E�_�����6X�����[~k7�����o�ae���������[z��[�j����gg���f�-������w�un�����~�����2?P����������_�{��_�K�2�������W���{<�*=h���|��/��R>���6������������B�_��n�����G��������������~�[����>=?�6_����o���������������oe���yrX�������=����{�=�U�!�kW��}_���:���[����[g��y{v���3����@�����p����c���L\��-������?U�6Y��������Y}�^���]��)z�p ����K/�z��r���p�O�Sk��1�>,U�����;������������M���r�����u7�[6b��M�L���lI�VU��8�<��p*��'�������+�h��Gl)���Y0���C���<����zz����n��B�k�lZ��S��,&���Q�?�����j�}HE�[9�||L�]V !�����)^����AD�AwAtP�wUK�*bH4YW7���g������vW����|���B���aD^�%0/��Wb	�{�D���Q� v/��C�^4�|/��1�{
�{��R�`��I1)������:���@[�������R�8���
��)h�PA��`����
��h�u�JD�MK`DkbH��cj�h���AD��
;�* ��3I��Qk�UD��Eq�+�[���%�*�E�@`���������>k���h�i�$-���!7^4G��qD{�8��g��h����I+��?�#;�2�w>s��[���������;2��R����!B�1�v�|hm_�Da)%m�B#�!��($I�l9;N(,)M�f��:K��KY@'���=��e���TI���R�P��~S*��6�J�ou{�KHd�Tx�T�Ro����eQ�������`���Ic���<V9��	�h�a�H��	�5Ukx1\"36/J����n�gZ�������(;$�U6�[D���`8!�k9��NJ#�E��N��Ds�p���/$��A2*�+�5^���\pa$ j(�����!"J$%�(��#X�������2�&,��Q���E)��r@)�[/���s��e]�����<R�U�G,Xi���hEM���%��+JLO@b*��J�u�@A�T�R��E��/n�L����%�����+T?�eWz6�	��@^/-�+�@����c� ����N6l#���h�=�,��w��L��r;[����O/?��_�6������_�L.�wg�f�_�=�b���6Q��b�f���t��9�}���&F8�����Qp\�5��2j�\��f�t���=2��u��&=�|�7.�Y��eIO������x"�,���������z��-�
,�):,�)V����~�6�h�O�-�)B�����-�a������`	�:��@cY
��i]F��� �-�,��uiify+u�*v��*#+���\%��!T��!T��C�K��,!B
�9���C^N��vI�����E(��EEX�����.3rRZ=��!�����A�P��������Fj�����)wg�*/p�������S�:-&p=���B	�V�V[�WQ��k�������UYR�����X�\y���.u��q���,����X��X^/k��t�X���]���]��\��r��J������5[���]���/���-<�_�E������^�r�d��+�R������u��[���]~}��5^�4��j���^k9�z/Y�~�OM���*�\�U�h��<s]V'W���7�E_n����Q�`���27���`N�����fA����-#]�.��[�`�B1���b�A�cN���xP>����x;-*���]XF�yY�fc�������eh�Xu$f�r�Y���Q;-�����T�Z��,4'X����xQZ������Q������J�B5�A��"��`����h�
�����QsO=�nb,��c���f�����.zs��~`u�����������p)�N����87�L����.�W��j��M�o]�-���~�V5���]M�������n���-�k]�Y��-X��
�ml��[�S*Xh�1rK�����	���
O���6��-nX����[?�������C���E+����o�������r�a���N+��^6�I�Ul���5�5�Oki#L.o�O,X�h�:�w���e2�p��Z�����nn�k{�����^v��w�}����GU�����?4�O�������R��1<

�FQ��?�3������������l�75O��`v�`m�V3�Z�x�\�N���gP�=�������<W2�y���������������g����.fg���O}�����w!/y�������=ccQ�K)�q���,-��`a�EF������ �`w�j�Cf���S#�lV�bNe�Q���T9M
P���"��U����L����M��P)c�@���F������	���������1�M���RS5^3���%������`(R�V�4�V�#8|�F`yI5����`����*}�$��6�����fOZ���z�"
_�V@+��2U1M�S�RL�����a`����MH-��@K�WVP����>�VKFP�P��'d�(�Z
�F@���*{������FJ�g~0y������Gs��4g��^f�an?�BG�a::� �0�a���X��b�@�m�1�iWT1��P��6a����}�������]��k�'xG��O��~�.k<-��f�A�6�5j�F�0
�X�i�&�
�j%`.����rX�����a�6��o�id2aLJ��-<�E������4!{0��f��e�u+l�����8D���q�.^�!Be�`R��D����
�B:�
Y�h"	J �R8�+��"Q��(q��������F_����s��z�>�`�	j��<+7�.�}�g�.�x���S(z�����c�n����0�#�8��`=����"9��[�������1ypl��cG��WG��R��]C��:��*�k��f�oSa4\�/�1��,���L"��*[b��������H8�/1�A��lc��~��K��t�=�q�����v=�
l��]����_#�=Do���dk�m>�|�����p���n
k����ksELH������d������	iC��!���_��x������|��#Jw?����brz9����{��8h�?�O`U:>s������x�>����M�7����n����W'-)=��c
9�����[��F�����&c���������[���+%������Y
������h���d#��A������ah����1�>�t<�^���6�������r���������@:X�H�`�@z�f�����������������t8W�W�	�WcHw\�H�f����UK�t0�@:��aL �Zk }�����K �c����@zu.�Hk-P0�,�%+,�-�BZWQ�x
������M)��6�;��v�����U��-h�%�_�������'�8������F����k{��������8?�!�O�F���p�������Q�q~���������������q���8��m��<w�7Wrx��e�$�6����[_8@~k��~���".�o0G�����}��[�}��b�cd�:pdFl�7����2����_��}�m�5�����`T��A"��,%�?(r�����Qzk������;�F���/���aR��4L��Q�F��\���N5J��"8Jo4�m��h|K]5E���F��A�(=XK��d���%J�&��������a/pE7�Q�H��i�CPJ���w��:L�^��7
)G������V�5OG\!�MQz%Qz/��2W��E��s� JO"F��8F�M������5z��>O{\��|�����]��|��\����\����a c���#��<0�aV3�q.|���`r4�7,��|3�����
����7?8�o~���5����������|��w����m�g���������c�5�
s�1mx3�8��1�&U������������J���X?h�%�N���x�!������f������o�����F�~�����K��M?�8�����i�X������[�[���~��b~����.n�@������������]�8�^N������r�s�8����u>=?�9�r�����vf�g��?�><��������������|�����fq=~���#i�w��I�����c��/���2���0��������Z?��Hhp��^�@����2�i�r6tc�uy7��/�[��?�L�7ydq}�`�
i{������zqz��o����^���)������+7���6{r}�������8)����{x7���bq����t���?��;��)���iRg�^O����	�/�T��P��<)��%�T3��XzPu�Up�*:�P���S'�
U�l�]=<���7��H�Fk��G�hKS4vo�nN�����,��d���c������Fx�N��C�t�Vi�S
� �pYFV��D� |;+!%"�K������x� 	9$R���x����'$UzR����p/����!Q!?�U����P
`�K(�j���[��U��������og��w��p3
����v�5�7�{-@}�+,�$:�d��]�����;�G3���aK��GH�|�K?B�������zJ�b�!�g,���X@D��D�T��E$kh9Yr�
��#�b��T����\��T��/��Ck�	���(�����e2��qOE���"'U�����I�b��ti�W+|*�Z�0�.b����*���"WU
��>s�[f��(�	n8wP���,����[��qq�7X��-*��ZA^���{����2c]��0��U�O�bl�h�?����T ���u�
.vdf<�6��_�DDEhM�]1	0-���<��Z���0`�V�)�������O�j���4�1�P@\�&X$k��r������c�t<P������������*�;5R���J�������_����C?����@����m�z<z�D
b?�k!�??u�x_
��N����[�c2���6��-F���@!y;ZHz��T�a�n�� z/��n�e1"Lr���� �Eo���&Xe�S�2"���@���+#����P;V��G�c~��?�_n��Xa�����N+�
�TNm�����I����t0�8�#����:I�F�������Me��7w�D[���.I���������������`��	
�|�`�y�t�����?n���%K���RQ���7vi1/7�Z��(-�1�D2�H.��z��!�+f��������U1�"zW�a��\�1�"���18vH��������+s�7/v�_x�y��/��b��/T,�Red%��J����_�D�Kz�����/�1�B������/'�5��%������SV���D��/�S�=�y��/������@��z��_��d����i������W���'��
y��e��
������q�y��#O���'/"y�!OJ=�g����o���g�*@�P��	K����	��<N@���y�d�h�R$:��?�)���W�w�&�	���N�����&���\,������}�Y���,bX4~�S�w��y���u3l:��O^�;N����]��������&�|�z��[�1��!�U>�56|�����9�r�y��hP����!�*rR�C<��zU>����h�i�
�%� ��<v��A��h,;�D�C�j�P����������G5�u|�'X�����E�����q��]���J#��"���h�H|�
�����������!1R���J�_�����_r���C?����/J�Cn|K��F
�!9��|�M0����������"��u9���5��9�&j{3���������.����nr$r^�������H>T
���x�U�+����N�;>�����=<T�CE|����C���Q7�|(�>�v:X�T��pR|��m��xCS�aZ��po��@�[	,9R}�G��w
����Ccr{$Z)�����m��:��F���������l�EB#�%�dg�2r�C�\����i�"\��/�/ZD�P������ms�����^kw��<m���@�����F��X4	�r�"[\T��2�A��`��ju1�&L|��X����/�i��`���Y�F��L�	o�&��DR�M,���AM��:?�&w���P0�	��2I'U���P��$"L�'����/9�����K�T�T�+��;]AKN�
�C��n��4�Jl�	��vj���}f���G��}�����
@��3��fm��j����.z��2��
��Q������Q��%G��P�\����D��b�
�8���>��P[r8G4k0�X�����N����f�<��Z�'��� �������!�wdY�;m�Jw���#K�
���W�Sn��y��uh�g�S'Hu��C�c:n`����P� �C-�����w�9N*4��Za����Q���9^x��N�8d��=�q�R����F��x3��~C�s�]�
���v�DB��h�:�s0"7�h�M����k�6h&"���.�������$6�8�-��E�t�'X���F8 ��FRC��j����l��&S1���Fv��`����9��~/�@�/���7*�m���[  z�3�D^�p/��R���*1����e+�������F.��E\��\��"��#����J[�zi���kqN�Zx~dI��y(�Rt�Y��1�x
ea�n|OB��>����,�]����y���=�&��=����r�����o������{��}�+8P�"�U���T��
������}������p}w��psosk��~������hskos{��Q�wz��h���[Ten9��4;�/h��"q�����K�8���-��j�R���o/�dl)fk�I�����;����t��_}����Y_���>P���V����6q�lu{�{�R�"�.���������>+��o_�C{�g{��=]���������������y�p��]�����f��n�x����=J���P�

�����@U��3UA�P�"�T+UA	���������3���w�n���R�J���*�t��8%�{�����X���X��f�]r�T�h�N ��:��*�q7$Qo������G��>�����7��
P�:3��ng���R�9���!���e���>��P���Z�>J<��g�b���3���,�A�P�qPT5�	|,������h�`^A}���>�)��������R����S��A��NL}�k�Q�0�G�E��v��g-?�>���J��>EPT����g-��F�nh9�n������;�}�zO�]{>>����lb�S&X�v�,r���'`5$�E�a���<�WX������a_��Q�,��[��2,"s�E��X���x�>�5*�������"�s�?R*,j9�����E��v���������a5���L$H5�5\*	G_�%�I�"q�EZL�BUL�y�E�������a�E4�������������2K���d��,����qWX��*,I��$�����p����=�$7�Y���$�J���F,K1K�����s�%���%�oEfI�;0`I�k�,)��fI�_�$��,�g]�%���bIE,)��%����$
Kb!1�bf����%9st�����Y�&���Q=K���XR�bYR��`�O�?�G����?V��
\�� Q}L�g�$���y��=}�w9[#�[�E_l>����\�xsk���Z���]�s=���-Zr�C��!'���<��q����P�5����
������l��Q���X>����x����cv1[L��w����7��a1��M�������.Y�����eq;���V�����l����u}?�4;O�[QM�~��3/e��t1{����l~}~�4�fk��5���7u�>�V���y���H��e���FW�����f�����[��Yw�������N�n]������~O����]cX��m�mL�;�Y\M��?�-����9Y�N���_7�6Z�]�i�������F��n�����Ery�����>���������N~�����=o��������~f��\z������b�UU��	�]%�[u����*��z*����$�WI�z���\Zo�W��S%�n�E��z���U�8�^8�������8������XdLS���a�C�*,��",P�,��%X�nW`yqj\E�.�����W�-�>�vf��Up�)����y����+���Z�EWV0k��y��+:U]qEBZe����4?����m=[��*6c�f�;��*+�����uUV�eU�h��*h�vQ��TA�+�����RYP��[O��r*�p5���f1����Y$�J*V�B*'�x;,���]Ee�v�q
����_�%T�VPA����
�>L�}���LY�;0��QsY�=�_��-��GS�da'l.����"K���,�x=
�~98��X�$-�jy��Xk��R,Q�~���,�Jv��*i�2,q��
+�#�������_=��<���
Z��f��,���+���W��y�4p�d�y������
kiV^�(�mn����]u���~<�k��j�\��+�H��pD>Vu��`����`�.ed�6k�b}��^!Gn����f�KI�\
ZWY-e���7��f�;�j����:)���������:�6�k�|Eq���i����)��i}8R����1�,�rc��T_1+��	�� u]�Nu���(��E����>�o*m�Qb��D�\.���1�.�rW�GC��I�EU�-��b����h�9�ZaD�n�������~��7��5D��a�A��^�	�8��X��-
"{ZD�� p�f���
%A,��(W�hX��r9\�R��s��Z{c$������m�������E���{sg�����?m����6������O�/gw
�������S�G�����P.������d40�����~t>��������3�L�AfV��6g����3��$#�����tw��~q:{�	��tO ����-��H!����;'|��1��8�����19�����4�|1��x�s�������e�~�[L�����������9�F����_\O��8]�F��|��__t�1�<����w������bi�B����S
����Bc�Qz������=�0j<`��F6��$�����PRd�Yr`#�['�&6�Y�x�ke�a���
����N�=�qR���W[7+~j�5���!�6�q�l%��F����>P����}����/N
��O�����>���#jW�(�>X!�rBl3���w�V}da��c����,��~/��	tZ��4��	�h�8��'��uO��TH��!�g�n����k�p�9�M���ps�8���1X/�c�d�����X�8�	�c�C�1N�G��c�v�"���f��o�8�c�np�����6i�c��8��a���7]���Q�>�D�n&*��ZDE�Q�.HT���
�1QACTTI$*M�JT�q��
�X��JT�]!��DE��|�pZ�2�A�BfOR���E*�6H!l�&��uE*��B��H�����HeU� g��IF*h�H�qA*,�B����KY���Zp�2�G�m���.Hj��nf @L0�������`�� ��YDcZ�Q1�?�j����	��H-QQ'��	�����:��@Av��`�#����#1	T�J�4~\�������W��
���H�4��a�F�}�D����s�4<�1�{oL�����������0�������}[k�������
#�����eT��I�$vW����aMv,g2�	��(�be��qaM`��"��eEdO����)�G
��� �2e�S&�7~=�/'���8U�a9U��`�KY��]�j9�#AN������z7�TQ��53O����K,l{{sws��a�_uQ�8�M;w9?��Mg��s�G'�sn"���i��s��{��^#�\)�7f���-+w�E�v�&a�p%�]��k�����>�8���^���p�t+�0�Kv@p���A0A`1[P��3�$T�����C��bUI���ix'Eik�(O`�D�|�.S `Dg�PJhot�?������"4�t��8%��3�4g��i��w��5� i&� +5� *6��*#+��]%J�A�u&� *QB�%kjR��9��I�!g!tV�����D
m"B�L&�"�JE�NYs:)��C{���T:B��|�^�		�������)	5�$��g��;��z��k�P1
>1!:��W�����(anB�jKrB��6;!��R�*9�Ps�K�B/�����(�"&)C��R���PzK����%S��N��
Q��
Q��
���
Q�N�����X(�����������3Ror)
�������I
g�w8QZC�ry
���'6$��P����m��p-GLn(��LL�VLz�����E��3����chf_���7Z�t�n:�
��R����#l�5�209�V�r�M�B�6PV���t9���+oE�*��n���P�:��/�Q�X��&0�v�`H��MaH�}IK &�a�cW�WT�h,;SSNd�6�a��RR+.����
U�[���*'X����8�a��)
��S�������JcZC�Ay
#��������
���s����JvC1R���J�_���Z���XS��C?����d9t�[�fH��I�P�C�c g:t3������j�Cquj$�)u���\�Cz
�Hx��������~�����C3Jz�� ��0�[����y��K|�2�|h'92�aqP��7%?�	V�~�JM�J�[X�.�SRDgUs I$A�;&� ��4���e��!��V:����I�Bl�EG�Y��8&���&��e���h�������x�<�!��y�����$�2��crhQLr��IEW��T����Y}���������d�8���'>���\����Hr�������!)�������}�����S�Lk����*���X�qf<g����h�V2	����}��+�,Y5�Kd�����
����.���%�*����d$Le/+P�P����f����?+):k�Q�lX�5 J��zUe�O$|�j"Od2���w\�����d]���4�3�}D,�&����LS���N��
[��f+���Tc����S �������4P�f�F�@;���;�a�d�v�1N/$��0��W��cm�-za1sg?qfK\���k6���Z��)����Z��+���OCW�U��tHZ=����`?i��	Ez C�Q�
�����n��(����P��^@L��������$�IR@I��
"��EoC��
��D�
ZqPu,����XIQh$�P����.
���P�	��b����	�}_��6��f�!	+!�FP�����X��P6"�)��!0�h�*	��]��G�#�'���ARg�M/Ck$����J��1�qW:D�������+��Q�����"0
'#���H3���(��D�)��G�L(����G��*���)~L$A�U��#��"4���z��4#�s�Dh~6��wpW�D
T�%�5�8�
���-WB���+Fp!��J��h�@��)���X�P��
%$Up9�"D�9E!h.��)����<R2�#^���
�����1t6���-���G	�;�>|�8��qh���aT�??����c�EZkW���?�x�����������������~�^��&�on.O���'C�����5�p��]''����O���;��������]����a���������>�x7��>-N��?���iA-�{�A��zq����;���?�]�N�.n.��>�{���w����kg��e;A������l��GZ����$c�r��Z���/��������=�n����l�d����E&B9�	t�|�V��D��{RIP��JT�R�jh���NTi�@a�T��%\��UP�'M&��<B!��ZE
N)��dY	���<�b�))������M�������@?!���X B�@D�f�_G�@��h�H��"��+i�b9n��j�$��?)&�L��������gEh�����|%�%��x�h�y#g�FN��{B�^~&��{j�]������%\T ��A�V�k�C���f���=/���b�~T�aX~<iu�k�4z�5����|M��Wg����I�H51����~�+s������*���O��i��Bu��j
5������)�T�z����}t��)�'Ge���E�������4����qk����K8�����vmB
\%��3��������mP�@���{t$_�%��,]�#w<��7�p��P��Q����PK��)%���UC�s�+c$���C����D����V|g}���������U�cX+�V:���r���[t4������pE����t����t���y�:��~���i����_��/~��q1���/��?�����O_��/�z�q��lg�vq�����S������	g]�/����u�kW�#�Y���r�>�p����p�/�:�U��7�����Wu�ek������Q(��:�������V3����k�m`�ZE@��.�T�V@��	?z���'���x�s�~����Lx��5 �g��<~RX������*!�Pk5T���"���dY	U�J�P)&TEJ�����5�����z�>�%�B�V�������I5�V��5��-����������yPHN�&$������Br��Br��jH��������f���Qp�C����R�$������ wK�]0��~��*,������&�\���B����X���q(=�%�������J:Q����$�%�|G�������;r�ss���v�e1�T[h:��@sg�4���v�����!9a��8��]��cv1Aj]?=^�S��9B [1�ln*�3���vU��>s	q��~@�7�����6������(��-�|D����U�������5n.{e�/��A�3���h0�kc�����.�{�|v��c]��������<{5� �`�?>���(��b:"E8V��'1�H5�"raF��83
��������S�BV'X����s���95Y��7������9�~�z�1�@1b.t��b�b$�4��h_�D��/����~��f?6�R�L�����F����I���z.�x��X��=��Q�)���HmxH�~u9�)��+��������m���Q�& ��K_}W\��������M8
�qJA<NI	W;#������C�S%p��y���7{pBpV8�t*�E9	��vG�?HF��7�t0�Y�yd���s����$���#���x6�������a�Z����
id],��^���Z�4�AG�&�A���2Xt
$3���1�����?]u�ut��8}�0fY����&w77����������P��7���!����^N�/�o?����pg���Iq��l�nn+n4<W
���������s�<���V����������a�H�W���j��`Ij�*UU �"�}a�hs$����FX�hRiT<=�T��R��02G0)U�HR=��Hp��!��R��=25O!dc)�m)=��'\DJeEV0����ED�������!c�X��#&�]|�
2� �5C 4Y��;��e?�n��h]E}�4��=�c�a�q��)�)��'�����l�[}
"#51j��a�������s-��6P�Il����vVu��P)h�����^�)HD����cm����X�O����[�a�{����t������:���*�a�z�a�C��~��	/�'��A���,px�����V�r�*�S��BH��m�>a�'F�D��	�J%�0�_��W;�
��0�I�wSI2
��P��l��8�4�B�P?%htu&�#�*JXA���"
��F��yV���J`,<���������;z�X����3��.��a���l�-(���;�`�^A
����5����qW:D����Fz ��v�Q�����"�	H9��y(��G��TD@#B�<"��At!�����
���{\Q����G����1�L�?;���Q��?
�5��W�D�-N�p�~�����<��=�ER�}~��Y��~W�x3��Vz}}8�:yyt���7O�_�<����o���������B�����������A�I]������JI]��K�b���W`(KP����J�B.���K��H�2������0W���?F��(hN����v�N��
p������H�%
���Ge��0I�#�+\������B(�����g����>Y��!�������= y��hg�_�r��lz7�'{{�f��[R/��7���%�����n�������?n7j*��f���'�'�w������3��2�/�9���-�g�������0�n���>M��V��FW; W��di��der!�.���'���8ib���c`��q�o|�����x�~��z�����	�z�������lI�����n�d���&��������5�S1Hv�b�>�V�m�}	u~����_�(�lQl�p�b���h�'�mO\�y.����?O�����+1i�|�`Ob��-��}���t:�!1)y7^kF�-�n�KG*����Zp�s7��b����u7Hj@f�^z�uw^h��9/T���Uw���5�,
��1/+�����v[]/G��P��sue���SN����Zv��l��Nr�O/e!�g���6��w�u���T���uyys��=�����{�bcno�+}i\��nk[����4�������m-��Mo�qy������v
?��v�y����~�
��K��
7��V���f������p��#������.���-�f�x��S��-If{[�����*��7�o�����`�V�������v�����~��H����-��V�� �v�8��J��Cu�>���!�a?X�����G^w��f��+>&��+����K���
��?4�}^}�t#q�����&����x�y�W�,y�W(r$�����}������h����������nw}�&#'�f�W�_��G<z�f�X��mKcB���������h��&@yoX����Bb����p	���"K�=ca�]�	l���?|��V�w��3�F���%��+t��������I����<�l��������j2��ZI�[��9:���5)j�V�
z�U�����|V���P�%���&)^��.Cp�=u���4��h���^�����}��������q}gH������_n�}O��M�|9��<]�6���!c����������������xy.�w��8G��5�>�~����^��{c8{�Qs�;���q����*��9�me�6j�� �����v���
Rg��lg���`����a�
B��r��G��n�|�s�[���P���F�P�E`��I%>�J
O��D��n���_�B�|���	L�=�K+Q������W� ��4�L\��w�V&*
B
Jg���4����Y��`
?�/�i	t���4�e	/5��N�aIk)���>5���!�����@�HK����N�cO0Qq��
�cs�1q��c)G����{��u�� ����K�q <����Ss$�'�n�� �0:�M��(Q����
��w������ .���?��;�����[Qr�
Ar�������y�vatt0�rU�M�'_�
�����L`����g�
cg-�r�3� 7���:`��4���7��m�{�-?6
�c7�JTkp���Z���U��?�GY�1�qg��I��������Y(qq�U]��������|���f���n_��o�������F�#7����L_;p��d���B��1�����C���
}�h���RK�^Q'��)�/*
}�c@?��x>v�1���Twr�|1aS�J���qe_�+���`=>�+������R��7��y$����K�1��&�)����1���%������&..[�*�u/�
hoZ)T,�\�k���b~�W�o24}�1�o;F��- ����!�����
�#��YafM
@dY��:��M4S+����P�=��le>��O�58H�Y�l��_e����p�Qp#��l��r����
�"������de��������Iy������)����f�a����[�[�h�b~��������GgL��������/��8{����p��������G�/�f�_�|�a������>|����Y� .�����y���,�x��8�-���Z��j�2����t8s:���Y~R2�����wS0��T~QJf/E��%KA�2X������A��d0�2�c��p�����R��(���XmLq�o�f*�4�������e��z0p�����s�,�X K5���|.`+p�V��P�j��s��T�R�@R�L�j�������:tR�����_�	XGxPM!+�.�}iVE�	�@�i~�f��hs��W-��E�Q��0��e~a�����\�V��v�����Z�V�ZP��SP�����ce}&��M���YO�h�D�Q�F�HDU4��e���dC���iE��Z��H�V�;�Q�m�-N!�R	����'`�sl��L�2H%b�"��>�#�����gXI�`T�a��R���]W>�n��������}��N��<�����
�xZD+���n�S���B�*(Ba�	��M�F�
&�\���SE8\��a����m0�b����*}��[�Xw���;s!hB�`�%�5��0G�E���!ww��Q#���@x+���iH(T�n
+�J	��+d��	(a`^Hqj��o���Z�HDX����N7b�z�}A��s��z�>�`�	j��<+7�.�g�.�P���S�z�������n�b�0��8���>����"9,�[���H����mpl��cG�k����R���]���:�
�*�
�����oS�4��/�������JL����*[b��������3���MPqg%��s���$&]��C<F��}���z9o��{�F������������l�$�����b��?��4[�_���;v^>L�\Z�`��1aWxuT���??�W	e���������on�w?<����M��3����!�n�)>��]�5F�w�W#.��.��jwN�������������o���I_e�^}Dp�}���/f����Y_�G{>L�]����/�]g�i�Q#0��5F��C?���/�`��������B���������:�q_=���/���`������<f�L�|��1����/W��'���������mW���I7�lM�����0�/�|H��*�m?J<���������;�H{{��;���c���o�L//�|}sz}��;;?����������w~=���Y���t��{{����M���~9��M�YK_�������������m����e[�>@Y6�h���i���/_=����^����oO��m0�f��~�_}����'����w����W�����*^�z��kj��vxSx%R3b�c+7�p�-�j�����2�	����b�h��S!g)v�Z����@��o�)�.P���1'���m����o_�z��3�q�1\^�Dl��Hm�V�
I���P
�����@s��3���U�
��N�������IDz�3�$OX2q g4,�i�|�
B�r�b_����
r�Hu�r"tCV
��"wB�J��P��S��v��rp�5����8Q������|��Ft��p�x)�"%3����T�A�0'�AU���������7/{��5�>t!�af;b$��D���,xTG��g�S�w���n��_�������3�:t��q���7m��p����^��5����-7���P1Q����O} �a;;���W�e;����P41o��*��OW��{�89�	#s���"���s'�C�Ju��/��cy^gx�����W]K�R��������	��G~z@<'
�	<��P��l�pT�X���q�5\��O�'���5� �QZ�X��"��Q��9����!?.���H���I��H"�_�H�����$����)XI�r �����$���@@��f[#R�c|�J��b|5�H7RY�1
�m���[���L��~�0vB9BO�k��)��FP�_a(��(��G���BREX��M�P�	33c*'������$deJxl�:�c�C�KP���������*�B��OL����x2A�z�x���5��d��j2���������"�O~�HJ��`���t�����]�Ky	����jz������|��p�������vv}�)�WXI\x������_�w�+�fzP�d�s.pZ-W�w�{ws�8�=�{%<(w��\=~���B�:\^Q-+w`�l�X�u���������������nr��^�&�7��?�z�w������/w�i�������rv6�����Og]�/�'}��.f��j�\��/���]�M������r��l��������������;c�u�������3�&�O�*�N�I���P�������r��c���������|�W��P��<~�5R��fC`��,���������T�@0Ut�J�K2X
c����
����gX�i�+4����)-������_)O�^C��;_�rE
���1\]��s�t�X�k�8�0R��ed%��Jd�����R���dM+�!
������C�8�j(����CR9UXAr�)���H\���)�����	��I�K���J���,
{_eN��$�$��YpCE�
�n�r(�����H�eL����L�-��&���Z��2�C�aK��KH��I���NBh���J��zJ�b���zkJ:Q�Ek$�F��k^�F��k���k����)����������������p�&^e�w=�6�[��"g@p���"/&u����`���y�4��>����@O1�Pn+�UE���k�����-~�q�83�Bn�7Z;r��C��;P���&Bx�{�a�eP�jy��?W�J���@Y���.g��P��� �+�
�,��R��n�>��*k��|��g�"���EH��M�]1_1�����b���0E�V�1"�	����O�����4���Phb�&b%k����@�"��cd�<P�P����r�����2\T#���t��|�[���X�;�+�1�K���o#L���$R�3�iM����R��
�TW�FrC����1���@�Ez��\�M4��2����l^P���i"�($���I�	���0�QT�:,�	0���`z���/���c�3���H0�=<TYvW%1���x��~wc8CK8W8�t*�S9��ym��h��j�%�C���>:�������}�|?�^�����?<�}�O�7�wz�:����We��������9%�M���rhSr�ZJEW��T��8�j�����������hN���a[�ky;]���e�|nyw6��W���o����,�KLr��ah��%-��t�����NO76&W�z-^7FU�eb����'��;��o?����?��lz7����_�V,/Oj\76���N<r���H��j�Q|RkN���*��0�d3@��<�_���h�b2	�!��-&��X������}����h�h2�b1�����H�b0���!�F���
�a��R�!����Bk6��{��!��f<���Ak��p���H�
��}��\�@b�d2��w\����r�d]��4���}�]��>����L#��N�=Rc+��l���4���,5�����uf�j�,2T�fl�T��4�&���k���q����@�\����K���,�w���������-��~}����j��5�Ef�^V��KzX����.�^���5Zw���%�_gV�+�*3{<���g�=��\�J4jz��r�(i
/�H��D���0P�H$[Q����~�g�����gC���	B�UI��_=�K�a�+��A����*J�����s%��Jz�i�C��xp�:�(�t���LX#!O�&��������A'%��%�t�BBv�dZ�4����x�p��$���}�b�#����$��?�'�d�C���5�%:@�a81�f�b&����G��Xa�*\�6�|�:E	�������k+��r��?L9�o�(�_A��G���~�Vq~r� ?�	���W�
�'U����XB�h.�z4�{2r���c����%@��>:o~��e:��-�q"��iu����5��C�i����,o.���rgs{�v9����!����m����8�x�������l���~�����d���}�������jP�W�D�����u#����'��� ���&�������X���wO���?D.�b�����}w]�r���}�;H^(3����d����������2��m�S�����W����x+��
��
TtTJ98ZE-Z��!2:�x{���IF�9G��������a�Ve��c�t4��)\�Lk�1d
�c���40�GH c�QP4����F1Ps�%�D@��@�Z���j�������x��4V�4� ��=\�j���!��vZa��D��|���jb���\���qE�OQ��h����<�F<k��O<I
m��6�l�f]CD�4b�9`C)QMc��%>������.m]l��6����s	9pIf������?	���[��N9��g�l��'-;�|�V�4f�4V�D+D4������3mcp�Ln�����|S��m������Ih����#|���|��)
�C�����&F�Ka�����j'�zw���>����hUa�Q	b��L%dj�T��>��1�
F�\,_�6�jI����������5���*���H)
�l�8�������-=�#��"��W"�h.R�������d�����|�n�fU��~���;-u�k�q��]����a����v��r���((��*�~��]���>\�����PRl��D�R�P�U��b�Y�c��v�1�l��|�(1f��9��=}��t�Gj|�>=?/�e�����x���S���1,?%�c�~��B�8�#�4F�@1��G7����s����1z�B�
O���+ 6Z+_��A]tt�Up=86�./fE�W|�������b�����hc�h��KDx4����F��6��m;��D[������A��|H�����E>���}�]}�`��zzL:�^��'��z�Uv�U\
L��������V��=d���|d�=ZAs����9�]8�%p���8[��A(S��9cCf�
}��>�����o�����+��V��Gk�����!�w?�^N�/&���E�t��t���:�ps}�Y�wgON����N��'�����
H��l��Y<As��k��>Q���D]|�M�S�&Es1�+{�c�x����6W�R�=��z�����e5�&�N���!) <�&�x�YS�V�<��Hz���z�����'����������G����c>[	��b"'P�JEEd/��	qj@F|���Ul�)Q�
�@|�
$�Bb��H,���I T���+`���$F��)����:e�r�����d�'�����%���J��>$���������hv���Xc,�[|�_ ��V�	v+���^��a����

���Y���y����D�T��	�8�E�%cN�l�'�n�N�+!�adlJ��d���2l6�����^�re^��w�P��4�w�e��*F�F�(-�9ca�vA�>����:��J"VkzT����5U�DH�
T�����e-@l����{�1[�� h#3����d��6|	��
���n!x������������������.Q0Z+��G\P��hz���0�v`P��%�*��7t�GR���=��B�*�p%�DYD���%|%*
����}�X��G���T�r���H����|��}K��
�����zq�W��/�����s�O"mG�&�	���f�`n�,�_�e��-U�a��S��o�5}	����b�c#c���h,���c����0 ��Ed��� Y�&��4fF��x�id/8����e+#5��P���A
X��Gkxo<\�Cz��]Q���"����
����m-'}$�mYY�Y�p��*�V��n�)~
���
���f�>P�������=1�R�Y�617Wf����K��Mb�K���.�-b���v���kl��|��*k���a�	�6@�l��������?��k��:N��%��U���3{����Z���������&�{{d+/�]3Rd��#��Y��zde��]=JuhS�l����v[z�[l�aO�S���������?�y�
�l�n�iu�
��f$��6@�[m�����������f�h�
���h��	�������`�����������j�b����U�j������%�o�njG
p�
5�h���K���/�MC�y3
Pq�t:��������S'�v��5�{l�^��s�;l��lps.�k`g��k`�`w
�Oe�7��=���p
���G+�1��#�Y���@^|+'B�
1@��a�`���')��\!�)�`���d�&	f���_�����x����m.�A�].�N�M.�4���������.pX�
.������V����x��K��/�qi������b?��b�)gx�}��f�}c�3{idA����h'
u������>�O�h��d���t`
|��-4�
���lb���,��3��f�P���o�����1�(�v�'��M��{��������c��4�l����P�����XV
�����Y���E�a���~��v�'�����f���u���luf���������G���\��N��"���xQ1�ByQ]���;��C��{j������7��B��������g���@��"{�������V7���-�z���g]��P���< �-.h�������/xn�6�p������z�/Y��vW�Yd)�!�+v�h:�����o�?���-��zw��^����v���lZa�r����-+�xN;V�\�nXAB������D6��*XH�U�9:N��"+b�
�Mb�
>�������"p�]*�>�|���GmQ��
��Tdi��)��e2oJQb�'�y��C����o~�"��g�6#������)�����l�m)��m��b~;��_���9�K����K���S�yT^1Wz��b����byn/"3��0������#��b������li?9�x�9�^�c�C���"���2����������
�+:�+V�J��>�X��Q1J)V�Di�����w���!��75H+��9��X��9s��T��fo��bM7F�I9�JM;��M=���J`
2W������(���55i�P��dN��d�`��9{���fN|'*o3��d��aUF3w����I)���f�'Pyk��M|�m"7�M��xvL��������������Q�����d1r���hC	���]R�Q����������\���G�
��X��y��(�,m^�Lmb�3���zJ�b�R(��iH'J�n(�<n��\n�D�E�b��
� �[�I��i��o�����j�
�p�M\8��%w�f2���N��\b8�������&���)I\��$�[����]$eZ����������dtE�9��%��g>8~�M��B;��u��t���<�2�������H�t�����6w������h�fUY��}rf;��6��{��wN�Y�x�h2��T��L����������"�9[]�<r��l=��
�YC�j�Ju�����&)�k�51��jr>~����{����Oh%9[0^��|-�]1�R�����HL�9O_��\}����G����C;��S�s��O�`�F�&z�/�+�s���=�s��Jc~?�A9�"���������
���8���������q�����7u�5�����5��:tC�@��kB:u���
�)� �S'�B	�O������SfB~
6;��2�S���,6��K���eH����w3�a������m�z���uA&�a\� ��+ s:/��������N�d����ro��n
Y�$�R3%���������5���C���E���,���"�"ur�M1����m���N5'�pR��n��0�b������l�x`�q�>� ��}�O�������^�����_w��������?d�v1�����fW����O�?�����N�6;q�7�,.&c�����t{g����lg��S��Q]��?O.g��d	)�Il�M-@���'��j8�K��V��]w5��'�j������8$��`u����~?����>`F����	0m.�?��7�A`�2-@n	���'�����U�8n���/������>�����O��>	��P�R�@>����Z��(�-�����7���`[S���i�d����-���Y���bv�G{�������_�w��S�m����o�����G��l
o�����!����\�<�lv�x��������`6�O�U;�����$����5�D�z	�:�F�����Fp"����A�em��U��(ot�f���L}|4����\v��^Rw���kO-�ll]��l�����?�-�y8���Ie{{,dt" F?zU�(��@x	-:�M(�x��� ������w�NPp"��F����Dl0#�fk��
�mA��=4w��xg���EZ�P�8�.�
q� h�����CUqa����u��[ �k���ox����UD����e-����*��A|�1,/v��d���!�,D@_}b�#���3OC��H�
A('���0�?��6F(�2�9�[���Z~����t���VP��`�.�B>z���J&4z\�x����Y�@{��z������f��v`���?=���m�G�t���=�^I/�^������l��DE�y�]������a�#�g�X�S��:7�eT���}1���W!����:���O7x���	5��akDo8��h;9�"�8���0���AqJ� �_��
G��A�a�/�6~c�|k�z_�@��[�2*t����+��>��hvga��)��e���1M�
d#{AldOT,[��}�kl
R�Z<V�{���#5��
��5]V���]Hk9�#D��z�z7T���5<3O�����,�[����?��y6
������}�aw���k������~:�0]N���~�MgdT�"e�rkffT>*;�:�m�\������:|�~��J:Gs/#Nv1&s��%:6<JRG���eEK��VqI����m��J�hu�����0%~�*R�G�	 ��qI ������)"�9y���T�JI����)#�M���R��#�l�G
���t�M#�����$U�JJI'���N�RKF�Q�M�I'c�I%��>9��l�I���u�	(�j�PZmU"Ju���R�)�������U%�tN��R:����DI*�''��r�J��&)��i91�����55���OR�|J^4��j�J�b�J��K�J��m�J_kH^�{lI`)���zId)U�+�*{diSb������[���j7��.%Q�VOf:�&�t�M��DL�������E���e����b�}����������a|bM�	]rM�K�M���I6cL��Q�M��n�W�O���lr���`s��I���/&��J�L`�����V��/�C�"3�EM��_�.U&L()]�������T�:H��_�*}�oU�B��,�WP��L*M%�t��LJM�
F��',msmJ��n�%���LjM��
�jM�)��aM�F�Z�������������1�L.�N�z��rz6��#=�������{���C�<�N�D�A�]�����Lk��{0m��rv^�r����q��l��e`�P�DYCN)s��R�P_�(��>�h0W��2T��� �&}�o^����FT
U���A� �Ul�����H�B�I9e�������[S����26�g�a��.[��E��z�_�QnO����{*�U9>U��SL� �'M�d�O��r~�c<������S�5��s�N+�<�JL�@��:f�	jU���R�T�A���L�m�A���~�����O�]��8&�����C�HX����������>��o��H[�mom����}�����������2�E�*@z��������s	������H.�����q�E��:�ES��2��ng�g�i����������V"��iA&.�;�a���|Zlr��V��\�x5i2�W��-������n��������������?M�����>��\�����/^�G����F�������������Y��(��x�x����A�����Z�I[��r�V�1,P��d�d�k`JHT�S��0�j2�l�I�Z�2p��i�j
o�0k�"�o5T�[�F���������F�[�u�4��V��5'{Lf��������I�
�����I�j���K��S�V:M�j��j�0Y�pRu��Z�D�ZIr�Z�^���r�����
2�Z�&bM��yX�t&
+)9�57��Z7���:��,BV��0��r�W�X����e���
)�W�N�1��OW�C�W�^�Qo0yW�BiW�u����� �*�s�B��)Wy9lh5�*+LA������5J��F5�������,T,��r����!`&V�@"V+@V(�*�I4��
mI�Yu���$�����
��X�;Y3�b7j'X���_U�pzU�����+F$W��*�rj�������%V% w<{��4	:�i�����&�)��|f�<���h��U�5�������	M�E�|���!�!
�6�)I&�)���2��[}�Q�e)�<��[�vj�P0�����M�PRL�Pe�e�
!�f��4��D�06�d�rl��Dc�]?���D�u���.��!����ID���������&���M����K����E�@��X�G���6�2���R�P��yC�CN
�@�
E�dg9C��Q@5+����$��M	
MB�B3	AiX��$�T?]nO�rON�{�Ix��I������9&���*1*C�M��e)����}|����U���4:<?���wO?�^���k�}}8��|�t���7O�_��ts��������������b����g�O^�eDZP��f�w`���V�%��'`���Nmt����L�����>qJe�|�`�|�PRs&�O�IB��I��8&�gRT�O�M*�'U������{jL���9X�c�q:������z&i��������V'��O3��Y���z�q�vTg3�����?f���6������p��ia<��1��^
�j����~!`�s��������#���o����Q3[+�d\W����`P(g���j`�����)�.����;�*�P��0`��	P4rW���>x�Bw��8]�!��ZE9N),�sdY	�9����b�)��^�����P�kDu�!ao5\���D

�!���*�`;���xidd��	�Cx�j_z�x��O�&����Rg�!!}�.`�$ 3��e4�}�����3�	2���aK�|FHh�K!4BD����h�zJ�b�b�gN���XRC�A5�V��5$�\����5��i-��9��������_\i��L�������w��0�b(�.�f�O�0�9��EL�����b��XKU��\h�8��I
�'�q�?��H�_-��p!(�=�����]���
�q5�`F����h�t9g��V4��g�^��o�x�7��zF#�ix�h(
��9�
 ��4=v�4���p,;3>b5�j`M����[q�5d'#�:>������gmBu�6�����]���J�Q�nB����@1�.t����7r��G�p�H�/G*�+��V�������
�	~����l�o�HA����	��9�Hs����uuj$7T&h��#~
��@z�V&�����1o��opi^P%.��i�����������Y4��f���3�����`<���g���J�3����h�=<T�4U������4����p7V�&���f���J��W���5m��h�k���A���+bc�F6�|?�Z��6}�G�l��l}��h��_����f�w�K�
RV�����D���a	q��G���p��c�
�]
or��"�������uy7�:������������������������/N�j�t�8��-�H�}�L������d{�7�EW�noL..�>t��nL��o&7W����bz5���t��l�1�nzy��;��n1�������_��&���q������������l�\���yw�����l2��������f�ew������fO:��u�)�t}�����������������4k�F���WC�V��u]�����_��_����oO����Ubco���tiE1sA+{*h�x�"�����[������,��6A��8`��`@KM�f�&�t���l��o|�qY������$���e��[O�u�=������_�{��l��d+�G84bG'��JE�d/��7
qj@�|��U��2*Q�
A��
�E�Zd��,�s�2P���yP�S�������D� t��N3/5@��DQk	��S�!����{[6S��ny�9Z�-�0H�@r+������X/��od�����X���	��C!�N���J�v�"�rF�f���o����n�"��-����v�\��[��x�qp��J��aP��I�L'��f6I}�E&�+pI��T|�I�K�It0<R�D���,r7 ���	�b;�2�b�Z@ ��w
��2�A�HfKw�	����&�Gl���� ]i#+�5R-+it���1eDY�1�����f��"Z+[�G\�"�+��z��R���"Q�Q��D�3��������f�##����C��!����!��L�J\P4���	�C���
�@x��|u�-�H��(pB�#%��b	!8R���A1T�J&�~\�����	��W?�
��Ha���@�F��}�D����s"�<���{o�����������0��������E��������>�����eT��Is>vW��}���d�>3�P|/����Q�M`
�#{�zdO(.[���}$zl
Rh^<��{�I�s<������5]V���]�k9�#��������nP;8�bv�jbg����u)m���m{��B:qV��Nonog�f���N�	?�N-\'�?�������)���+O����vz�g-*��]='��������`�n1=�
���r0
����k��KC�.�c�7���lz7�����b�����������	�����!i��������������B��/6&�����nz�c���nvzw��t=��M�;�Y\M�zB�X�,����]���b><F���������H�q}���v���;�=���lc����]�x��_���';M�e��`��yx���`����8)�r��.c`����mx�x�V	��J�`��M!a�����jF|�����d������2>Tf�>F�Yx��Fbi|n�iJ-D���y�p5�Z��tM���d���m�l,�-p�����E@nB$��	�	�aoB}��ik�e��-(Nh#�b!r�(���S�!s�p�����rBt�1+���
#YHO)��g�
Ep���8���a���|/����`@�����a�t��H�u����w�T3T�A�S�R���rB-����f��r��Pj'R���5Y2�PH�Y�1�� ��:����y�?����$�Pt�o��q��Z ��q�uH���9e��rE��@#C/���LR�k�t>�L�N�r�|rMO@�A�um��J#)i�Wg/��NKz���N�������,�kD)]G0�E�C*�b�����X���43�tAIC/��VB�a:�bL���Z��~�?jW���j�a��M���+D*�l���Y�����v�f��:C�������k��y�@PS7���*���X�������B#9�7]����U(*]���.#u��HG]����:F������I��������L]�	~p*��|���	�
GX����PB���H4U�|G���u��������Q�J2_u/�6b�-����@��y����ppk��*qm�OCWQBqW������,}�	���C0�����O�
��R��^J(��d�4RY!�G+l�h����	�8�����+N;YT���`�W���K0�~�x����tm�����0�wj`Y>�"���i8��p
>��/Oz�7��������O�����M�9�>[�/[�*��N��^"q!�4c��G����k���E��Y1���O/��f��
��,~p}�3�����/w=�|��6�[OT'�;-���s�[W���7wVx�P�zE�:;��t1_}u�c���^U�b�(�0W3�b���V�o���o���3���U��S������J1{~<����'���E�j��;�!^=������h����/�<����;�����r5�z�������noY��v�Z.�l?���lmo�������/����{�����q�c;���N:�����������=��WW��������wv~����]���M���z��{�����������w1�v����r�*���^������l�}���+�p'�����p�����z���o����_��~��6���?^��{���F��'��������GO�&�k)�9H��t����������^��\-/���>�#�Lq�%���E�[#7^��6[
�<d�����}<&��2���F��6k>�m9����7:c-]�KXk������ ��-��V������^��S�|�l�Z1s\8<%�uZ����I�KB���M�+J��c�[>�~���$�!�}��TM�[�0�-K���>�|�����	q�h�������f��$���U�p�t5.+),��D��6����m2��	s�Yg�����������j:Z<$��VT����T��:���~hr�
�8R�EJI���!@�VPl�Vl�V0g+�A�V�[��d�)�S0��������������Oh���T�Q}�W�y%�k6��z;�9������Z�L����3����YWy0IW�.&��:~�ru���2)a]��~������`�fA�i���u����_~������w�
k��JvR|&V~�A"V|��d����/��F�Ng����z&��M]rU�Y�"���I��h6T���,�4���Z��cY����Z��J����p�[^I-
f�*n�.&g�?�.q�����8�������QTh��P�D��
R6Q�/)�(9����
u�������}CQ�O�U?���d�� g�5(w*�pj�P9������S�P��e�yJ�
�F����\�^6��l���K�������L
�t���8�w)AA3�6��$
��e���\6Pz�w�OA���yU�
����qDQ{NH �82f���������q�������)*�r�y�z���o\���r}6}�'F@�2`H��e��Yn�c>2���=�7?��������t�����7��������6vwR2MQ�}��L���aI}��G����|��c��]M|r�O|>"�/����{�RB�����,:��+����Ul����WZy,*��9�leD6j�� ������������Hp���q�\�8� ,�*5�s6��2]+��I|�������)��Cf�9�V� �-���J��>&{������85����9rv8{7V>�v5j
�Y��1�)0�6f�����
�P����"&��*!a��-X��0x��S���)��ESx���)p��RZKk�l���j�)P�������k�j�R'�s��[|�a�����L����%����c���p74�R�;��+y��X�Ia�U
��8�E�]���{������;&�vwg;��A�Qw�b���l�$�x�u��!(�B���y������Z,�]!�]p��p���n�:���*���G�����|U��i����{���{���@��e�5:\�C��_�����s��>�i�u�}����>���R"l6��~a��<��D�$@��D�
���az��A���5��Z97��F���h�=Vu)K������ �s�Zu9PC�u��(������i����L4�Mf�V��1�����z�G�We�@2��b��N�e���u��>2��#��G�;��<b~����0���/���*����~az�=^=��.��;B<������#�P���>��#�p��4����0	�RU�84�Y��PF��H�\c���������1�:i���
b�3�"Yza&j�M��J=J�2���56d/l����d+S
��P���A���,x`������C��4��<,�h��p)�]��X9�rrG����h,��)nR�^*c������������lo�nnM�>O�%2������\^�����$�!9	;��5{�8	�~'���9I.��$7�w7T���r�i�v4[+bIs�t����R<�s{�����%=��J������s^��M.onn��z7���6���\/m��������t6�g�^��K6^
+$|^�r���~�4����}f��D����= 2j��e#"o��(��d�DYr�(���RD��]+"�G@dn�D��)����8�����DN*��
��^�
 ��������"��H���U@
�z�i�Ih�m
������!*��h�OU�#(k���K�!�	
9��!��
��!�%4d{NEC|rf�g�L=u4;4r�Wr[/hH<pod�-6##�ha}-2�����,c)##'���O�>B;�g�`��W���\\�EB^8�v��p�:�g��lH�
)b;�"5)�.�akq���ek]A���#E��������N�iW 
�I�0)�fa@�O<jzT��� U����yV����d-A���+�7�*�PD:d�!�!�AX�������x�}����?!l�&��cpE>n>qx�r�Vp]a�A8������B���bV��!�� ������o]��	� q�*���hx>Vu�,��a�����@Q)QC�u�A�����M�i�P"����q�D`%$ZL��aq��yB����x��l�yDE�x1O���;��y���j���9�/2�����/T/�����T0�K� �g<����
��2���'��PH���	�����@!5~�4lG�kU���m(��-(��%(�?Q
���
5.�B��N
���B��P��K
����BYPH��h
T��"{�9��P��#bkp���������
aWTP(��P��r�����"�P�I	����z[`��[j�U"F��ibd�G�|����.�����mA������jc���������������r�50���D3�{�������C2#v�Al�h1#��f�eW3�\�������e���:�F��b�P��`�S�,�^�����\p��J]�^>�D�������>��M>�\����"��+Ne��������v-Gt5d1�p>����X�&����>��
;h]�L�~��
����z~7�m�dz9����]���n1���w]��Yw�����Y��i7�TV���a��~�����A���I7�8<|�1y���_����������z����H���oz�O^�z�~\�q���a���;��&�V[Am&�K#��]u�3�M.�3��x�2n�U���r�����=�3j<�1��v���jqZ�	�%��`�\�IEpg�v���BS�������[�)�=e��[�W����o��t���v���G�`�}3&�x4[�����h`/�����n8��������Z�x`8�����x�.��"����p<�����B�x������
�ca�Z`
9x	�:q<����p<p"�����l����C�x��]�<9�~�LC�hvx���.P������1�S�qS��{�|Xc��e��F������Z��|~\��Oh���,*�s��P8�v��@0�������E���<a<�b1�	��|��0�#e��Q�5(��v�{x�3�����{���vA�G���L�:0~��������Q���"lzT2����u��:���2Ulv�6f{6!�����YX��Oa��dY��"�L��c�<�,2k����`��Z�E�7	�-���He��IWW9$��7�o���N��2�I�>����_�9~�]O\o��J�>zt�H������@z�u�f����f��v`��O=#=���[/��/�k���GmpJ��(�^�������|�5�O��}�~�KF���T��`=�S���s3?�1�E�T1�
���T��0�b���GW�Z3��7��#�S���x�6�<7t����&������u�-�2��GP��p�`4vZ������-"3oI���,������ 2�DF�D����GD��� �e�#2�7��!="��Y�aY��`�K[�E ���> �������!2�"+�M#2���Gd����pL?��w�6qB��^�8��v����b9��n�nnmnm�a�N�w������rsw����Dm/�7����m2��o�T���.gg�W�C5.gw�����?���M�2
#16Tom Lane
tgl@sss.pgh.pa.us
In reply to: Thomas Munro (#13)
Re: Cleaning up historical portability baggage

Thomas Munro <thomas.munro@gmail.com> writes:

Here are some more, a couple of which I posted before but I've now
gone a bit further with them in terms of removing configure checks
etc:

After looking through these briefly, I'm pretty concerned about
whether this won't break our Cygwin build in significant ways.
For example, lorikeet reports "HAVE_SETSID 1", a condition that
you want to replace with !WIN32. The question here is whether
or not WIN32 is defined in a Cygwin build. I see some places
in our code that believe it is not, but others that believe that
it is --- and the former ones are mostly like
#if defined(__CYGWIN__) || defined(WIN32)
which means they wouldn't actually fail if they are wrong about that.

More generally, I'm not exactly convinced that changes like
this are a readability improvement:

-#ifdef HAVE_SETSID
+#ifndef WIN32

I'd rather not have the code cluttered with a sea of
indistinguishable "#ifndef WIN32" tests when some of them could be
more specific and more mnemonic. So I think we'd be better off
leaving that as-is. I don't mind nuking the configure-time test
and hard-wiring "#define HAVE_SETSID 1" somewhere, but changing
the code's #if tests doesn't seem to bring any advantage.

Specific to 0001, I don't especially like what you did to
src/port/dlopen.c. The original intent (and reality until
not so long ago) was that that would be a container for
various dlopen replacements. Well, okay, maybe there will
never be any more besides Windows, but I think then we should
either rename the file to (say) win32dlopen.c or move it to
src/backend/port/win32. Likewise for link.c in 0007 and
pread.c et al in 0011. (But 0010 is fine, because the
replacement code is already handled that way.)

OTOH, 0012 seems to immediately change pread.c et al back
to NOT being Windows-only, though it's hard to tell for
sure because the configure support seems all wrong.
I'm quite confused by those two patches ... are they really
correct?

regards, tom lane

#17Thomas Munro
thomas.munro@gmail.com
In reply to: Tom Lane (#16)
Re: Cleaning up historical portability baggage

On Sun, Jul 24, 2022 at 12:23 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:

After looking through these briefly, I'm pretty concerned about
whether this won't break our Cygwin build in significant ways.
For example, lorikeet reports "HAVE_SETSID 1", a condition that
you want to replace with !WIN32. The question here is whether
or not WIN32 is defined in a Cygwin build. I see some places
in our code that believe it is not, but others that believe that
it is --- and the former ones are mostly like
#if defined(__CYGWIN__) || defined(WIN32)
which means they wouldn't actually fail if they are wrong about that.

I spent a large chunk of today figuring out how to build PostgreSQL
under Cygwin/GCC on CI. My method for answering this question was to
put the following on the end of 192 .c files that contain the pattern
/#if.*WIN32/:

+
+#if defined(WIN32) && defined(__CYGWIN__)
+#pragma message "contradiction"
+#endif

Only one of them printed that message: dirmod.c. The reason is that
it goes out of its way to include Windows headers:

#if defined(WIN32) || defined(__CYGWIN__)
#ifndef __CYGWIN__
#include <winioctl.h>
#else
#include <windows.h>
#include <w32api/winioctl.h>
#endif
#endif

The chain <windows.h> -> <windef.h> -> <minwindef.h> leads to WIN32 here:

https://github.com/mirror/mingw-w64/blob/master/mingw-w64-headers/include/minwindef.h#L15

I'm left wondering if we should de-confuse matters by ripping out all
the checks and comments that assume that this problem is more
widespread, and then stick a big notice about it in dirmod.c, to
contain this Jekyll/Hide situation safely inside about 8 feet of
concrete.

I'll respond to your other complaints with new patches tomorrow.

#18Andrew Dunstan
andrew@dunslane.net
In reply to: Thomas Munro (#17)
Re: Cleaning up historical portability baggage

On 2022-07-25 Mo 10:35, Thomas Munro wrote:

On Sun, Jul 24, 2022 at 12:23 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:

After looking through these briefly, I'm pretty concerned about
whether this won't break our Cygwin build in significant ways.
For example, lorikeet reports "HAVE_SETSID 1", a condition that
you want to replace with !WIN32. The question here is whether
or not WIN32 is defined in a Cygwin build. I see some places
in our code that believe it is not, but others that believe that
it is --- and the former ones are mostly like
#if defined(__CYGWIN__) || defined(WIN32)
which means they wouldn't actually fail if they are wrong about that.

I spent a large chunk of today figuring out how to build PostgreSQL
under Cygwin/GCC on CI. My method for answering this question was to
put the following on the end of 192 .c files that contain the pattern
/#if.*WIN32/:

+
+#if defined(WIN32) && defined(__CYGWIN__)
+#pragma message "contradiction"
+#endif

Only one of them printed that message: dirmod.c. The reason is that
it goes out of its way to include Windows headers:

#if defined(WIN32) || defined(__CYGWIN__)
#ifndef __CYGWIN__
#include <winioctl.h>
#else
#include <windows.h>
#include <w32api/winioctl.h>
#endif
#endif

The chain <windows.h> -> <windef.h> -> <minwindef.h> leads to WIN32 here:

https://github.com/mirror/mingw-w64/blob/master/mingw-w64-headers/include/minwindef.h#L15

I'm left wondering if we should de-confuse matters by ripping out all
the checks and comments that assume that this problem is more
widespread, and then stick a big notice about it in dirmod.c, to
contain this Jekyll/Hide situation safely inside about 8 feet of
concrete.

Clearly it's something we've been aware of before, port.h has:

* Note: Some CYGWIN includes might #define WIN32.
 */
#if defined(WIN32) && !defined(__CYGWIN__)
#include "port/win32_port.h"
#endif

I can test any patches you want on lorikeet.

cheers

andrew

--
Andrew Dunstan
EDB: https://www.enterprisedb.com

#19Thomas Munro
thomas.munro@gmail.com
In reply to: Tom Lane (#16)
13 attachment(s)
Re: Cleaning up historical portability baggage

On Sun, Jul 24, 2022 at 12:23 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Thomas Munro <thomas.munro@gmail.com> writes:

Here are some more, a couple of which I posted before but I've now
gone a bit further with them in terms of removing configure checks
etc:

After looking through these briefly, I'm pretty concerned about
whether this won't break our Cygwin build in significant ways.
For example, lorikeet reports "HAVE_SETSID 1", a condition that
you want to replace with !WIN32. The question here is whether
or not WIN32 is defined in a Cygwin build. ...

No, it should not be unless someone screws up and leaks <windows.h>
into a header when WIN32 isn't already defined. I've done some
analysis and testing of that, and proposed to nail it down a bit and
remove the confusion created by the inconsistent macro tests, over at
[1]: /messages/by-id/CA+hUKG+e13wK0PBX5Z63CCwWm7MfRQuwBRabM_3aKWSko2AUww@mail.gmail.com

More generally, I'm not exactly convinced that changes like
this are a readability improvement:

-#ifdef HAVE_SETSID
+#ifndef WIN32

I'd rather not have the code cluttered with a sea of
indistinguishable "#ifndef WIN32" tests when some of them could be
more specific and more mnemonic. So I think we'd be better off
leaving that as-is. I don't mind nuking the configure-time test
and hard-wiring "#define HAVE_SETSID 1" somewhere, but changing
the code's #if tests doesn't seem to bring any advantage.

OK, in this version of the patch series I did this:

1. If it's something that only Unix has, and for Windows we do
nothing or skip a feature, then I've now hard-wired the macro as you
suggested. I put that in port.h. I agree that's a little easier to
grok than no-context !defined(WIN32). Examples: HAVE_SETSID,
HAVE_SHM_OPEN.

2. If it's something that Unix has and we supply a Windows
replacements, and we just can't cope without that function, then I
didn't bother with a vestigial macro. There generally weren't tests
for such things already (mostly stuff auto-generated by
AC_REPLACE_FUNCS). Example: HAVE_LINK.

3. In the special case of symlink() and readlink(), I defined the
macros on Unix even though we also have replacements on Windows.
(Previously we effectively did that for one but not the other...) My
idea here is that, wherever we are OK using our pseudo-symlinks made
from junction points (ie for tablespaces), then we should just go
ahead and use them without testing. But in just a couple of places
where fully compliant symlinks are clearly expected (ie non-directory
or relative path, eg tz file or executable symlinks), then the tests
can still be used. See also commit message. Does this make sense?

(I also propose to supply S_ISLNK and lstat() for Windows and make
usage of that stuff unconditional, but I put that in another
thread[2]/messages/by-id/CA+hUKGLfOOeyZpm5ByVcAt7x5Pn-=xGRNCvgiUPVVzjFLtnY0w@mail.gmail.com, as that's new code, and this thread is just about ripping
old dead stuff out.)

4. If it's something that already had very obvious Windows and Unix
code paths, then I didn't bother with a HAVE_XXX macro, because I
think it'd be more confusing than just #ifdef WIN32 ...windows stuff
... #else ...unix stuff... #endif. Example: HAVE_CLOCK_GETTIME.

Specific to 0001, I don't especially like what you did to
src/port/dlopen.c. The original intent (and reality until
not so long ago) was that that would be a container for
various dlopen replacements. Well, okay, maybe there will
never be any more besides Windows, but I think then we should
either rename the file to (say) win32dlopen.c or move it to
src/backend/port/win32. Likewise for link.c in 0007 and
pread.c et al in 0011. (But 0010 is fine, because the
replacement code is already handled that way.)

Agreed on the file names win32dlopen.c, win32link.c, win32pread.c,
win32pwrite.c, and done.

Another characteristic of other Windows-only replacement code is that
it's called pgwin32_THING and then a macro replaces THING() with
pgwin32_THING(). I guess I should do that too, for consistency, and
move relevant declarations into win32_port.h? Done.

There are clearly many other candidates for X.c -> win32X.c renamings
by the same only-for-Windows argument, but I haven't touched those (at
least dirent.c, dirmod.c, gettimeofday.c, kill.c, open.c, system.c).

I'll also include the fdatasync configure change here (moved from
another thread). Now it also renames fdatasync.c -> win32datasync.c.
Erm, but I didn't add the pgwin32_ prefix to the function name,
because it shares a function declaration with macOS in c.h.

OTOH, 0012 seems to immediately change pread.c et al back
to NOT being Windows-only, though it's hard to tell for
sure because the configure support seems all wrong.
I'm quite confused by those two patches ... are they really
correct?

The 0012 patch (now 0011 in v2) is about the variants with -v on the
end. The patches are as I intended. I've now put a longer
explanation into the commit message, but here's a short recap:

pread()/pwrite() replacements (without 'v' for vector) are now needed
only by Windows. HP-UX < 11 was the last Unix system I knew of
without these functions. That makes sense, as I think they were
related to the final POSIX threading push (multi-threaded programs
want to be able to skip file position side-effects), which HP-UX 10.x
predated slightly. Gaur's retirement unblocked this cleanup.

preadv()/pwritev() replacements (with 'v' for vector) are needed by
Solaris, macOS < 11 and Windows, and will likely be required for a
long time, because these functions still haven't been standardised.
My goal is to make our replacement code side-effect free, thread-safe,
in line with the de facto standard/convention seen on Linux, *BSD,
macOS, AIX, illumos.

Note that I have some better vector I/O code for Windows to propose a
bit later, so the real effect of this choice will be to drop true
vector I/O on Solaris, until such time as they get around to providing
the modern interface that almost every other Unix managed to agree on.

[1]: /messages/by-id/CA+hUKG+e13wK0PBX5Z63CCwWm7MfRQuwBRabM_3aKWSko2AUww@mail.gmail.com
[2]: /messages/by-id/CA+hUKGLfOOeyZpm5ByVcAt7x5Pn-=xGRNCvgiUPVVzjFLtnY0w@mail.gmail.com

Attachments:

v2-0001-Remove-configure-probe-for-dlopen.patchtext/x-patch; charset=US-ASCII; name=v2-0001-Remove-configure-probe-for-dlopen.patchDownload
From 9f6feda7c467953af4aafeaf573a7035169baced Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Tue, 19 Jul 2022 18:07:51 +1200
Subject: [PATCH v2 01/13] Remove configure probe for dlopen.

dlopen() is in SUSv2 and all targeted Unix systems have it.  We still
need replacement functions for Windows, but we don't need a configure
probe for that.  Since it's no longer needed by other operating systems,
rename dlopen.c to win32dlopen.c.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CA+hUKGJ3LHeP9w5Fgzdr4G8AnEtJ=z=p6hGDEm4qYGEUX5B6fQ@mail.gmail.com
---
 configure                            | 19 ++++++-------------
 configure.ac                         |  2 +-
 src/backend/utils/fmgr/dfmgr.c       |  4 ++--
 src/include/pg_config.h.in           |  3 ---
 src/include/port.h                   |  3 ++-
 src/port/{dlopen.c => win32dlopen.c} |  6 +-----
 src/tools/msvc/Mkvcbuild.pm          |  3 ++-
 src/tools/msvc/Solution.pm           |  1 -
 8 files changed, 14 insertions(+), 27 deletions(-)
 rename src/port/{dlopen.c => win32dlopen.c} (95%)

diff --git a/configure b/configure
index c5bc382395..dbff2028a5 100755
--- a/configure
+++ b/configure
@@ -16687,19 +16687,6 @@ $as_echo "#define HAVE_PS_STRINGS 1" >>confdefs.h
 
 fi
 
-ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
-if test "x$ac_cv_func_dlopen" = xyes; then :
-  $as_echo "#define HAVE_DLOPEN 1" >>confdefs.h
-
-else
-  case " $LIBOBJS " in
-  *" dlopen.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS dlopen.$ac_objext"
- ;;
-esac
-
-fi
-
 ac_fn_c_check_func "$LINENO" "explicit_bzero" "ac_cv_func_explicit_bzero"
 if test "x$ac_cv_func_explicit_bzero" = xyes; then :
   $as_echo "#define HAVE_EXPLICIT_BZERO 1" >>confdefs.h
@@ -17078,6 +17065,12 @@ esac
  ;;
 esac
 
+  case " $LIBOBJS " in
+  *" win32dlopen.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS win32dlopen.$ac_objext"
+ ;;
+esac
+
   case " $LIBOBJS " in
   *" win32env.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS win32env.$ac_objext"
diff --git a/configure.ac b/configure.ac
index 61d0dd5d58..68ef649258 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1880,7 +1880,6 @@ if test "$pgac_cv_var_PS_STRINGS" = yes ; then
 fi
 
 AC_REPLACE_FUNCS(m4_normalize([
-	dlopen
 	explicit_bzero
 	getopt
 	getpeereid
@@ -1962,6 +1961,7 @@ if test "$PORTNAME" = "win32"; then
   AC_LIBOBJ(kill)
   AC_LIBOBJ(open)
   AC_LIBOBJ(system)
+  AC_LIBOBJ(win32dlopen)
   AC_LIBOBJ(win32env)
   AC_LIBOBJ(win32error)
   AC_LIBOBJ(win32ntdll)
diff --git a/src/backend/utils/fmgr/dfmgr.c b/src/backend/utils/fmgr/dfmgr.c
index 7f9ea97280..08fd7e1264 100644
--- a/src/backend/utils/fmgr/dfmgr.c
+++ b/src/backend/utils/fmgr/dfmgr.c
@@ -16,7 +16,7 @@
 
 #include <sys/stat.h>
 
-#ifdef HAVE_DLOPEN
+#ifndef WIN32
 #include <dlfcn.h>
 
 /*
@@ -28,7 +28,7 @@
 #undef bool
 #endif
 #endif
-#endif							/* HAVE_DLOPEN */
+#endif							/* !WIN32 */
 
 #include "fmgr.h"
 #include "lib/stringinfo.h"
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index f9618e1986..c213f31273 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -169,9 +169,6 @@
    don't. */
 #undef HAVE_DECL_STRTOULL
 
-/* Define to 1 if you have the `dlopen' function. */
-#undef HAVE_DLOPEN
-
 /* Define to 1 if you have the <editline/history.h> header file. */
 #undef HAVE_EDITLINE_HISTORY_H
 
diff --git a/src/include/port.h b/src/include/port.h
index d39b04141f..27189cd12b 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -455,7 +455,8 @@ extern int	setenv(const char *name, const char *value, int overwrite);
 extern int	unsetenv(const char *name);
 #endif
 
-#ifndef HAVE_DLOPEN
+#ifdef WIN32
+/* src/port/win32dlopen.c */
 extern void *dlopen(const char *file, int mode);
 extern void *dlsym(void *handle, const char *symbol);
 extern int	dlclose(void *handle);
diff --git a/src/port/dlopen.c b/src/port/win32dlopen.c
similarity index 95%
rename from src/port/dlopen.c
rename to src/port/win32dlopen.c
index 6ff9f4bf64..48aa37129d 100644
--- a/src/port/dlopen.c
+++ b/src/port/win32dlopen.c
@@ -1,7 +1,7 @@
 /*-------------------------------------------------------------------------
  *
  * dlopen.c
- *	  dynamic loader for platforms without dlopen()
+ *	  dynamic loader for Windows
  *
  * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
@@ -15,8 +15,6 @@
 
 #include "c.h"
 
-#if defined(WIN32)
-
 static char last_dyn_error[512];
 
 static void
@@ -93,5 +91,3 @@ dlopen(const char *file, int mode)
 	last_dyn_error[0] = 0;
 	return (void *) h;
 }
-
-#endif
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index c935f776e5..266f98e2ed 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -103,11 +103,12 @@ sub mkvcbuild
 	  getpeereid.c getrusage.c inet_aton.c
 	  getaddrinfo.c gettimeofday.c inet_net_ntop.c kill.c open.c
 	  snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c
-	  dirent.c dlopen.c getopt.c getopt_long.c link.c
+	  dirent.c getopt.c getopt_long.c link.c
 	  pread.c preadv.c pwrite.c pwritev.c pg_bitutils.c
 	  pg_strong_random.c pgcheckdir.c pgmkdirp.c pgsleep.c pgstrcasecmp.c
 	  pqsignal.c mkdtemp.c qsort.c qsort_arg.c bsearch_arg.c quotes.c system.c
 	  strerror.c tar.c
+	  win32dlopen.c
 	  win32env.c win32error.c win32ntdll.c
 	  win32security.c win32setlocale.c win32stat.c);
 
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index b09872e018..ce56b23bba 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -251,7 +251,6 @@ sub GenerateFiles
 		HAVE_DECL_STRNLEN                           => 1,
 		HAVE_DECL_STRTOLL                           => 1,
 		HAVE_DECL_STRTOULL                          => 1,
-		HAVE_DLOPEN                                 => undef,
 		HAVE_EDITLINE_HISTORY_H                     => undef,
 		HAVE_EDITLINE_READLINE_H                    => undef,
 		HAVE_EXECINFO_H                             => undef,
-- 
2.35.1

v2-0002-Remove-configure-probe-and-extra-tests-for-getrli.patchtext/x-patch; charset=US-ASCII; name=v2-0002-Remove-configure-probe-and-extra-tests-for-getrli.patchDownload
From dc4308a53ed99224467390436b1339c319d9dbf2 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 23 Jul 2022 21:34:14 +1200
Subject: [PATCH v2 02/13] Remove configure probe and extra tests for
 getrlimit.

getrlimit() is in SUSv2 and all targeted systems have it.

Windows doesn't have it.  We could just use #ifndef WIN32, but for a
little more explanation about why we're making things conditional, let's
retain the HAVE_GETRLIMIT macro.  It's defined in port.h for Unix systems.

On systems that have it, it's not necessary to test for RLIMIT_CORE,
RLIMIT_STACK or RLIMIT_NOFILE macros, since SUSv2 requires those and all
targeted systems have them.  Also remove references to a pre-historic
alternative spelling of RLIMIT_NOFILE, and coding that seemed to believe
that Cygwin didn't have it.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CA+hUKGJ3LHeP9w5Fgzdr4G8AnEtJ=z=p6hGDEm4qYGEUX5B6fQ@mail.gmail.com
---
 configure                     | 2 +-
 configure.ac                  | 1 -
 src/backend/storage/file/fd.c | 6 +-----
 src/backend/tcop/postgres.c   | 8 ++------
 src/bin/pg_ctl/pg_ctl.c       | 8 ++++----
 src/bin/pgbench/pgbench.c     | 4 ----
 src/include/pg_config.h.in    | 3 ---
 src/include/port.h            | 8 ++++++++
 src/test/regress/pg_regress.c | 4 ++--
 src/tools/msvc/Solution.pm    | 1 -
 10 files changed, 18 insertions(+), 27 deletions(-)

diff --git a/configure b/configure
index dbff2028a5..6b4be12869 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 getrlimit inet_pton kqueue mbstowcs_l memset_s poll posix_fallocate ppoll pthread_is_threaded_np readlink readv setproctitle setproctitle_fast setsid shm_open 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 readlink readv setproctitle setproctitle_fast setsid shm_open strchrnul strsignal symlink 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"
diff --git a/configure.ac b/configure.ac
index 68ef649258..b656af9cc5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1797,7 +1797,6 @@ AC_CHECK_FUNCS(m4_normalize([
 	fdatasync
 	getifaddrs
 	getpeerucred
-	getrlimit
 	inet_pton
 	kqueue
 	mbstowcs_l
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index f904f60c08..23ef22a60d 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -895,14 +895,10 @@ count_usable_fds(int max_to_probe, int *usable_fds, int *already_open)
 	fd = (int *) palloc(size * sizeof(int));
 
 #ifdef HAVE_GETRLIMIT
-#ifdef RLIMIT_NOFILE			/* most platforms use RLIMIT_NOFILE */
 	getrlimit_status = getrlimit(RLIMIT_NOFILE, &rlim);
-#else							/* but BSD doesn't ... */
-	getrlimit_status = getrlimit(RLIMIT_OFILE, &rlim);
-#endif							/* RLIMIT_NOFILE */
 	if (getrlimit_status != 0)
 		ereport(WARNING, (errmsg("getrlimit failed: %m")));
-#endif							/* HAVE_GETRLIMIT */
+#endif							/* !HAVE_GETRLIMIT */
 
 	/* dup until failure or probe limit reached */
 	for (;;)
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 078fbdb5a0..11e802eba9 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -4770,7 +4770,7 @@ forbidden_in_wal_sender(char firstchar)
 long
 get_stack_depth_rlimit(void)
 {
-#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_STACK)
+#if defined(HAVE_GETRLIMIT)
 	static long val = 0;
 
 	/* This won't change after process launch, so check just once */
@@ -4789,13 +4789,9 @@ get_stack_depth_rlimit(void)
 			val = rlim.rlim_cur;
 	}
 	return val;
-#else							/* no getrlimit */
-#if defined(WIN32) || defined(__CYGWIN__)
+#else
 	/* On Windows we set the backend stack size in src/backend/Makefile */
 	return WIN32_STACK_RLIMIT;
-#else							/* not windows ... give up */
-	return -1;
-#endif
 #endif
 }
 
diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
index ef58883a5c..2762e8590d 100644
--- a/src/bin/pg_ctl/pg_ctl.c
+++ b/src/bin/pg_ctl/pg_ctl.c
@@ -160,7 +160,7 @@ static bool wait_for_postmaster_stop(void);
 static bool wait_for_postmaster_promote(void);
 static bool postmaster_is_alive(pid_t pid);
 
-#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
+#if defined(HAVE_GETRLIMIT)
 static void unlimit_core_size(void);
 #endif
 
@@ -776,7 +776,7 @@ wait_for_postmaster_promote(void)
 }
 
 
-#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
+#if defined(HAVE_GETRLIMIT)
 static void
 unlimit_core_size(void)
 {
@@ -949,7 +949,7 @@ do_start(void)
 	if (exec_path == NULL)
 		exec_path = find_other_exec_or_die(argv0, "postgres", PG_BACKEND_VERSIONSTR);
 
-#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
+#if defined(HAVE_GETRLIMIT)
 	if (allow_core_files)
 		unlimit_core_size();
 #endif
@@ -2069,7 +2069,7 @@ do_help(void)
 	printf(_("If the -D option is omitted, the environment variable PGDATA is used.\n"));
 
 	printf(_("\nOptions for start or restart:\n"));
-#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
+#if defined(HAVE_GETRLIMIT)
 	printf(_("  -c, --core-files       allow postgres to produce core files\n"));
 #else
 	printf(_("  -c, --core-files       not applicable on this platform\n"));
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index bcaea8f5ea..0778656794 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -6662,11 +6662,7 @@ main(int argc, char **argv)
 					exit(1);
 				}
 #ifdef HAVE_GETRLIMIT
-#ifdef RLIMIT_NOFILE			/* most platforms use RLIMIT_NOFILE */
 				if (getrlimit(RLIMIT_NOFILE, &rlim) == -1)
-#else							/* but BSD doesn't ... */
-				if (getrlimit(RLIMIT_OFILE, &rlim) == -1)
-#endif							/* RLIMIT_NOFILE */
 					pg_fatal("getrlimit failed: %m");
 				if (rlim.rlim_cur < nclients + 3)
 				{
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index c213f31273..8e9318904f 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -237,9 +237,6 @@
 /* Define to 1 if you have the `getpeerucred' function. */
 #undef HAVE_GETPEERUCRED
 
-/* Define to 1 if you have the `getrlimit' function. */
-#undef HAVE_GETRLIMIT
-
 /* Define to 1 if you have the `gettimeofday' function. */
 #undef HAVE_GETTIMEOFDAY
 
diff --git a/src/include/port.h b/src/include/port.h
index 27189cd12b..630d55fcb7 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -543,4 +543,12 @@ extern char *wait_result_to_str(int exit_status);
 extern bool wait_result_is_signal(int exit_status, int signum);
 extern bool wait_result_is_any_signal(int exit_status, bool include_command_not_found);
 
+/*
+ * Interfaces that we assume all Unix system have.  We retain individual macros
+ * for better documentation.
+ */
+#ifndef WIN32
+#define HAVE_GETRLIMIT 1
+#endif
+
 #endif							/* PG_PORT_H */
diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c
index 982801e029..04ab513b7c 100644
--- a/src/test/regress/pg_regress.c
+++ b/src/test/regress/pg_regress.c
@@ -129,7 +129,7 @@ static void psql_end_command(StringInfo buf, const char *database);
 /*
  * allow core files if possible.
  */
-#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
+#if defined(HAVE_GETRLIMIT)
 static void
 unlimit_core_size(void)
 {
@@ -2229,7 +2229,7 @@ regression_main(int argc, char *argv[],
 
 	initialize_environment();
 
-#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
+#if defined(HAVE_GETRLIMIT)
 	unlimit_core_size();
 #endif
 
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index ce56b23bba..1018b57f00 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -273,7 +273,6 @@ sub GenerateFiles
 		HAVE_GETOPT_LONG                            => undef,
 		HAVE_GETPEEREID                             => undef,
 		HAVE_GETPEERUCRED                           => undef,
-		HAVE_GETRLIMIT                              => undef,
 		HAVE_GETTIMEOFDAY                           => undef,
 		HAVE_GSSAPI_GSSAPI_H                        => undef,
 		HAVE_GSSAPI_H                               => undef,
-- 
2.35.1

v2-0003-Remove-configure-probe-for-shm_open.patchtext/x-patch; charset=US-ASCII; name=v2-0003-Remove-configure-probe-for-shm_open.patchDownload
From 0446b2ac6432bc16beb4a4cbc4ff3a965c848ecd Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 23 Jul 2022 23:49:27 +1200
Subject: [PATCH v2 03/13] Remove configure probe for shm_open.

shm_open() is in SUSv2 (realtime) and all targeted Unix systems have it.

We retain a HAVE_SHM_OPEN macro, because it's clearer to readers than
something like !defined(WIN32).

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CA+hUKGJ3LHeP9w5Fgzdr4G8AnEtJ=z=p6hGDEm4qYGEUX5B6fQ@mail.gmail.com
---
 configure                  | 2 +-
 configure.ac               | 1 -
 src/include/pg_config.h.in | 3 ---
 src/include/port.h         | 1 +
 src/tools/msvc/Solution.pm | 1 -
 5 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/configure b/configure
index 6b4be12869..0c3ee5ab3f 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 setsid shm_open 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 readlink readv setproctitle setproctitle_fast setsid strchrnul strsignal symlink 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"
diff --git a/configure.ac b/configure.ac
index b656af9cc5..dab6927cdc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1810,7 +1810,6 @@ AC_CHECK_FUNCS(m4_normalize([
 	setproctitle
 	setproctitle_fast
 	setsid
-	shm_open
 	strchrnul
 	strsignal
 	symlink
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 8e9318904f..922756568e 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -480,9 +480,6 @@
 /* Define to 1 if you have the `setsid' function. */
 #undef HAVE_SETSID
 
-/* Define to 1 if you have the `shm_open' function. */
-#undef HAVE_SHM_OPEN
-
 /* Define to 1 if the system has the type `socklen_t'. */
 #undef HAVE_SOCKLEN_T
 
diff --git a/src/include/port.h b/src/include/port.h
index 630d55fcb7..e14e8fbf7e 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -549,6 +549,7 @@ extern bool wait_result_is_any_signal(int exit_status, bool include_command_not_
  */
 #ifndef WIN32
 #define HAVE_GETRLIMIT 1
+#define HAVE_SHM_OPEN 1
 #endif
 
 #endif							/* PG_PORT_H */
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 1018b57f00..893feb6eaf 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -353,7 +353,6 @@ sub GenerateFiles
 		HAVE_SETPROCTITLE                        => undef,
 		HAVE_SETPROCTITLE_FAST                   => undef,
 		HAVE_SETSID                              => undef,
-		HAVE_SHM_OPEN                            => undef,
 		HAVE_SOCKLEN_T                           => 1,
 		HAVE_SPINLOCKS                           => 1,
 		HAVE_STDBOOL_H                           => 1,
-- 
2.35.1

v2-0004-Remove-configure-probe-for-setsid.patchtext/x-patch; charset=US-ASCII; name=v2-0004-Remove-configure-probe-for-setsid.patchDownload
From 390610706189d23b8aec69754b7b8ba28e30d8b5 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sun, 24 Jul 2022 00:54:07 +1200
Subject: [PATCH v2 04/13] Remove configure probe for setsid.

setsid() is in SUSv2 and all targeted Unix systems have it.  Retain a
HAVE_SETSID macro, defined on Unix only.  That's easier to understand
than !defined(WIN32), for the optional code it governs.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CA+hUKGJ3LHeP9w5Fgzdr4G8AnEtJ=z=p6hGDEm4qYGEUX5B6fQ@mail.gmail.com
---
 configure                  | 2 +-
 configure.ac               | 1 -
 src/include/pg_config.h.in | 3 ---
 src/include/port.h         | 1 +
 src/tools/msvc/Solution.pm | 1 -
 5 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/configure b/configure
index 0c3ee5ab3f..4a332d2296 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 setsid 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 readlink readv setproctitle setproctitle_fast strchrnul strsignal symlink 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"
diff --git a/configure.ac b/configure.ac
index dab6927cdc..ce14199902 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1809,7 +1809,6 @@ AC_CHECK_FUNCS(m4_normalize([
 	readv
 	setproctitle
 	setproctitle_fast
-	setsid
 	strchrnul
 	strsignal
 	symlink
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 922756568e..9a3372f7de 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -477,9 +477,6 @@
 /* Define to 1 if you have the `setproctitle_fast' function. */
 #undef HAVE_SETPROCTITLE_FAST
 
-/* Define to 1 if you have the `setsid' function. */
-#undef HAVE_SETSID
-
 /* Define to 1 if the system has the type `socklen_t'. */
 #undef HAVE_SOCKLEN_T
 
diff --git a/src/include/port.h b/src/include/port.h
index e14e8fbf7e..f46352b1eb 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -549,6 +549,7 @@ extern bool wait_result_is_any_signal(int exit_status, bool include_command_not_
  */
 #ifndef WIN32
 #define HAVE_GETRLIMIT 1
+#define HAVE_SETSID 1
 #define HAVE_SHM_OPEN 1
 #endif
 
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 893feb6eaf..e3b60a773a 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -352,7 +352,6 @@ sub GenerateFiles
 		HAVE_SETENV                              => undef,
 		HAVE_SETPROCTITLE                        => undef,
 		HAVE_SETPROCTITLE_FAST                   => undef,
-		HAVE_SETSID                              => undef,
 		HAVE_SOCKLEN_T                           => 1,
 		HAVE_SPINLOCKS                           => 1,
 		HAVE_STDBOOL_H                           => 1,
-- 
2.35.1

v2-0005-Remove-configure-probes-for-symlink-readlink-and-.patchtext/x-patch; charset=US-ASCII; name=v2-0005-Remove-configure-probes-for-symlink-readlink-and-.patchDownload
From b5aecfc1ebf8cbd74060fdb26e7cfa91448ab15c 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 v2 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 4a332d2296..88189754c3 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"
@@ -17107,9 +17107,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 ce14199902..0ad072f092 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
@@ -1965,8 +1963,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 9a3372f7de..61634347d5 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -435,9 +435,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
 
@@ -564,9 +561,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 f46352b1eb..f3eece40f3 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -546,11 +546,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 e3b60a773a..5030f63e9a 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -339,7 +339,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,
@@ -382,7 +381,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.35.1

v2-0006-Remove-configure-probe-for-link.patchtext/x-patch; charset=US-ASCII; name=v2-0006-Remove-configure-probe-for-link.patchDownload
From 196ba828c4b63b8c79cbb2546ab0c08a1f1b82db Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sun, 24 Jul 2022 01:19:05 +1200
Subject: [PATCH v2 06/13] Remove configure probe for link.

link() is in SUSv2 and all targeted Unix systems have it.  We have
replacement code for Windows that doesn't require a configure probe.
Since only Windows needs it, rename src/port/link.c to win32link.c like
other similar things.

There is no need for a vestigial HAVE_LINK macro, because we expect all
Unix and, with our replacement function, Windows systems to have it, so
we didn't have any tests around link() usage.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CA+hUKGJ3LHeP9w5Fgzdr4G8AnEtJ=z=p6hGDEm4qYGEUX5B6fQ@mail.gmail.com
---
 configure                        | 19 ++++++-------------
 configure.ac                     |  2 +-
 src/include/pg_config.h.in       |  3 ---
 src/include/port.h               |  3 ++-
 src/port/{link.c => win32link.c} |  6 +-----
 src/tools/msvc/Mkvcbuild.pm      |  6 ++++--
 src/tools/msvc/Solution.pm       |  1 -
 7 files changed, 14 insertions(+), 26 deletions(-)
 rename src/port/{link.c => win32link.c} (93%)

diff --git a/configure b/configure
index 88189754c3..d86a8db1ff 100755
--- a/configure
+++ b/configure
@@ -16739,19 +16739,6 @@ esac
 
 fi
 
-ac_fn_c_check_func "$LINENO" "link" "ac_cv_func_link"
-if test "x$ac_cv_func_link" = xyes; then :
-  $as_echo "#define HAVE_LINK 1" >>confdefs.h
-
-else
-  case " $LIBOBJS " in
-  *" link.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS link.$ac_objext"
- ;;
-esac
-
-fi
-
 ac_fn_c_check_func "$LINENO" "mkdtemp" "ac_cv_func_mkdtemp"
 if test "x$ac_cv_func_mkdtemp" = xyes; then :
   $as_echo "#define HAVE_MKDTEMP 1" >>confdefs.h
@@ -17083,6 +17070,12 @@ esac
  ;;
 esac
 
+  case " $LIBOBJS " in
+  *" win32link.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS win32link.$ac_objext"
+ ;;
+esac
+
   case " $LIBOBJS " in
   *" win32ntdll.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS win32ntdll.$ac_objext"
diff --git a/configure.ac b/configure.ac
index 0ad072f092..9d2d338a65 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1879,7 +1879,6 @@ AC_REPLACE_FUNCS(m4_normalize([
 	getopt
 	getpeereid
 	inet_aton
-	link
 	mkdtemp
 	pread
 	pwrite
@@ -1959,6 +1958,7 @@ if test "$PORTNAME" = "win32"; then
   AC_LIBOBJ(win32dlopen)
   AC_LIBOBJ(win32env)
   AC_LIBOBJ(win32error)
+  AC_LIBOBJ(win32link)
   AC_LIBOBJ(win32ntdll)
   AC_LIBOBJ(win32security)
   AC_LIBOBJ(win32setlocale)
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 61634347d5..ba9d702101 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -342,9 +342,6 @@
 /* Define to 1 if you have the `zstd' library (-lzstd). */
 #undef HAVE_LIBZSTD
 
-/* Define to 1 if you have the `link' function. */
-#undef HAVE_LINK
-
 /* Define to 1 if the system has the type `locale_t'. */
 #undef HAVE_LOCALE_T
 
diff --git a/src/include/port.h b/src/include/port.h
index f3eece40f3..090f34ed60 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -402,7 +402,8 @@ extern float pg_strtof(const char *nptr, char **endptr);
 #define strtof(a,b) (pg_strtof((a),(b)))
 #endif
 
-#ifndef HAVE_LINK
+#ifdef WIN32
+/* src/port/win32link.c */
 extern int	link(const char *src, const char *dst);
 #endif
 
diff --git a/src/port/link.c b/src/port/win32link.c
similarity index 93%
rename from src/port/link.c
rename to src/port/win32link.c
index 1e0ccd4648..e8556bbfad 100644
--- a/src/port/link.c
+++ b/src/port/win32link.c
@@ -7,15 +7,13 @@
  *
  *
  * IDENTIFICATION
- *	  src/port/link.c
+ *	  src/port/win32link.c
  *
  *-------------------------------------------------------------------------
  */
 
 #include "c.h"
 
-#ifdef WIN32
-
 int
 link(const char *src, const char *dst)
 {
@@ -31,5 +29,3 @@ link(const char *src, const char *dst)
 	else
 		return 0;
 }
-
-#endif
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index 266f98e2ed..1ffe6e66d5 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -103,13 +103,15 @@ sub mkvcbuild
 	  getpeereid.c getrusage.c inet_aton.c
 	  getaddrinfo.c gettimeofday.c inet_net_ntop.c kill.c open.c
 	  snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c
-	  dirent.c getopt.c getopt_long.c link.c
+	  dirent.c getopt.c getopt_long.c
 	  pread.c preadv.c pwrite.c pwritev.c pg_bitutils.c
 	  pg_strong_random.c pgcheckdir.c pgmkdirp.c pgsleep.c pgstrcasecmp.c
 	  pqsignal.c mkdtemp.c qsort.c qsort_arg.c bsearch_arg.c quotes.c system.c
 	  strerror.c tar.c
 	  win32dlopen.c
-	  win32env.c win32error.c win32ntdll.c
+	  win32env.c win32error.c
+	  win32link.c
+	  win32ntdll.c
 	  win32security.c win32setlocale.c win32stat.c);
 
 	push(@pgportfiles, 'strtof.c') if ($vsVersion < '14.00');
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 5030f63e9a..d904f42d53 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -308,7 +308,6 @@ sub GenerateFiles
 		HAVE_LIBXSLT                                => undef,
 		HAVE_LIBZ                   => $self->{options}->{zlib} ? 1 : undef,
 		HAVE_LIBZSTD                => undef,
-		HAVE_LINK                   => undef,
 		HAVE_LOCALE_T               => 1,
 		HAVE_LONG_INT_64            => undef,
 		HAVE_LONG_LONG_INT_64       => 1,
-- 
2.35.1

v2-0007-Remove-dead-replacement-code-for-clock_gettime.patchtext/x-patch; charset=US-ASCII; name=v2-0007-Remove-dead-replacement-code-for-clock_gettime.patchDownload
From 86454dab30c55e521e2bd6908be08cccae8647f0 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sun, 24 Jul 2022 00:12:37 +1200
Subject: [PATCH v2 07/13] Remove dead replacement code for clock_gettime().

clock_gettime() is in SUSv2 (realtime) and all targeted Unix systems
have it.  Fallback code for old Unix is no longer reachable on modern
systems, though we still need Windows-specific code.

There is no need to retain a HAVE_CLOCK_GETTIME macro here, because it
is used in contexts that have very obvious Unix and Windows code
variants.

XXX This can only be committed once prairedog is decommissioned, because
macOS 10.4 didn't have clock_gettime().

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CA+hUKGJ3LHeP9w5Fgzdr4G8AnEtJ=z=p6hGDEm4qYGEUX5B6fQ@mail.gmail.com
---
 configure                            |  2 +-
 configure.ac                         |  1 -
 src/include/pg_config.h.in           |  3 --
 src/include/portability/instr_time.h | 68 ----------------------------
 src/tools/msvc/Solution.pm           |  1 -
 5 files changed, 1 insertion(+), 74 deletions(-)

diff --git a/configure b/configure
index d86a8db1ff..5f0f519466 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 readv setproctitle setproctitle_fast strchrnul strsignal syncfs sync_file_range uselocale wcstombs_l writev
+for ac_func in backtrace_symbols 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"
diff --git a/configure.ac b/configure.ac
index 9d2d338a65..62d5d635a3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1792,7 +1792,6 @@ LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'`
 
 AC_CHECK_FUNCS(m4_normalize([
 	backtrace_symbols
-	clock_gettime
 	copyfile
 	fdatasync
 	getifaddrs
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index ba9d702101..9c426ca8a0 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -83,9 +83,6 @@
 /* Define to 1 if you have the `BIO_meth_new' function. */
 #undef HAVE_BIO_METH_NEW
 
-/* Define to 1 if you have the `clock_gettime' function. */
-#undef HAVE_CLOCK_GETTIME
-
 /* Define to 1 if your compiler handles computed gotos. */
 #undef HAVE_COMPUTED_GOTO
 
diff --git a/src/include/portability/instr_time.h b/src/include/portability/instr_time.h
index ca09a1608f..8faeca8b49 100644
--- a/src/include/portability/instr_time.h
+++ b/src/include/portability/instr_time.h
@@ -57,8 +57,6 @@
 
 #ifndef WIN32
 
-#ifdef HAVE_CLOCK_GETTIME
-
 /* Use clock_gettime() */
 
 #include <time.h>
@@ -141,72 +139,6 @@ typedef struct timespec instr_time;
 #define INSTR_TIME_GET_MICROSEC(t) \
 	(((uint64) (t).tv_sec * (uint64) 1000000) + (uint64) ((t).tv_nsec / 1000))
 
-#else							/* !HAVE_CLOCK_GETTIME */
-
-/* Use gettimeofday() */
-
-#include <sys/time.h>
-
-typedef struct timeval instr_time;
-
-#define INSTR_TIME_IS_ZERO(t)	((t).tv_usec == 0 && (t).tv_sec == 0)
-
-#define INSTR_TIME_SET_ZERO(t)	((t).tv_sec = 0, (t).tv_usec = 0)
-
-#define INSTR_TIME_SET_CURRENT(t)	gettimeofday(&(t), NULL)
-
-#define INSTR_TIME_ADD(x,y) \
-	do { \
-		(x).tv_sec += (y).tv_sec; \
-		(x).tv_usec += (y).tv_usec; \
-		/* Normalize */ \
-		while ((x).tv_usec >= 1000000) \
-		{ \
-			(x).tv_usec -= 1000000; \
-			(x).tv_sec++; \
-		} \
-	} while (0)
-
-#define INSTR_TIME_SUBTRACT(x,y) \
-	do { \
-		(x).tv_sec -= (y).tv_sec; \
-		(x).tv_usec -= (y).tv_usec; \
-		/* Normalize */ \
-		while ((x).tv_usec < 0) \
-		{ \
-			(x).tv_usec += 1000000; \
-			(x).tv_sec--; \
-		} \
-	} while (0)
-
-#define INSTR_TIME_ACCUM_DIFF(x,y,z) \
-	do { \
-		(x).tv_sec += (y).tv_sec - (z).tv_sec; \
-		(x).tv_usec += (y).tv_usec - (z).tv_usec; \
-		/* Normalize after each add to avoid overflow/underflow of tv_usec */ \
-		while ((x).tv_usec < 0) \
-		{ \
-			(x).tv_usec += 1000000; \
-			(x).tv_sec--; \
-		} \
-		while ((x).tv_usec >= 1000000) \
-		{ \
-			(x).tv_usec -= 1000000; \
-			(x).tv_sec++; \
-		} \
-	} while (0)
-
-#define INSTR_TIME_GET_DOUBLE(t) \
-	(((double) (t).tv_sec) + ((double) (t).tv_usec) / 1000000.0)
-
-#define INSTR_TIME_GET_MILLISEC(t) \
-	(((double) (t).tv_sec * 1000.0) + ((double) (t).tv_usec) / 1000.0)
-
-#define INSTR_TIME_GET_MICROSEC(t) \
-	(((uint64) (t).tv_sec * (uint64) 1000000) + (uint64) (t).tv_usec)
-
-#endif							/* HAVE_CLOCK_GETTIME */
-
 #else							/* WIN32 */
 
 /* Use QueryPerformanceCounter() */
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index d904f42d53..8ccd9d6ab0 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -228,7 +228,6 @@ sub GenerateFiles
 		HAVE_BACKTRACE_SYMBOLS     => undef,
 		HAVE_BIO_GET_DATA          => undef,
 		HAVE_BIO_METH_NEW          => undef,
-		HAVE_CLOCK_GETTIME         => undef,
 		HAVE_COMPUTED_GOTO         => undef,
 		HAVE_COPYFILE              => undef,
 		HAVE_COPYFILE_H            => undef,
-- 
2.35.1

v2-0008-Remove-configure-probes-for-poll-and-poll.h.patchtext/x-patch; charset=US-ASCII; name=v2-0008-Remove-configure-probes-for-poll-and-poll.h.patchDownload
From bdc5dbc74edef5432b87ec8b9420a7c670113271 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 30 Jul 2022 15:35:11 +1200
Subject: [PATCH v2 08/13] Remove configure probes for poll and poll.h.

poll() and <poll.h> are in SUSv2 and all targeted Unix systems have
them.

Retain HAVE_POLL and HAVE_POLL_H macros for readability.  There's an
error in latch.c that is now unreachable (since logically always have
one of WIN32 or HAVE_POLL defined), but that falls out of a decision to
keep using defined(HAVE_POLL) instead of !defined(WIN32) to guard the
poll() code.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CA+hUKGJ3LHeP9w5Fgzdr4G8AnEtJ=z=p6hGDEm4qYGEUX5B6fQ@mail.gmail.com
---
 configure                  | 4 ++--
 configure.ac               | 2 --
 src/include/pg_config.h.in | 6 ------
 src/include/port.h         | 2 ++
 src/tools/msvc/Solution.pm | 2 --
 5 files changed, 4 insertions(+), 12 deletions(-)

diff --git a/configure b/configure
index 5f0f519466..088e1bcca7 100755
--- a/configure
+++ b/configure
@@ -13875,7 +13875,7 @@ $as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h
 fi
 
 
-for ac_header in atomic.h copyfile.h execinfo.h getopt.h ifaddrs.h langinfo.h mbarrier.h poll.h sys/epoll.h sys/event.h sys/ipc.h sys/personality.h sys/prctl.h sys/procctl.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/signalfd.h sys/sockio.h sys/uio.h sys/un.h termios.h ucred.h
+for ac_header in atomic.h copyfile.h execinfo.h getopt.h ifaddrs.h langinfo.h mbarrier.h sys/epoll.h sys/event.h sys/ipc.h sys/personality.h sys/prctl.h sys/procctl.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/signalfd.h sys/sockio.h sys/uio.h sys/un.h termios.h ucred.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@@ -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 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
+for ac_func in backtrace_symbols copyfile fdatasync getifaddrs getpeerucred inet_pton kqueue mbstowcs_l memset_s 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"
diff --git a/configure.ac b/configure.ac
index 62d5d635a3..bf40a8f686 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1452,7 +1452,6 @@ AC_CHECK_HEADERS(m4_normalize([
 	ifaddrs.h
 	langinfo.h
 	mbarrier.h
-	poll.h
 	sys/epoll.h
 	sys/event.h
 	sys/ipc.h
@@ -1800,7 +1799,6 @@ AC_CHECK_FUNCS(m4_normalize([
 	kqueue
 	mbstowcs_l
 	memset_s
-	poll
 	posix_fallocate
 	ppoll
 	pthread_is_threaded_np
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 9c426ca8a0..be96c292be 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -381,12 +381,6 @@
 /* Define to 1 if you have the <pam/pam_appl.h> header file. */
 #undef HAVE_PAM_PAM_APPL_H
 
-/* Define to 1 if you have the `poll' function. */
-#undef HAVE_POLL
-
-/* Define to 1 if you have the <poll.h> header file. */
-#undef HAVE_POLL_H
-
 /* Define to 1 if you have the `posix_fadvise' function. */
 #undef HAVE_POSIX_FADVISE
 
diff --git a/src/include/port.h b/src/include/port.h
index 090f34ed60..55f58edf0c 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -556,6 +556,8 @@ extern bool wait_result_is_any_signal(int exit_status, bool include_command_not_
  */
 #ifndef WIN32
 #define HAVE_GETRLIMIT 1
+#define HAVE_POLL 1
+#define HAVE_POLL_H 1
 #define HAVE_READLINK 1
 #define HAVE_SETSID 1
 #define HAVE_SHM_OPEN 1
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 8ccd9d6ab0..6e6c7126d4 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -321,8 +321,6 @@ sub GenerateFiles
 		HAVE_OPENSSL_INIT_SSL       => undef,
 		HAVE_OSSP_UUID_H            => undef,
 		HAVE_PAM_PAM_APPL_H         => undef,
-		HAVE_POLL                   => undef,
-		HAVE_POLL_H                 => undef,
 		HAVE_POSIX_FADVISE          => undef,
 		HAVE_POSIX_FALLOCATE        => undef,
 		HAVE_PPC_LWARX_MUTEX_HINT   => undef,
-- 
2.35.1

v2-0009-Remove-dead-setenv-unsetenv-replacement-code.patchtext/x-patch; charset=US-ASCII; name=v2-0009-Remove-dead-setenv-unsetenv-replacement-code.patchDownload
From de75f86fa1c21b0246a2c28de3afcf7c1ef8162a Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 9 Jul 2022 23:00:49 +1200
Subject: [PATCH v2 09/13] Remove dead setenv, unsetenv replacement code.

setenv() and unsetenv() are in SUSv3 and targeted Unix systems have
them.  We still need special code for these on Windows, but that doesn't
require a configure probe.

This marks the first time we require a SUSv3 (POSIX.1-2001) facility
(rather than SUSv2).  The replacement code removed here was not needed
on any targeted system or any known non-EOL'd Unix system, and was
therefore dead and untested.

No need for vestigial HAVE_SETENV and HAVE_UNSETENV macros, because we
provide a replacement for Windows, and we didn't previously test the
macros.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Greg Stark <stark@mit.edu>
Reviewed-by: Robert Haas <robertmhaas@gmail.com>
Discussion: https://postgr.es/m/CA+hUKGJ3LHeP9w5Fgzdr4G8AnEtJ=z=p6hGDEm4qYGEUX5B6fQ@mail.gmail.com
---
 configure                  | 43 -------------------------
 configure.ac               | 13 --------
 src/include/pg_config.h.in |  6 ----
 src/include/port.h         |  6 ++--
 src/port/setenv.c          | 48 ----------------------------
 src/port/unsetenv.c        | 65 --------------------------------------
 src/tools/msvc/Solution.pm |  2 --
 7 files changed, 2 insertions(+), 181 deletions(-)
 delete mode 100644 src/port/setenv.c
 delete mode 100644 src/port/unsetenv.c

diff --git a/configure b/configure
index 088e1bcca7..edf966c88e 100755
--- a/configure
+++ b/configure
@@ -16865,49 +16865,6 @@ esac
 $as_echo "$as_me: On $host_os we will use our strtof wrapper." >&6;}
 fi
 
-case $host_os in
-        # Windows uses a specialised env handler
-        mingw*)
-
-$as_echo "#define HAVE_SETENV 1" >>confdefs.h
-
-
-$as_echo "#define HAVE_UNSETENV 1" >>confdefs.h
-
-                ac_cv_func_setenv=yes
-                ac_cv_func_unsetenv=yes
-                ;;
-        *)
-                ac_fn_c_check_func "$LINENO" "setenv" "ac_cv_func_setenv"
-if test "x$ac_cv_func_setenv" = xyes; then :
-  $as_echo "#define HAVE_SETENV 1" >>confdefs.h
-
-else
-  case " $LIBOBJS " in
-  *" setenv.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS setenv.$ac_objext"
- ;;
-esac
-
-fi
-
-ac_fn_c_check_func "$LINENO" "unsetenv" "ac_cv_func_unsetenv"
-if test "x$ac_cv_func_unsetenv" = xyes; then :
-  $as_echo "#define HAVE_UNSETENV 1" >>confdefs.h
-
-else
-  case " $LIBOBJS " in
-  *" unsetenv.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS unsetenv.$ac_objext"
- ;;
-esac
-
-fi
-
-
-                ;;
-esac
-
 # System's version of getaddrinfo(), if any, may be used only if we found
 # a definition for struct addrinfo; see notes in src/include/getaddrinfo.h.
 # We use only our own getaddrinfo.c on Windows, but it's time to revisit that.
diff --git a/configure.ac b/configure.ac
index bf40a8f686..6e028df37b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1899,19 +1899,6 @@ if test "$PORTNAME" = "win32" -o "$PORTNAME" = "cygwin"; then
 	AC_MSG_NOTICE([On $host_os we will use our strtof wrapper.])
 fi
 
-case $host_os in
-        # Windows uses a specialised env handler
-        mingw*)
-                AC_DEFINE(HAVE_SETENV, 1, [Define to 1 because replacement version used.])
-                AC_DEFINE(HAVE_UNSETENV, 1, [Define to 1 because replacement version used.])
-                ac_cv_func_setenv=yes
-                ac_cv_func_unsetenv=yes
-                ;;
-        *)
-                AC_REPLACE_FUNCS([setenv unsetenv])
-                ;;
-esac
-
 # System's version of getaddrinfo(), if any, may be used only if we found
 # a definition for struct addrinfo; see notes in src/include/getaddrinfo.h.
 # We use only our own getaddrinfo.c on Windows, but it's time to revisit that.
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index be96c292be..6ea38998f8 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -453,9 +453,6 @@
 /* Define to 1 if you have the <security/pam_appl.h> header file. */
 #undef HAVE_SECURITY_PAM_APPL_H
 
-/* Define to 1 if you have the `setenv' function. */
-#undef HAVE_SETENV
-
 /* Define to 1 if you have the `setproctitle' function. */
 #undef HAVE_SETPROCTITLE
 
@@ -630,9 +627,6 @@
 /* Define to 1 if you have the <unistd.h> header file. */
 #undef HAVE_UNISTD_H
 
-/* Define to 1 if you have the `unsetenv' function. */
-#undef HAVE_UNSETENV
-
 /* Define to 1 if you have the `uselocale' function. */
 #undef HAVE_USELOCALE
 
diff --git a/src/include/port.h b/src/include/port.h
index 55f58edf0c..97181141fc 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -448,11 +448,9 @@ extern size_t strlcpy(char *dst, const char *src, size_t siz);
 extern size_t strnlen(const char *str, size_t maxlen);
 #endif
 
-#ifndef HAVE_SETENV
+#ifdef WIN32
+/* src/port/win32env.c */
 extern int	setenv(const char *name, const char *value, int overwrite);
-#endif
-
-#ifndef HAVE_UNSETENV
 extern int	unsetenv(const char *name);
 #endif
 
diff --git a/src/port/setenv.c b/src/port/setenv.c
deleted file mode 100644
index d13c882467..0000000000
--- a/src/port/setenv.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * setenv.c
- *	  setenv() emulation for machines without it
- *
- * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- *
- * IDENTIFICATION
- *	  src/port/setenv.c
- *
- *-------------------------------------------------------------------------
- */
-
-#include "c.h"
-
-
-int
-setenv(const char *name, const char *value, int overwrite)
-{
-	char	   *envstr;
-
-	/* Error conditions, per POSIX */
-	if (name == NULL || name[0] == '\0' || strchr(name, '=') != NULL ||
-		value == NULL)
-	{
-		errno = EINVAL;
-		return -1;
-	}
-
-	/* No work if variable exists and we're not to replace it */
-	if (overwrite == 0 && getenv(name) != NULL)
-		return 0;
-
-	/*
-	 * Add or replace the value using putenv().  This will leak memory if the
-	 * same variable is repeatedly redefined, but there's little we can do
-	 * about that when sitting atop putenv().
-	 */
-	envstr = (char *) malloc(strlen(name) + strlen(value) + 2);
-	if (!envstr)				/* not much we can do if no memory */
-		return -1;
-
-	sprintf(envstr, "%s=%s", name, value);
-
-	return putenv(envstr);
-}
diff --git a/src/port/unsetenv.c b/src/port/unsetenv.c
deleted file mode 100644
index 62b806d796..0000000000
--- a/src/port/unsetenv.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * unsetenv.c
- *	  unsetenv() emulation for machines without it
- *
- * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- *
- * IDENTIFICATION
- *	  src/port/unsetenv.c
- *
- *-------------------------------------------------------------------------
- */
-
-#include "c.h"
-
-
-int
-unsetenv(const char *name)
-{
-	char	   *envstr;
-
-	/* Error conditions, per POSIX */
-	if (name == NULL || name[0] == '\0' || strchr(name, '=') != NULL)
-	{
-		errno = EINVAL;
-		return -1;
-	}
-
-	if (getenv(name) == NULL)
-		return 0;				/* no work */
-
-	/*
-	 * The technique embodied here works if libc follows the Single Unix Spec
-	 * and actually uses the storage passed to putenv() to hold the environ
-	 * entry.  When we clobber the entry in the second step we are ensuring
-	 * that we zap the actual environ member.  However, there are some libc
-	 * implementations (notably recent BSDs) that do not obey SUS but copy the
-	 * presented string.  This method fails on such platforms.  Hopefully all
-	 * such platforms have unsetenv() and thus won't be using this hack. See:
-	 * http://www.greenend.org.uk/rjk/2008/putenv.html
-	 *
-	 * Note that repeatedly setting and unsetting a var using this code will
-	 * leak memory.
-	 */
-
-	envstr = (char *) malloc(strlen(name) + 2);
-	if (!envstr)				/* not much we can do if no memory */
-		return -1;
-
-	/* Override the existing setting by forcibly defining the var */
-	sprintf(envstr, "%s=", name);
-	if (putenv(envstr))
-		return -1;
-
-	/* Now we can clobber the variable definition this way: */
-	strcpy(envstr, "=");
-
-	/*
-	 * This last putenv cleans up if we have multiple zero-length names as a
-	 * result of unsetting multiple things.
-	 */
-	return putenv(envstr);
-}
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 6e6c7126d4..0d4ca94e7f 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -344,7 +344,6 @@ sub GenerateFiles
 		HAVE_RL_RESET_SCREEN_SIZE                => undef,
 		HAVE_RL_VARIABLE_BIND                    => undef,
 		HAVE_SECURITY_PAM_APPL_H                 => undef,
-		HAVE_SETENV                              => undef,
 		HAVE_SETPROCTITLE                        => undef,
 		HAVE_SETPROCTITLE_FAST                   => undef,
 		HAVE_SOCKLEN_T                           => 1,
@@ -403,7 +402,6 @@ sub GenerateFiles
 		HAVE_UINT8                               => undef,
 		HAVE_UNION_SEMUN                         => undef,
 		HAVE_UNISTD_H                            => 1,
-		HAVE_UNSETENV                            => undef,
 		HAVE_USELOCALE                           => undef,
 		HAVE_UUID_BSD                            => undef,
 		HAVE_UUID_E2FS                           => undef,
-- 
2.35.1

v2-0010-Remove-dead-pread-and-pwrite-replacement-code.patchtext/x-patch; charset=US-ASCII; name=v2-0010-Remove-dead-pread-and-pwrite-replacement-code.patchDownload
From 71de6ad7496024978ea4a0ff5cb16827a18acccf Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 9 Jul 2022 21:31:56 +1200
Subject: [PATCH v2 10/13] Remove dead pread and pwrite replacement code.

pread() and pwrite() are in SUSv2, and all targeted Unix systems have
them.

Previously, we defined pg_pread and pg_pwrite to emulate these function
with lseek() on old Unixen.  The names with a pg_ prefix were a reminder
of a portability hazard: they might change the current file position.
That hazard is gone, so we can drop the prefixes.

Since the remaining replacement code is Windows-only, move it into
src/port/win32p{read,write}.c, move the declarations into
src/include/port/win32_port.h and adopt the usual convention of a
pgwin32_ prefix and a macro.

No need for vestigial HAVE_PREAD, HAVE_PWRITE macros as they were only
used for declarations in port.h which have now moved into win32_port.h.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Greg Stark <stark@mit.edu>
Reviewed-by: Robert Haas <robertmhaas@gmail.com>
Discussion: https://postgr.es/m/CA+hUKGJ3LHeP9w5Fgzdr4G8AnEtJ=z=p6hGDEm4qYGEUX5B6fQ@mail.gmail.com
---
 configure                                     | 38 +++++---------
 configure.ac                                  |  4 +-
 .../pg_stat_statements/pg_stat_statements.c   |  4 +-
 src/backend/access/heap/rewriteheap.c         |  2 +-
 src/backend/access/transam/slru.c             |  4 +-
 src/backend/access/transam/xlog.c             |  4 +-
 src/backend/access/transam/xlogreader.c       |  2 +-
 src/backend/access/transam/xlogrecovery.c     |  2 +-
 src/backend/replication/basebackup.c          |  2 +-
 src/backend/replication/walreceiver.c         |  2 +-
 src/backend/storage/file/fd.c                 |  4 +-
 src/backend/utils/init/miscinit.c             |  2 +-
 src/bin/pg_test_fsync/pg_test_fsync.c         | 50 +++++++++----------
 src/include/access/xlogreader.h               |  4 +-
 src/include/pg_config.h.in                    |  6 ---
 src/include/port.h                            | 19 -------
 src/include/port/win32_port.h                 |  9 ++++
 src/port/preadv.c                             |  4 +-
 src/port/pwritev.c                            |  4 +-
 src/port/{pread.c => win32pread.c}            | 22 ++------
 src/port/{pwrite.c => win32pwrite.c}          | 22 ++------
 src/tools/msvc/Mkvcbuild.pm                   |  4 +-
 src/tools/msvc/Solution.pm                    |  2 -
 23 files changed, 79 insertions(+), 137 deletions(-)
 rename src/port/{pread.c => win32pread.c} (61%)
 rename src/port/{pwrite.c => win32pwrite.c} (59%)

diff --git a/configure b/configure
index edf966c88e..d2f6f4b0eb 100755
--- a/configure
+++ b/configure
@@ -16752,32 +16752,6 @@ esac
 
 fi
 
-ac_fn_c_check_func "$LINENO" "pread" "ac_cv_func_pread"
-if test "x$ac_cv_func_pread" = xyes; then :
-  $as_echo "#define HAVE_PREAD 1" >>confdefs.h
-
-else
-  case " $LIBOBJS " in
-  *" pread.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS pread.$ac_objext"
- ;;
-esac
-
-fi
-
-ac_fn_c_check_func "$LINENO" "pwrite" "ac_cv_func_pwrite"
-if test "x$ac_cv_func_pwrite" = xyes; then :
-  $as_echo "#define HAVE_PWRITE 1" >>confdefs.h
-
-else
-  case " $LIBOBJS " in
-  *" pwrite.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS pwrite.$ac_objext"
- ;;
-esac
-
-fi
-
 ac_fn_c_check_func "$LINENO" "strlcat" "ac_cv_func_strlcat"
 if test "x$ac_cv_func_strlcat" = xyes; then :
   $as_echo "#define HAVE_STRLCAT 1" >>confdefs.h
@@ -17039,6 +17013,18 @@ esac
  ;;
 esac
 
+  case " $LIBOBJS " in
+  *" win32pread.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS win32pread.$ac_objext"
+ ;;
+esac
+
+  case " $LIBOBJS " in
+  *" win32pwrite.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS win32pwrite.$ac_objext"
+ ;;
+esac
+
   case " $LIBOBJS " in
   *" win32security.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS win32security.$ac_objext"
diff --git a/configure.ac b/configure.ac
index 6e028df37b..070fafaa0a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1877,8 +1877,6 @@ AC_REPLACE_FUNCS(m4_normalize([
 	getpeereid
 	inet_aton
 	mkdtemp
-	pread
-	pwrite
 	strlcat
 	strlcpy
 	strnlen
@@ -1944,6 +1942,8 @@ if test "$PORTNAME" = "win32"; then
   AC_LIBOBJ(win32error)
   AC_LIBOBJ(win32link)
   AC_LIBOBJ(win32ntdll)
+  AC_LIBOBJ(win32pread)
+  AC_LIBOBJ(win32pwrite)
   AC_LIBOBJ(win32security)
   AC_LIBOBJ(win32setlocale)
   AC_LIBOBJ(win32stat)
diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c
index 049da9fe6d..0d72ea212e 100644
--- a/contrib/pg_stat_statements/pg_stat_statements.c
+++ b/contrib/pg_stat_statements/pg_stat_statements.c
@@ -2091,9 +2091,9 @@ qtext_store(const char *query, int query_len,
 	if (fd < 0)
 		goto error;
 
-	if (pg_pwrite(fd, query, query_len, off) != query_len)
+	if (pwrite(fd, query, query_len, off) != query_len)
 		goto error;
-	if (pg_pwrite(fd, "\0", 1, off + query_len) != 1)
+	if (pwrite(fd, "\0", 1, off + query_len) != 1)
 		goto error;
 
 	CloseTransientFile(fd);
diff --git a/src/backend/access/heap/rewriteheap.c b/src/backend/access/heap/rewriteheap.c
index 197f06b5ec..9dd885d936 100644
--- a/src/backend/access/heap/rewriteheap.c
+++ b/src/backend/access/heap/rewriteheap.c
@@ -1149,7 +1149,7 @@ heap_xlog_logical_rewrite(XLogReaderState *r)
 	/* write out tail end of mapping file (again) */
 	errno = 0;
 	pgstat_report_wait_start(WAIT_EVENT_LOGICAL_REWRITE_MAPPING_WRITE);
-	if (pg_pwrite(fd, data, len, xlrec->offset) != len)
+	if (pwrite(fd, data, len, xlrec->offset) != len)
 	{
 		/* if write didn't set errno, assume problem is no disk space */
 		if (errno == 0)
diff --git a/src/backend/access/transam/slru.c b/src/backend/access/transam/slru.c
index b65cb49d7f..c9a7b97949 100644
--- a/src/backend/access/transam/slru.c
+++ b/src/backend/access/transam/slru.c
@@ -718,7 +718,7 @@ SlruPhysicalReadPage(SlruCtl ctl, int pageno, int slotno)
 
 	errno = 0;
 	pgstat_report_wait_start(WAIT_EVENT_SLRU_READ);
-	if (pg_pread(fd, shared->page_buffer[slotno], BLCKSZ, offset) != BLCKSZ)
+	if (pread(fd, shared->page_buffer[slotno], BLCKSZ, offset) != BLCKSZ)
 	{
 		pgstat_report_wait_end();
 		slru_errcause = SLRU_READ_FAILED;
@@ -873,7 +873,7 @@ SlruPhysicalWritePage(SlruCtl ctl, int pageno, int slotno, SlruWriteAll fdata)
 
 	errno = 0;
 	pgstat_report_wait_start(WAIT_EVENT_SLRU_WRITE);
-	if (pg_pwrite(fd, shared->page_buffer[slotno], BLCKSZ, offset) != BLCKSZ)
+	if (pwrite(fd, shared->page_buffer[slotno], BLCKSZ, offset) != BLCKSZ)
 	{
 		pgstat_report_wait_end();
 		/* if write didn't set errno, assume problem is no disk space */
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 26fbed00a4..eb5115fd5a 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -2189,7 +2189,7 @@ XLogWrite(XLogwrtRqst WriteRqst, TimeLineID tli, bool flexible)
 					INSTR_TIME_SET_CURRENT(start);
 
 				pgstat_report_wait_start(WAIT_EVENT_WAL_WRITE);
-				written = pg_pwrite(openLogFile, from, nleft, startoffset);
+				written = pwrite(openLogFile, from, nleft, startoffset);
 				pgstat_report_wait_end();
 
 				/*
@@ -3011,7 +3011,7 @@ XLogFileInitInternal(XLogSegNo logsegno, TimeLineID logtli,
 		 * enough.
 		 */
 		errno = 0;
-		if (pg_pwrite(fd, zbuffer.data, 1, wal_segment_size - 1) != 1)
+		if (pwrite(fd, zbuffer.data, 1, wal_segment_size - 1) != 1)
 		{
 			/* if write didn't set errno, assume no disk space */
 			save_errno = errno ? errno : ENOSPC;
diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c
index f3dc4b7797..06e91547dd 100644
--- a/src/backend/access/transam/xlogreader.c
+++ b/src/backend/access/transam/xlogreader.c
@@ -1514,7 +1514,7 @@ WALRead(XLogReaderState *state,
 
 		/* Reset errno first; eases reporting non-errno-affecting errors */
 		errno = 0;
-		readbytes = pg_pread(state->seg.ws_file, p, segbytes, (off_t) startoff);
+		readbytes = pread(state->seg.ws_file, p, segbytes, (off_t) startoff);
 
 #ifndef FRONTEND
 		pgstat_report_wait_end();
diff --git a/src/backend/access/transam/xlogrecovery.c b/src/backend/access/transam/xlogrecovery.c
index 27e02fbfcd..21088e78f6 100644
--- a/src/backend/access/transam/xlogrecovery.c
+++ b/src/backend/access/transam/xlogrecovery.c
@@ -3260,7 +3260,7 @@ retry:
 	readOff = targetPageOff;
 
 	pgstat_report_wait_start(WAIT_EVENT_WAL_READ);
-	r = pg_pread(readFile, readBuf, XLOG_BLCKSZ, (off_t) readOff);
+	r = pread(readFile, readBuf, XLOG_BLCKSZ, (off_t) readOff);
 	if (r != XLOG_BLCKSZ)
 	{
 		char		fname[MAXFNAMELEN];
diff --git a/src/backend/replication/basebackup.c b/src/backend/replication/basebackup.c
index 09f071300d..5e457f9be9 100644
--- a/src/backend/replication/basebackup.c
+++ b/src/backend/replication/basebackup.c
@@ -1822,7 +1822,7 @@ basebackup_read_file(int fd, char *buf, size_t nbytes, off_t offset,
 	int			rc;
 
 	pgstat_report_wait_start(WAIT_EVENT_BASEBACKUP_READ);
-	rc = pg_pread(fd, buf, nbytes, offset);
+	rc = pread(fd, buf, nbytes, offset);
 	pgstat_report_wait_end();
 
 	if (rc < 0)
diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c
index 3d37c1fe62..8604fd4bc2 100644
--- a/src/backend/replication/walreceiver.c
+++ b/src/backend/replication/walreceiver.c
@@ -915,7 +915,7 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr, TimeLineID tli)
 		/* OK to write the logs */
 		errno = 0;
 
-		byteswritten = pg_pwrite(recvFile, buf, segbytes, (off_t) startoff);
+		byteswritten = pwrite(recvFile, buf, segbytes, (off_t) startoff);
 		if (byteswritten <= 0)
 		{
 			char		xlogfname[MAXFNAMELEN];
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index 23ef22a60d..fa9ef6d118 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -2063,7 +2063,7 @@ FileRead(File file, char *buffer, int amount, off_t offset,
 
 retry:
 	pgstat_report_wait_start(wait_event_info);
-	returnCode = pg_pread(vfdP->fd, buffer, amount, offset);
+	returnCode = pread(vfdP->fd, buffer, amount, offset);
 	pgstat_report_wait_end();
 
 	if (returnCode < 0)
@@ -2145,7 +2145,7 @@ FileWrite(File file, char *buffer, int amount, off_t offset,
 retry:
 	errno = 0;
 	pgstat_report_wait_start(wait_event_info);
-	returnCode = pg_pwrite(VfdCache[file].fd, buffer, amount, offset);
+	returnCode = pwrite(VfdCache[file].fd, buffer, amount, offset);
 	pgstat_report_wait_end();
 
 	/* if write didn't set errno, assume problem is no disk space */
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index eb43b2c5e5..bd973ba613 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -1429,7 +1429,7 @@ AddToDataDirLockFile(int target_line, const char *str)
 	len = strlen(destbuffer);
 	errno = 0;
 	pgstat_report_wait_start(WAIT_EVENT_LOCK_FILE_ADDTODATADIR_WRITE);
-	if (pg_pwrite(fd, destbuffer, len, 0) != len)
+	if (pwrite(fd, destbuffer, len, 0) != len)
 	{
 		pgstat_report_wait_end();
 		/* if write didn't set errno, assume problem is no disk space */
diff --git a/src/bin/pg_test_fsync/pg_test_fsync.c b/src/bin/pg_test_fsync/pg_test_fsync.c
index 6739214eb8..8f0ef8e66b 100644
--- a/src/bin/pg_test_fsync/pg_test_fsync.c
+++ b/src/bin/pg_test_fsync/pg_test_fsync.c
@@ -312,10 +312,10 @@ test_sync(int writes_per_op)
 		for (ops = 0; alarm_triggered == false; ops++)
 		{
 			for (writes = 0; writes < writes_per_op; writes++)
-				if (pg_pwrite(tmpfile,
-							  buf,
-							  XLOG_BLCKSZ,
-							  writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
+				if (pwrite(tmpfile,
+						   buf,
+						   XLOG_BLCKSZ,
+						   writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
 					die("write failed");
 		}
 		STOP_TIMER;
@@ -338,10 +338,10 @@ test_sync(int writes_per_op)
 	for (ops = 0; alarm_triggered == false; ops++)
 	{
 		for (writes = 0; writes < writes_per_op; writes++)
-			if (pg_pwrite(tmpfile,
-						  buf,
-						  XLOG_BLCKSZ,
-						  writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
+			if (pwrite(tmpfile,
+					   buf,
+					   XLOG_BLCKSZ,
+					   writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
 				die("write failed");
 		fdatasync(tmpfile);
 	}
@@ -363,10 +363,10 @@ test_sync(int writes_per_op)
 	for (ops = 0; alarm_triggered == false; ops++)
 	{
 		for (writes = 0; writes < writes_per_op; writes++)
-			if (pg_pwrite(tmpfile,
-						  buf,
-						  XLOG_BLCKSZ,
-						  writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
+			if (pwrite(tmpfile,
+					   buf,
+					   XLOG_BLCKSZ,
+					   writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
 				die("write failed");
 		if (fsync(tmpfile) != 0)
 			die("fsync failed");
@@ -387,10 +387,10 @@ test_sync(int writes_per_op)
 	for (ops = 0; alarm_triggered == false; ops++)
 	{
 		for (writes = 0; writes < writes_per_op; writes++)
-			if (pg_pwrite(tmpfile,
-						  buf,
-						  XLOG_BLCKSZ,
-						  writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
+			if (pwrite(tmpfile,
+					   buf,
+					   XLOG_BLCKSZ,
+					   writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
 				die("write failed");
 		if (pg_fsync_writethrough(tmpfile) != 0)
 			die("fsync failed");
@@ -419,10 +419,10 @@ test_sync(int writes_per_op)
 		for (ops = 0; alarm_triggered == false; ops++)
 		{
 			for (writes = 0; writes < writes_per_op; writes++)
-				if (pg_pwrite(tmpfile,
-							  buf,
-							  XLOG_BLCKSZ,
-							  writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
+				if (pwrite(tmpfile,
+						   buf,
+						   XLOG_BLCKSZ,
+						   writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
 
 					/*
 					 * This can generate write failures if the filesystem has
@@ -484,10 +484,10 @@ test_open_sync(const char *msg, int writes_size)
 		for (ops = 0; alarm_triggered == false; ops++)
 		{
 			for (writes = 0; writes < 16 / writes_size; writes++)
-				if (pg_pwrite(tmpfile,
-							  buf,
-							  writes_size * 1024,
-							  writes * writes_size * 1024) !=
+				if (pwrite(tmpfile,
+						   buf,
+						   writes_size * 1024,
+						   writes * writes_size * 1024) !=
 					writes_size * 1024)
 					die("write failed");
 		}
@@ -586,7 +586,7 @@ test_non_sync(void)
 	START_TIMER;
 	for (ops = 0; alarm_triggered == false; ops++)
 	{
-		if (pg_pwrite(tmpfile, buf, XLOG_BLCKSZ, 0) != XLOG_BLCKSZ)
+		if (pwrite(tmpfile, buf, XLOG_BLCKSZ, 0) != XLOG_BLCKSZ)
 			die("write failed");
 	}
 	STOP_TIMER;
diff --git a/src/include/access/xlogreader.h b/src/include/access/xlogreader.h
index 5395f155aa..87ff00feb7 100644
--- a/src/include/access/xlogreader.h
+++ b/src/include/access/xlogreader.h
@@ -375,11 +375,11 @@ extern bool XLogReaderValidatePageHeader(XLogReaderState *state,
 
 /*
  * Error information from WALRead that both backend and frontend caller can
- * process.  Currently only errors from pg_pread can be reported.
+ * process.  Currently only errors from pread can be reported.
  */
 typedef struct WALReadError
 {
-	int			wre_errno;		/* errno set by the last pg_pread() */
+	int			wre_errno;		/* errno set by the last pread() */
 	int			wre_off;		/* Offset we tried to read from. */
 	int			wre_req;		/* Bytes requested to be read. */
 	int			wre_read;		/* Bytes read by the last read(). */
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 6ea38998f8..e8633878d2 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -393,9 +393,6 @@
 /* Define to 1 if you have the `ppoll' function. */
 #undef HAVE_PPOLL
 
-/* Define to 1 if you have the `pread' function. */
-#undef HAVE_PREAD
-
 /* Define to 1 if the PS_STRINGS thing exists. */
 #undef HAVE_PS_STRINGS
 
@@ -411,9 +408,6 @@
 /* Have PTHREAD_PRIO_INHERIT. */
 #undef HAVE_PTHREAD_PRIO_INHERIT
 
-/* Define to 1 if you have the `pwrite' function. */
-#undef HAVE_PWRITE
-
 /* Define to 1 if you have the <readline.h> header file. */
 #undef HAVE_READLINE_H
 
diff --git a/src/include/port.h b/src/include/port.h
index 97181141fc..dfa94e67b0 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -417,25 +417,6 @@ extern char *mkdtemp(char *path);
 extern int	inet_aton(const char *cp, struct in_addr *addr);
 #endif
 
-/*
- * Windows and older Unix don't have pread(2) and pwrite(2).  We have
- * replacement functions, but they have slightly different semantics so we'll
- * use a name with a pg_ prefix to avoid confusion.
- */
-#ifdef HAVE_PREAD
-#define pg_pread pread
-#else
-extern ssize_t pg_pread(int fd, void *buf, size_t nbyte, off_t offset);
-#endif
-
-#ifdef HAVE_PWRITE
-#define pg_pwrite pwrite
-#else
-extern ssize_t pg_pwrite(int fd, const void *buf, size_t nbyte, off_t offset);
-#endif
-
-/* For pg_pwritev() and pg_preadv(), see port/pg_iovec.h. */
-
 #if !HAVE_DECL_STRLCAT
 extern size_t strlcat(char *dst, const char *src, size_t siz);
 #endif
diff --git a/src/include/port/win32_port.h b/src/include/port/win32_port.h
index 4de5bf3bf6..d5872e1076 100644
--- a/src/include/port/win32_port.h
+++ b/src/include/port/win32_port.h
@@ -553,4 +553,13 @@ typedef unsigned short mode_t;
 #define HAVE_BUGGY_STRTOF 1
 #endif
 
+/* in port/win32pread.c */
+extern ssize_t pgwin32_pread(int fd, void *buf, size_t nbyte, off_t offset);
+
+/* in port/win32pwrite.c */
+extern ssize_t pgwin32_pwrite(int fd, const void *buf, size_t nbyte, off_t offset);
+
+#define pread pgwin32_pread
+#define pwrite pgwin32_pwrite
+
 #endif							/* PG_WIN32_PORT_H */
diff --git a/src/port/preadv.c b/src/port/preadv.c
index d12e5a122b..aa7537503f 100644
--- a/src/port/preadv.c
+++ b/src/port/preadv.c
@@ -30,7 +30,7 @@ pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 {
 #ifdef HAVE_READV
 	if (iovcnt == 1)
-		return pg_pread(fd, iov[0].iov_base, iov[0].iov_len, offset);
+		return pread(fd, iov[0].iov_base, iov[0].iov_len, offset);
 	if (lseek(fd, offset, SEEK_SET) < 0)
 		return -1;
 	return readv(fd, iov, iovcnt);
@@ -40,7 +40,7 @@ pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 
 	for (int i = 0; i < iovcnt; ++i)
 	{
-		part = pg_pread(fd, iov[i].iov_base, iov[i].iov_len, offset);
+		part = pread(fd, iov[i].iov_base, iov[i].iov_len, offset);
 		if (part < 0)
 		{
 			if (i == 0)
diff --git a/src/port/pwritev.c b/src/port/pwritev.c
index 0bdd69fffc..cb7421381e 100644
--- a/src/port/pwritev.c
+++ b/src/port/pwritev.c
@@ -30,7 +30,7 @@ pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 {
 #ifdef HAVE_WRITEV
 	if (iovcnt == 1)
-		return pg_pwrite(fd, iov[0].iov_base, iov[0].iov_len, offset);
+		return pwrite(fd, iov[0].iov_base, iov[0].iov_len, offset);
 	if (lseek(fd, offset, SEEK_SET) < 0)
 		return -1;
 	return writev(fd, iov, iovcnt);
@@ -40,7 +40,7 @@ pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 
 	for (int i = 0; i < iovcnt; ++i)
 	{
-		part = pg_pwrite(fd, iov[i].iov_base, iov[i].iov_len, offset);
+		part = pwrite(fd, iov[i].iov_base, iov[i].iov_len, offset);
 		if (part < 0)
 		{
 			if (i == 0)
diff --git a/src/port/pread.c b/src/port/win32pread.c
similarity index 61%
rename from src/port/pread.c
rename to src/port/win32pread.c
index 491605926f..381cf0be2c 100644
--- a/src/port/pread.c
+++ b/src/port/win32pread.c
@@ -1,15 +1,12 @@
 /*-------------------------------------------------------------------------
  *
- * pread.c
- *	  Implementation of pread(2) for platforms that lack one.
+ * win32pread.c
+ *	  Implementation of pread(2) for Windows.
  *
  * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *	  src/port/pread.c
- *
- * Note that this implementation changes the current file position, unlike
- * the POSIX function, so we use the name pg_pread().
+ *	  src/port/win32pread.c
  *
  *-------------------------------------------------------------------------
  */
@@ -17,16 +14,11 @@
 
 #include "postgres.h"
 
-#ifdef WIN32
 #include <windows.h>
-#else
-#include <unistd.h>
-#endif
 
 ssize_t
-pg_pread(int fd, void *buf, size_t size, off_t offset)
+pgwin32_pread(int fd, void *buf, size_t size, off_t offset)
 {
-#ifdef WIN32
 	OVERLAPPED	overlapped = {0};
 	HANDLE		handle;
 	DWORD		result;
@@ -49,10 +41,4 @@ pg_pread(int fd, void *buf, size_t size, off_t offset)
 	}
 
 	return result;
-#else
-	if (lseek(fd, offset, SEEK_SET) < 0)
-		return -1;
-
-	return read(fd, buf, size);
-#endif
 }
diff --git a/src/port/pwrite.c b/src/port/win32pwrite.c
similarity index 59%
rename from src/port/pwrite.c
rename to src/port/win32pwrite.c
index eeaffacc48..989005fa5c 100644
--- a/src/port/pwrite.c
+++ b/src/port/win32pwrite.c
@@ -1,15 +1,12 @@
 /*-------------------------------------------------------------------------
  *
- * pwrite.c
- *	  Implementation of pwrite(2) for platforms that lack one.
+ * win32pwrite.c
+ *	  Implementation of pwrite(2) for Windows.
  *
  * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *	  src/port/pwrite.c
- *
- * Note that this implementation changes the current file position, unlike
- * the POSIX function, so we use the name pg_pwrite().
+ *	  src/port/win32pwrite.c
  *
  *-------------------------------------------------------------------------
  */
@@ -17,16 +14,11 @@
 
 #include "postgres.h"
 
-#ifdef WIN32
 #include <windows.h>
-#else
-#include <unistd.h>
-#endif
 
 ssize_t
-pg_pwrite(int fd, const void *buf, size_t size, off_t offset)
+pgwin32_pwrite(int fd, const void *buf, size_t size, off_t offset)
 {
-#ifdef WIN32
 	OVERLAPPED	overlapped = {0};
 	HANDLE		handle;
 	DWORD		result;
@@ -46,10 +38,4 @@ pg_pwrite(int fd, const void *buf, size_t size, off_t offset)
 	}
 
 	return result;
-#else
-	if (lseek(fd, offset, SEEK_SET) < 0)
-		return -1;
-
-	return write(fd, buf, size);
-#endif
 }
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index 1ffe6e66d5..a06dbcae4d 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -104,13 +104,15 @@ sub mkvcbuild
 	  getaddrinfo.c gettimeofday.c inet_net_ntop.c kill.c open.c
 	  snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c
 	  dirent.c getopt.c getopt_long.c
-	  pread.c preadv.c pwrite.c pwritev.c pg_bitutils.c
+	  preadv.c pwritev.c pg_bitutils.c
 	  pg_strong_random.c pgcheckdir.c pgmkdirp.c pgsleep.c pgstrcasecmp.c
 	  pqsignal.c mkdtemp.c qsort.c qsort_arg.c bsearch_arg.c quotes.c system.c
 	  strerror.c tar.c
 	  win32dlopen.c
 	  win32env.c win32error.c
 	  win32link.c
+	  win32pread.c
+	  win32pwrite.c
 	  win32ntdll.c
 	  win32security.c win32setlocale.c win32stat.c);
 
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 0d4ca94e7f..811cfe1ff3 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -325,13 +325,11 @@ sub GenerateFiles
 		HAVE_POSIX_FALLOCATE        => undef,
 		HAVE_PPC_LWARX_MUTEX_HINT   => undef,
 		HAVE_PPOLL                  => undef,
-		HAVE_PREAD                  => undef,
 		HAVE_PS_STRINGS             => undef,
 		HAVE_PTHREAD                => undef,
 		HAVE_PTHREAD_BARRIER_WAIT   => undef,
 		HAVE_PTHREAD_IS_THREADED_NP => undef,
 		HAVE_PTHREAD_PRIO_INHERIT   => undef,
-		HAVE_PWRITE                 => undef,
 		HAVE_READLINE_H             => undef,
 		HAVE_READLINE_HISTORY_H     => undef,
 		HAVE_READLINE_READLINE_H    => undef,
-- 
2.35.1

v2-0011-Simplify-replacement-code-for-preadv-and-pwritev.patchtext/x-patch; charset=US-ASCII; name=v2-0011-Simplify-replacement-code-for-preadv-and-pwritev.patchDownload
From 77ad135a960569adf65c70dead8747c339bae0d0 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 23 Jul 2022 23:24:14 +1200
Subject: [PATCH v2 11/13] Simplify replacement code for preadv and pwritev.

preadv() and pwritev() are not standardized by POSIX.  Most targeted
Unix systems have had them for more than a decade, since they are
obvious combinations of standard p- and -v functions.

In 15, we had two replacement implementations: one based on lseek() + -v
function if available, and the other based on a loop over p- function.
They aren't used for much yet, but are heavily used in a current
proposal.

Supporting two ways of falling back, at the cost of having a
pg_preadv/pg_pwritev that could never be used in a multi-threaded
program accessing the same file descriptor from two threads without
unpleasant locking does not sound like a good trade.

Therefore, drop the lseek()-based variant, and also the pg_ prefix, now
that the file position portability hazard is gone.  Previously, both
fallbacks had the file position portability hazard, because our
pread()/pwrite() replacement had the same hazard, but that problem has
been fixed for pread()/pwrite() by an earlier commit.  Now the way is
clear to expunge the file position portability hazard of the
lseek()-based variants too.

At the time of writing, the following systems in our build farm lack
native preadv/pwritev and thus use fallback code:

 * Solaris (but not illumos)
 * macOS before release 11.0
 * Windows with Cygwin
 * Windows native

With this commit, all of the above systems will now use the *same*
fallback code, the one that loops over pread()/pwrite() (which is
translated to equivalent calls in Windows).  Previously, all but Windows
native would use the readv()/writev()-based fallback that this commit
removes.

(Note that later work intending to make more use of scatter/gather I/O
will propose something better for Windows using true native
scatter/gather, but that has constraints that don't fit into the
preadv/pwritev contract very well, so it's really just Solaris that we
won't have a way to do true scatter/gather on by opting not to use
readv/writev.)

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CA+hUKGJ3LHeP9w5Fgzdr4G8AnEtJ=z=p6hGDEm4qYGEUX5B6fQ@mail.gmail.com
---
 configure                     |  2 +-
 configure.ac                  |  2 --
 src/backend/storage/file/fd.c |  4 ++--
 src/include/pg_config.h.in    |  6 ------
 src/include/port/pg_iovec.h   | 12 ++++--------
 src/port/preadv.c             | 13 +------------
 src/port/pwritev.c            | 13 +------------
 src/tools/msvc/Solution.pm    |  2 --
 8 files changed, 9 insertions(+), 45 deletions(-)

diff --git a/configure b/configure
index d2f6f4b0eb..1aa57b6686 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 copyfile fdatasync getifaddrs getpeerucred inet_pton kqueue mbstowcs_l memset_s posix_fallocate ppoll pthread_is_threaded_np readv setproctitle setproctitle_fast strchrnul strsignal syncfs sync_file_range uselocale wcstombs_l writev
+for ac_func in backtrace_symbols copyfile fdatasync getifaddrs getpeerucred inet_pton kqueue mbstowcs_l memset_s posix_fallocate ppoll pthread_is_threaded_np setproctitle setproctitle_fast strchrnul strsignal syncfs sync_file_range uselocale wcstombs_l
 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"
diff --git a/configure.ac b/configure.ac
index 070fafaa0a..c4b81466a5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1802,7 +1802,6 @@ AC_CHECK_FUNCS(m4_normalize([
 	posix_fallocate
 	ppoll
 	pthread_is_threaded_np
-	readv
 	setproctitle
 	setproctitle_fast
 	strchrnul
@@ -1811,7 +1810,6 @@ AC_CHECK_FUNCS(m4_normalize([
 	sync_file_range
 	uselocale
 	wcstombs_l
-	writev
 ]))
 
 # These typically are compiler builtins, for which AC_CHECK_FUNCS fails.
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index fa9ef6d118..3c5dfb2dc8 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -3762,7 +3762,7 @@ data_sync_elevel(int elevel)
 }
 
 /*
- * A convenience wrapper for pg_pwritev() that retries on partial write.  If an
+ * A convenience wrapper for pwritev() that retries on partial write.  If an
  * error is returned, it is unspecified how much has been written.
  */
 ssize_t
@@ -3782,7 +3782,7 @@ pg_pwritev_with_retry(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 	for (;;)
 	{
 		/* Write as much as we can. */
-		part = pg_pwritev(fd, iov, iovcnt, offset);
+		part = pwritev(fd, iov, iovcnt, offset);
 		if (part < 0)
 			return -1;
 
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index e8633878d2..f7a7b8116c 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -417,9 +417,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 `readv' function. */
-#undef HAVE_READV
-
 /* Define to 1 if you have the `rl_completion_matches' function. */
 #undef HAVE_RL_COMPLETION_MATCHES
 
@@ -648,9 +645,6 @@
 /* Define to 1 if you have the <winldap.h> header file. */
 #undef HAVE_WINLDAP_H
 
-/* Define to 1 if you have the `writev' function. */
-#undef HAVE_WRITEV
-
 /* Define to 1 if you have the `X509_get_signature_nid' function. */
 #undef HAVE_X509_GET_SIGNATURE_NID
 
diff --git a/src/include/port/pg_iovec.h b/src/include/port/pg_iovec.h
index f0b1a71bcb..f0a50c0e01 100644
--- a/src/include/port/pg_iovec.h
+++ b/src/include/port/pg_iovec.h
@@ -39,16 +39,12 @@ struct iovec
 /* Define a reasonable maximum that is safe to use on the stack. */
 #define PG_IOV_MAX Min(IOV_MAX, 32)
 
-#if HAVE_DECL_PREADV
-#define pg_preadv preadv
-#else
-extern ssize_t pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset);
+#if !HAVE_DECL_PREADV
+extern ssize_t preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset);
 #endif
 
-#if HAVE_DECL_PWRITEV
-#define pg_pwritev pwritev
-#else
-extern ssize_t pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset);
+#if !HAVE_DECL_PWRITEV
+extern ssize_t pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset);
 #endif
 
 #endif							/* PG_IOVEC_H */
diff --git a/src/port/preadv.c b/src/port/preadv.c
index aa7537503f..0aaf99222f 100644
--- a/src/port/preadv.c
+++ b/src/port/preadv.c
@@ -8,9 +8,6 @@
  * IDENTIFICATION
  *	  src/port/preadv.c
  *
- * Note that this implementation changes the current file position, unlike
- * the POSIX-like function, so we use the name pg_preadv().
- *
  *-------------------------------------------------------------------------
  */
 
@@ -26,15 +23,8 @@
 #include "port/pg_iovec.h"
 
 ssize_t
-pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
+preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 {
-#ifdef HAVE_READV
-	if (iovcnt == 1)
-		return pread(fd, iov[0].iov_base, iov[0].iov_len, offset);
-	if (lseek(fd, offset, SEEK_SET) < 0)
-		return -1;
-	return readv(fd, iov, iovcnt);
-#else
 	ssize_t		sum = 0;
 	ssize_t		part;
 
@@ -54,5 +44,4 @@ pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 			return sum;
 	}
 	return sum;
-#endif
 }
diff --git a/src/port/pwritev.c b/src/port/pwritev.c
index cb7421381e..a0fa4b8edd 100644
--- a/src/port/pwritev.c
+++ b/src/port/pwritev.c
@@ -8,9 +8,6 @@
  * IDENTIFICATION
  *	  src/port/pwritev.c
  *
- * Note that this implementation changes the current file position, unlike
- * the POSIX-like function, so we use the name pg_pwritev().
- *
  *-------------------------------------------------------------------------
  */
 
@@ -26,15 +23,8 @@
 #include "port/pg_iovec.h"
 
 ssize_t
-pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
+pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 {
-#ifdef HAVE_WRITEV
-	if (iovcnt == 1)
-		return pwrite(fd, iov[0].iov_base, iov[0].iov_len, offset);
-	if (lseek(fd, offset, SEEK_SET) < 0)
-		return -1;
-	return writev(fd, iov, iovcnt);
-#else
 	ssize_t		sum = 0;
 	ssize_t		part;
 
@@ -54,5 +44,4 @@ pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 			return sum;
 	}
 	return sum;
-#endif
 }
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 811cfe1ff3..a4cebdcf96 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -333,7 +333,6 @@ sub GenerateFiles
 		HAVE_READLINE_H             => undef,
 		HAVE_READLINE_HISTORY_H     => undef,
 		HAVE_READLINE_READLINE_H    => undef,
-		HAVE_READV                  => undef,
 		HAVE_RL_COMPLETION_MATCHES  => undef,
 		HAVE_RL_COMPLETION_SUPPRESS_QUOTE        => undef,
 		HAVE_RL_FILENAME_COMPLETION_FUNCTION     => undef,
@@ -409,7 +408,6 @@ sub GenerateFiles
 		HAVE_WINLDAP_H                           => undef,
 		HAVE_WCSTOMBS_L                          => 1,
 		HAVE_VISIBILITY_ATTRIBUTE                => undef,
-		HAVE_WRITEV                              => undef,
 		HAVE_X509_GET_SIGNATURE_NID              => 1,
 		HAVE_X86_64_POPCNTQ                      => undef,
 		HAVE__BOOL                               => undef,
-- 
2.35.1

v2-0012-Remove-fdatasync-configure-probe.patchtext/x-patch; charset=US-ASCII; name=v2-0012-Remove-fdatasync-configure-probe.patchDownload
From fcb70b8ece39812e051e922ea3e990f2805aa1cc Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Wed, 20 Jul 2022 14:10:37 +1200
Subject: [PATCH v2 12/13] Remove fdatasync configure probe.

fdatasync() is in SUSv2, and all targeted Unix systems have it.  We have
a replacement function for Windows.

We retain the probe for the function declaration, which allows us to
supply the missing declaration for macOS and Windows.  No need to keep a
HAVE_FDATASYNC macro around.

Also rename src/port/fdatasync.c to win32fdatasync.c since the replacement
code is Windows-only.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CA+hUKGJ3LHeP9w5Fgzdr4G8AnEtJ=z=p6hGDEm4qYGEUX5B6fQ@mail.gmail.com
Discussion: https://postgr.es/m/CA%2BhUKGJZJVO%3DiX%2Beb-PXi2_XS9ZRqnn_4URh0NUQOwt6-_51xQ%40mail.gmail.com
---
 configure                                  | 71 +++-------------------
 configure.ac                               |  5 +-
 src/backend/access/transam/xlog.c          |  4 --
 src/backend/storage/file/fd.c              |  8 ---
 src/bin/pg_test_fsync/pg_test_fsync.c      |  4 --
 src/include/access/xlogdefs.h              |  7 +--
 src/include/pg_config.h.in                 |  3 -
 src/include/port/freebsd.h                 |  2 -
 src/include/port/win32_port.h              |  8 ---
 src/port/{fdatasync.c => win32fdatasync.c} |  2 +-
 src/tools/msvc/Mkvcbuild.pm                |  3 +-
 src/tools/msvc/Solution.pm                 |  1 -
 12 files changed, 13 insertions(+), 105 deletions(-)
 rename src/port/{fdatasync.c => win32fdatasync.c} (96%)

diff --git a/configure b/configure
index 1aa57b6686..cf52af6335 100755
--- a/configure
+++ b/configure
@@ -12315,63 +12315,6 @@ if test "$ac_res" != no; then :
 
 fi
 
-# Solaris:
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing fdatasync" >&5
-$as_echo_n "checking for library containing fdatasync... " >&6; }
-if ${ac_cv_search_fdatasync+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_func_search_save_LIBS=$LIBS
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char fdatasync ();
-int
-main ()
-{
-return fdatasync ();
-  ;
-  return 0;
-}
-_ACEOF
-for ac_lib in '' rt posix4; do
-  if test -z "$ac_lib"; then
-    ac_res="none required"
-  else
-    ac_res=-l$ac_lib
-    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
-  fi
-  if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_search_fdatasync=$ac_res
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext
-  if ${ac_cv_search_fdatasync+:} false; then :
-  break
-fi
-done
-if ${ac_cv_search_fdatasync+:} false; then :
-
-else
-  ac_cv_search_fdatasync=no
-fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_fdatasync" >&5
-$as_echo "$ac_cv_search_fdatasync" >&6; }
-ac_res=$ac_cv_search_fdatasync
-if test "$ac_res" != no; then :
-  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-
-fi
-
 # Cygwin:
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing shmget" >&5
 $as_echo_n "checking for library containing shmget... " >&6; }
@@ -16039,7 +15982,7 @@ fi
 LIBS_including_readline="$LIBS"
 LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'`
 
-for ac_func in backtrace_symbols copyfile fdatasync getifaddrs getpeerucred inet_pton kqueue mbstowcs_l memset_s posix_fallocate ppoll pthread_is_threaded_np setproctitle setproctitle_fast strchrnul strsignal syncfs sync_file_range uselocale wcstombs_l
+for ac_func in backtrace_symbols copyfile getifaddrs getpeerucred inet_pton kqueue mbstowcs_l memset_s posix_fallocate ppoll pthread_is_threaded_np setproctitle setproctitle_fast strchrnul strsignal syncfs sync_file_range uselocale wcstombs_l
 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"
@@ -16953,12 +16896,6 @@ fi
  ;;
 esac
 
-  case " $LIBOBJS " in
-  *" fdatasync.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS fdatasync.$ac_objext"
- ;;
-esac
-
   case " $LIBOBJS " in
   *" getrusage.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS getrusage.$ac_objext"
@@ -17001,6 +16938,12 @@ esac
  ;;
 esac
 
+  case " $LIBOBJS " in
+  *" win32fdatasync.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS win32fdatasync.$ac_objext"
+ ;;
+esac
+
   case " $LIBOBJS " in
   *" win32link.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS win32link.$ac_objext"
diff --git a/configure.ac b/configure.ac
index c4b81466a5..6e9d5342cc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1253,8 +1253,6 @@ AC_SEARCH_LIBS(getopt_long, [getopt gnugetopt])
 AC_SEARCH_LIBS(shm_open, rt)
 AC_SEARCH_LIBS(shm_unlink, rt)
 AC_SEARCH_LIBS(clock_gettime, [rt posix4])
-# Solaris:
-AC_SEARCH_LIBS(fdatasync, [rt posix4])
 # Cygwin:
 AC_SEARCH_LIBS(shmget, cygipc)
 # *BSD:
@@ -1792,7 +1790,6 @@ LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'`
 AC_CHECK_FUNCS(m4_normalize([
 	backtrace_symbols
 	copyfile
-	fdatasync
 	getifaddrs
 	getpeerucred
 	inet_pton
@@ -1930,7 +1927,6 @@ if test "$PORTNAME" = "win32"; then
   AC_CHECK_FUNCS(_configthreadlocale)
   AC_REPLACE_FUNCS(gettimeofday)
   AC_LIBOBJ(dirmod)
-  AC_LIBOBJ(fdatasync)
   AC_LIBOBJ(getrusage)
   AC_LIBOBJ(kill)
   AC_LIBOBJ(open)
@@ -1938,6 +1934,7 @@ if test "$PORTNAME" = "win32"; then
   AC_LIBOBJ(win32dlopen)
   AC_LIBOBJ(win32env)
   AC_LIBOBJ(win32error)
+  AC_LIBOBJ(win32fdatasync)
   AC_LIBOBJ(win32link)
   AC_LIBOBJ(win32ntdll)
   AC_LIBOBJ(win32pread)
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index eb5115fd5a..34f0150d1e 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -168,9 +168,7 @@ const struct config_enum_entry sync_method_options[] = {
 #ifdef HAVE_FSYNC_WRITETHROUGH
 	{"fsync_writethrough", SYNC_METHOD_FSYNC_WRITETHROUGH, false},
 #endif
-#ifdef HAVE_FDATASYNC
 	{"fdatasync", SYNC_METHOD_FDATASYNC, false},
-#endif
 #ifdef O_SYNC
 	{"open_sync", SYNC_METHOD_OPEN, false},
 #endif
@@ -8015,12 +8013,10 @@ issue_xlog_fsync(int fd, XLogSegNo segno, TimeLineID tli)
 				msg = _("could not fsync write-through file \"%s\": %m");
 			break;
 #endif
-#ifdef HAVE_FDATASYNC
 		case SYNC_METHOD_FDATASYNC:
 			if (pg_fdatasync(fd) != 0)
 				msg = _("could not fdatasync file \"%s\": %m");
 			break;
-#endif
 		case SYNC_METHOD_OPEN:
 		case SYNC_METHOD_OPEN_DSYNC:
 			/* not reachable */
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index 3c5dfb2dc8..3ecc1f0854 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -442,20 +442,12 @@ pg_fsync_writethrough(int fd)
 
 /*
  * pg_fdatasync --- same as fdatasync except does nothing if enableFsync is off
- *
- * Not all platforms have fdatasync; treat as fsync if not available.
  */
 int
 pg_fdatasync(int fd)
 {
 	if (enableFsync)
-	{
-#ifdef HAVE_FDATASYNC
 		return fdatasync(fd);
-#else
-		return fsync(fd);
-#endif
-	}
 	else
 		return 0;
 }
diff --git a/src/bin/pg_test_fsync/pg_test_fsync.c b/src/bin/pg_test_fsync/pg_test_fsync.c
index 8f0ef8e66b..77f0db0376 100644
--- a/src/bin/pg_test_fsync/pg_test_fsync.c
+++ b/src/bin/pg_test_fsync/pg_test_fsync.c
@@ -331,7 +331,6 @@ test_sync(int writes_per_op)
 	printf(LABEL_FORMAT, "fdatasync");
 	fflush(stdout);
 
-#ifdef HAVE_FDATASYNC
 	if ((tmpfile = open(filename, O_RDWR | PG_BINARY, 0)) == -1)
 		die("could not open output file");
 	START_TIMER;
@@ -347,9 +346,6 @@ test_sync(int writes_per_op)
 	}
 	STOP_TIMER;
 	close(tmpfile);
-#else
-	printf(NA_FORMAT, _("n/a"));
-#endif
 
 /*
  * Test fsync
diff --git a/src/include/access/xlogdefs.h b/src/include/access/xlogdefs.h
index 810cd1fd86..49e581925c 100644
--- a/src/include/access/xlogdefs.h
+++ b/src/include/access/xlogdefs.h
@@ -67,8 +67,7 @@ typedef uint16 RepOriginId;
 /*
  * This chunk of hackery attempts to determine which file sync methods
  * are available on the current platform, and to choose an appropriate
- * default method.  We assume that fsync() is always available, and that
- * configure determined whether fdatasync() is.
+ * default method.
  *
  * Note that we define our own O_DSYNC on Windows, but not O_SYNC.
  */
@@ -76,10 +75,8 @@ typedef uint16 RepOriginId;
 #define DEFAULT_SYNC_METHOD		PLATFORM_DEFAULT_SYNC_METHOD
 #elif defined(O_DSYNC) && (!defined(O_SYNC) || O_DSYNC != O_SYNC)
 #define DEFAULT_SYNC_METHOD		SYNC_METHOD_OPEN_DSYNC
-#elif defined(HAVE_FDATASYNC)
-#define DEFAULT_SYNC_METHOD		SYNC_METHOD_FDATASYNC
 #else
-#define DEFAULT_SYNC_METHOD		SYNC_METHOD_FSYNC
+#define DEFAULT_SYNC_METHOD		SYNC_METHOD_FDATASYNC
 #endif
 
 #endif							/* XLOG_DEFS_H */
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index f7a7b8116c..6c8e3fe0a7 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -178,9 +178,6 @@
 /* Define to 1 if you have the `explicit_bzero' function. */
 #undef HAVE_EXPLICIT_BZERO
 
-/* Define to 1 if you have the `fdatasync' function. */
-#undef HAVE_FDATASYNC
-
 /* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
 #undef HAVE_FSEEKO
 
diff --git a/src/include/port/freebsd.h b/src/include/port/freebsd.h
index 2e2e749a6b..0e3fde55d6 100644
--- a/src/include/port/freebsd.h
+++ b/src/include/port/freebsd.h
@@ -5,6 +5,4 @@
  * would prefer open_datasync on FreeBSD 13+, but that is not a good choice on
  * many systems.
  */
-#ifdef HAVE_FDATASYNC
 #define PLATFORM_DEFAULT_SYNC_METHOD	SYNC_METHOD_FDATASYNC
-#endif
diff --git a/src/include/port/win32_port.h b/src/include/port/win32_port.h
index d5872e1076..b41607e462 100644
--- a/src/include/port/win32_port.h
+++ b/src/include/port/win32_port.h
@@ -83,14 +83,6 @@
 #define HAVE_FSYNC_WRITETHROUGH
 #define FSYNC_WRITETHROUGH_IS_FSYNC
 
-/*
- * We have a replacement for fdatasync() in src/port/fdatasync.c, which is
- * unconditionally used by MSVC and Mingw builds.
- */
-#ifndef HAVE_FDATASYNC
-#define HAVE_FDATASYNC
-#endif
-
 #define USES_WINSOCK
 
 /*
diff --git a/src/port/fdatasync.c b/src/port/win32fdatasync.c
similarity index 96%
rename from src/port/fdatasync.c
rename to src/port/win32fdatasync.c
index afef853aa3..ab11fad955 100644
--- a/src/port/fdatasync.c
+++ b/src/port/win32fdatasync.c
@@ -6,7 +6,7 @@
  *
  * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
  *
- * src/port/fdatasync.c
+ * src/port/win32fdatasync.c
  *
  *-------------------------------------------------------------------------
  */
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index a06dbcae4d..8d88e78f05 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -99,7 +99,7 @@ sub mkvcbuild
 	$solution = CreateSolution($vsVersion, $config);
 
 	our @pgportfiles = qw(
-	  chklocale.c explicit_bzero.c fdatasync.c
+	  chklocale.c explicit_bzero.c
 	  getpeereid.c getrusage.c inet_aton.c
 	  getaddrinfo.c gettimeofday.c inet_net_ntop.c kill.c open.c
 	  snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c
@@ -110,6 +110,7 @@ sub mkvcbuild
 	  strerror.c tar.c
 	  win32dlopen.c
 	  win32env.c win32error.c
+	  win32fdatasync.c
 	  win32link.c
 	  win32pread.c
 	  win32pwrite.c
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index a4cebdcf96..1cd1c44fed 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -254,7 +254,6 @@ sub GenerateFiles
 		HAVE_EDITLINE_READLINE_H                    => undef,
 		HAVE_EXECINFO_H                             => undef,
 		HAVE_EXPLICIT_BZERO                         => undef,
-		HAVE_FDATASYNC                              => 1,
 		HAVE_FSEEKO                                 => 1,
 		HAVE_FUNCNAME__FUNC                         => undef,
 		HAVE_FUNCNAME__FUNCTION                     => 1,
-- 
2.35.1

v2-0013-Remove-disable-thread-safety.patchtext/x-patch; charset=US-ASCII; name=v2-0013-Remove-disable-thread-safety.patchDownload
From a9b53dcaa5e15ad2046edef5ef3cbc89520dd637 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Fri, 26 Mar 2021 22:58:06 +1300
Subject: [PATCH v2 13/13] Remove --disable-thread-safety.

Threads are in SUSv2 and all targeted Unix systems have the option.
There are no known Unix systems that don't choose to implement the
threading option, and we're no longer testing such builds.

Future work to improve our use of threads will be simplified by not
having to cope with a no-threads build option.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Greg Stark <stark@mit.edu>
Reviewed-by: Robert Haas <robertmhaas@gmail.com>
Discussion: https://postgr.es/m/CA+hUKGJ3LHeP9w5Fgzdr4G8AnEtJ=z=p6hGDEm4qYGEUX5B6fQ@mail.gmail.com
---
 configure                                     | 56 ++-------------
 configure.ac                                  | 28 ++------
 doc/src/sgml/installation.sgml                | 13 ----
 doc/src/sgml/libpq.sgml                       |  3 +-
 src/Makefile.global.in                        |  1 -
 src/bin/pgbench/pgbench.c                     | 22 +-----
 src/include/pg_config.h.in                    |  4 --
 src/interfaces/ecpg/ecpglib/connect.c         | 40 -----------
 src/interfaces/ecpg/ecpglib/descriptor.c      |  9 ---
 src/interfaces/ecpg/ecpglib/ecpglib_extern.h  |  2 -
 src/interfaces/ecpg/ecpglib/execute.c         |  2 -
 src/interfaces/ecpg/ecpglib/memory.c          |  7 --
 src/interfaces/ecpg/ecpglib/misc.c            | 47 ------------
 .../ecpg/include/ecpg-pthread-win32.h         |  3 -
 src/interfaces/ecpg/include/ecpg_config.h.in  |  4 --
 src/interfaces/ecpg/include/ecpglib.h         |  2 -
 .../ecpg/test/expected/thread-alloc.c         | 43 +++++------
 .../ecpg/test/expected/thread-alloc_2.stdout  |  1 -
 .../ecpg/test/expected/thread-descriptor.c    | 22 +++---
 .../ecpg/test/expected/thread-prep.c          | 71 ++++++++-----------
 .../ecpg/test/expected/thread-prep.stdout     |  1 -
 .../ecpg/test/expected/thread-prep_2.stdout   |  0
 .../ecpg/test/expected/thread-thread.c        | 63 +++++++---------
 .../ecpg/test/expected/thread-thread.stdout   |  2 +-
 .../ecpg/test/expected/thread-thread_2.stdout |  1 -
 .../test/expected/thread-thread_implicit.c    | 63 +++++++---------
 .../expected/thread-thread_implicit.stdout    |  2 +-
 .../expected/thread-thread_implicit_2.stdout  |  1 -
 src/interfaces/ecpg/test/thread/alloc.pgc     |  9 ---
 .../ecpg/test/thread/descriptor.pgc           |  8 +--
 src/interfaces/ecpg/test/thread/prep.pgc      |  9 ---
 src/interfaces/ecpg/test/thread/thread.pgc    |  9 ---
 .../ecpg/test/thread/thread_implicit.pgc      |  9 ---
 src/interfaces/libpq/Makefile                 |  2 -
 src/interfaces/libpq/fe-auth.c                |  9 ++-
 src/interfaces/libpq/fe-connect.c             |  4 --
 src/interfaces/libpq/fe-exec.c                |  4 --
 src/interfaces/libpq/fe-print.c               | 13 +---
 src/interfaces/libpq/fe-secure-openssl.c      | 17 +----
 src/interfaces/libpq/fe-secure.c              | 26 +------
 src/interfaces/libpq/legacy-pqsignal.c        |  4 --
 src/interfaces/libpq/libpq-int.h              |  9 +--
 src/port/getaddrinfo.c                        |  2 +-
 src/tools/msvc/Solution.pm                    |  3 +-
 src/tools/msvc/ecpg_regression.proj           |  2 +-
 45 files changed, 142 insertions(+), 510 deletions(-)
 delete mode 100644 src/interfaces/ecpg/test/expected/thread-alloc_2.stdout
 delete mode 100644 src/interfaces/ecpg/test/expected/thread-prep_2.stdout
 delete mode 100644 src/interfaces/ecpg/test/expected/thread-thread_2.stdout
 delete mode 100644 src/interfaces/ecpg/test/expected/thread-thread_implicit_2.stdout

diff --git a/configure b/configure
index cf52af6335..2469f858cb 100755
--- a/configure
+++ b/configure
@@ -728,7 +728,6 @@ with_tcl
 ICU_LIBS
 ICU_CFLAGS
 with_icu
-enable_thread_safety
 INCLUDES
 autodepend
 PKG_CONFIG_LIBDIR
@@ -853,7 +852,6 @@ with_CC
 with_llvm
 enable_depend
 enable_cassert
-enable_thread_safety
 with_icu
 with_tcl
 with_tclconfig
@@ -1542,7 +1540,6 @@ Optional Features:
   --enable-tap-tests      enable TAP tests (requires Perl and IPC::Run)
   --enable-depend         turn on automatic dependency tracking
   --enable-cassert        enable assertion checks (for debugging)
-  --disable-thread-safety disable thread-safety in client libraries
   --disable-largefile     omit support for large files
 
 Optional Packages:
@@ -7972,43 +7969,6 @@ $as_echo "$as_me: WARNING: *** Library directory $dir does not exist." >&2;}
 done
 IFS=$ac_save_IFS
 
-#
-# Enable thread-safe client libraries
-#
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking allow thread-safe client libraries" >&5
-$as_echo_n "checking allow thread-safe client libraries... " >&6; }
-
-
-# Check whether --enable-thread-safety was given.
-if test "${enable_thread_safety+set}" = set; then :
-  enableval=$enable_thread_safety;
-  case $enableval in
-    yes)
-      :
-      ;;
-    no)
-      :
-      ;;
-    *)
-      as_fn_error $? "no argument expected for --enable-thread-safety option" "$LINENO" 5
-      ;;
-  esac
-
-else
-  enable_thread_safety=yes
-
-fi
-
-
-if test "$enable_thread_safety" = yes; then
-
-$as_echo "#define ENABLE_THREAD_SAFETY 1" >>confdefs.h
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_thread_safety" >&5
-$as_echo "$enable_thread_safety" >&6; }
-
-
 #
 # ICU
 #
@@ -11087,7 +11047,7 @@ fi
 done
 
 
-if test "$enable_thread_safety" = yes -a "$PORTNAME" != "win32"; then :
+if "$PORTNAME" != "win32"; then :
    # then
 
 
@@ -11746,7 +11706,7 @@ if test "x$ac_cv_header_pthread_h" = xyes; then :
 
 else
   as_fn_error $? "
-pthread.h not found;  use --disable-thread-safety to disable thread safety" "$LINENO" 5
+pthread.h not found" "$LINENO" 5
 fi
 
 
@@ -12430,8 +12390,7 @@ if test "$ac_res" != no; then :
 fi
 
 
-if test "$enable_thread_safety" = yes; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gethostbyname_r" >&5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gethostbyname_r" >&5
 $as_echo_n "checking for library containing gethostbyname_r... " >&6; }
 if ${ac_cv_search_gethostbyname_r+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -12487,7 +12446,7 @@ if test "$ac_res" != no; then :
 
 fi
 
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_barrier_wait" >&5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_barrier_wait" >&5
 $as_echo_n "checking for library containing pthread_barrier_wait... " >&6; }
 if ${ac_cv_search_pthread_barrier_wait+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -12543,7 +12502,6 @@ if test "$ac_res" != no; then :
 
 fi
 
-fi
 
 if test "$with_readline" = yes; then
 
@@ -13416,7 +13374,7 @@ else
   thread_safe_libldap=no
 fi
 
-    if test "$enable_thread_safety" = yes -a "$thread_safe_libldap" = no; then
+    if test "$thread_safe_libldap" = no; then
       # Use ldap_r for FE if available, else assume ldap is thread-safe.
       # On some platforms ldap_r fails to link without PTHREAD_LIBS.
       LIBS="$_LIBS"
@@ -16749,8 +16707,7 @@ fi
 
 
 
-if test "$enable_thread_safety" = yes; then
-  ac_fn_c_check_func "$LINENO" "pthread_barrier_wait" "ac_cv_func_pthread_barrier_wait"
+ac_fn_c_check_func "$LINENO" "pthread_barrier_wait" "ac_cv_func_pthread_barrier_wait"
 if test "x$ac_cv_func_pthread_barrier_wait" = xyes; then :
   $as_echo "#define HAVE_PTHREAD_BARRIER_WAIT 1" >>confdefs.h
 
@@ -16764,7 +16721,6 @@ esac
 fi
 
 
-fi
 
 if test "$PORTNAME" = "win32" -o "$PORTNAME" = "cygwin"; then
 	# Cygwin and (apparently, based on test results) Mingw both
diff --git a/configure.ac b/configure.ac
index 6e9d5342cc..f13d54408f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -788,18 +788,6 @@ for dir in $LIBRARY_DIRS $SRCH_LIB; do
 done
 IFS=$ac_save_IFS
 
-#
-# Enable thread-safe client libraries
-#
-AC_MSG_CHECKING([allow thread-safe client libraries])
-PGAC_ARG_BOOL(enable, thread-safety, yes, [disable thread-safety in client libraries])
-if test "$enable_thread_safety" = yes; then
-  AC_DEFINE([ENABLE_THREAD_SAFETY], 1,
-          [Define to 1 to build client libraries as thread-safe code. (--enable-thread-safety)])
-fi
-AC_MSG_RESULT([$enable_thread_safety])
-AC_SUBST(enable_thread_safety)
-
 #
 # ICU
 #
@@ -1197,7 +1185,7 @@ dnl note: We have to use AS_IF here rather than plain if. The AC_CHECK_HEADER
 dnl invocation below is the first one in the script, and autoconf generates
 dnl additional code for that, which must not be inside the if-block. AS_IF
 dnl knows how to do that.
-AS_IF([test "$enable_thread_safety" = yes -a "$PORTNAME" != "win32"],
+AS_IF(["$PORTNAME" != "win32"],
 [ # then
 AX_PTHREAD	# set thread flags
 
@@ -1212,7 +1200,7 @@ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
 LIBS="$LIBS $PTHREAD_LIBS"
 
 AC_CHECK_HEADER(pthread.h, [], [AC_MSG_ERROR([
-pthread.h not found;  use --disable-thread-safety to disable thread safety])])
+pthread.h not found])])
 
 AC_CHECK_FUNCS([strerror_r gethostbyname_r])
 
@@ -1258,10 +1246,8 @@ AC_SEARCH_LIBS(shmget, cygipc)
 # *BSD:
 AC_SEARCH_LIBS(backtrace_symbols, execinfo)
 
-if test "$enable_thread_safety" = yes; then
-  AC_SEARCH_LIBS(gethostbyname_r, nsl)
-  AC_SEARCH_LIBS(pthread_barrier_wait, pthread)
-fi
+AC_SEARCH_LIBS(gethostbyname_r, nsl)
+AC_SEARCH_LIBS(pthread_barrier_wait, pthread)
 
 if test "$with_readline" = yes; then
   PGAC_CHECK_READLINE
@@ -1386,7 +1372,7 @@ if test "$with_ldap" = yes ; then
     AC_CHECK_FUNC([ldap_verify_credentials],
 		  [thread_safe_libldap=yes],
 		  [thread_safe_libldap=no])
-    if test "$enable_thread_safety" = yes -a "$thread_safe_libldap" = no; then
+    if test "$thread_safe_libldap" = no; then
       # Use ldap_r for FE if available, else assume ldap is thread-safe.
       # On some platforms ldap_r fails to link without PTHREAD_LIBS.
       LIBS="$_LIBS"
@@ -1878,9 +1864,7 @@ AC_REPLACE_FUNCS(m4_normalize([
 	strtof
 ]))
 
-if test "$enable_thread_safety" = yes; then
-  AC_REPLACE_FUNCS(pthread_barrier_wait)
-fi
+AC_REPLACE_FUNCS(pthread_barrier_wait)
 
 if test "$PORTNAME" = "win32" -o "$PORTNAME" = "cygwin"; then
 	# Cygwin and (apparently, based on test results) Mingw both
diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml
index 70d188e2bc..f31e1f9160 100644
--- a/doc/src/sgml/installation.sgml
+++ b/doc/src/sgml/installation.sgml
@@ -1285,19 +1285,6 @@ build-postgresql:
        </listitem>
       </varlistentry>
 
-      <varlistentry>
-       <term><option>--disable-thread-safety</option></term>
-       <listitem>
-        <para>
-         Disable the thread-safety of client libraries.  This prevents
-         concurrent threads in <application>libpq</application> and
-         <application>ECPG</application> programs from safely controlling
-         their private connection handles.  Use this only on platforms
-         with deficient threading support.
-        </para>
-       </listitem>
-      </varlistentry>
-
      </variablelist>
 
    </sect3>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 74456aa69d..655b4db31e 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -8837,7 +8837,8 @@ int PQisthreadsafe();
 
      <para>
       Returns 1 if the <application>libpq</application> is thread-safe
-      and 0 if it is not.
+      and 0 if it is not.  Since <productname>PostgreSQL</productname> version
+      16, this function always returns 1.
      </para>
     </listitem>
    </varlistentry>
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index 14fdd4ef7b..cb35cd9eba 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -202,7 +202,6 @@ enable_debug	= @enable_debug@
 enable_dtrace	= @enable_dtrace@
 enable_coverage	= @enable_coverage@
 enable_tap_tests	= @enable_tap_tests@
-enable_thread_safety	= @enable_thread_safety@
 
 python_includespec	= @python_includespec@
 python_libdir		= @python_libdir@
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 0778656794..5397bcaee6 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -140,7 +140,7 @@ typedef struct socket_set
 	EnterSynchronizationBarrier((barrier), \
 								SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY)
 #define THREAD_BARRIER_DESTROY(barrier)
-#elif defined(ENABLE_THREAD_SAFETY)
+#else
 /* Use POSIX threads */
 #include "port/pg_pthread.h"
 #define THREAD_T pthread_t
@@ -156,16 +156,6 @@ typedef struct socket_set
 	pthread_barrier_init((barrier), NULL, (n))
 #define THREAD_BARRIER_WAIT(barrier) pthread_barrier_wait((barrier))
 #define THREAD_BARRIER_DESTROY(barrier) pthread_barrier_destroy((barrier))
-#else
-/* No threads implementation, use none (-j 1) */
-#define THREAD_T void *
-#define THREAD_FUNC_RETURN_TYPE void *
-#define THREAD_FUNC_RETURN return NULL
-#define THREAD_FUNC_CC
-#define THREAD_BARRIER_T int
-#define THREAD_BARRIER_INIT(barrier, n) (*(barrier) = 0)
-#define THREAD_BARRIER_WAIT(barrier)
-#define THREAD_BARRIER_DESTROY(barrier)
 #endif
 
 
@@ -6680,10 +6670,6 @@ main(int argc, char **argv)
 				{
 					exit(1);
 				}
-#ifndef ENABLE_THREAD_SAFETY
-				if (nthreads != 1)
-					pg_fatal("threads are not supported on this platform; use -j1");
-#endif							/* !ENABLE_THREAD_SAFETY */
 				break;
 			case 'C':
 				benchmarking_option_set = true;
@@ -7197,7 +7183,6 @@ main(int argc, char **argv)
 	if (errno != 0)
 		pg_fatal("could not initialize barrier: %m");
 
-#ifdef ENABLE_THREAD_SAFETY
 	/* start all threads but thread 0 which is executed directly later */
 	for (i = 1; i < nthreads; i++)
 	{
@@ -7209,9 +7194,6 @@ main(int argc, char **argv)
 		if (errno != 0)
 			pg_fatal("could not create thread: %m");
 	}
-#else
-	Assert(nthreads == 1);
-#endif							/* ENABLE_THREAD_SAFETY */
 
 	/* compute when to stop */
 	threads[0].create_time = pg_time_now();
@@ -7229,10 +7211,8 @@ main(int argc, char **argv)
 	{
 		TState	   *thread = &threads[i];
 
-#ifdef ENABLE_THREAD_SAFETY
 		if (i > 0)
 			THREAD_JOIN(thread->thread);
-#endif							/* ENABLE_THREAD_SAFETY */
 
 		for (int j = 0; j < thread->nstate; j++)
 			if (thread->state[j].state != CSTATE_FINISHED)
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 6c8e3fe0a7..3fec48413d 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -51,10 +51,6 @@
 /* Define to 1 if you want National Language Support. (--enable-nls) */
 #undef ENABLE_NLS
 
-/* Define to 1 to build client libraries as thread-safe code.
-   (--enable-thread-safety) */
-#undef ENABLE_THREAD_SAFETY
-
 /* Define to 1 if gettimeofday() takes only 1 argument. */
 #undef GETTIMEOFDAY_1ARG
 
diff --git a/src/interfaces/ecpg/ecpglib/connect.c b/src/interfaces/ecpg/ecpglib/connect.c
index db0bae1fe0..8afb1f0a26 100644
--- a/src/interfaces/ecpg/ecpglib/connect.c
+++ b/src/interfaces/ecpg/ecpglib/connect.c
@@ -14,15 +14,12 @@
 locale_t	ecpg_clocale = (locale_t) 0;
 #endif
 
-#ifdef ENABLE_THREAD_SAFETY
 static pthread_mutex_t connections_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_key_t actual_connection_key;
 static pthread_once_t actual_connection_key_once = PTHREAD_ONCE_INIT;
-#endif
 static struct connection *actual_connection = NULL;
 static struct connection *all_connections = NULL;
 
-#ifdef ENABLE_THREAD_SAFETY
 static void
 ecpg_actual_connection_init(void)
 {
@@ -34,7 +31,6 @@ ecpg_pthreads_init(void)
 {
 	pthread_once(&actual_connection_key_once, ecpg_actual_connection_init);
 }
-#endif
 
 static struct connection *
 ecpg_get_connection_nr(const char *connection_name)
@@ -43,7 +39,6 @@ ecpg_get_connection_nr(const char *connection_name)
 
 	if ((connection_name == NULL) || (strcmp(connection_name, "CURRENT") == 0))
 	{
-#ifdef ENABLE_THREAD_SAFETY
 		ecpg_pthreads_init();	/* ensure actual_connection_key is valid */
 
 		ret = pthread_getspecific(actual_connection_key);
@@ -56,9 +51,6 @@ ecpg_get_connection_nr(const char *connection_name)
 		if (ret == NULL)
 			/* no TSD connection, going for global */
 			ret = actual_connection;
-#else
-		ret = actual_connection;
-#endif
 	}
 	else
 	{
@@ -82,7 +74,6 @@ ecpg_get_connection(const char *connection_name)
 
 	if ((connection_name == NULL) || (strcmp(connection_name, "CURRENT") == 0))
 	{
-#ifdef ENABLE_THREAD_SAFETY
 		ecpg_pthreads_init();	/* ensure actual_connection_key is valid */
 
 		ret = pthread_getspecific(actual_connection_key);
@@ -95,21 +86,14 @@ ecpg_get_connection(const char *connection_name)
 		if (ret == NULL)
 			/* no TSD connection here either, using global */
 			ret = actual_connection;
-#else
-		ret = actual_connection;
-#endif
 	}
 	else
 	{
-#ifdef ENABLE_THREAD_SAFETY
 		pthread_mutex_lock(&connections_mutex);
-#endif
 
 		ret = ecpg_get_connection_nr(connection_name);
 
-#ifdef ENABLE_THREAD_SAFETY
 		pthread_mutex_unlock(&connections_mutex);
-#endif
 	}
 
 	return ret;
@@ -143,10 +127,8 @@ ecpg_finish(struct connection *act)
 				con->next = act->next;
 		}
 
-#ifdef ENABLE_THREAD_SAFETY
 		if (pthread_getspecific(actual_connection_key) == act)
 			pthread_setspecific(actual_connection_key, all_connections);
-#endif
 		if (actual_connection == act)
 			actual_connection = all_connections;
 
@@ -212,11 +194,7 @@ ECPGsetconn(int lineno, const char *connection_name)
 	if (!ecpg_init(con, connection_name, lineno))
 		return false;
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_setspecific(actual_connection_key, con);
-#else
-	actual_connection = con;
-#endif
 	return true;
 }
 
@@ -326,9 +304,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
 	if (dbname == NULL && connection_name == NULL)
 		connection_name = "DEFAULT";
 
-#if ENABLE_THREAD_SAFETY
 	ecpg_pthreads_init();
-#endif
 
 	/* check if the identifier is unique */
 	if (ecpg_get_connection(connection_name))
@@ -505,9 +481,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
 	}
 
 	/* add connection to our list */
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_lock(&connections_mutex);
-#endif
 
 	/*
 	 * ... but first, make certain we have created ecpg_clocale.  Rely on
@@ -519,9 +493,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
 		ecpg_clocale = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
 		if (!ecpg_clocale)
 		{
-#ifdef ENABLE_THREAD_SAFETY
 			pthread_mutex_unlock(&connections_mutex);
-#endif
 			ecpg_raise(lineno, ECPG_OUT_OF_MEMORY,
 					   ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
 			if (host)
@@ -558,9 +530,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
 		this->next = all_connections;
 
 	all_connections = this;
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_setspecific(actual_connection_key, all_connections);
-#endif
 	actual_connection = all_connections;
 
 	ecpg_log("ECPGconnect: opening database %s on %s port %s %s%s %s%s\n",
@@ -678,9 +648,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
 		ecpg_log("ECPGconnect: %s", errmsg);
 
 		ecpg_finish(this);
-#ifdef ENABLE_THREAD_SAFETY
 		pthread_mutex_unlock(&connections_mutex);
-#endif
 
 		ecpg_raise(lineno, ECPG_CONNECT, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, db);
 		if (realname)
@@ -692,9 +660,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
 	if (realname)
 		ecpg_free(realname);
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_unlock(&connections_mutex);
-#endif
 
 	this->autocommit = autocommit;
 
@@ -716,9 +682,7 @@ ECPGdisconnect(int lineno, const char *connection_name)
 		return false;
 	}
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_lock(&connections_mutex);
-#endif
 
 	if (strcmp(connection_name, "ALL") == 0)
 	{
@@ -737,18 +701,14 @@ ECPGdisconnect(int lineno, const char *connection_name)
 
 		if (!ecpg_init(con, connection_name, lineno))
 		{
-#ifdef ENABLE_THREAD_SAFETY
 			pthread_mutex_unlock(&connections_mutex);
-#endif
 			return false;
 		}
 		else
 			ecpg_finish(con);
 	}
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_unlock(&connections_mutex);
-#endif
 
 	return true;
 }
diff --git a/src/interfaces/ecpg/ecpglib/descriptor.c b/src/interfaces/ecpg/ecpglib/descriptor.c
index 649a71c286..b47f422d92 100644
--- a/src/interfaces/ecpg/ecpglib/descriptor.c
+++ b/src/interfaces/ecpg/ecpglib/descriptor.c
@@ -19,7 +19,6 @@
 static void descriptor_free(struct descriptor *desc);
 
 /* We manage descriptors separately for each thread. */
-#ifdef ENABLE_THREAD_SAFETY
 static pthread_key_t descriptor_key;
 static pthread_once_t descriptor_once = PTHREAD_ONCE_INIT;
 
@@ -49,12 +48,6 @@ set_descriptors(struct descriptor *value)
 {
 	pthread_setspecific(descriptor_key, value);
 }
-#else
-static struct descriptor *all_descriptors = NULL;
-
-#define get_descriptors()		(all_descriptors)
-#define set_descriptors(value)	do { all_descriptors = (value); } while(0)
-#endif
 
 /* old internal convenience function that might go away later */
 static PGresult *
@@ -782,7 +775,6 @@ ECPGdeallocate_desc(int line, const char *name)
 	return false;
 }
 
-#ifdef ENABLE_THREAD_SAFETY
 
 /* Deallocate all descriptors in the list */
 static void
@@ -796,7 +788,6 @@ descriptor_deallocate_all(struct descriptor *list)
 		list = next;
 	}
 }
-#endif							/* ENABLE_THREAD_SAFETY */
 
 bool
 ECPGallocate_desc(int line, const char *name)
diff --git a/src/interfaces/ecpg/ecpglib/ecpglib_extern.h b/src/interfaces/ecpg/ecpglib/ecpglib_extern.h
index c438cfb820..968f1211b8 100644
--- a/src/interfaces/ecpg/ecpglib/ecpglib_extern.h
+++ b/src/interfaces/ecpg/ecpglib/ecpglib_extern.h
@@ -169,9 +169,7 @@ bool		ecpg_get_data(const PGresult *, int, int, int, enum ECPGttype type,
 						  enum ECPGttype, char *, char *, long, long, long,
 						  enum ARRAY_TYPE, enum COMPAT_MODE, bool);
 
-#ifdef ENABLE_THREAD_SAFETY
 void		ecpg_pthreads_init(void);
-#endif
 struct connection *ecpg_get_connection(const char *);
 char	   *ecpg_alloc(long, int);
 char	   *ecpg_auto_alloc(long, int);
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index bd94bd4e6c..0b2716d921 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1961,9 +1961,7 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator,
 		return false;
 	}
 
-#ifdef ENABLE_THREAD_SAFETY
 	ecpg_pthreads_init();
-#endif
 
 	con = ecpg_get_connection(connection_name);
 
diff --git a/src/interfaces/ecpg/ecpglib/memory.c b/src/interfaces/ecpg/ecpglib/memory.c
index bd81251054..a83637ac75 100644
--- a/src/interfaces/ecpg/ecpglib/memory.c
+++ b/src/interfaces/ecpg/ecpglib/memory.c
@@ -68,7 +68,6 @@ struct auto_mem
 	struct auto_mem *next;
 };
 
-#ifdef ENABLE_THREAD_SAFETY
 static pthread_key_t auto_mem_key;
 static pthread_once_t auto_mem_once = PTHREAD_ONCE_INIT;
 
@@ -97,12 +96,6 @@ set_auto_allocs(struct auto_mem *am)
 {
 	pthread_setspecific(auto_mem_key, am);
 }
-#else
-static struct auto_mem *auto_allocs = NULL;
-
-#define get_auto_allocs()		(auto_allocs)
-#define set_auto_allocs(am)		do { auto_allocs = (am); } while(0)
-#endif
 
 char *
 ecpg_auto_alloc(long size, int lineno)
diff --git a/src/interfaces/ecpg/ecpglib/misc.c b/src/interfaces/ecpg/ecpglib/misc.c
index 1eef1ec044..71f07c4e4f 100644
--- a/src/interfaces/ecpg/ecpglib/misc.c
+++ b/src/interfaces/ecpg/ecpglib/misc.c
@@ -55,42 +55,11 @@ static struct sqlca_t sqlca_init =
 	}
 };
 
-#ifdef ENABLE_THREAD_SAFETY
 static pthread_key_t sqlca_key;
 static pthread_once_t sqlca_key_once = PTHREAD_ONCE_INIT;
-#else
-static struct sqlca_t sqlca =
-{
-	{
-		'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '
-	},
-	sizeof(struct sqlca_t),
-	0,
-	{
-		0,
-		{
-			0
-		}
-	},
-	{
-		'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '
-	},
-	{
-		0, 0, 0, 0, 0, 0
-	},
-	{
-		0, 0, 0, 0, 0, 0, 0, 0
-	},
-	{
-		'0', '0', '0', '0', '0'
-	}
-};
-#endif
 
-#ifdef ENABLE_THREAD_SAFETY
 static pthread_mutex_t debug_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t debug_init_mutex = PTHREAD_MUTEX_INITIALIZER;
-#endif
 static int	simple_debug = 0;
 static FILE *debugstream = NULL;
 
@@ -123,7 +92,6 @@ ecpg_init(const struct connection *con, const char *connection_name, const int l
 	return true;
 }
 
-#ifdef ENABLE_THREAD_SAFETY
 static void
 ecpg_sqlca_key_destructor(void *arg)
 {
@@ -135,12 +103,10 @@ ecpg_sqlca_key_init(void)
 {
 	pthread_key_create(&sqlca_key, ecpg_sqlca_key_destructor);
 }
-#endif
 
 struct sqlca_t *
 ECPGget_sqlca(void)
 {
-#ifdef ENABLE_THREAD_SAFETY
 	struct sqlca_t *sqlca;
 
 	pthread_once(&sqlca_key_once, ecpg_sqlca_key_init);
@@ -155,9 +121,6 @@ ECPGget_sqlca(void)
 		pthread_setspecific(sqlca_key, sqlca);
 	}
 	return sqlca;
-#else
-	return &sqlca;
-#endif
 }
 
 bool
@@ -240,9 +203,7 @@ ECPGtrans(int lineno, const char *connection_name, const char *transaction)
 void
 ECPGdebug(int n, FILE *dbgs)
 {
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_lock(&debug_init_mutex);
-#endif
 
 	if (n > 100)
 	{
@@ -256,9 +217,7 @@ ECPGdebug(int n, FILE *dbgs)
 
 	ecpg_log("ECPGdebug: set to %d\n", simple_debug);
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_unlock(&debug_init_mutex);
-#endif
 }
 
 void
@@ -290,9 +249,7 @@ ecpg_log(const char *format,...)
 	else
 		snprintf(fmt, bufsize, "[%d]: %s", (int) getpid(), intl_format);
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_lock(&debug_mutex);
-#endif
 
 	va_start(ap, format);
 	vfprintf(debugstream, fmt, ap);
@@ -307,9 +264,7 @@ ecpg_log(const char *format,...)
 
 	fflush(debugstream);
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_unlock(&debug_mutex);
-#endif
 
 	free(fmt);
 }
@@ -451,7 +406,6 @@ ECPGis_noind_null(enum ECPGttype type, const void *ptr)
 }
 
 #ifdef WIN32
-#ifdef ENABLE_THREAD_SAFETY
 
 void
 win32_pthread_mutex(volatile pthread_mutex_t *mutex)
@@ -482,7 +436,6 @@ win32_pthread_once(volatile pthread_once_t *once, void (*fn) (void))
 		pthread_mutex_unlock(&win32_pthread_once_lock);
 	}
 }
-#endif							/* ENABLE_THREAD_SAFETY */
 #endif							/* WIN32 */
 
 #ifdef ENABLE_NLS
diff --git a/src/interfaces/ecpg/include/ecpg-pthread-win32.h b/src/interfaces/ecpg/include/ecpg-pthread-win32.h
index 33c897b633..8252a17809 100644
--- a/src/interfaces/ecpg/include/ecpg-pthread-win32.h
+++ b/src/interfaces/ecpg/include/ecpg-pthread-win32.h
@@ -5,8 +5,6 @@
 #ifndef _ECPG_PTHREAD_WIN32_H
 #define _ECPG_PTHREAD_WIN32_H
 
-#ifdef ENABLE_THREAD_SAFETY
-
 #ifndef WIN32
 
 #include <pthread.h>
@@ -53,6 +51,5 @@ void		win32_pthread_once(volatile pthread_once_t *once, void (*fn) (void));
 			win32_pthread_once((once), (fn)); \
 	} while(0)
 #endif							/* WIN32 */
-#endif							/* ENABLE_THREAD_SAFETY */
 
 #endif							/* _ECPG_PTHREAD_WIN32_H */
diff --git a/src/interfaces/ecpg/include/ecpg_config.h.in b/src/interfaces/ecpg/include/ecpg_config.h.in
index cbd24f11a0..6d01608a49 100644
--- a/src/interfaces/ecpg/include/ecpg_config.h.in
+++ b/src/interfaces/ecpg/include/ecpg_config.h.in
@@ -1,7 +1,3 @@
-/* Define to 1 to build client libraries as thread-safe code.
- *    (--enable-thread-safety) */
-#undef ENABLE_THREAD_SAFETY
-
 /* Define to 1 if the system has the type `int64'. */
 #undef HAVE_INT64
 
diff --git a/src/interfaces/ecpg/include/ecpglib.h b/src/interfaces/ecpg/include/ecpglib.h
index 00240109a6..05433726ac 100644
--- a/src/interfaces/ecpg/include/ecpglib.h
+++ b/src/interfaces/ecpg/include/ecpglib.h
@@ -92,9 +92,7 @@ void	   *ECPGget_var(int number);
 /* dynamic result allocation */
 void		ECPGfree_auto_mem(void);
 
-#ifdef ENABLE_THREAD_SAFETY
 void		ecpg_pthreads_init(void);
-#endif
 
 #ifdef __cplusplus
 }
diff --git a/src/interfaces/ecpg/test/expected/thread-alloc.c b/src/interfaces/ecpg/test/expected/thread-alloc.c
index 37ef44ed94..3b31d27fd3 100644
--- a/src/interfaces/ecpg/test/expected/thread-alloc.c
+++ b/src/interfaces/ecpg/test/expected/thread-alloc.c
@@ -11,14 +11,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifdef WIN32
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
@@ -101,7 +93,7 @@ struct sqlca_t *ECPGget_sqlca(void);
 
 #endif
 
-#line 26 "alloc.pgc"
+#line 18 "alloc.pgc"
 
 
 #line 1 "regression.h"
@@ -111,14 +103,14 @@ struct sqlca_t *ECPGget_sqlca(void);
 
 
 
-#line 27 "alloc.pgc"
+#line 19 "alloc.pgc"
 
 
 /* exec sql whenever sqlerror  sqlprint ; */
-#line 29 "alloc.pgc"
+#line 21 "alloc.pgc"
 
 /* exec sql whenever not found  sqlprint ; */
-#line 30 "alloc.pgc"
+#line 22 "alloc.pgc"
 
 
 #ifdef WIN32
@@ -134,54 +126,54 @@ static void* fn(void* arg)
 	 
 	   
 	
-#line 41 "alloc.pgc"
+#line 33 "alloc.pgc"
  int value ;
  
-#line 42 "alloc.pgc"
+#line 34 "alloc.pgc"
  char name [ 100 ] ;
  
-#line 43 "alloc.pgc"
+#line 35 "alloc.pgc"
  char ** r = NULL ;
 /* exec sql end declare section */
-#line 44 "alloc.pgc"
+#line 36 "alloc.pgc"
 
 
 	value = (intptr_t) arg;
 	sprintf(name, "Connection: %d", value);
 
 	{ ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , name, 0); 
-#line 49 "alloc.pgc"
+#line 41 "alloc.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 49 "alloc.pgc"
+#line 41 "alloc.pgc"
 
 	{ ECPGsetcommit(__LINE__, "on", NULL);
-#line 50 "alloc.pgc"
+#line 42 "alloc.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 50 "alloc.pgc"
+#line 42 "alloc.pgc"
 
 	for (i = 1; i <= REPEATS; ++i)
 	{
 		{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select relname from pg_class where relname = 'pg_class'", ECPGt_EOIT, 
 	ECPGt_char,&(r),(long)0,(long)0,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
-#line 53 "alloc.pgc"
+#line 45 "alloc.pgc"
 
 if (sqlca.sqlcode == ECPG_NOT_FOUND) sqlprint();
-#line 53 "alloc.pgc"
+#line 45 "alloc.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 53 "alloc.pgc"
+#line 45 "alloc.pgc"
 
 		free(r);
 		r = NULL;
 	}
 	{ ECPGdisconnect(__LINE__, name);
-#line 57 "alloc.pgc"
+#line 49 "alloc.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 57 "alloc.pgc"
+#line 49 "alloc.pgc"
 
 
 	return 0;
@@ -215,4 +207,3 @@ int main ()
 
 	return 0;
 }
-#endif
diff --git a/src/interfaces/ecpg/test/expected/thread-alloc_2.stdout b/src/interfaces/ecpg/test/expected/thread-alloc_2.stdout
deleted file mode 100644
index 75fe16bb36..0000000000
--- a/src/interfaces/ecpg/test/expected/thread-alloc_2.stdout
+++ /dev/null
@@ -1 +0,0 @@
-No threading enabled.
diff --git a/src/interfaces/ecpg/test/expected/thread-descriptor.c b/src/interfaces/ecpg/test/expected/thread-descriptor.c
index f56cc25ab0..e34f4708d1 100644
--- a/src/interfaces/ecpg/test/expected/thread-descriptor.c
+++ b/src/interfaces/ecpg/test/expected/thread-descriptor.c
@@ -7,7 +7,6 @@
 #define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y))
 
 #line 1 "descriptor.pgc"
-#ifdef ENABLE_THREAD_SAFETY
 #ifdef WIN32
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
@@ -16,7 +15,6 @@
 #else
 #include <pthread.h>
 #endif
-#endif
 #include <stdio.h>
 
 #define THREADS		16
@@ -91,16 +89,16 @@ struct sqlca_t *ECPGget_sqlca(void);
 
 #endif
 
-#line 16 "descriptor.pgc"
+#line 14 "descriptor.pgc"
 
 /* exec sql whenever sqlerror  sqlprint ; */
-#line 17 "descriptor.pgc"
+#line 15 "descriptor.pgc"
 
 /* exec sql whenever not found  sqlprint ; */
-#line 18 "descriptor.pgc"
+#line 16 "descriptor.pgc"
 
 
-#if defined(ENABLE_THREAD_SAFETY) && defined(WIN32)
+#if defined(WIN32)
 static unsigned __stdcall fn(void* arg)
 #else
 static void* fn(void* arg)
@@ -111,16 +109,16 @@ static void* fn(void* arg)
 	for (i = 1; i <= REPEATS; ++i)
 	{
 		ECPGallocate_desc(__LINE__, "mydesc");
-#line 30 "descriptor.pgc"
+#line 28 "descriptor.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();
-#line 30 "descriptor.pgc"
+#line 28 "descriptor.pgc"
 
 		ECPGdeallocate_desc(__LINE__, "mydesc");
-#line 31 "descriptor.pgc"
+#line 29 "descriptor.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();
-#line 31 "descriptor.pgc"
+#line 29 "descriptor.pgc"
 
 	}
 
@@ -129,7 +127,6 @@ if (sqlca.sqlcode < 0) sqlprint();
 
 int main ()
 {
-#ifdef ENABLE_THREAD_SAFETY
 	int i;
 #ifdef WIN32
 	HANDLE threads[THREADS];
@@ -153,9 +150,6 @@ int main ()
 	for (i = 0; i < THREADS; ++i)
 		pthread_join(threads[i], NULL);
 #endif
-#else
-	fn(NULL);
-#endif
 
 	return 0;
 }
diff --git a/src/interfaces/ecpg/test/expected/thread-prep.c b/src/interfaces/ecpg/test/expected/thread-prep.c
index 7cdf2505d3..052e27b634 100644
--- a/src/interfaces/ecpg/test/expected/thread-prep.c
+++ b/src/interfaces/ecpg/test/expected/thread-prep.c
@@ -11,14 +11,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifdef WIN32
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
@@ -101,7 +93,7 @@ struct sqlca_t *ECPGget_sqlca(void);
 
 #endif
 
-#line 26 "prep.pgc"
+#line 18 "prep.pgc"
 
 
 #line 1 "regression.h"
@@ -111,14 +103,14 @@ struct sqlca_t *ECPGget_sqlca(void);
 
 
 
-#line 27 "prep.pgc"
+#line 19 "prep.pgc"
 
 
 /* exec sql whenever sqlerror  sqlprint ; */
-#line 29 "prep.pgc"
+#line 21 "prep.pgc"
 
 /* exec sql whenever not found  sqlprint ; */
-#line 30 "prep.pgc"
+#line 22 "prep.pgc"
 
 
 #ifdef WIN32
@@ -134,64 +126,64 @@ static void* fn(void* arg)
 	 
 	   
 	
-#line 41 "prep.pgc"
+#line 33 "prep.pgc"
  int value ;
  
-#line 42 "prep.pgc"
+#line 34 "prep.pgc"
  char name [ 100 ] ;
  
-#line 43 "prep.pgc"
+#line 35 "prep.pgc"
  char query [ 256 ] = "INSERT INTO T VALUES ( ? )" ;
 /* exec sql end declare section */
-#line 44 "prep.pgc"
+#line 36 "prep.pgc"
 
 
 	value = (intptr_t) arg;
 	sprintf(name, "Connection: %d", value);
 
 	{ ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , name, 0); 
-#line 49 "prep.pgc"
+#line 41 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 49 "prep.pgc"
+#line 41 "prep.pgc"
 
 	{ ECPGsetcommit(__LINE__, "on", NULL);
-#line 50 "prep.pgc"
+#line 42 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 50 "prep.pgc"
+#line 42 "prep.pgc"
 
 	for (i = 1; i <= REPEATS; ++i)
 	{
 		{ ECPGprepare(__LINE__, NULL, 0, "i", query);
-#line 53 "prep.pgc"
+#line 45 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 53 "prep.pgc"
+#line 45 "prep.pgc"
 
 		{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_execute, "i", 
 	ECPGt_int,&(value),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
-#line 54 "prep.pgc"
+#line 46 "prep.pgc"
 
 if (sqlca.sqlcode == ECPG_NOT_FOUND) sqlprint();
-#line 54 "prep.pgc"
+#line 46 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 54 "prep.pgc"
+#line 46 "prep.pgc"
 
 	}
 	{ ECPGdeallocate(__LINE__, 0, NULL, "i");
-#line 56 "prep.pgc"
+#line 48 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 56 "prep.pgc"
+#line 48 "prep.pgc"
 
 	{ ECPGdisconnect(__LINE__, name);
-#line 57 "prep.pgc"
+#line 49 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 57 "prep.pgc"
+#line 49 "prep.pgc"
 
 
 	return 0;
@@ -207,34 +199,34 @@ int main ()
 #endif
 
 	{ ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0); 
-#line 71 "prep.pgc"
+#line 63 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 71 "prep.pgc"
+#line 63 "prep.pgc"
 
 	{ ECPGsetcommit(__LINE__, "on", NULL);
-#line 72 "prep.pgc"
+#line 64 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 72 "prep.pgc"
+#line 64 "prep.pgc"
 
 	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table if exists T", ECPGt_EOIT, ECPGt_EORT);
-#line 73 "prep.pgc"
+#line 65 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 73 "prep.pgc"
+#line 65 "prep.pgc"
 
 	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table T ( i int )", ECPGt_EOIT, ECPGt_EORT);
-#line 74 "prep.pgc"
+#line 66 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 74 "prep.pgc"
+#line 66 "prep.pgc"
 
 	{ ECPGdisconnect(__LINE__, "CURRENT");
-#line 75 "prep.pgc"
+#line 67 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 75 "prep.pgc"
+#line 67 "prep.pgc"
 
 
 #ifdef WIN32
@@ -256,4 +248,3 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	return 0;
 }
-#endif
diff --git a/src/interfaces/ecpg/test/expected/thread-prep.stdout b/src/interfaces/ecpg/test/expected/thread-prep.stdout
index 75fe16bb36..e69de29bb2 100644
--- a/src/interfaces/ecpg/test/expected/thread-prep.stdout
+++ b/src/interfaces/ecpg/test/expected/thread-prep.stdout
@@ -1 +0,0 @@
-No threading enabled.
diff --git a/src/interfaces/ecpg/test/expected/thread-prep_2.stdout b/src/interfaces/ecpg/test/expected/thread-prep_2.stdout
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/src/interfaces/ecpg/test/expected/thread-thread.c b/src/interfaces/ecpg/test/expected/thread-thread.c
index 0e75c47fab..95faa223c2 100644
--- a/src/interfaces/ecpg/test/expected/thread-thread.c
+++ b/src/interfaces/ecpg/test/expected/thread-thread.c
@@ -15,14 +15,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifndef WIN32
 #include <pthread.h>
 #else
@@ -38,7 +30,7 @@ main(void)
 
 
 
-#line 24 "thread.pgc"
+#line 16 "thread.pgc"
 
 
 void *test_thread(void *arg);
@@ -57,10 +49,10 @@ int main()
   /* exec sql begin declare section */
    
   
-#line 40 "thread.pgc"
+#line 32 "thread.pgc"
  int l_rows ;
 /* exec sql end declare section */
-#line 41 "thread.pgc"
+#line 33 "thread.pgc"
 
 
  /* Do not switch on debug output for regression tests. The threads get executed in
@@ -69,22 +61,22 @@ int main()
 
   /* setup test_thread table */
   { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0); }
-#line 48 "thread.pgc"
+#line 40 "thread.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table test_thread", ECPGt_EOIT, ECPGt_EORT);}
-#line 49 "thread.pgc"
+#line 41 "thread.pgc"
  /* DROP might fail */
   { ECPGtrans(__LINE__, NULL, "commit");}
-#line 50 "thread.pgc"
+#line 42 "thread.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table test_thread ( tstamp timestamp not null default cast ( timeofday ( ) as timestamp ) , thread text not null , iteration integer not null , primary key ( thread , iteration ) )", ECPGt_EOIT, ECPGt_EORT);}
-#line 55 "thread.pgc"
+#line 47 "thread.pgc"
 
   { ECPGtrans(__LINE__, NULL, "commit");}
-#line 56 "thread.pgc"
+#line 48 "thread.pgc"
 
   { ECPGdisconnect(__LINE__, "CURRENT");}
-#line 57 "thread.pgc"
+#line 49 "thread.pgc"
 
 
   /* create, and start, threads */
@@ -116,18 +108,18 @@ int main()
 
   /* and check results */
   { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0); }
-#line 87 "thread.pgc"
+#line 79 "thread.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count ( * ) from test_thread", ECPGt_EOIT, 
 	ECPGt_int,&(l_rows),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
-#line 88 "thread.pgc"
+#line 80 "thread.pgc"
 
   { ECPGtrans(__LINE__, NULL, "commit");}
-#line 89 "thread.pgc"
+#line 81 "thread.pgc"
 
   { ECPGdisconnect(__LINE__, "CURRENT");}
-#line 90 "thread.pgc"
+#line 82 "thread.pgc"
 
   if( l_rows == (nthreads * iterations) )
     printf("Success.\n");
@@ -145,13 +137,13 @@ void *test_thread(void *arg)
     
    
   
-#line 104 "thread.pgc"
+#line 96 "thread.pgc"
  int l_i ;
  
-#line 105 "thread.pgc"
+#line 97 "thread.pgc"
  char l_connection [ 128 ] ;
 /* exec sql end declare section */
-#line 106 "thread.pgc"
+#line 98 "thread.pgc"
 
 
   /* build up connection name, and connect to database */
@@ -161,13 +153,13 @@ void *test_thread(void *arg)
   _snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum);
 #endif
   /* exec sql whenever sqlerror  sqlprint ; */
-#line 114 "thread.pgc"
+#line 106 "thread.pgc"
 
   { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , l_connection, 0); 
-#line 115 "thread.pgc"
+#line 107 "thread.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 115 "thread.pgc"
+#line 107 "thread.pgc"
 
   if( sqlca.sqlcode != 0 )
     {
@@ -175,10 +167,10 @@ if (sqlca.sqlcode < 0) sqlprint();}
       return NULL;
     }
   { ECPGtrans(__LINE__, l_connection, "begin");
-#line 121 "thread.pgc"
+#line 113 "thread.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 121 "thread.pgc"
+#line 113 "thread.pgc"
 
 
   /* insert into test_thread table */
@@ -189,10 +181,10 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_int,&(l_i),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
-#line 126 "thread.pgc"
+#line 118 "thread.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 126 "thread.pgc"
+#line 118 "thread.pgc"
 
       if( sqlca.sqlcode != 0 )
 	printf("%s: ERROR: insert failed!\n", l_connection);
@@ -200,17 +192,16 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
   /* all done */
   { ECPGtrans(__LINE__, l_connection, "commit");
-#line 132 "thread.pgc"
+#line 124 "thread.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 132 "thread.pgc"
+#line 124 "thread.pgc"
 
   { ECPGdisconnect(__LINE__, l_connection);
-#line 133 "thread.pgc"
+#line 125 "thread.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 133 "thread.pgc"
+#line 125 "thread.pgc"
 
   return NULL;
 }
-#endif /* ENABLE_THREAD_SAFETY */
diff --git a/src/interfaces/ecpg/test/expected/thread-thread.stdout b/src/interfaces/ecpg/test/expected/thread-thread.stdout
index 75fe16bb36..a9d787cc55 100644
--- a/src/interfaces/ecpg/test/expected/thread-thread.stdout
+++ b/src/interfaces/ecpg/test/expected/thread-thread.stdout
@@ -1 +1 @@
-No threading enabled.
+Success.
diff --git a/src/interfaces/ecpg/test/expected/thread-thread_2.stdout b/src/interfaces/ecpg/test/expected/thread-thread_2.stdout
deleted file mode 100644
index a9d787cc55..0000000000
--- a/src/interfaces/ecpg/test/expected/thread-thread_2.stdout
+++ /dev/null
@@ -1 +0,0 @@
-Success.
diff --git a/src/interfaces/ecpg/test/expected/thread-thread_implicit.c b/src/interfaces/ecpg/test/expected/thread-thread_implicit.c
index 0df2794530..7ac0297a23 100644
--- a/src/interfaces/ecpg/test/expected/thread-thread_implicit.c
+++ b/src/interfaces/ecpg/test/expected/thread-thread_implicit.c
@@ -15,14 +15,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifndef WIN32
 #include <pthread.h>
 #else
@@ -38,7 +30,7 @@ main(void)
 
 
 
-#line 24 "thread_implicit.pgc"
+#line 16 "thread_implicit.pgc"
 
 
 void *test_thread(void *arg);
@@ -57,10 +49,10 @@ int main()
   /* exec sql begin declare section */
    
   
-#line 40 "thread_implicit.pgc"
+#line 32 "thread_implicit.pgc"
  int l_rows ;
 /* exec sql end declare section */
-#line 41 "thread_implicit.pgc"
+#line 33 "thread_implicit.pgc"
 
 
  /* Do not switch on debug output for regression tests. The threads get executed in
@@ -69,22 +61,22 @@ int main()
 
   /* setup test_thread table */
   { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0); }
-#line 48 "thread_implicit.pgc"
+#line 40 "thread_implicit.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table test_thread", ECPGt_EOIT, ECPGt_EORT);}
-#line 49 "thread_implicit.pgc"
+#line 41 "thread_implicit.pgc"
  /* DROP might fail */
   { ECPGtrans(__LINE__, NULL, "commit");}
-#line 50 "thread_implicit.pgc"
+#line 42 "thread_implicit.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table test_thread ( tstamp timestamp not null default cast ( timeofday ( ) as timestamp ) , thread text not null , iteration integer not null , primary key ( thread , iteration ) )", ECPGt_EOIT, ECPGt_EORT);}
-#line 55 "thread_implicit.pgc"
+#line 47 "thread_implicit.pgc"
 
   { ECPGtrans(__LINE__, NULL, "commit");}
-#line 56 "thread_implicit.pgc"
+#line 48 "thread_implicit.pgc"
 
   { ECPGdisconnect(__LINE__, "CURRENT");}
-#line 57 "thread_implicit.pgc"
+#line 49 "thread_implicit.pgc"
 
 
   /* create, and start, threads */
@@ -116,18 +108,18 @@ int main()
 
   /* and check results */
   { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0); }
-#line 87 "thread_implicit.pgc"
+#line 79 "thread_implicit.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count ( * ) from test_thread", ECPGt_EOIT, 
 	ECPGt_int,&(l_rows),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
-#line 88 "thread_implicit.pgc"
+#line 80 "thread_implicit.pgc"
 
   { ECPGtrans(__LINE__, NULL, "commit");}
-#line 89 "thread_implicit.pgc"
+#line 81 "thread_implicit.pgc"
 
   { ECPGdisconnect(__LINE__, "CURRENT");}
-#line 90 "thread_implicit.pgc"
+#line 82 "thread_implicit.pgc"
 
   if( l_rows == (nthreads * iterations) )
     printf("Success.\n");
@@ -145,13 +137,13 @@ void *test_thread(void *arg)
     
    
   
-#line 104 "thread_implicit.pgc"
+#line 96 "thread_implicit.pgc"
  int l_i ;
  
-#line 105 "thread_implicit.pgc"
+#line 97 "thread_implicit.pgc"
  char l_connection [ 128 ] ;
 /* exec sql end declare section */
-#line 106 "thread_implicit.pgc"
+#line 98 "thread_implicit.pgc"
 
 
   /* build up connection name, and connect to database */
@@ -161,13 +153,13 @@ void *test_thread(void *arg)
   _snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum);
 #endif
   /* exec sql whenever sqlerror  sqlprint ; */
-#line 114 "thread_implicit.pgc"
+#line 106 "thread_implicit.pgc"
 
   { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , l_connection, 0); 
-#line 115 "thread_implicit.pgc"
+#line 107 "thread_implicit.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 115 "thread_implicit.pgc"
+#line 107 "thread_implicit.pgc"
 
   if( sqlca.sqlcode != 0 )
     {
@@ -175,10 +167,10 @@ if (sqlca.sqlcode < 0) sqlprint();}
       return NULL;
     }
   { ECPGtrans(__LINE__, NULL, "begin");
-#line 121 "thread_implicit.pgc"
+#line 113 "thread_implicit.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 121 "thread_implicit.pgc"
+#line 113 "thread_implicit.pgc"
 
 
   /* insert into test_thread table */
@@ -189,10 +181,10 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_int,&(l_i),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
-#line 126 "thread_implicit.pgc"
+#line 118 "thread_implicit.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 126 "thread_implicit.pgc"
+#line 118 "thread_implicit.pgc"
 
       if( sqlca.sqlcode != 0 )
 	printf("%s: ERROR: insert failed!\n", l_connection);
@@ -200,17 +192,16 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
   /* all done */
   { ECPGtrans(__LINE__, NULL, "commit");
-#line 132 "thread_implicit.pgc"
+#line 124 "thread_implicit.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 132 "thread_implicit.pgc"
+#line 124 "thread_implicit.pgc"
 
   { ECPGdisconnect(__LINE__, l_connection);
-#line 133 "thread_implicit.pgc"
+#line 125 "thread_implicit.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 133 "thread_implicit.pgc"
+#line 125 "thread_implicit.pgc"
 
   return NULL;
 }
-#endif /* ENABLE_THREAD_SAFETY */
diff --git a/src/interfaces/ecpg/test/expected/thread-thread_implicit.stdout b/src/interfaces/ecpg/test/expected/thread-thread_implicit.stdout
index 75fe16bb36..a9d787cc55 100644
--- a/src/interfaces/ecpg/test/expected/thread-thread_implicit.stdout
+++ b/src/interfaces/ecpg/test/expected/thread-thread_implicit.stdout
@@ -1 +1 @@
-No threading enabled.
+Success.
diff --git a/src/interfaces/ecpg/test/expected/thread-thread_implicit_2.stdout b/src/interfaces/ecpg/test/expected/thread-thread_implicit_2.stdout
deleted file mode 100644
index a9d787cc55..0000000000
--- a/src/interfaces/ecpg/test/expected/thread-thread_implicit_2.stdout
+++ /dev/null
@@ -1 +0,0 @@
-Success.
diff --git a/src/interfaces/ecpg/test/thread/alloc.pgc b/src/interfaces/ecpg/test/thread/alloc.pgc
index c0021a737e..d3d35493bf 100644
--- a/src/interfaces/ecpg/test/thread/alloc.pgc
+++ b/src/interfaces/ecpg/test/thread/alloc.pgc
@@ -2,14 +2,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifdef WIN32
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
@@ -87,4 +79,3 @@ int main ()
 
 	return 0;
 }
-#endif
diff --git a/src/interfaces/ecpg/test/thread/descriptor.pgc b/src/interfaces/ecpg/test/thread/descriptor.pgc
index 76a7a5dff5..30bce7c87b 100644
--- a/src/interfaces/ecpg/test/thread/descriptor.pgc
+++ b/src/interfaces/ecpg/test/thread/descriptor.pgc
@@ -1,4 +1,3 @@
-#ifdef ENABLE_THREAD_SAFETY
 #ifdef WIN32
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
@@ -7,7 +6,6 @@
 #else
 #include <pthread.h>
 #endif
-#endif
 #include <stdio.h>
 
 #define THREADS		16
@@ -17,7 +15,7 @@ EXEC SQL include sqlca;
 EXEC SQL whenever sqlerror sqlprint;
 EXEC SQL whenever not found sqlprint;
 
-#if defined(ENABLE_THREAD_SAFETY) && defined(WIN32)
+#if defined(WIN32)
 static unsigned __stdcall fn(void* arg)
 #else
 static void* fn(void* arg)
@@ -36,7 +34,6 @@ static void* fn(void* arg)
 
 int main ()
 {
-#ifdef ENABLE_THREAD_SAFETY
 	int i;
 #ifdef WIN32
 	HANDLE threads[THREADS];
@@ -60,9 +57,6 @@ int main ()
 	for (i = 0; i < THREADS; ++i)
 		pthread_join(threads[i], NULL);
 #endif
-#else
-	fn(NULL);
-#endif
 
 	return 0;
 }
diff --git a/src/interfaces/ecpg/test/thread/prep.pgc b/src/interfaces/ecpg/test/thread/prep.pgc
index d7ecfd4855..f61b31ce10 100644
--- a/src/interfaces/ecpg/test/thread/prep.pgc
+++ b/src/interfaces/ecpg/test/thread/prep.pgc
@@ -2,14 +2,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifdef WIN32
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
@@ -93,4 +85,3 @@ int main ()
 
 	return 0;
 }
-#endif
diff --git a/src/interfaces/ecpg/test/thread/thread.pgc b/src/interfaces/ecpg/test/thread/thread.pgc
index e7d8c00af6..b9b9ebb441 100644
--- a/src/interfaces/ecpg/test/thread/thread.pgc
+++ b/src/interfaces/ecpg/test/thread/thread.pgc
@@ -6,14 +6,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifndef WIN32
 #include <pthread.h>
 #else
@@ -133,4 +125,3 @@ void *test_thread(void *arg)
   EXEC SQL DISCONNECT :l_connection;
   return NULL;
 }
-#endif /* ENABLE_THREAD_SAFETY */
diff --git a/src/interfaces/ecpg/test/thread/thread_implicit.pgc b/src/interfaces/ecpg/test/thread/thread_implicit.pgc
index b4cae7e1ae..ff9b12a943 100644
--- a/src/interfaces/ecpg/test/thread/thread_implicit.pgc
+++ b/src/interfaces/ecpg/test/thread/thread_implicit.pgc
@@ -6,14 +6,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifndef WIN32
 #include <pthread.h>
 #else
@@ -133,4 +125,3 @@ void *test_thread(void *arg)
   EXEC SQL DISCONNECT :l_connection;
   return NULL;
 }
-#endif /* ENABLE_THREAD_SAFETY */
diff --git a/src/interfaces/libpq/Makefile b/src/interfaces/libpq/Makefile
index 8abdb092c2..6af1dbfe8e 100644
--- a/src/interfaces/libpq/Makefile
+++ b/src/interfaces/libpq/Makefile
@@ -71,10 +71,8 @@ ifeq ($(PORTNAME), win32)
 OBJS += \
 	win32.o
 
-ifeq ($(enable_thread_safety), yes)
 OBJS += pthread-win32.o
 endif
-endif
 
 
 # Add libraries that libpq depends (or might depend) on into the
diff --git a/src/interfaces/libpq/fe-auth.c b/src/interfaces/libpq/fe-auth.c
index 49a1c626f6..3504ab2c34 100644
--- a/src/interfaces/libpq/fe-auth.c
+++ b/src/interfaces/libpq/fe-auth.c
@@ -1116,11 +1116,10 @@ pg_fe_getusername(uid_t user_id, PQExpBuffer errorMessage)
 #endif
 
 	/*
-	 * Some users are using configure --enable-thread-safety-force, so we
-	 * might as well do the locking within our library to protect getpwuid().
-	 * In fact, application developers can use getpwuid() in their application
-	 * if they use the locking call we provide, or install their own locking
-	 * function using PQregisterThreadLock().
+	 * We do the locking within our library to protect getpwuid().  Application
+	 * developers can use getpwuid() in their application if they use the
+	 * locking call we provide, or install their own locking function using
+	 * PQregisterThreadLock().
 	 */
 	pglock_thread();
 
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index dc49387d6c..7f14026777 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -55,13 +55,11 @@
 #endif
 #endif
 
-#ifdef ENABLE_THREAD_SAFETY
 #ifdef WIN32
 #include "pthread-win32.h"
 #else
 #include <pthread.h>
 #endif
-#endif
 
 #ifdef USE_LDAP
 #ifdef WIN32
@@ -7364,7 +7362,6 @@ pqGetHomeDirectory(char *buf, int bufsize)
 static void
 default_threadlock(int acquire)
 {
-#ifdef ENABLE_THREAD_SAFETY
 #ifndef WIN32
 	static pthread_mutex_t singlethread_lock = PTHREAD_MUTEX_INITIALIZER;
 #else
@@ -7393,7 +7390,6 @@ default_threadlock(int acquire)
 		if (pthread_mutex_unlock(&singlethread_lock))
 			Assert(false);
 	}
-#endif
 }
 
 pgthreadlock_t
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index a36f5eb310..41861e6a11 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -3924,11 +3924,7 @@ PQisnonblocking(const PGconn *conn)
 int
 PQisthreadsafe(void)
 {
-#ifdef ENABLE_THREAD_SAFETY
 	return true;
-#else
-	return false;
-#endif
 }
 
 
diff --git a/src/interfaces/libpq/fe-print.c b/src/interfaces/libpq/fe-print.c
index 783cd9b756..2dc0f1afb9 100644
--- a/src/interfaces/libpq/fe-print.c
+++ b/src/interfaces/libpq/fe-print.c
@@ -88,14 +88,11 @@ PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
 		bool		usePipe = false;
 		char	   *pagerenv;
 
-#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
+#if !defined(WIN32)
 		sigset_t	osigset;
 		bool		sigpipe_masked = false;
 		bool		sigpipe_pending;
 #endif
-#if !defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
-		pqsigfunc	oldsigpipehandler = NULL;
-#endif
 
 #ifdef TIOCGWINSZ
 		struct winsize screen_size;
@@ -185,12 +182,8 @@ PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
 				{
 					usePipe = true;
 #ifndef WIN32
-#ifdef ENABLE_THREAD_SAFETY
 					if (pq_block_sigpipe(&osigset, &sigpipe_pending) == 0)
 						sigpipe_masked = true;
-#else
-					oldsigpipehandler = pqsignal(SIGPIPE, SIG_IGN);
-#endif							/* ENABLE_THREAD_SAFETY */
 #endif							/* WIN32 */
 				}
 				else
@@ -323,13 +316,9 @@ exit:
 #else
 			pclose(fout);
 
-#ifdef ENABLE_THREAD_SAFETY
 			/* we can't easily verify if EPIPE occurred, so say it did */
 			if (sigpipe_masked)
 				pq_reset_sigpipe(&osigset, sigpipe_pending, true);
-#else
-			pqsignal(SIGPIPE, oldsigpipehandler);
-#endif							/* ENABLE_THREAD_SAFETY */
 #endif							/* WIN32 */
 		}
 	}
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index 8117cbd40f..01b2494bb4 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -46,13 +46,11 @@
 
 #include <sys/stat.h>
 
-#ifdef ENABLE_THREAD_SAFETY
 #ifdef WIN32
 #include "pthread-win32.h"
 #else
 #include <pthread.h>
 #endif
-#endif
 
 /*
  * These SSL-related #includes must come after all system-provided headers.
@@ -93,7 +91,6 @@ static bool pq_init_crypto_lib = true;
 
 static bool ssl_lib_initialized = false;
 
-#ifdef ENABLE_THREAD_SAFETY
 static long crypto_open_connections = 0;
 
 #ifndef WIN32
@@ -102,7 +99,6 @@ static pthread_mutex_t ssl_config_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t ssl_config_mutex = NULL;
 static long win32_ssl_create_mutex = 0;
 #endif
-#endif							/* ENABLE_THREAD_SAFETY */
 
 static PQsslKeyPassHook_OpenSSL_type PQsslKeyPassHook = NULL;
 static int	ssl_protocol_version_to_openssl(const char *protocol);
@@ -114,15 +110,12 @@ static int	ssl_protocol_version_to_openssl(const char *protocol);
 void
 pgtls_init_library(bool do_ssl, int do_crypto)
 {
-#ifdef ENABLE_THREAD_SAFETY
-
 	/*
 	 * Disallow changing the flags while we have open connections, else we'd
 	 * get completely confused.
 	 */
 	if (crypto_open_connections != 0)
 		return;
-#endif
 
 	pq_init_ssl_lib = do_ssl;
 	pq_init_crypto_lib = do_crypto;
@@ -709,7 +702,7 @@ pgtls_verify_peer_name_matches_certificate_guts(PGconn *conn,
 	return rc;
 }
 
-#if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_CRYPTO_LOCK)
+#if defined(HAVE_CRYPTO_LOCK)
 /*
  *	Callback functions for OpenSSL internal locking.  (OpenSSL 1.1.0
  *	does its own locking, and doesn't need these anymore.  The
@@ -750,7 +743,7 @@ pq_lockingcallback(int mode, int n, const char *file, int line)
 			Assert(false);
 	}
 }
-#endif							/* ENABLE_THREAD_SAFETY && HAVE_CRYPTO_LOCK */
+#endif							/* HAVE_CRYPTO_LOCK */
 
 /*
  * Initialize SSL library.
@@ -765,7 +758,6 @@ pq_lockingcallback(int mode, int n, const char *file, int line)
 int
 pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto)
 {
-#ifdef ENABLE_THREAD_SAFETY
 #ifdef WIN32
 	/* Also see similar code in fe-connect.c, default_threadlock() */
 	if (ssl_config_mutex == NULL)
@@ -831,7 +823,6 @@ pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto)
 		}
 	}
 #endif							/* HAVE_CRYPTO_LOCK */
-#endif							/* ENABLE_THREAD_SAFETY */
 
 	if (!ssl_lib_initialized && do_ssl)
 	{
@@ -848,9 +839,7 @@ pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto)
 		ssl_lib_initialized = true;
 	}
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_unlock(&ssl_config_mutex);
-#endif
 	return 0;
 }
 
@@ -869,7 +858,7 @@ pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto)
 static void
 destroy_ssl_system(void)
 {
-#if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_CRYPTO_LOCK)
+#if defined(HAVE_CRYPTO_LOCK)
 	/* Mutex is created in pgtls_init() */
 	if (pthread_mutex_lock(&ssl_config_mutex))
 		return;
diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c
index a1dc7b796d..88607fb65b 100644
--- a/src/interfaces/libpq/fe-secure.c
+++ b/src/interfaces/libpq/fe-secure.c
@@ -37,13 +37,11 @@
 
 #include <sys/stat.h>
 
-#ifdef ENABLE_THREAD_SAFETY
 #ifdef WIN32
 #include "pthread-win32.h"
 #else
 #include <pthread.h>
 #endif
-#endif
 
 #include "fe-auth.h"
 #include "libpq-fe.h"
@@ -58,8 +56,6 @@
 
 #define SIGPIPE_MASKED(conn)	((conn)->sigpipe_so || (conn)->sigpipe_flag)
 
-#ifdef ENABLE_THREAD_SAFETY
-
 struct sigpipe_info
 {
 	sigset_t	oldsigmask;
@@ -92,24 +88,6 @@ struct sigpipe_info
 			pq_reset_sigpipe(&(spinfo).oldsigmask, (spinfo).sigpipe_pending, \
 							 (spinfo).got_epipe); \
 	} while (0)
-#else							/* !ENABLE_THREAD_SAFETY */
-
-#define DECLARE_SIGPIPE_INFO(spinfo) pqsigfunc spinfo = NULL
-
-#define DISABLE_SIGPIPE(conn, spinfo, failaction) \
-	do { \
-		if (!SIGPIPE_MASKED(conn)) \
-			spinfo = pqsignal(SIGPIPE, SIG_IGN); \
-	} while (0)
-
-#define REMEMBER_EPIPE(spinfo, cond)
-
-#define RESTORE_SIGPIPE(conn, spinfo) \
-	do { \
-		if (!SIGPIPE_MASKED(conn)) \
-			pqsignal(SIGPIPE, spinfo); \
-	} while (0)
-#endif							/* ENABLE_THREAD_SAFETY */
 #else							/* WIN32 */
 
 #define DECLARE_SIGPIPE_INFO(spinfo)
@@ -524,7 +502,7 @@ PQgssEncInUse(PGconn *conn)
 #endif							/* ENABLE_GSS */
 
 
-#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
+#if !defined(WIN32)
 
 /*
  *	Block SIGPIPE for this thread.  This prevents send()/write() from exiting
@@ -608,4 +586,4 @@ pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, bool got_epipe)
 	SOCK_ERRNO_SET(save_errno);
 }
 
-#endif							/* ENABLE_THREAD_SAFETY && !WIN32 */
+#endif							/* !WIN32 */
diff --git a/src/interfaces/libpq/legacy-pqsignal.c b/src/interfaces/libpq/legacy-pqsignal.c
index db470df9ea..1b4424eabb 100644
--- a/src/interfaces/libpq/legacy-pqsignal.c
+++ b/src/interfaces/libpq/legacy-pqsignal.c
@@ -27,10 +27,6 @@
  * Because it is only intended for backwards compatibility, we freeze it
  * with the semantics it had in 9.2; in particular, this has different
  * behavior for SIGALRM than the version in src/port/pqsignal.c.
- *
- * libpq itself uses this only for SIGPIPE (and even then, only in
- * non-ENABLE_THREAD_SAFETY builds), so the incompatibility isn't
- * troublesome for internal references.
  */
 pqsigfunc
 pqsignal(int signo, pqsigfunc func)
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index 51ab51f9f9..99c40af8cf 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -28,14 +28,12 @@
 #include <sys/time.h>
 #endif
 
-#ifdef ENABLE_THREAD_SAFETY
 #ifdef WIN32
 #include "pthread-win32.h"
 #else
 #include <pthread.h>
 #endif
 #include <signal.h>
-#endif
 
 /* include stuff common to fe and be */
 #include "getaddrinfo.h"
@@ -649,15 +647,10 @@ extern int	pqPacketSend(PGconn *conn, char pack_type,
 						 const void *buf, size_t buf_len);
 extern bool pqGetHomeDirectory(char *buf, int bufsize);
 
-#ifdef ENABLE_THREAD_SAFETY
 extern pgthreadlock_t pg_g_threadlock;
 
 #define pglock_thread()		pg_g_threadlock(true)
 #define pgunlock_thread()	pg_g_threadlock(false)
-#else
-#define pglock_thread()		((void) 0)
-#define pgunlock_thread()	((void) 0)
-#endif
 
 /* === in fe-exec.c === */
 
@@ -732,7 +725,7 @@ extern ssize_t pqsecure_write(PGconn *, const void *ptr, size_t len);
 extern ssize_t pqsecure_raw_read(PGconn *, void *ptr, size_t len);
 extern ssize_t pqsecure_raw_write(PGconn *, const void *ptr, size_t len);
 
-#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
+#if !defined(WIN32)
 extern int	pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending);
 extern void pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending,
 							 bool got_epipe);
diff --git a/src/port/getaddrinfo.c b/src/port/getaddrinfo.c
index bea7b520f0..8cb3a4db2f 100644
--- a/src/port/getaddrinfo.c
+++ b/src/port/getaddrinfo.c
@@ -414,7 +414,7 @@ pqGethostbyname(const char *name,
 				struct hostent **result,
 				int *herrno)
 {
-#if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_GETHOSTBYNAME_R)
+#if defined(HAVE_GETHOSTBYNAME_R)
 
 	/*
 	 * broken (well early POSIX draft) gethostbyname_r() which returns 'struct
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 1cd1c44fed..f67f60bd54 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -219,7 +219,6 @@ sub GenerateFiles
 		DLSUFFIX                   => '".dll"',
 		ENABLE_GSS                 => $self->{options}->{gss} ? 1 : undef,
 		ENABLE_NLS                 => $self->{options}->{nls} ? 1 : undef,
-		ENABLE_THREAD_SAFETY       => 1,
 		GETTIMEOFDAY_1ARG          => undef,
 		HAVE_APPEND_HISTORY        => undef,
 		HAVE_ASN1_STRING_GET0_DATA => undef,
@@ -1210,7 +1209,7 @@ sub GetFakeConfigure
 {
 	my $self = shift;
 
-	my $cfg = '--enable-thread-safety';
+	my $cfg = '';
 	$cfg .= ' --enable-cassert'   if ($self->{options}->{asserts});
 	$cfg .= ' --enable-nls'       if ($self->{options}->{nls});
 	$cfg .= ' --enable-tap-tests' if ($self->{options}->{tap_tests});
diff --git a/src/tools/msvc/ecpg_regression.proj b/src/tools/msvc/ecpg_regression.proj
index ec2760b1f6..0ec60a275e 100644
--- a/src/tools/msvc/ecpg_regression.proj
+++ b/src/tools/msvc/ecpg_regression.proj
@@ -54,7 +54,7 @@
 
   <!-- Run ECPG and the Visual C++ compiler on the files. Don't bother with dependency check between the steps -->
   <Exec WorkingDirectory="%(Pgc.RelativeDir)" Command="$(OUTDIR)ecpg\ecpg -I ../../include --regression $(ECPGPARAM) -o %(Pgc.Filename).c %(Pgc.Filename).pgc" />
-  <Exec WorkingDirectory="%(Pgc.RelativeDir)" Command="cl /nologo %(Pgc.FileName).c /TC /MD$(DEBUGLIB) /DENABLE_THREAD_SAFETY /DWIN32 /I. /I..\..\include /I..\..\..\libpq /I..\..\..\..\include /link /defaultlib:$(OUTDIR)libecpg\libecpg.lib /defaultlib:$(OUTDIR)libecpg_compat\libecpg_compat.lib /defaultlib:$(OUTDIR)libpgtypes\libpgtypes.lib" />
+  <Exec WorkingDirectory="%(Pgc.RelativeDir)" Command="cl /nologo %(Pgc.FileName).c /TC /MD$(DEBUGLIB) /DWIN32 /I. /I..\..\include /I..\..\..\libpq /I..\..\..\..\include /link /defaultlib:$(OUTDIR)libecpg\libecpg.lib /defaultlib:$(OUTDIR)libecpg_compat\libecpg_compat.lib /defaultlib:$(OUTDIR)libpgtypes\libpgtypes.lib" />
  </Target>
 
  <!-- Clean up all output files -->
-- 
2.35.1

#20Thomas Munro
thomas.munro@gmail.com
In reply to: Thomas Munro (#19)
13 attachment(s)
Re: Cleaning up historical portability baggage

Sorry, I know this is really tedious stuff, but I found a couple more
cleanup opportunities nearby:

For dlopen(), we don't have to worry about old Unix systems without
RTLD_NOW and RTLD_GLOBAL macros anymore. They're in SUSv2 and present
on all our BF Unixes, so that's some more configure probes that we can
remove. Also, we might as well move the declarations for everything
relating to dlopen into win32_port.h.

(Why some WIN32 things are done in port.h while others are done in
win32_port.h is something I don't grok; probably depends whether there
were ever non-Windows systems that needed something... I might propose
to tidy that up some more, later...)

For setenv()/unsetenv(), I removed the declarations from port.h. Only
the ones in win32_port.h are needed now.

I fixed a couple of places where I'd renamed a file but forgotten to
update that IDENTIFICATION section from the CVS days, and a stray 2021
copyright year.

It'd be good to find a new home for pg_get_user_name() and
pg_get_user_home_dir(), which really shouldn't be left in the now
bogusly named src/port/thread.c. Any suggestions?

Was it a mistake to add pgwin32_ prefixes to some Windows replacement
functions? It seems a little arbitrary that we do that sometimes even
though we don't need to. Perhaps we should only do that kind of thing
when we want to avoid name-clash with a real Windows function that
we're replacing?

I'd like to push these soon, if there are no further objections. If
you prefer, I could hold back on the two that will break prairiedog
until you give the word, namely clock_gettime() and fdatasync().

Attachments:

v3-0001-Remove-configure-probe-for-dlopen.patchtext/x-patch; charset=US-ASCII; name=v3-0001-Remove-configure-probe-for-dlopen.patchDownload
From 925247600c56fafc9d4a60f25e006ee04ebc1d30 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Tue, 19 Jul 2022 18:07:51 +1200
Subject: [PATCH v3 01/13] Remove configure probe for dlopen.

dlopen() is in SUSv2 and all targeted Unix systems have it.  We still
need replacement functions for Windows, but we don't need a configure
probe for that.

Since it's no longer needed by other operating systems, rename dlopen.c
to win32dlopen.c and move the declarations into win32_port.h.

Likewise, the macros RTLD_NOW and RTLD_GLOBAL now only need to defined
on Windows, since all targeted Unix systems have 'em.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CA+hUKGJ3LHeP9w5Fgzdr4G8AnEtJ=z=p6hGDEm4qYGEUX5B6fQ@mail.gmail.com
---
 configure                            | 43 ++++------------------------
 configure.ac                         |  4 +--
 src/backend/utils/fmgr/dfmgr.c       |  4 +--
 src/include/pg_config.h.in           | 11 -------
 src/include/port.h                   | 23 ---------------
 src/include/port/win32_port.h        |  9 ++++++
 src/port/{dlopen.c => win32dlopen.c} | 10 ++-----
 src/tools/msvc/Mkvcbuild.pm          |  3 +-
 src/tools/msvc/Solution.pm           |  3 --
 9 files changed, 23 insertions(+), 87 deletions(-)
 rename src/port/{dlopen.c => win32dlopen.c} (93%)

diff --git a/configure b/configure
index c5bc382395..2583a04a87 100755
--- a/configure
+++ b/configure
@@ -16618,30 +16618,6 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
-ac_fn_c_check_decl "$LINENO" "RTLD_GLOBAL" "ac_cv_have_decl_RTLD_GLOBAL" "#include <dlfcn.h>
-"
-if test "x$ac_cv_have_decl_RTLD_GLOBAL" = xyes; then :
-  ac_have_decl=1
-else
-  ac_have_decl=0
-fi
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL_RTLD_GLOBAL $ac_have_decl
-_ACEOF
-ac_fn_c_check_decl "$LINENO" "RTLD_NOW" "ac_cv_have_decl_RTLD_NOW" "#include <dlfcn.h>
-"
-if test "x$ac_cv_have_decl_RTLD_NOW" = xyes; then :
-  ac_have_decl=1
-else
-  ac_have_decl=0
-fi
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL_RTLD_NOW $ac_have_decl
-_ACEOF
-
-
 ac_fn_c_check_type "$LINENO" "struct sockaddr_in6" "ac_cv_type_struct_sockaddr_in6" "$ac_includes_default
 #include <netinet/in.h>
 "
@@ -16687,19 +16663,6 @@ $as_echo "#define HAVE_PS_STRINGS 1" >>confdefs.h
 
 fi
 
-ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
-if test "x$ac_cv_func_dlopen" = xyes; then :
-  $as_echo "#define HAVE_DLOPEN 1" >>confdefs.h
-
-else
-  case " $LIBOBJS " in
-  *" dlopen.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS dlopen.$ac_objext"
- ;;
-esac
-
-fi
-
 ac_fn_c_check_func "$LINENO" "explicit_bzero" "ac_cv_func_explicit_bzero"
 if test "x$ac_cv_func_explicit_bzero" = xyes; then :
   $as_echo "#define HAVE_EXPLICIT_BZERO 1" >>confdefs.h
@@ -17078,6 +17041,12 @@ esac
  ;;
 esac
 
+  case " $LIBOBJS " in
+  *" win32dlopen.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS win32dlopen.$ac_objext"
+ ;;
+esac
+
   case " $LIBOBJS " in
   *" win32env.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS win32env.$ac_objext"
diff --git a/configure.ac b/configure.ac
index 61d0dd5d58..84bdaeb46c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1858,8 +1858,6 @@ AC_CHECK_DECLS([pwritev], [], [AC_LIBOBJ(pwritev)], [#include <sys/uio.h>])
 # This is probably only present on macOS, but may as well check always
 AC_CHECK_DECLS(F_FULLFSYNC, [], [], [#include <fcntl.h>])
 
-AC_CHECK_DECLS([RTLD_GLOBAL, RTLD_NOW], [], [], [#include <dlfcn.h>])
-
 AC_CHECK_TYPE([struct sockaddr_in6],
         [AC_DEFINE(HAVE_IPV6, 1, [Define to 1 if you have support for IPv6.])],
         [],
@@ -1880,7 +1878,6 @@ if test "$pgac_cv_var_PS_STRINGS" = yes ; then
 fi
 
 AC_REPLACE_FUNCS(m4_normalize([
-	dlopen
 	explicit_bzero
 	getopt
 	getpeereid
@@ -1962,6 +1959,7 @@ if test "$PORTNAME" = "win32"; then
   AC_LIBOBJ(kill)
   AC_LIBOBJ(open)
   AC_LIBOBJ(system)
+  AC_LIBOBJ(win32dlopen)
   AC_LIBOBJ(win32env)
   AC_LIBOBJ(win32error)
   AC_LIBOBJ(win32ntdll)
diff --git a/src/backend/utils/fmgr/dfmgr.c b/src/backend/utils/fmgr/dfmgr.c
index 7f9ea97280..08fd7e1264 100644
--- a/src/backend/utils/fmgr/dfmgr.c
+++ b/src/backend/utils/fmgr/dfmgr.c
@@ -16,7 +16,7 @@
 
 #include <sys/stat.h>
 
-#ifdef HAVE_DLOPEN
+#ifndef WIN32
 #include <dlfcn.h>
 
 /*
@@ -28,7 +28,7 @@
 #undef bool
 #endif
 #endif
-#endif							/* HAVE_DLOPEN */
+#endif							/* !WIN32 */
 
 #include "fmgr.h"
 #include "lib/stringinfo.h"
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index f9618e1986..ab812bca89 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -141,14 +141,6 @@
    don't. */
 #undef HAVE_DECL_PWRITEV
 
-/* Define to 1 if you have the declaration of `RTLD_GLOBAL', and to 0 if you
-   don't. */
-#undef HAVE_DECL_RTLD_GLOBAL
-
-/* Define to 1 if you have the declaration of `RTLD_NOW', and to 0 if you
-   don't. */
-#undef HAVE_DECL_RTLD_NOW
-
 /* Define to 1 if you have the declaration of `strlcat', and to 0 if you
    don't. */
 #undef HAVE_DECL_STRLCAT
@@ -169,9 +161,6 @@
    don't. */
 #undef HAVE_DECL_STRTOULL
 
-/* Define to 1 if you have the `dlopen' function. */
-#undef HAVE_DLOPEN
-
 /* Define to 1 if you have the <editline/history.h> header file. */
 #undef HAVE_EDITLINE_HISTORY_H
 
diff --git a/src/include/port.h b/src/include/port.h
index d39b04141f..323df8f9ed 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -455,29 +455,6 @@ extern int	setenv(const char *name, const char *value, int overwrite);
 extern int	unsetenv(const char *name);
 #endif
 
-#ifndef HAVE_DLOPEN
-extern void *dlopen(const char *file, int mode);
-extern void *dlsym(void *handle, const char *symbol);
-extern int	dlclose(void *handle);
-extern char *dlerror(void);
-#endif
-
-/*
- * In some older systems, the RTLD_NOW flag isn't defined and the mode
- * argument to dlopen must always be 1.
- */
-#if !HAVE_DECL_RTLD_NOW
-#define RTLD_NOW 1
-#endif
-
-/*
- * The RTLD_GLOBAL flag is wanted if available, but it doesn't exist
- * everywhere.  If it doesn't exist, set it to 0 so it has no effect.
- */
-#if !HAVE_DECL_RTLD_GLOBAL
-#define RTLD_GLOBAL 0
-#endif
-
 /* thread.c */
 #ifndef WIN32
 extern bool pg_get_user_name(uid_t user_id, char *buffer, size_t buflen);
diff --git a/src/include/port/win32_port.h b/src/include/port/win32_port.h
index 4de5bf3bf6..5cc35600a0 100644
--- a/src/include/port/win32_port.h
+++ b/src/include/port/win32_port.h
@@ -503,6 +503,15 @@ extern int	pgwin32_ReserveSharedMemoryRegion(HANDLE);
 /* in backend/port/win32/crashdump.c */
 extern void pgwin32_install_crashdump_handler(void);
 
+/* in port/win32dlopen.c */
+extern void *dlopen(const char *file, int mode);
+extern void *dlsym(void *handle, const char *symbol);
+extern int  dlclose(void *handle);
+extern char *dlerror(void);
+
+#define RTLD_NOW 1
+#define RTLD_GLOBAL 0
+
 /* in port/win32error.c */
 extern void _dosmaperr(unsigned long);
 
diff --git a/src/port/dlopen.c b/src/port/win32dlopen.c
similarity index 93%
rename from src/port/dlopen.c
rename to src/port/win32dlopen.c
index 6ff9f4bf64..2657537c29 100644
--- a/src/port/dlopen.c
+++ b/src/port/win32dlopen.c
@@ -1,22 +1,20 @@
 /*-------------------------------------------------------------------------
  *
- * dlopen.c
- *	  dynamic loader for platforms without dlopen()
+ * win32dlopen.c
+ *	  dynamic loader for Windows
  *
  * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  *
  * IDENTIFICATION
- *	  src/port/dlopen.c
+ *	  src/port/win32dlopen.c
  *
  *-------------------------------------------------------------------------
  */
 
 #include "c.h"
 
-#if defined(WIN32)
-
 static char last_dyn_error[512];
 
 static void
@@ -93,5 +91,3 @@ dlopen(const char *file, int mode)
 	last_dyn_error[0] = 0;
 	return (void *) h;
 }
-
-#endif
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index c935f776e5..266f98e2ed 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -103,11 +103,12 @@ sub mkvcbuild
 	  getpeereid.c getrusage.c inet_aton.c
 	  getaddrinfo.c gettimeofday.c inet_net_ntop.c kill.c open.c
 	  snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c
-	  dirent.c dlopen.c getopt.c getopt_long.c link.c
+	  dirent.c getopt.c getopt_long.c link.c
 	  pread.c preadv.c pwrite.c pwritev.c pg_bitutils.c
 	  pg_strong_random.c pgcheckdir.c pgmkdirp.c pgsleep.c pgstrcasecmp.c
 	  pqsignal.c mkdtemp.c qsort.c qsort_arg.c bsearch_arg.c quotes.c system.c
 	  strerror.c tar.c
+	  win32dlopen.c
 	  win32env.c win32error.c win32ntdll.c
 	  win32security.c win32setlocale.c win32stat.c);
 
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index b09872e018..a7a5c31a5b 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -244,14 +244,11 @@ sub GenerateFiles
 		HAVE_DECL_POSIX_FADVISE                     => 0,
 		HAVE_DECL_PREADV                            => 0,
 		HAVE_DECL_PWRITEV                           => 0,
-		HAVE_DECL_RTLD_GLOBAL                       => 0,
-		HAVE_DECL_RTLD_NOW                          => 0,
 		HAVE_DECL_STRLCAT                           => 0,
 		HAVE_DECL_STRLCPY                           => 0,
 		HAVE_DECL_STRNLEN                           => 1,
 		HAVE_DECL_STRTOLL                           => 1,
 		HAVE_DECL_STRTOULL                          => 1,
-		HAVE_DLOPEN                                 => undef,
 		HAVE_EDITLINE_HISTORY_H                     => undef,
 		HAVE_EDITLINE_READLINE_H                    => undef,
 		HAVE_EXECINFO_H                             => undef,
-- 
2.37.1

v3-0002-Remove-configure-probe-and-extra-tests-for-getrli.patchtext/x-patch; charset=US-ASCII; name=v3-0002-Remove-configure-probe-and-extra-tests-for-getrli.patchDownload
From c81d35b8842ac4e5aae1ede48da9a75c8a5bce1b Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 23 Jul 2022 21:34:14 +1200
Subject: [PATCH v3 02/13] Remove configure probe and extra tests for
 getrlimit.

getrlimit() is in SUSv2 and all targeted systems have it.

Windows doesn't have it.  We could just use #ifndef WIN32, but for a
little more explanation about why we're making things conditional, let's
retain the HAVE_GETRLIMIT macro.  It's defined in port.h for Unix systems.

On systems that have it, it's not necessary to test for RLIMIT_CORE,
RLIMIT_STACK or RLIMIT_NOFILE macros, since SUSv2 requires those and all
targeted systems have them.  Also remove references to a pre-historic
alternative spelling of RLIMIT_NOFILE, and coding that seemed to believe
that Cygwin didn't have it.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CA+hUKGJ3LHeP9w5Fgzdr4G8AnEtJ=z=p6hGDEm4qYGEUX5B6fQ@mail.gmail.com
---
 configure                     | 2 +-
 configure.ac                  | 1 -
 src/backend/storage/file/fd.c | 4 ----
 src/backend/tcop/postgres.c   | 8 ++------
 src/bin/pg_ctl/pg_ctl.c       | 8 ++++----
 src/bin/pgbench/pgbench.c     | 4 ----
 src/include/pg_config.h.in    | 3 ---
 src/include/port.h            | 8 ++++++++
 src/test/regress/pg_regress.c | 4 ++--
 src/tools/msvc/Solution.pm    | 1 -
 10 files changed, 17 insertions(+), 26 deletions(-)

diff --git a/configure b/configure
index 2583a04a87..691cdd9d61 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 getrlimit inet_pton kqueue mbstowcs_l memset_s poll posix_fallocate ppoll pthread_is_threaded_np readlink readv setproctitle setproctitle_fast setsid shm_open 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 readlink readv setproctitle setproctitle_fast setsid shm_open strchrnul strsignal symlink 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"
diff --git a/configure.ac b/configure.ac
index 84bdaeb46c..39a55f6264 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1797,7 +1797,6 @@ AC_CHECK_FUNCS(m4_normalize([
 	fdatasync
 	getifaddrs
 	getpeerucred
-	getrlimit
 	inet_pton
 	kqueue
 	mbstowcs_l
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index f904f60c08..447d5a86c3 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -895,11 +895,7 @@ count_usable_fds(int max_to_probe, int *usable_fds, int *already_open)
 	fd = (int *) palloc(size * sizeof(int));
 
 #ifdef HAVE_GETRLIMIT
-#ifdef RLIMIT_NOFILE			/* most platforms use RLIMIT_NOFILE */
 	getrlimit_status = getrlimit(RLIMIT_NOFILE, &rlim);
-#else							/* but BSD doesn't ... */
-	getrlimit_status = getrlimit(RLIMIT_OFILE, &rlim);
-#endif							/* RLIMIT_NOFILE */
 	if (getrlimit_status != 0)
 		ereport(WARNING, (errmsg("getrlimit failed: %m")));
 #endif							/* HAVE_GETRLIMIT */
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 078fbdb5a0..11e802eba9 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -4770,7 +4770,7 @@ forbidden_in_wal_sender(char firstchar)
 long
 get_stack_depth_rlimit(void)
 {
-#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_STACK)
+#if defined(HAVE_GETRLIMIT)
 	static long val = 0;
 
 	/* This won't change after process launch, so check just once */
@@ -4789,13 +4789,9 @@ get_stack_depth_rlimit(void)
 			val = rlim.rlim_cur;
 	}
 	return val;
-#else							/* no getrlimit */
-#if defined(WIN32) || defined(__CYGWIN__)
+#else
 	/* On Windows we set the backend stack size in src/backend/Makefile */
 	return WIN32_STACK_RLIMIT;
-#else							/* not windows ... give up */
-	return -1;
-#endif
 #endif
 }
 
diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
index ef58883a5c..2762e8590d 100644
--- a/src/bin/pg_ctl/pg_ctl.c
+++ b/src/bin/pg_ctl/pg_ctl.c
@@ -160,7 +160,7 @@ static bool wait_for_postmaster_stop(void);
 static bool wait_for_postmaster_promote(void);
 static bool postmaster_is_alive(pid_t pid);
 
-#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
+#if defined(HAVE_GETRLIMIT)
 static void unlimit_core_size(void);
 #endif
 
@@ -776,7 +776,7 @@ wait_for_postmaster_promote(void)
 }
 
 
-#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
+#if defined(HAVE_GETRLIMIT)
 static void
 unlimit_core_size(void)
 {
@@ -949,7 +949,7 @@ do_start(void)
 	if (exec_path == NULL)
 		exec_path = find_other_exec_or_die(argv0, "postgres", PG_BACKEND_VERSIONSTR);
 
-#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
+#if defined(HAVE_GETRLIMIT)
 	if (allow_core_files)
 		unlimit_core_size();
 #endif
@@ -2069,7 +2069,7 @@ do_help(void)
 	printf(_("If the -D option is omitted, the environment variable PGDATA is used.\n"));
 
 	printf(_("\nOptions for start or restart:\n"));
-#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
+#if defined(HAVE_GETRLIMIT)
 	printf(_("  -c, --core-files       allow postgres to produce core files\n"));
 #else
 	printf(_("  -c, --core-files       not applicable on this platform\n"));
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index bcaea8f5ea..0778656794 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -6662,11 +6662,7 @@ main(int argc, char **argv)
 					exit(1);
 				}
 #ifdef HAVE_GETRLIMIT
-#ifdef RLIMIT_NOFILE			/* most platforms use RLIMIT_NOFILE */
 				if (getrlimit(RLIMIT_NOFILE, &rlim) == -1)
-#else							/* but BSD doesn't ... */
-				if (getrlimit(RLIMIT_OFILE, &rlim) == -1)
-#endif							/* RLIMIT_NOFILE */
 					pg_fatal("getrlimit failed: %m");
 				if (rlim.rlim_cur < nclients + 3)
 				{
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index ab812bca89..93173d67c0 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -229,9 +229,6 @@
 /* Define to 1 if you have the `getpeerucred' function. */
 #undef HAVE_GETPEERUCRED
 
-/* Define to 1 if you have the `getrlimit' function. */
-#undef HAVE_GETRLIMIT
-
 /* Define to 1 if you have the `gettimeofday' function. */
 #undef HAVE_GETTIMEOFDAY
 
diff --git a/src/include/port.h b/src/include/port.h
index 323df8f9ed..2c25498add 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -519,4 +519,12 @@ extern char *wait_result_to_str(int exit_status);
 extern bool wait_result_is_signal(int exit_status, int signum);
 extern bool wait_result_is_any_signal(int exit_status, bool include_command_not_found);
 
+/*
+ * Interfaces that we assume all Unix system have.  We retain individual macros
+ * for better documentation.
+ */
+#ifndef WIN32
+#define HAVE_GETRLIMIT 1
+#endif
+
 #endif							/* PG_PORT_H */
diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c
index 982801e029..04ab513b7c 100644
--- a/src/test/regress/pg_regress.c
+++ b/src/test/regress/pg_regress.c
@@ -129,7 +129,7 @@ static void psql_end_command(StringInfo buf, const char *database);
 /*
  * allow core files if possible.
  */
-#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
+#if defined(HAVE_GETRLIMIT)
 static void
 unlimit_core_size(void)
 {
@@ -2229,7 +2229,7 @@ regression_main(int argc, char *argv[],
 
 	initialize_environment();
 
-#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
+#if defined(HAVE_GETRLIMIT)
 	unlimit_core_size();
 #endif
 
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index a7a5c31a5b..c703708b50 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -271,7 +271,6 @@ sub GenerateFiles
 		HAVE_GETOPT_LONG                            => undef,
 		HAVE_GETPEEREID                             => undef,
 		HAVE_GETPEERUCRED                           => undef,
-		HAVE_GETRLIMIT                              => undef,
 		HAVE_GETTIMEOFDAY                           => undef,
 		HAVE_GSSAPI_GSSAPI_H                        => undef,
 		HAVE_GSSAPI_H                               => undef,
-- 
2.37.1

v3-0003-Remove-configure-probe-for-shm_open.patchtext/x-patch; charset=US-ASCII; name=v3-0003-Remove-configure-probe-for-shm_open.patchDownload
From 96a4935ff9480c2786634e9892b1f44782b403fb Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 23 Jul 2022 23:49:27 +1200
Subject: [PATCH v3 03/13] Remove configure probe for shm_open.

shm_open() is in SUSv2 (realtime) and all targeted Unix systems have it.

We retain a HAVE_SHM_OPEN macro, because it's clearer to readers than
something like !defined(WIN32).

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CA+hUKGJ3LHeP9w5Fgzdr4G8AnEtJ=z=p6hGDEm4qYGEUX5B6fQ@mail.gmail.com
---
 configure                  | 2 +-
 configure.ac               | 1 -
 src/include/pg_config.h.in | 3 ---
 src/include/port.h         | 1 +
 src/tools/msvc/Solution.pm | 1 -
 5 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/configure b/configure
index 691cdd9d61..8cbd03fe0a 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 setsid shm_open 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 readlink readv setproctitle setproctitle_fast setsid strchrnul strsignal symlink 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"
diff --git a/configure.ac b/configure.ac
index 39a55f6264..9ef2a373f2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1810,7 +1810,6 @@ AC_CHECK_FUNCS(m4_normalize([
 	setproctitle
 	setproctitle_fast
 	setsid
-	shm_open
 	strchrnul
 	strsignal
 	symlink
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 93173d67c0..5015ac6a3e 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -472,9 +472,6 @@
 /* Define to 1 if you have the `setsid' function. */
 #undef HAVE_SETSID
 
-/* Define to 1 if you have the `shm_open' function. */
-#undef HAVE_SHM_OPEN
-
 /* Define to 1 if the system has the type `socklen_t'. */
 #undef HAVE_SOCKLEN_T
 
diff --git a/src/include/port.h b/src/include/port.h
index 2c25498add..a8598532c0 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -525,6 +525,7 @@ extern bool wait_result_is_any_signal(int exit_status, bool include_command_not_
  */
 #ifndef WIN32
 #define HAVE_GETRLIMIT 1
+#define HAVE_SHM_OPEN 1
 #endif
 
 #endif							/* PG_PORT_H */
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index c703708b50..5499498137 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -351,7 +351,6 @@ sub GenerateFiles
 		HAVE_SETPROCTITLE                        => undef,
 		HAVE_SETPROCTITLE_FAST                   => undef,
 		HAVE_SETSID                              => undef,
-		HAVE_SHM_OPEN                            => undef,
 		HAVE_SOCKLEN_T                           => 1,
 		HAVE_SPINLOCKS                           => 1,
 		HAVE_STDBOOL_H                           => 1,
-- 
2.37.1

v3-0004-Remove-configure-probe-for-setsid.patchtext/x-patch; charset=US-ASCII; name=v3-0004-Remove-configure-probe-for-setsid.patchDownload
From 5d7415ceac70ee3adec7df2fd3fba5fc15368ac0 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sun, 24 Jul 2022 00:54:07 +1200
Subject: [PATCH v3 04/13] Remove configure probe for setsid.

setsid() is in SUSv2 and all targeted Unix systems have it.  Retain a
HAVE_SETSID macro, defined on Unix only.  That's easier to understand
than !defined(WIN32), for the optional code it governs.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CA+hUKGJ3LHeP9w5Fgzdr4G8AnEtJ=z=p6hGDEm4qYGEUX5B6fQ@mail.gmail.com
---
 configure                  | 2 +-
 configure.ac               | 1 -
 src/include/pg_config.h.in | 3 ---
 src/include/port.h         | 1 +
 src/tools/msvc/Solution.pm | 1 -
 5 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/configure b/configure
index 8cbd03fe0a..232f19a0cd 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 setsid 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 readlink readv setproctitle setproctitle_fast strchrnul strsignal symlink 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"
diff --git a/configure.ac b/configure.ac
index 9ef2a373f2..33dffe0ce5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1809,7 +1809,6 @@ AC_CHECK_FUNCS(m4_normalize([
 	readv
 	setproctitle
 	setproctitle_fast
-	setsid
 	strchrnul
 	strsignal
 	symlink
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 5015ac6a3e..120eacfb20 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -469,9 +469,6 @@
 /* Define to 1 if you have the `setproctitle_fast' function. */
 #undef HAVE_SETPROCTITLE_FAST
 
-/* Define to 1 if you have the `setsid' function. */
-#undef HAVE_SETSID
-
 /* Define to 1 if the system has the type `socklen_t'. */
 #undef HAVE_SOCKLEN_T
 
diff --git a/src/include/port.h b/src/include/port.h
index a8598532c0..7a1a02f659 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -525,6 +525,7 @@ extern bool wait_result_is_any_signal(int exit_status, bool include_command_not_
  */
 #ifndef WIN32
 #define HAVE_GETRLIMIT 1
+#define HAVE_SETSID 1
 #define HAVE_SHM_OPEN 1
 #endif
 
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 5499498137..a9680dc863 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -350,7 +350,6 @@ sub GenerateFiles
 		HAVE_SETENV                              => undef,
 		HAVE_SETPROCTITLE                        => undef,
 		HAVE_SETPROCTITLE_FAST                   => undef,
-		HAVE_SETSID                              => undef,
 		HAVE_SOCKLEN_T                           => 1,
 		HAVE_SPINLOCKS                           => 1,
 		HAVE_STDBOOL_H                           => 1,
-- 
2.37.1

v3-0005-Remove-configure-probes-for-symlink-readlink-and-.patchtext/x-patch; charset=US-ASCII; name=v3-0005-Remove-configure-probes-for-symlink-readlink-and-.patchDownload
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

v3-0006-Remove-configure-probe-for-link.patchtext/x-patch; charset=US-ASCII; name=v3-0006-Remove-configure-probe-for-link.patchDownload
From 143f6917bbc7d8f457d52d02a5fbc79d849744e1 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sun, 24 Jul 2022 01:19:05 +1200
Subject: [PATCH v3 06/13] Remove configure probe for link.

link() is in SUSv2 and all targeted Unix systems have it.  We have
replacement code for Windows that doesn't require a configure probe.
Since only Windows needs it, rename src/port/link.c to win32link.c like
other similar things.

There is no need for a vestigial HAVE_LINK macro, because we expect all
Unix and, with our replacement function, Windows systems to have it, so
we didn't have any tests around link() usage.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CA+hUKGJ3LHeP9w5Fgzdr4G8AnEtJ=z=p6hGDEm4qYGEUX5B6fQ@mail.gmail.com
---
 configure                        | 19 ++++++-------------
 configure.ac                     |  2 +-
 src/include/pg_config.h.in       |  3 ---
 src/include/port.h               |  3 ++-
 src/port/{link.c => win32link.c} |  8 ++------
 src/tools/msvc/Mkvcbuild.pm      |  6 ++++--
 src/tools/msvc/Solution.pm       |  1 -
 7 files changed, 15 insertions(+), 27 deletions(-)
 rename src/port/{link.c => win32link.c} (92%)

diff --git a/configure b/configure
index 1f852078e7..6358bdcabc 100755
--- a/configure
+++ b/configure
@@ -16715,19 +16715,6 @@ esac
 
 fi
 
-ac_fn_c_check_func "$LINENO" "link" "ac_cv_func_link"
-if test "x$ac_cv_func_link" = xyes; then :
-  $as_echo "#define HAVE_LINK 1" >>confdefs.h
-
-else
-  case " $LIBOBJS " in
-  *" link.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS link.$ac_objext"
- ;;
-esac
-
-fi
-
 ac_fn_c_check_func "$LINENO" "mkdtemp" "ac_cv_func_mkdtemp"
 if test "x$ac_cv_func_mkdtemp" = xyes; then :
   $as_echo "#define HAVE_MKDTEMP 1" >>confdefs.h
@@ -17059,6 +17046,12 @@ esac
  ;;
 esac
 
+  case " $LIBOBJS " in
+  *" win32link.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS win32link.$ac_objext"
+ ;;
+esac
+
   case " $LIBOBJS " in
   *" win32ntdll.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS win32ntdll.$ac_objext"
diff --git a/configure.ac b/configure.ac
index ca0c65fbd9..3cf42d1ce4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1877,7 +1877,6 @@ AC_REPLACE_FUNCS(m4_normalize([
 	getopt
 	getpeereid
 	inet_aton
-	link
 	mkdtemp
 	pread
 	pwrite
@@ -1957,6 +1956,7 @@ if test "$PORTNAME" = "win32"; then
   AC_LIBOBJ(win32dlopen)
   AC_LIBOBJ(win32env)
   AC_LIBOBJ(win32error)
+  AC_LIBOBJ(win32link)
   AC_LIBOBJ(win32ntdll)
   AC_LIBOBJ(win32security)
   AC_LIBOBJ(win32setlocale)
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 15e01efa06..beb42549c1 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -334,9 +334,6 @@
 /* Define to 1 if you have the `zstd' library (-lzstd). */
 #undef HAVE_LIBZSTD
 
-/* Define to 1 if you have the `link' function. */
-#undef HAVE_LINK
-
 /* Define to 1 if the system has the type `locale_t'. */
 #undef HAVE_LOCALE_T
 
diff --git a/src/include/port.h b/src/include/port.h
index daab10ead4..a409cfee4c 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -402,7 +402,8 @@ extern float pg_strtof(const char *nptr, char **endptr);
 #define strtof(a,b) (pg_strtof((a),(b)))
 #endif
 
-#ifndef HAVE_LINK
+#ifdef WIN32
+/* src/port/win32link.c */
 extern int	link(const char *src, const char *dst);
 #endif
 
diff --git a/src/port/link.c b/src/port/win32link.c
similarity index 92%
rename from src/port/link.c
rename to src/port/win32link.c
index 1e0ccd4648..0658479046 100644
--- a/src/port/link.c
+++ b/src/port/win32link.c
@@ -1,21 +1,19 @@
 /*-------------------------------------------------------------------------
  *
- * link.c
+ * win32link.c
  *
  * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  *
  * IDENTIFICATION
- *	  src/port/link.c
+ *	  src/port/win32link.c
  *
  *-------------------------------------------------------------------------
  */
 
 #include "c.h"
 
-#ifdef WIN32
-
 int
 link(const char *src, const char *dst)
 {
@@ -31,5 +29,3 @@ link(const char *src, const char *dst)
 	else
 		return 0;
 }
-
-#endif
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index 266f98e2ed..1ffe6e66d5 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -103,13 +103,15 @@ sub mkvcbuild
 	  getpeereid.c getrusage.c inet_aton.c
 	  getaddrinfo.c gettimeofday.c inet_net_ntop.c kill.c open.c
 	  snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c
-	  dirent.c getopt.c getopt_long.c link.c
+	  dirent.c getopt.c getopt_long.c
 	  pread.c preadv.c pwrite.c pwritev.c pg_bitutils.c
 	  pg_strong_random.c pgcheckdir.c pgmkdirp.c pgsleep.c pgstrcasecmp.c
 	  pqsignal.c mkdtemp.c qsort.c qsort_arg.c bsearch_arg.c quotes.c system.c
 	  strerror.c tar.c
 	  win32dlopen.c
-	  win32env.c win32error.c win32ntdll.c
+	  win32env.c win32error.c
+	  win32link.c
+	  win32ntdll.c
 	  win32security.c win32setlocale.c win32stat.c);
 
 	push(@pgportfiles, 'strtof.c') if ($vsVersion < '14.00');
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 71db5f60f8..7806ad67d0 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -306,7 +306,6 @@ sub GenerateFiles
 		HAVE_LIBXSLT                                => undef,
 		HAVE_LIBZ                   => $self->{options}->{zlib} ? 1 : undef,
 		HAVE_LIBZSTD                => undef,
-		HAVE_LINK                   => undef,
 		HAVE_LOCALE_T               => 1,
 		HAVE_LONG_INT_64            => undef,
 		HAVE_LONG_LONG_INT_64       => 1,
-- 
2.37.1

v3-0007-Remove-dead-replacement-code-for-clock_gettime.patchtext/x-patch; charset=US-ASCII; name=v3-0007-Remove-dead-replacement-code-for-clock_gettime.patchDownload
From 2b6b5b7ff749a9b84c75ea07332a636671ad64ee Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sun, 24 Jul 2022 00:12:37 +1200
Subject: [PATCH v3 07/13] Remove dead replacement code for clock_gettime().

clock_gettime() is in SUSv2 (realtime) and all targeted Unix systems
have it.  Fallback code for old Unix is no longer reachable on modern
systems, though we still need Windows-specific code.

There is no need to retain a HAVE_CLOCK_GETTIME macro here, because it
is used in contexts that have very obvious Unix and Windows code
variants.

XXX This can only be committed once prairedog is decommissioned, because
macOS 10.4 didn't have clock_gettime().

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CA+hUKGJ3LHeP9w5Fgzdr4G8AnEtJ=z=p6hGDEm4qYGEUX5B6fQ@mail.gmail.com
---
 configure                            |  2 +-
 configure.ac                         |  1 -
 src/include/pg_config.h.in           |  3 --
 src/include/portability/instr_time.h | 68 ----------------------------
 src/tools/msvc/Solution.pm           |  1 -
 5 files changed, 1 insertion(+), 74 deletions(-)

diff --git a/configure b/configure
index 6358bdcabc..fc1739b431 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 readv setproctitle setproctitle_fast strchrnul strsignal syncfs sync_file_range uselocale wcstombs_l writev
+for ac_func in backtrace_symbols 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"
diff --git a/configure.ac b/configure.ac
index 3cf42d1ce4..7e071ce585 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1792,7 +1792,6 @@ LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'`
 
 AC_CHECK_FUNCS(m4_normalize([
 	backtrace_symbols
-	clock_gettime
 	copyfile
 	fdatasync
 	getifaddrs
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index beb42549c1..16c160af4c 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -83,9 +83,6 @@
 /* Define to 1 if you have the `BIO_meth_new' function. */
 #undef HAVE_BIO_METH_NEW
 
-/* Define to 1 if you have the `clock_gettime' function. */
-#undef HAVE_CLOCK_GETTIME
-
 /* Define to 1 if your compiler handles computed gotos. */
 #undef HAVE_COMPUTED_GOTO
 
diff --git a/src/include/portability/instr_time.h b/src/include/portability/instr_time.h
index ca09a1608f..8faeca8b49 100644
--- a/src/include/portability/instr_time.h
+++ b/src/include/portability/instr_time.h
@@ -57,8 +57,6 @@
 
 #ifndef WIN32
 
-#ifdef HAVE_CLOCK_GETTIME
-
 /* Use clock_gettime() */
 
 #include <time.h>
@@ -141,72 +139,6 @@ typedef struct timespec instr_time;
 #define INSTR_TIME_GET_MICROSEC(t) \
 	(((uint64) (t).tv_sec * (uint64) 1000000) + (uint64) ((t).tv_nsec / 1000))
 
-#else							/* !HAVE_CLOCK_GETTIME */
-
-/* Use gettimeofday() */
-
-#include <sys/time.h>
-
-typedef struct timeval instr_time;
-
-#define INSTR_TIME_IS_ZERO(t)	((t).tv_usec == 0 && (t).tv_sec == 0)
-
-#define INSTR_TIME_SET_ZERO(t)	((t).tv_sec = 0, (t).tv_usec = 0)
-
-#define INSTR_TIME_SET_CURRENT(t)	gettimeofday(&(t), NULL)
-
-#define INSTR_TIME_ADD(x,y) \
-	do { \
-		(x).tv_sec += (y).tv_sec; \
-		(x).tv_usec += (y).tv_usec; \
-		/* Normalize */ \
-		while ((x).tv_usec >= 1000000) \
-		{ \
-			(x).tv_usec -= 1000000; \
-			(x).tv_sec++; \
-		} \
-	} while (0)
-
-#define INSTR_TIME_SUBTRACT(x,y) \
-	do { \
-		(x).tv_sec -= (y).tv_sec; \
-		(x).tv_usec -= (y).tv_usec; \
-		/* Normalize */ \
-		while ((x).tv_usec < 0) \
-		{ \
-			(x).tv_usec += 1000000; \
-			(x).tv_sec--; \
-		} \
-	} while (0)
-
-#define INSTR_TIME_ACCUM_DIFF(x,y,z) \
-	do { \
-		(x).tv_sec += (y).tv_sec - (z).tv_sec; \
-		(x).tv_usec += (y).tv_usec - (z).tv_usec; \
-		/* Normalize after each add to avoid overflow/underflow of tv_usec */ \
-		while ((x).tv_usec < 0) \
-		{ \
-			(x).tv_usec += 1000000; \
-			(x).tv_sec--; \
-		} \
-		while ((x).tv_usec >= 1000000) \
-		{ \
-			(x).tv_usec -= 1000000; \
-			(x).tv_sec++; \
-		} \
-	} while (0)
-
-#define INSTR_TIME_GET_DOUBLE(t) \
-	(((double) (t).tv_sec) + ((double) (t).tv_usec) / 1000000.0)
-
-#define INSTR_TIME_GET_MILLISEC(t) \
-	(((double) (t).tv_sec * 1000.0) + ((double) (t).tv_usec) / 1000.0)
-
-#define INSTR_TIME_GET_MICROSEC(t) \
-	(((uint64) (t).tv_sec * (uint64) 1000000) + (uint64) (t).tv_usec)
-
-#endif							/* HAVE_CLOCK_GETTIME */
-
 #else							/* WIN32 */
 
 /* Use QueryPerformanceCounter() */
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 7806ad67d0..9bc23ae919 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -228,7 +228,6 @@ sub GenerateFiles
 		HAVE_BACKTRACE_SYMBOLS     => undef,
 		HAVE_BIO_GET_DATA          => undef,
 		HAVE_BIO_METH_NEW          => undef,
-		HAVE_CLOCK_GETTIME         => undef,
 		HAVE_COMPUTED_GOTO         => undef,
 		HAVE_COPYFILE              => undef,
 		HAVE_COPYFILE_H            => undef,
-- 
2.37.1

v3-0008-Remove-configure-probes-for-poll-and-poll.h.patchtext/x-patch; charset=US-ASCII; name=v3-0008-Remove-configure-probes-for-poll-and-poll.h.patchDownload
From efb9375fc11e9fe29b8fe5dffc561a78d0bf0fce Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 30 Jul 2022 15:35:11 +1200
Subject: [PATCH v3 08/13] Remove configure probes for poll and poll.h.

poll() and <poll.h> are in SUSv2 and all targeted Unix systems have
them.

Retain HAVE_POLL and HAVE_POLL_H macros for readability.  There's an
error in latch.c that is now unreachable (since logically always have
one of WIN32 or HAVE_POLL defined), but that falls out of a decision to
keep using defined(HAVE_POLL) instead of !defined(WIN32) to guard the
poll() code.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CA+hUKGJ3LHeP9w5Fgzdr4G8AnEtJ=z=p6hGDEm4qYGEUX5B6fQ@mail.gmail.com
---
 configure                  | 4 ++--
 configure.ac               | 2 --
 src/include/pg_config.h.in | 6 ------
 src/include/port.h         | 2 ++
 src/tools/msvc/Solution.pm | 2 --
 5 files changed, 4 insertions(+), 12 deletions(-)

diff --git a/configure b/configure
index fc1739b431..4dd90cd9ef 100755
--- a/configure
+++ b/configure
@@ -13875,7 +13875,7 @@ $as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h
 fi
 
 
-for ac_header in atomic.h copyfile.h execinfo.h getopt.h ifaddrs.h langinfo.h mbarrier.h poll.h sys/epoll.h sys/event.h sys/ipc.h sys/personality.h sys/prctl.h sys/procctl.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/signalfd.h sys/sockio.h sys/uio.h sys/un.h termios.h ucred.h
+for ac_header in atomic.h copyfile.h execinfo.h getopt.h ifaddrs.h langinfo.h mbarrier.h sys/epoll.h sys/event.h sys/ipc.h sys/personality.h sys/prctl.h sys/procctl.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/signalfd.h sys/sockio.h sys/uio.h sys/un.h termios.h ucred.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@@ -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 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
+for ac_func in backtrace_symbols copyfile fdatasync getifaddrs getpeerucred inet_pton kqueue mbstowcs_l memset_s 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"
diff --git a/configure.ac b/configure.ac
index 7e071ce585..b2304bb4de 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1452,7 +1452,6 @@ AC_CHECK_HEADERS(m4_normalize([
 	ifaddrs.h
 	langinfo.h
 	mbarrier.h
-	poll.h
 	sys/epoll.h
 	sys/event.h
 	sys/ipc.h
@@ -1800,7 +1799,6 @@ AC_CHECK_FUNCS(m4_normalize([
 	kqueue
 	mbstowcs_l
 	memset_s
-	poll
 	posix_fallocate
 	ppoll
 	pthread_is_threaded_np
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 16c160af4c..131c27c1d6 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -373,12 +373,6 @@
 /* Define to 1 if you have the <pam/pam_appl.h> header file. */
 #undef HAVE_PAM_PAM_APPL_H
 
-/* Define to 1 if you have the `poll' function. */
-#undef HAVE_POLL
-
-/* Define to 1 if you have the <poll.h> header file. */
-#undef HAVE_POLL_H
-
 /* Define to 1 if you have the `posix_fadvise' function. */
 #undef HAVE_POSIX_FADVISE
 
diff --git a/src/include/port.h b/src/include/port.h
index a409cfee4c..d29b301292 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -532,6 +532,8 @@ extern bool wait_result_is_any_signal(int exit_status, bool include_command_not_
  */
 #ifndef WIN32
 #define HAVE_GETRLIMIT 1
+#define HAVE_POLL 1
+#define HAVE_POLL_H 1
 #define HAVE_READLINK 1
 #define HAVE_SETSID 1
 #define HAVE_SHM_OPEN 1
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 9bc23ae919..f3e7c16524 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -319,8 +319,6 @@ sub GenerateFiles
 		HAVE_OPENSSL_INIT_SSL       => undef,
 		HAVE_OSSP_UUID_H            => undef,
 		HAVE_PAM_PAM_APPL_H         => undef,
-		HAVE_POLL                   => undef,
-		HAVE_POLL_H                 => undef,
 		HAVE_POSIX_FADVISE          => undef,
 		HAVE_POSIX_FALLOCATE        => undef,
 		HAVE_PPC_LWARX_MUTEX_HINT   => undef,
-- 
2.37.1

v3-0009-Remove-dead-setenv-unsetenv-replacement-code.patchtext/x-patch; charset=US-ASCII; name=v3-0009-Remove-dead-setenv-unsetenv-replacement-code.patchDownload
From 21f700dc78af415ec3bea2e4461b555e559bf55b Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 9 Jul 2022 23:00:49 +1200
Subject: [PATCH v3 09/13] Remove dead setenv, unsetenv replacement code.

setenv() and unsetenv() are in SUSv3 and targeted Unix systems have
them.  We still need special code for these on Windows, but that doesn't
require a configure probe.

This marks the first time we require a SUSv3 (POSIX.1-2001) facility
(rather than SUSv2).  The replacement code removed here was not needed
on any targeted system or any known non-EOL'd Unix system, and was
therefore dead and untested.

No need for vestigial HAVE_SETENV and HAVE_UNSETENV macros, because we
provide a replacement for Windows, and we didn't previously test the
macros.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Greg Stark <stark@mit.edu>
Reviewed-by: Robert Haas <robertmhaas@gmail.com>
Discussion: https://postgr.es/m/CA+hUKGJ3LHeP9w5Fgzdr4G8AnEtJ=z=p6hGDEm4qYGEUX5B6fQ@mail.gmail.com
---
 configure                  | 43 -------------------------
 configure.ac               | 13 --------
 src/include/pg_config.h.in |  6 ----
 src/include/port.h         |  8 -----
 src/port/setenv.c          | 48 ----------------------------
 src/port/unsetenv.c        | 65 --------------------------------------
 src/tools/msvc/Solution.pm |  2 --
 7 files changed, 185 deletions(-)
 delete mode 100644 src/port/setenv.c
 delete mode 100644 src/port/unsetenv.c

diff --git a/configure b/configure
index 4dd90cd9ef..ec1aba0c35 100755
--- a/configure
+++ b/configure
@@ -16841,49 +16841,6 @@ esac
 $as_echo "$as_me: On $host_os we will use our strtof wrapper." >&6;}
 fi
 
-case $host_os in
-        # Windows uses a specialised env handler
-        mingw*)
-
-$as_echo "#define HAVE_SETENV 1" >>confdefs.h
-
-
-$as_echo "#define HAVE_UNSETENV 1" >>confdefs.h
-
-                ac_cv_func_setenv=yes
-                ac_cv_func_unsetenv=yes
-                ;;
-        *)
-                ac_fn_c_check_func "$LINENO" "setenv" "ac_cv_func_setenv"
-if test "x$ac_cv_func_setenv" = xyes; then :
-  $as_echo "#define HAVE_SETENV 1" >>confdefs.h
-
-else
-  case " $LIBOBJS " in
-  *" setenv.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS setenv.$ac_objext"
- ;;
-esac
-
-fi
-
-ac_fn_c_check_func "$LINENO" "unsetenv" "ac_cv_func_unsetenv"
-if test "x$ac_cv_func_unsetenv" = xyes; then :
-  $as_echo "#define HAVE_UNSETENV 1" >>confdefs.h
-
-else
-  case " $LIBOBJS " in
-  *" unsetenv.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS unsetenv.$ac_objext"
- ;;
-esac
-
-fi
-
-
-                ;;
-esac
-
 # System's version of getaddrinfo(), if any, may be used only if we found
 # a definition for struct addrinfo; see notes in src/include/getaddrinfo.h.
 # We use only our own getaddrinfo.c on Windows, but it's time to revisit that.
diff --git a/configure.ac b/configure.ac
index b2304bb4de..672c673bc8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1897,19 +1897,6 @@ if test "$PORTNAME" = "win32" -o "$PORTNAME" = "cygwin"; then
 	AC_MSG_NOTICE([On $host_os we will use our strtof wrapper.])
 fi
 
-case $host_os in
-        # Windows uses a specialised env handler
-        mingw*)
-                AC_DEFINE(HAVE_SETENV, 1, [Define to 1 because replacement version used.])
-                AC_DEFINE(HAVE_UNSETENV, 1, [Define to 1 because replacement version used.])
-                ac_cv_func_setenv=yes
-                ac_cv_func_unsetenv=yes
-                ;;
-        *)
-                AC_REPLACE_FUNCS([setenv unsetenv])
-                ;;
-esac
-
 # System's version of getaddrinfo(), if any, may be used only if we found
 # a definition for struct addrinfo; see notes in src/include/getaddrinfo.h.
 # We use only our own getaddrinfo.c on Windows, but it's time to revisit that.
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 131c27c1d6..db143766c9 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -445,9 +445,6 @@
 /* Define to 1 if you have the <security/pam_appl.h> header file. */
 #undef HAVE_SECURITY_PAM_APPL_H
 
-/* Define to 1 if you have the `setenv' function. */
-#undef HAVE_SETENV
-
 /* Define to 1 if you have the `setproctitle' function. */
 #undef HAVE_SETPROCTITLE
 
@@ -622,9 +619,6 @@
 /* Define to 1 if you have the <unistd.h> header file. */
 #undef HAVE_UNISTD_H
 
-/* Define to 1 if you have the `unsetenv' function. */
-#undef HAVE_UNSETENV
-
 /* Define to 1 if you have the `uselocale' function. */
 #undef HAVE_USELOCALE
 
diff --git a/src/include/port.h b/src/include/port.h
index d29b301292..7d631d1750 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -448,14 +448,6 @@ extern size_t strlcpy(char *dst, const char *src, size_t siz);
 extern size_t strnlen(const char *str, size_t maxlen);
 #endif
 
-#ifndef HAVE_SETENV
-extern int	setenv(const char *name, const char *value, int overwrite);
-#endif
-
-#ifndef HAVE_UNSETENV
-extern int	unsetenv(const char *name);
-#endif
-
 /* thread.c */
 #ifndef WIN32
 extern bool pg_get_user_name(uid_t user_id, char *buffer, size_t buflen);
diff --git a/src/port/setenv.c b/src/port/setenv.c
deleted file mode 100644
index d13c882467..0000000000
--- a/src/port/setenv.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * setenv.c
- *	  setenv() emulation for machines without it
- *
- * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- *
- * IDENTIFICATION
- *	  src/port/setenv.c
- *
- *-------------------------------------------------------------------------
- */
-
-#include "c.h"
-
-
-int
-setenv(const char *name, const char *value, int overwrite)
-{
-	char	   *envstr;
-
-	/* Error conditions, per POSIX */
-	if (name == NULL || name[0] == '\0' || strchr(name, '=') != NULL ||
-		value == NULL)
-	{
-		errno = EINVAL;
-		return -1;
-	}
-
-	/* No work if variable exists and we're not to replace it */
-	if (overwrite == 0 && getenv(name) != NULL)
-		return 0;
-
-	/*
-	 * Add or replace the value using putenv().  This will leak memory if the
-	 * same variable is repeatedly redefined, but there's little we can do
-	 * about that when sitting atop putenv().
-	 */
-	envstr = (char *) malloc(strlen(name) + strlen(value) + 2);
-	if (!envstr)				/* not much we can do if no memory */
-		return -1;
-
-	sprintf(envstr, "%s=%s", name, value);
-
-	return putenv(envstr);
-}
diff --git a/src/port/unsetenv.c b/src/port/unsetenv.c
deleted file mode 100644
index 62b806d796..0000000000
--- a/src/port/unsetenv.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * unsetenv.c
- *	  unsetenv() emulation for machines without it
- *
- * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- *
- * IDENTIFICATION
- *	  src/port/unsetenv.c
- *
- *-------------------------------------------------------------------------
- */
-
-#include "c.h"
-
-
-int
-unsetenv(const char *name)
-{
-	char	   *envstr;
-
-	/* Error conditions, per POSIX */
-	if (name == NULL || name[0] == '\0' || strchr(name, '=') != NULL)
-	{
-		errno = EINVAL;
-		return -1;
-	}
-
-	if (getenv(name) == NULL)
-		return 0;				/* no work */
-
-	/*
-	 * The technique embodied here works if libc follows the Single Unix Spec
-	 * and actually uses the storage passed to putenv() to hold the environ
-	 * entry.  When we clobber the entry in the second step we are ensuring
-	 * that we zap the actual environ member.  However, there are some libc
-	 * implementations (notably recent BSDs) that do not obey SUS but copy the
-	 * presented string.  This method fails on such platforms.  Hopefully all
-	 * such platforms have unsetenv() and thus won't be using this hack. See:
-	 * http://www.greenend.org.uk/rjk/2008/putenv.html
-	 *
-	 * Note that repeatedly setting and unsetting a var using this code will
-	 * leak memory.
-	 */
-
-	envstr = (char *) malloc(strlen(name) + 2);
-	if (!envstr)				/* not much we can do if no memory */
-		return -1;
-
-	/* Override the existing setting by forcibly defining the var */
-	sprintf(envstr, "%s=", name);
-	if (putenv(envstr))
-		return -1;
-
-	/* Now we can clobber the variable definition this way: */
-	strcpy(envstr, "=");
-
-	/*
-	 * This last putenv cleans up if we have multiple zero-length names as a
-	 * result of unsetting multiple things.
-	 */
-	return putenv(envstr);
-}
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index f3e7c16524..bfc639c150 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -342,7 +342,6 @@ sub GenerateFiles
 		HAVE_RL_RESET_SCREEN_SIZE                => undef,
 		HAVE_RL_VARIABLE_BIND                    => undef,
 		HAVE_SECURITY_PAM_APPL_H                 => undef,
-		HAVE_SETENV                              => undef,
 		HAVE_SETPROCTITLE                        => undef,
 		HAVE_SETPROCTITLE_FAST                   => undef,
 		HAVE_SOCKLEN_T                           => 1,
@@ -401,7 +400,6 @@ sub GenerateFiles
 		HAVE_UINT8                               => undef,
 		HAVE_UNION_SEMUN                         => undef,
 		HAVE_UNISTD_H                            => 1,
-		HAVE_UNSETENV                            => undef,
 		HAVE_USELOCALE                           => undef,
 		HAVE_UUID_BSD                            => undef,
 		HAVE_UUID_E2FS                           => undef,
-- 
2.37.1

v3-0010-Remove-dead-pread-and-pwrite-replacement-code.patchtext/x-patch; charset=US-ASCII; name=v3-0010-Remove-dead-pread-and-pwrite-replacement-code.patchDownload
From de5d364e83ad456d4acdf77618513148ddf99a76 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 9 Jul 2022 21:31:56 +1200
Subject: [PATCH v3 10/13] Remove dead pread and pwrite replacement code.

pread() and pwrite() are in SUSv2, and all targeted Unix systems have
them.

Previously, we defined pg_pread and pg_pwrite to emulate these function
with lseek() on old Unixen.  The names with a pg_ prefix were a reminder
of a portability hazard: they might change the current file position.
That hazard is gone, so we can drop the prefixes.

Since the remaining replacement code is Windows-only, move it into
src/port/win32p{read,write}.c, move the declarations into
src/include/port/win32_port.h and adopt the usual convention of a
pgwin32_ prefix and a macro.

No need for vestigial HAVE_PREAD, HAVE_PWRITE macros as they were only
used for declarations in port.h which have now moved into win32_port.h.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Greg Stark <stark@mit.edu>
Reviewed-by: Robert Haas <robertmhaas@gmail.com>
Discussion: https://postgr.es/m/CA+hUKGJ3LHeP9w5Fgzdr4G8AnEtJ=z=p6hGDEm4qYGEUX5B6fQ@mail.gmail.com
---
 configure                                     | 38 +++++---------
 configure.ac                                  |  4 +-
 .../pg_stat_statements/pg_stat_statements.c   |  4 +-
 src/backend/access/heap/rewriteheap.c         |  2 +-
 src/backend/access/transam/slru.c             |  4 +-
 src/backend/access/transam/xlog.c             |  4 +-
 src/backend/access/transam/xlogreader.c       |  2 +-
 src/backend/access/transam/xlogrecovery.c     |  2 +-
 src/backend/replication/basebackup.c          |  2 +-
 src/backend/replication/walreceiver.c         |  2 +-
 src/backend/storage/file/fd.c                 |  4 +-
 src/backend/utils/init/miscinit.c             |  2 +-
 src/bin/pg_test_fsync/pg_test_fsync.c         | 50 +++++++++----------
 src/include/access/xlogreader.h               |  4 +-
 src/include/pg_config.h.in                    |  6 ---
 src/include/port.h                            | 19 -------
 src/include/port/win32_port.h                 |  9 ++++
 src/port/preadv.c                             |  4 +-
 src/port/pwritev.c                            |  4 +-
 src/port/{pread.c => win32pread.c}            | 22 ++------
 src/port/{pwrite.c => win32pwrite.c}          | 22 ++------
 src/tools/msvc/Mkvcbuild.pm                   |  4 +-
 src/tools/msvc/Solution.pm                    |  2 -
 23 files changed, 79 insertions(+), 137 deletions(-)
 rename src/port/{pread.c => win32pread.c} (61%)
 rename src/port/{pwrite.c => win32pwrite.c} (59%)

diff --git a/configure b/configure
index ec1aba0c35..4d81993515 100755
--- a/configure
+++ b/configure
@@ -16728,32 +16728,6 @@ esac
 
 fi
 
-ac_fn_c_check_func "$LINENO" "pread" "ac_cv_func_pread"
-if test "x$ac_cv_func_pread" = xyes; then :
-  $as_echo "#define HAVE_PREAD 1" >>confdefs.h
-
-else
-  case " $LIBOBJS " in
-  *" pread.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS pread.$ac_objext"
- ;;
-esac
-
-fi
-
-ac_fn_c_check_func "$LINENO" "pwrite" "ac_cv_func_pwrite"
-if test "x$ac_cv_func_pwrite" = xyes; then :
-  $as_echo "#define HAVE_PWRITE 1" >>confdefs.h
-
-else
-  case " $LIBOBJS " in
-  *" pwrite.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS pwrite.$ac_objext"
- ;;
-esac
-
-fi
-
 ac_fn_c_check_func "$LINENO" "strlcat" "ac_cv_func_strlcat"
 if test "x$ac_cv_func_strlcat" = xyes; then :
   $as_echo "#define HAVE_STRLCAT 1" >>confdefs.h
@@ -17015,6 +16989,18 @@ esac
  ;;
 esac
 
+  case " $LIBOBJS " in
+  *" win32pread.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS win32pread.$ac_objext"
+ ;;
+esac
+
+  case " $LIBOBJS " in
+  *" win32pwrite.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS win32pwrite.$ac_objext"
+ ;;
+esac
+
   case " $LIBOBJS " in
   *" win32security.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS win32security.$ac_objext"
diff --git a/configure.ac b/configure.ac
index 672c673bc8..d36d983a57 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1875,8 +1875,6 @@ AC_REPLACE_FUNCS(m4_normalize([
 	getpeereid
 	inet_aton
 	mkdtemp
-	pread
-	pwrite
 	strlcat
 	strlcpy
 	strnlen
@@ -1942,6 +1940,8 @@ if test "$PORTNAME" = "win32"; then
   AC_LIBOBJ(win32error)
   AC_LIBOBJ(win32link)
   AC_LIBOBJ(win32ntdll)
+  AC_LIBOBJ(win32pread)
+  AC_LIBOBJ(win32pwrite)
   AC_LIBOBJ(win32security)
   AC_LIBOBJ(win32setlocale)
   AC_LIBOBJ(win32stat)
diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c
index 049da9fe6d..0d72ea212e 100644
--- a/contrib/pg_stat_statements/pg_stat_statements.c
+++ b/contrib/pg_stat_statements/pg_stat_statements.c
@@ -2091,9 +2091,9 @@ qtext_store(const char *query, int query_len,
 	if (fd < 0)
 		goto error;
 
-	if (pg_pwrite(fd, query, query_len, off) != query_len)
+	if (pwrite(fd, query, query_len, off) != query_len)
 		goto error;
-	if (pg_pwrite(fd, "\0", 1, off + query_len) != 1)
+	if (pwrite(fd, "\0", 1, off + query_len) != 1)
 		goto error;
 
 	CloseTransientFile(fd);
diff --git a/src/backend/access/heap/rewriteheap.c b/src/backend/access/heap/rewriteheap.c
index 197f06b5ec..9dd885d936 100644
--- a/src/backend/access/heap/rewriteheap.c
+++ b/src/backend/access/heap/rewriteheap.c
@@ -1149,7 +1149,7 @@ heap_xlog_logical_rewrite(XLogReaderState *r)
 	/* write out tail end of mapping file (again) */
 	errno = 0;
 	pgstat_report_wait_start(WAIT_EVENT_LOGICAL_REWRITE_MAPPING_WRITE);
-	if (pg_pwrite(fd, data, len, xlrec->offset) != len)
+	if (pwrite(fd, data, len, xlrec->offset) != len)
 	{
 		/* if write didn't set errno, assume problem is no disk space */
 		if (errno == 0)
diff --git a/src/backend/access/transam/slru.c b/src/backend/access/transam/slru.c
index b65cb49d7f..c9a7b97949 100644
--- a/src/backend/access/transam/slru.c
+++ b/src/backend/access/transam/slru.c
@@ -718,7 +718,7 @@ SlruPhysicalReadPage(SlruCtl ctl, int pageno, int slotno)
 
 	errno = 0;
 	pgstat_report_wait_start(WAIT_EVENT_SLRU_READ);
-	if (pg_pread(fd, shared->page_buffer[slotno], BLCKSZ, offset) != BLCKSZ)
+	if (pread(fd, shared->page_buffer[slotno], BLCKSZ, offset) != BLCKSZ)
 	{
 		pgstat_report_wait_end();
 		slru_errcause = SLRU_READ_FAILED;
@@ -873,7 +873,7 @@ SlruPhysicalWritePage(SlruCtl ctl, int pageno, int slotno, SlruWriteAll fdata)
 
 	errno = 0;
 	pgstat_report_wait_start(WAIT_EVENT_SLRU_WRITE);
-	if (pg_pwrite(fd, shared->page_buffer[slotno], BLCKSZ, offset) != BLCKSZ)
+	if (pwrite(fd, shared->page_buffer[slotno], BLCKSZ, offset) != BLCKSZ)
 	{
 		pgstat_report_wait_end();
 		/* if write didn't set errno, assume problem is no disk space */
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 26fbed00a4..eb5115fd5a 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -2189,7 +2189,7 @@ XLogWrite(XLogwrtRqst WriteRqst, TimeLineID tli, bool flexible)
 					INSTR_TIME_SET_CURRENT(start);
 
 				pgstat_report_wait_start(WAIT_EVENT_WAL_WRITE);
-				written = pg_pwrite(openLogFile, from, nleft, startoffset);
+				written = pwrite(openLogFile, from, nleft, startoffset);
 				pgstat_report_wait_end();
 
 				/*
@@ -3011,7 +3011,7 @@ XLogFileInitInternal(XLogSegNo logsegno, TimeLineID logtli,
 		 * enough.
 		 */
 		errno = 0;
-		if (pg_pwrite(fd, zbuffer.data, 1, wal_segment_size - 1) != 1)
+		if (pwrite(fd, zbuffer.data, 1, wal_segment_size - 1) != 1)
 		{
 			/* if write didn't set errno, assume no disk space */
 			save_errno = errno ? errno : ENOSPC;
diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c
index f3dc4b7797..06e91547dd 100644
--- a/src/backend/access/transam/xlogreader.c
+++ b/src/backend/access/transam/xlogreader.c
@@ -1514,7 +1514,7 @@ WALRead(XLogReaderState *state,
 
 		/* Reset errno first; eases reporting non-errno-affecting errors */
 		errno = 0;
-		readbytes = pg_pread(state->seg.ws_file, p, segbytes, (off_t) startoff);
+		readbytes = pread(state->seg.ws_file, p, segbytes, (off_t) startoff);
 
 #ifndef FRONTEND
 		pgstat_report_wait_end();
diff --git a/src/backend/access/transam/xlogrecovery.c b/src/backend/access/transam/xlogrecovery.c
index 27e02fbfcd..21088e78f6 100644
--- a/src/backend/access/transam/xlogrecovery.c
+++ b/src/backend/access/transam/xlogrecovery.c
@@ -3260,7 +3260,7 @@ retry:
 	readOff = targetPageOff;
 
 	pgstat_report_wait_start(WAIT_EVENT_WAL_READ);
-	r = pg_pread(readFile, readBuf, XLOG_BLCKSZ, (off_t) readOff);
+	r = pread(readFile, readBuf, XLOG_BLCKSZ, (off_t) readOff);
 	if (r != XLOG_BLCKSZ)
 	{
 		char		fname[MAXFNAMELEN];
diff --git a/src/backend/replication/basebackup.c b/src/backend/replication/basebackup.c
index 09f071300d..5e457f9be9 100644
--- a/src/backend/replication/basebackup.c
+++ b/src/backend/replication/basebackup.c
@@ -1822,7 +1822,7 @@ basebackup_read_file(int fd, char *buf, size_t nbytes, off_t offset,
 	int			rc;
 
 	pgstat_report_wait_start(WAIT_EVENT_BASEBACKUP_READ);
-	rc = pg_pread(fd, buf, nbytes, offset);
+	rc = pread(fd, buf, nbytes, offset);
 	pgstat_report_wait_end();
 
 	if (rc < 0)
diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c
index 3d37c1fe62..8604fd4bc2 100644
--- a/src/backend/replication/walreceiver.c
+++ b/src/backend/replication/walreceiver.c
@@ -915,7 +915,7 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr, TimeLineID tli)
 		/* OK to write the logs */
 		errno = 0;
 
-		byteswritten = pg_pwrite(recvFile, buf, segbytes, (off_t) startoff);
+		byteswritten = pwrite(recvFile, buf, segbytes, (off_t) startoff);
 		if (byteswritten <= 0)
 		{
 			char		xlogfname[MAXFNAMELEN];
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index 447d5a86c3..3d1a973354 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -2063,7 +2063,7 @@ FileRead(File file, char *buffer, int amount, off_t offset,
 
 retry:
 	pgstat_report_wait_start(wait_event_info);
-	returnCode = pg_pread(vfdP->fd, buffer, amount, offset);
+	returnCode = pread(vfdP->fd, buffer, amount, offset);
 	pgstat_report_wait_end();
 
 	if (returnCode < 0)
@@ -2145,7 +2145,7 @@ FileWrite(File file, char *buffer, int amount, off_t offset,
 retry:
 	errno = 0;
 	pgstat_report_wait_start(wait_event_info);
-	returnCode = pg_pwrite(VfdCache[file].fd, buffer, amount, offset);
+	returnCode = pwrite(VfdCache[file].fd, buffer, amount, offset);
 	pgstat_report_wait_end();
 
 	/* if write didn't set errno, assume problem is no disk space */
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index eb43b2c5e5..bd973ba613 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -1429,7 +1429,7 @@ AddToDataDirLockFile(int target_line, const char *str)
 	len = strlen(destbuffer);
 	errno = 0;
 	pgstat_report_wait_start(WAIT_EVENT_LOCK_FILE_ADDTODATADIR_WRITE);
-	if (pg_pwrite(fd, destbuffer, len, 0) != len)
+	if (pwrite(fd, destbuffer, len, 0) != len)
 	{
 		pgstat_report_wait_end();
 		/* if write didn't set errno, assume problem is no disk space */
diff --git a/src/bin/pg_test_fsync/pg_test_fsync.c b/src/bin/pg_test_fsync/pg_test_fsync.c
index 6739214eb8..8f0ef8e66b 100644
--- a/src/bin/pg_test_fsync/pg_test_fsync.c
+++ b/src/bin/pg_test_fsync/pg_test_fsync.c
@@ -312,10 +312,10 @@ test_sync(int writes_per_op)
 		for (ops = 0; alarm_triggered == false; ops++)
 		{
 			for (writes = 0; writes < writes_per_op; writes++)
-				if (pg_pwrite(tmpfile,
-							  buf,
-							  XLOG_BLCKSZ,
-							  writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
+				if (pwrite(tmpfile,
+						   buf,
+						   XLOG_BLCKSZ,
+						   writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
 					die("write failed");
 		}
 		STOP_TIMER;
@@ -338,10 +338,10 @@ test_sync(int writes_per_op)
 	for (ops = 0; alarm_triggered == false; ops++)
 	{
 		for (writes = 0; writes < writes_per_op; writes++)
-			if (pg_pwrite(tmpfile,
-						  buf,
-						  XLOG_BLCKSZ,
-						  writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
+			if (pwrite(tmpfile,
+					   buf,
+					   XLOG_BLCKSZ,
+					   writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
 				die("write failed");
 		fdatasync(tmpfile);
 	}
@@ -363,10 +363,10 @@ test_sync(int writes_per_op)
 	for (ops = 0; alarm_triggered == false; ops++)
 	{
 		for (writes = 0; writes < writes_per_op; writes++)
-			if (pg_pwrite(tmpfile,
-						  buf,
-						  XLOG_BLCKSZ,
-						  writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
+			if (pwrite(tmpfile,
+					   buf,
+					   XLOG_BLCKSZ,
+					   writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
 				die("write failed");
 		if (fsync(tmpfile) != 0)
 			die("fsync failed");
@@ -387,10 +387,10 @@ test_sync(int writes_per_op)
 	for (ops = 0; alarm_triggered == false; ops++)
 	{
 		for (writes = 0; writes < writes_per_op; writes++)
-			if (pg_pwrite(tmpfile,
-						  buf,
-						  XLOG_BLCKSZ,
-						  writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
+			if (pwrite(tmpfile,
+					   buf,
+					   XLOG_BLCKSZ,
+					   writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
 				die("write failed");
 		if (pg_fsync_writethrough(tmpfile) != 0)
 			die("fsync failed");
@@ -419,10 +419,10 @@ test_sync(int writes_per_op)
 		for (ops = 0; alarm_triggered == false; ops++)
 		{
 			for (writes = 0; writes < writes_per_op; writes++)
-				if (pg_pwrite(tmpfile,
-							  buf,
-							  XLOG_BLCKSZ,
-							  writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
+				if (pwrite(tmpfile,
+						   buf,
+						   XLOG_BLCKSZ,
+						   writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
 
 					/*
 					 * This can generate write failures if the filesystem has
@@ -484,10 +484,10 @@ test_open_sync(const char *msg, int writes_size)
 		for (ops = 0; alarm_triggered == false; ops++)
 		{
 			for (writes = 0; writes < 16 / writes_size; writes++)
-				if (pg_pwrite(tmpfile,
-							  buf,
-							  writes_size * 1024,
-							  writes * writes_size * 1024) !=
+				if (pwrite(tmpfile,
+						   buf,
+						   writes_size * 1024,
+						   writes * writes_size * 1024) !=
 					writes_size * 1024)
 					die("write failed");
 		}
@@ -586,7 +586,7 @@ test_non_sync(void)
 	START_TIMER;
 	for (ops = 0; alarm_triggered == false; ops++)
 	{
-		if (pg_pwrite(tmpfile, buf, XLOG_BLCKSZ, 0) != XLOG_BLCKSZ)
+		if (pwrite(tmpfile, buf, XLOG_BLCKSZ, 0) != XLOG_BLCKSZ)
 			die("write failed");
 	}
 	STOP_TIMER;
diff --git a/src/include/access/xlogreader.h b/src/include/access/xlogreader.h
index 5395f155aa..87ff00feb7 100644
--- a/src/include/access/xlogreader.h
+++ b/src/include/access/xlogreader.h
@@ -375,11 +375,11 @@ extern bool XLogReaderValidatePageHeader(XLogReaderState *state,
 
 /*
  * Error information from WALRead that both backend and frontend caller can
- * process.  Currently only errors from pg_pread can be reported.
+ * process.  Currently only errors from pread can be reported.
  */
 typedef struct WALReadError
 {
-	int			wre_errno;		/* errno set by the last pg_pread() */
+	int			wre_errno;		/* errno set by the last pread() */
 	int			wre_off;		/* Offset we tried to read from. */
 	int			wre_req;		/* Bytes requested to be read. */
 	int			wre_read;		/* Bytes read by the last read(). */
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index db143766c9..29c5d60210 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -385,9 +385,6 @@
 /* Define to 1 if you have the `ppoll' function. */
 #undef HAVE_PPOLL
 
-/* Define to 1 if you have the `pread' function. */
-#undef HAVE_PREAD
-
 /* Define to 1 if the PS_STRINGS thing exists. */
 #undef HAVE_PS_STRINGS
 
@@ -403,9 +400,6 @@
 /* Have PTHREAD_PRIO_INHERIT. */
 #undef HAVE_PTHREAD_PRIO_INHERIT
 
-/* Define to 1 if you have the `pwrite' function. */
-#undef HAVE_PWRITE
-
 /* Define to 1 if you have the <readline.h> header file. */
 #undef HAVE_READLINE_H
 
diff --git a/src/include/port.h b/src/include/port.h
index 7d631d1750..5e90987834 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -417,25 +417,6 @@ extern char *mkdtemp(char *path);
 extern int	inet_aton(const char *cp, struct in_addr *addr);
 #endif
 
-/*
- * Windows and older Unix don't have pread(2) and pwrite(2).  We have
- * replacement functions, but they have slightly different semantics so we'll
- * use a name with a pg_ prefix to avoid confusion.
- */
-#ifdef HAVE_PREAD
-#define pg_pread pread
-#else
-extern ssize_t pg_pread(int fd, void *buf, size_t nbyte, off_t offset);
-#endif
-
-#ifdef HAVE_PWRITE
-#define pg_pwrite pwrite
-#else
-extern ssize_t pg_pwrite(int fd, const void *buf, size_t nbyte, off_t offset);
-#endif
-
-/* For pg_pwritev() and pg_preadv(), see port/pg_iovec.h. */
-
 #if !HAVE_DECL_STRLCAT
 extern size_t strlcat(char *dst, const char *src, size_t siz);
 #endif
diff --git a/src/include/port/win32_port.h b/src/include/port/win32_port.h
index 5cc35600a0..2954fabaa5 100644
--- a/src/include/port/win32_port.h
+++ b/src/include/port/win32_port.h
@@ -562,4 +562,13 @@ typedef unsigned short mode_t;
 #define HAVE_BUGGY_STRTOF 1
 #endif
 
+/* in port/win32pread.c */
+extern ssize_t pgwin32_pread(int fd, void *buf, size_t nbyte, off_t offset);
+
+/* in port/win32pwrite.c */
+extern ssize_t pgwin32_pwrite(int fd, const void *buf, size_t nbyte, off_t offset);
+
+#define pread pgwin32_pread
+#define pwrite pgwin32_pwrite
+
 #endif							/* PG_WIN32_PORT_H */
diff --git a/src/port/preadv.c b/src/port/preadv.c
index d12e5a122b..aa7537503f 100644
--- a/src/port/preadv.c
+++ b/src/port/preadv.c
@@ -30,7 +30,7 @@ pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 {
 #ifdef HAVE_READV
 	if (iovcnt == 1)
-		return pg_pread(fd, iov[0].iov_base, iov[0].iov_len, offset);
+		return pread(fd, iov[0].iov_base, iov[0].iov_len, offset);
 	if (lseek(fd, offset, SEEK_SET) < 0)
 		return -1;
 	return readv(fd, iov, iovcnt);
@@ -40,7 +40,7 @@ pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 
 	for (int i = 0; i < iovcnt; ++i)
 	{
-		part = pg_pread(fd, iov[i].iov_base, iov[i].iov_len, offset);
+		part = pread(fd, iov[i].iov_base, iov[i].iov_len, offset);
 		if (part < 0)
 		{
 			if (i == 0)
diff --git a/src/port/pwritev.c b/src/port/pwritev.c
index 0bdd69fffc..cb7421381e 100644
--- a/src/port/pwritev.c
+++ b/src/port/pwritev.c
@@ -30,7 +30,7 @@ pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 {
 #ifdef HAVE_WRITEV
 	if (iovcnt == 1)
-		return pg_pwrite(fd, iov[0].iov_base, iov[0].iov_len, offset);
+		return pwrite(fd, iov[0].iov_base, iov[0].iov_len, offset);
 	if (lseek(fd, offset, SEEK_SET) < 0)
 		return -1;
 	return writev(fd, iov, iovcnt);
@@ -40,7 +40,7 @@ pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 
 	for (int i = 0; i < iovcnt; ++i)
 	{
-		part = pg_pwrite(fd, iov[i].iov_base, iov[i].iov_len, offset);
+		part = pwrite(fd, iov[i].iov_base, iov[i].iov_len, offset);
 		if (part < 0)
 		{
 			if (i == 0)
diff --git a/src/port/pread.c b/src/port/win32pread.c
similarity index 61%
rename from src/port/pread.c
rename to src/port/win32pread.c
index 491605926f..381cf0be2c 100644
--- a/src/port/pread.c
+++ b/src/port/win32pread.c
@@ -1,15 +1,12 @@
 /*-------------------------------------------------------------------------
  *
- * pread.c
- *	  Implementation of pread(2) for platforms that lack one.
+ * win32pread.c
+ *	  Implementation of pread(2) for Windows.
  *
  * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *	  src/port/pread.c
- *
- * Note that this implementation changes the current file position, unlike
- * the POSIX function, so we use the name pg_pread().
+ *	  src/port/win32pread.c
  *
  *-------------------------------------------------------------------------
  */
@@ -17,16 +14,11 @@
 
 #include "postgres.h"
 
-#ifdef WIN32
 #include <windows.h>
-#else
-#include <unistd.h>
-#endif
 
 ssize_t
-pg_pread(int fd, void *buf, size_t size, off_t offset)
+pgwin32_pread(int fd, void *buf, size_t size, off_t offset)
 {
-#ifdef WIN32
 	OVERLAPPED	overlapped = {0};
 	HANDLE		handle;
 	DWORD		result;
@@ -49,10 +41,4 @@ pg_pread(int fd, void *buf, size_t size, off_t offset)
 	}
 
 	return result;
-#else
-	if (lseek(fd, offset, SEEK_SET) < 0)
-		return -1;
-
-	return read(fd, buf, size);
-#endif
 }
diff --git a/src/port/pwrite.c b/src/port/win32pwrite.c
similarity index 59%
rename from src/port/pwrite.c
rename to src/port/win32pwrite.c
index eeaffacc48..989005fa5c 100644
--- a/src/port/pwrite.c
+++ b/src/port/win32pwrite.c
@@ -1,15 +1,12 @@
 /*-------------------------------------------------------------------------
  *
- * pwrite.c
- *	  Implementation of pwrite(2) for platforms that lack one.
+ * win32pwrite.c
+ *	  Implementation of pwrite(2) for Windows.
  *
  * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *	  src/port/pwrite.c
- *
- * Note that this implementation changes the current file position, unlike
- * the POSIX function, so we use the name pg_pwrite().
+ *	  src/port/win32pwrite.c
  *
  *-------------------------------------------------------------------------
  */
@@ -17,16 +14,11 @@
 
 #include "postgres.h"
 
-#ifdef WIN32
 #include <windows.h>
-#else
-#include <unistd.h>
-#endif
 
 ssize_t
-pg_pwrite(int fd, const void *buf, size_t size, off_t offset)
+pgwin32_pwrite(int fd, const void *buf, size_t size, off_t offset)
 {
-#ifdef WIN32
 	OVERLAPPED	overlapped = {0};
 	HANDLE		handle;
 	DWORD		result;
@@ -46,10 +38,4 @@ pg_pwrite(int fd, const void *buf, size_t size, off_t offset)
 	}
 
 	return result;
-#else
-	if (lseek(fd, offset, SEEK_SET) < 0)
-		return -1;
-
-	return write(fd, buf, size);
-#endif
 }
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index 1ffe6e66d5..a06dbcae4d 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -104,13 +104,15 @@ sub mkvcbuild
 	  getaddrinfo.c gettimeofday.c inet_net_ntop.c kill.c open.c
 	  snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c
 	  dirent.c getopt.c getopt_long.c
-	  pread.c preadv.c pwrite.c pwritev.c pg_bitutils.c
+	  preadv.c pwritev.c pg_bitutils.c
 	  pg_strong_random.c pgcheckdir.c pgmkdirp.c pgsleep.c pgstrcasecmp.c
 	  pqsignal.c mkdtemp.c qsort.c qsort_arg.c bsearch_arg.c quotes.c system.c
 	  strerror.c tar.c
 	  win32dlopen.c
 	  win32env.c win32error.c
 	  win32link.c
+	  win32pread.c
+	  win32pwrite.c
 	  win32ntdll.c
 	  win32security.c win32setlocale.c win32stat.c);
 
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index bfc639c150..7a02198621 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -323,13 +323,11 @@ sub GenerateFiles
 		HAVE_POSIX_FALLOCATE        => undef,
 		HAVE_PPC_LWARX_MUTEX_HINT   => undef,
 		HAVE_PPOLL                  => undef,
-		HAVE_PREAD                  => undef,
 		HAVE_PS_STRINGS             => undef,
 		HAVE_PTHREAD                => undef,
 		HAVE_PTHREAD_BARRIER_WAIT   => undef,
 		HAVE_PTHREAD_IS_THREADED_NP => undef,
 		HAVE_PTHREAD_PRIO_INHERIT   => undef,
-		HAVE_PWRITE                 => undef,
 		HAVE_READLINE_H             => undef,
 		HAVE_READLINE_HISTORY_H     => undef,
 		HAVE_READLINE_READLINE_H    => undef,
-- 
2.37.1

v3-0011-Simplify-replacement-code-for-preadv-and-pwritev.patchtext/x-patch; charset=US-ASCII; name=v3-0011-Simplify-replacement-code-for-preadv-and-pwritev.patchDownload
From 81c6a55c7bc3788c77798e51197851f926ccd221 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 23 Jul 2022 23:24:14 +1200
Subject: [PATCH v3 11/13] Simplify replacement code for preadv and pwritev.

preadv() and pwritev() are not standardized by POSIX.  Most targeted
Unix systems have had them for more than a decade, since they are
obvious combinations of standard p- and -v functions.

In 15, we had two replacement implementations: one based on lseek() + -v
function if available, and the other based on a loop over p- function.
They aren't used for much yet, but are heavily used in a current
proposal.

Supporting two ways of falling back, at the cost of having a
pg_preadv/pg_pwritev that could never be used in a multi-threaded
program accessing the same file descriptor from two threads without
unpleasant locking does not sound like a good trade.

Therefore, drop the lseek()-based variant, and also the pg_ prefix, now
that the file position portability hazard is gone.  Previously, both
fallbacks had the file position portability hazard, because our
pread()/pwrite() replacement had the same hazard, but that problem has
been fixed for pread()/pwrite() by an earlier commit.  Now the way is
clear to expunge the file position portability hazard of the
lseek()-based variants too.

At the time of writing, the following systems in our build farm lack
native preadv/pwritev and thus use fallback code:

 * Solaris (but not illumos)
 * macOS before release 11.0
 * Windows with Cygwin
 * Windows native

With this commit, all of the above systems will now use the *same*
fallback code, the one that loops over pread()/pwrite() (which is
translated to equivalent calls in Windows).  Previously, all but Windows
native would use the readv()/writev()-based fallback that this commit
removes.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CA+hUKGJ3LHeP9w5Fgzdr4G8AnEtJ=z=p6hGDEm4qYGEUX5B6fQ@mail.gmail.com
---
 configure                     |  2 +-
 configure.ac                  |  2 --
 src/backend/storage/file/fd.c |  4 ++--
 src/include/pg_config.h.in    |  6 ------
 src/include/port/pg_iovec.h   | 12 ++++--------
 src/port/preadv.c             | 13 +------------
 src/port/pwritev.c            | 13 +------------
 src/tools/msvc/Solution.pm    |  2 --
 8 files changed, 9 insertions(+), 45 deletions(-)

diff --git a/configure b/configure
index 4d81993515..21f4520f81 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 copyfile fdatasync getifaddrs getpeerucred inet_pton kqueue mbstowcs_l memset_s posix_fallocate ppoll pthread_is_threaded_np readv setproctitle setproctitle_fast strchrnul strsignal syncfs sync_file_range uselocale wcstombs_l writev
+for ac_func in backtrace_symbols copyfile fdatasync getifaddrs getpeerucred inet_pton kqueue mbstowcs_l memset_s posix_fallocate ppoll pthread_is_threaded_np setproctitle setproctitle_fast strchrnul strsignal syncfs sync_file_range uselocale wcstombs_l
 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"
diff --git a/configure.ac b/configure.ac
index d36d983a57..a7ab660179 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1802,7 +1802,6 @@ AC_CHECK_FUNCS(m4_normalize([
 	posix_fallocate
 	ppoll
 	pthread_is_threaded_np
-	readv
 	setproctitle
 	setproctitle_fast
 	strchrnul
@@ -1811,7 +1810,6 @@ AC_CHECK_FUNCS(m4_normalize([
 	sync_file_range
 	uselocale
 	wcstombs_l
-	writev
 ]))
 
 # These typically are compiler builtins, for which AC_CHECK_FUNCS fails.
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index 3d1a973354..5a2eb01238 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -3762,7 +3762,7 @@ data_sync_elevel(int elevel)
 }
 
 /*
- * A convenience wrapper for pg_pwritev() that retries on partial write.  If an
+ * A convenience wrapper for pwritev() that retries on partial write.  If an
  * error is returned, it is unspecified how much has been written.
  */
 ssize_t
@@ -3782,7 +3782,7 @@ pg_pwritev_with_retry(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 	for (;;)
 	{
 		/* Write as much as we can. */
-		part = pg_pwritev(fd, iov, iovcnt, offset);
+		part = pwritev(fd, iov, iovcnt, offset);
 		if (part < 0)
 			return -1;
 
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 29c5d60210..6505a84211 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -409,9 +409,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 `readv' function. */
-#undef HAVE_READV
-
 /* Define to 1 if you have the `rl_completion_matches' function. */
 #undef HAVE_RL_COMPLETION_MATCHES
 
@@ -640,9 +637,6 @@
 /* Define to 1 if you have the <winldap.h> header file. */
 #undef HAVE_WINLDAP_H
 
-/* Define to 1 if you have the `writev' function. */
-#undef HAVE_WRITEV
-
 /* Define to 1 if you have the `X509_get_signature_nid' function. */
 #undef HAVE_X509_GET_SIGNATURE_NID
 
diff --git a/src/include/port/pg_iovec.h b/src/include/port/pg_iovec.h
index f0b1a71bcb..f0a50c0e01 100644
--- a/src/include/port/pg_iovec.h
+++ b/src/include/port/pg_iovec.h
@@ -39,16 +39,12 @@ struct iovec
 /* Define a reasonable maximum that is safe to use on the stack. */
 #define PG_IOV_MAX Min(IOV_MAX, 32)
 
-#if HAVE_DECL_PREADV
-#define pg_preadv preadv
-#else
-extern ssize_t pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset);
+#if !HAVE_DECL_PREADV
+extern ssize_t preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset);
 #endif
 
-#if HAVE_DECL_PWRITEV
-#define pg_pwritev pwritev
-#else
-extern ssize_t pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset);
+#if !HAVE_DECL_PWRITEV
+extern ssize_t pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset);
 #endif
 
 #endif							/* PG_IOVEC_H */
diff --git a/src/port/preadv.c b/src/port/preadv.c
index aa7537503f..0aaf99222f 100644
--- a/src/port/preadv.c
+++ b/src/port/preadv.c
@@ -8,9 +8,6 @@
  * IDENTIFICATION
  *	  src/port/preadv.c
  *
- * Note that this implementation changes the current file position, unlike
- * the POSIX-like function, so we use the name pg_preadv().
- *
  *-------------------------------------------------------------------------
  */
 
@@ -26,15 +23,8 @@
 #include "port/pg_iovec.h"
 
 ssize_t
-pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
+preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 {
-#ifdef HAVE_READV
-	if (iovcnt == 1)
-		return pread(fd, iov[0].iov_base, iov[0].iov_len, offset);
-	if (lseek(fd, offset, SEEK_SET) < 0)
-		return -1;
-	return readv(fd, iov, iovcnt);
-#else
 	ssize_t		sum = 0;
 	ssize_t		part;
 
@@ -54,5 +44,4 @@ pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 			return sum;
 	}
 	return sum;
-#endif
 }
diff --git a/src/port/pwritev.c b/src/port/pwritev.c
index cb7421381e..a0fa4b8edd 100644
--- a/src/port/pwritev.c
+++ b/src/port/pwritev.c
@@ -8,9 +8,6 @@
  * IDENTIFICATION
  *	  src/port/pwritev.c
  *
- * Note that this implementation changes the current file position, unlike
- * the POSIX-like function, so we use the name pg_pwritev().
- *
  *-------------------------------------------------------------------------
  */
 
@@ -26,15 +23,8 @@
 #include "port/pg_iovec.h"
 
 ssize_t
-pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
+pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 {
-#ifdef HAVE_WRITEV
-	if (iovcnt == 1)
-		return pwrite(fd, iov[0].iov_base, iov[0].iov_len, offset);
-	if (lseek(fd, offset, SEEK_SET) < 0)
-		return -1;
-	return writev(fd, iov, iovcnt);
-#else
 	ssize_t		sum = 0;
 	ssize_t		part;
 
@@ -54,5 +44,4 @@ pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 			return sum;
 	}
 	return sum;
-#endif
 }
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 7a02198621..bd8b755b96 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -331,7 +331,6 @@ sub GenerateFiles
 		HAVE_READLINE_H             => undef,
 		HAVE_READLINE_HISTORY_H     => undef,
 		HAVE_READLINE_READLINE_H    => undef,
-		HAVE_READV                  => undef,
 		HAVE_RL_COMPLETION_MATCHES  => undef,
 		HAVE_RL_COMPLETION_SUPPRESS_QUOTE        => undef,
 		HAVE_RL_FILENAME_COMPLETION_FUNCTION     => undef,
@@ -407,7 +406,6 @@ sub GenerateFiles
 		HAVE_WINLDAP_H                           => undef,
 		HAVE_WCSTOMBS_L                          => 1,
 		HAVE_VISIBILITY_ATTRIBUTE                => undef,
-		HAVE_WRITEV                              => undef,
 		HAVE_X509_GET_SIGNATURE_NID              => 1,
 		HAVE_X86_64_POPCNTQ                      => undef,
 		HAVE__BOOL                               => undef,
-- 
2.37.1

v3-0012-Remove-fdatasync-configure-probe.patchtext/x-patch; charset=US-ASCII; name=v3-0012-Remove-fdatasync-configure-probe.patchDownload
From 064bc8ecb31ea7f00068f860f23b2254065e1fce Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Wed, 20 Jul 2022 14:10:37 +1200
Subject: [PATCH v3 12/13] Remove fdatasync configure probe.

fdatasync() is in SUSv2, and all targeted Unix systems have it.  We have
a replacement function for Windows.

We retain the probe for the function declaration, which allows us to
supply the missing declaration for macOS and Windows.  No need to keep a
HAVE_FDATASYNC macro around.

Also rename src/port/fdatasync.c to win32fdatasync.c since the replacement
code is Windows-only.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CA+hUKGJ3LHeP9w5Fgzdr4G8AnEtJ=z=p6hGDEm4qYGEUX5B6fQ@mail.gmail.com
Discussion: https://postgr.es/m/CA%2BhUKGJZJVO%3DiX%2Beb-PXi2_XS9ZRqnn_4URh0NUQOwt6-_51xQ%40mail.gmail.com
---
 configure                                  | 71 +++-------------------
 configure.ac                               |  5 +-
 src/backend/access/transam/xlog.c          |  4 --
 src/backend/storage/file/fd.c              |  8 ---
 src/bin/pg_test_fsync/pg_test_fsync.c      |  4 --
 src/include/access/xlogdefs.h              |  7 +--
 src/include/pg_config.h.in                 |  3 -
 src/include/port/freebsd.h                 |  2 -
 src/include/port/win32_port.h              |  8 ---
 src/port/{fdatasync.c => win32fdatasync.c} |  6 +-
 src/tools/msvc/Mkvcbuild.pm                |  3 +-
 src/tools/msvc/Solution.pm                 |  1 -
 12 files changed, 15 insertions(+), 107 deletions(-)
 rename src/port/{fdatasync.c => win32fdatasync.c} (88%)

diff --git a/configure b/configure
index 21f4520f81..a70768f04e 100755
--- a/configure
+++ b/configure
@@ -12315,63 +12315,6 @@ if test "$ac_res" != no; then :
 
 fi
 
-# Solaris:
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing fdatasync" >&5
-$as_echo_n "checking for library containing fdatasync... " >&6; }
-if ${ac_cv_search_fdatasync+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_func_search_save_LIBS=$LIBS
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char fdatasync ();
-int
-main ()
-{
-return fdatasync ();
-  ;
-  return 0;
-}
-_ACEOF
-for ac_lib in '' rt posix4; do
-  if test -z "$ac_lib"; then
-    ac_res="none required"
-  else
-    ac_res=-l$ac_lib
-    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
-  fi
-  if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_search_fdatasync=$ac_res
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext
-  if ${ac_cv_search_fdatasync+:} false; then :
-  break
-fi
-done
-if ${ac_cv_search_fdatasync+:} false; then :
-
-else
-  ac_cv_search_fdatasync=no
-fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_fdatasync" >&5
-$as_echo "$ac_cv_search_fdatasync" >&6; }
-ac_res=$ac_cv_search_fdatasync
-if test "$ac_res" != no; then :
-  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-
-fi
-
 # Cygwin:
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing shmget" >&5
 $as_echo_n "checking for library containing shmget... " >&6; }
@@ -16039,7 +15982,7 @@ fi
 LIBS_including_readline="$LIBS"
 LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'`
 
-for ac_func in backtrace_symbols copyfile fdatasync getifaddrs getpeerucred inet_pton kqueue mbstowcs_l memset_s posix_fallocate ppoll pthread_is_threaded_np setproctitle setproctitle_fast strchrnul strsignal syncfs sync_file_range uselocale wcstombs_l
+for ac_func in backtrace_symbols copyfile getifaddrs getpeerucred inet_pton kqueue mbstowcs_l memset_s posix_fallocate ppoll pthread_is_threaded_np setproctitle setproctitle_fast strchrnul strsignal syncfs sync_file_range uselocale wcstombs_l
 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"
@@ -16929,12 +16872,6 @@ fi
  ;;
 esac
 
-  case " $LIBOBJS " in
-  *" fdatasync.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS fdatasync.$ac_objext"
- ;;
-esac
-
   case " $LIBOBJS " in
   *" getrusage.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS getrusage.$ac_objext"
@@ -16977,6 +16914,12 @@ esac
  ;;
 esac
 
+  case " $LIBOBJS " in
+  *" win32fdatasync.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS win32fdatasync.$ac_objext"
+ ;;
+esac
+
   case " $LIBOBJS " in
   *" win32link.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS win32link.$ac_objext"
diff --git a/configure.ac b/configure.ac
index a7ab660179..6c035d8e20 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1253,8 +1253,6 @@ AC_SEARCH_LIBS(getopt_long, [getopt gnugetopt])
 AC_SEARCH_LIBS(shm_open, rt)
 AC_SEARCH_LIBS(shm_unlink, rt)
 AC_SEARCH_LIBS(clock_gettime, [rt posix4])
-# Solaris:
-AC_SEARCH_LIBS(fdatasync, [rt posix4])
 # Cygwin:
 AC_SEARCH_LIBS(shmget, cygipc)
 # *BSD:
@@ -1792,7 +1790,6 @@ LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'`
 AC_CHECK_FUNCS(m4_normalize([
 	backtrace_symbols
 	copyfile
-	fdatasync
 	getifaddrs
 	getpeerucred
 	inet_pton
@@ -1928,7 +1925,6 @@ if test "$PORTNAME" = "win32"; then
   AC_CHECK_FUNCS(_configthreadlocale)
   AC_REPLACE_FUNCS(gettimeofday)
   AC_LIBOBJ(dirmod)
-  AC_LIBOBJ(fdatasync)
   AC_LIBOBJ(getrusage)
   AC_LIBOBJ(kill)
   AC_LIBOBJ(open)
@@ -1936,6 +1932,7 @@ if test "$PORTNAME" = "win32"; then
   AC_LIBOBJ(win32dlopen)
   AC_LIBOBJ(win32env)
   AC_LIBOBJ(win32error)
+  AC_LIBOBJ(win32fdatasync)
   AC_LIBOBJ(win32link)
   AC_LIBOBJ(win32ntdll)
   AC_LIBOBJ(win32pread)
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index eb5115fd5a..34f0150d1e 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -168,9 +168,7 @@ const struct config_enum_entry sync_method_options[] = {
 #ifdef HAVE_FSYNC_WRITETHROUGH
 	{"fsync_writethrough", SYNC_METHOD_FSYNC_WRITETHROUGH, false},
 #endif
-#ifdef HAVE_FDATASYNC
 	{"fdatasync", SYNC_METHOD_FDATASYNC, false},
-#endif
 #ifdef O_SYNC
 	{"open_sync", SYNC_METHOD_OPEN, false},
 #endif
@@ -8015,12 +8013,10 @@ issue_xlog_fsync(int fd, XLogSegNo segno, TimeLineID tli)
 				msg = _("could not fsync write-through file \"%s\": %m");
 			break;
 #endif
-#ifdef HAVE_FDATASYNC
 		case SYNC_METHOD_FDATASYNC:
 			if (pg_fdatasync(fd) != 0)
 				msg = _("could not fdatasync file \"%s\": %m");
 			break;
-#endif
 		case SYNC_METHOD_OPEN:
 		case SYNC_METHOD_OPEN_DSYNC:
 			/* not reachable */
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index 5a2eb01238..ccb540d617 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -442,20 +442,12 @@ pg_fsync_writethrough(int fd)
 
 /*
  * pg_fdatasync --- same as fdatasync except does nothing if enableFsync is off
- *
- * Not all platforms have fdatasync; treat as fsync if not available.
  */
 int
 pg_fdatasync(int fd)
 {
 	if (enableFsync)
-	{
-#ifdef HAVE_FDATASYNC
 		return fdatasync(fd);
-#else
-		return fsync(fd);
-#endif
-	}
 	else
 		return 0;
 }
diff --git a/src/bin/pg_test_fsync/pg_test_fsync.c b/src/bin/pg_test_fsync/pg_test_fsync.c
index 8f0ef8e66b..77f0db0376 100644
--- a/src/bin/pg_test_fsync/pg_test_fsync.c
+++ b/src/bin/pg_test_fsync/pg_test_fsync.c
@@ -331,7 +331,6 @@ test_sync(int writes_per_op)
 	printf(LABEL_FORMAT, "fdatasync");
 	fflush(stdout);
 
-#ifdef HAVE_FDATASYNC
 	if ((tmpfile = open(filename, O_RDWR | PG_BINARY, 0)) == -1)
 		die("could not open output file");
 	START_TIMER;
@@ -347,9 +346,6 @@ test_sync(int writes_per_op)
 	}
 	STOP_TIMER;
 	close(tmpfile);
-#else
-	printf(NA_FORMAT, _("n/a"));
-#endif
 
 /*
  * Test fsync
diff --git a/src/include/access/xlogdefs.h b/src/include/access/xlogdefs.h
index 810cd1fd86..49e581925c 100644
--- a/src/include/access/xlogdefs.h
+++ b/src/include/access/xlogdefs.h
@@ -67,8 +67,7 @@ typedef uint16 RepOriginId;
 /*
  * This chunk of hackery attempts to determine which file sync methods
  * are available on the current platform, and to choose an appropriate
- * default method.  We assume that fsync() is always available, and that
- * configure determined whether fdatasync() is.
+ * default method.
  *
  * Note that we define our own O_DSYNC on Windows, but not O_SYNC.
  */
@@ -76,10 +75,8 @@ typedef uint16 RepOriginId;
 #define DEFAULT_SYNC_METHOD		PLATFORM_DEFAULT_SYNC_METHOD
 #elif defined(O_DSYNC) && (!defined(O_SYNC) || O_DSYNC != O_SYNC)
 #define DEFAULT_SYNC_METHOD		SYNC_METHOD_OPEN_DSYNC
-#elif defined(HAVE_FDATASYNC)
-#define DEFAULT_SYNC_METHOD		SYNC_METHOD_FDATASYNC
 #else
-#define DEFAULT_SYNC_METHOD		SYNC_METHOD_FSYNC
+#define DEFAULT_SYNC_METHOD		SYNC_METHOD_FDATASYNC
 #endif
 
 #endif							/* XLOG_DEFS_H */
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 6505a84211..2a0d08d10f 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -170,9 +170,6 @@
 /* Define to 1 if you have the `explicit_bzero' function. */
 #undef HAVE_EXPLICIT_BZERO
 
-/* Define to 1 if you have the `fdatasync' function. */
-#undef HAVE_FDATASYNC
-
 /* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
 #undef HAVE_FSEEKO
 
diff --git a/src/include/port/freebsd.h b/src/include/port/freebsd.h
index 2e2e749a6b..0e3fde55d6 100644
--- a/src/include/port/freebsd.h
+++ b/src/include/port/freebsd.h
@@ -5,6 +5,4 @@
  * would prefer open_datasync on FreeBSD 13+, but that is not a good choice on
  * many systems.
  */
-#ifdef HAVE_FDATASYNC
 #define PLATFORM_DEFAULT_SYNC_METHOD	SYNC_METHOD_FDATASYNC
-#endif
diff --git a/src/include/port/win32_port.h b/src/include/port/win32_port.h
index 2954fabaa5..cd6c9c7515 100644
--- a/src/include/port/win32_port.h
+++ b/src/include/port/win32_port.h
@@ -83,14 +83,6 @@
 #define HAVE_FSYNC_WRITETHROUGH
 #define FSYNC_WRITETHROUGH_IS_FSYNC
 
-/*
- * We have a replacement for fdatasync() in src/port/fdatasync.c, which is
- * unconditionally used by MSVC and Mingw builds.
- */
-#ifndef HAVE_FDATASYNC
-#define HAVE_FDATASYNC
-#endif
-
 #define USES_WINSOCK
 
 /*
diff --git a/src/port/fdatasync.c b/src/port/win32fdatasync.c
similarity index 88%
rename from src/port/fdatasync.c
rename to src/port/win32fdatasync.c
index afef853aa3..31d631c696 100644
--- a/src/port/fdatasync.c
+++ b/src/port/win32fdatasync.c
@@ -1,12 +1,12 @@
 /*-------------------------------------------------------------------------
  *
- * fdatasync.c
+ * win32fdatasync.c
  *	   Win32 fdatasync() replacement
  *
  *
- * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
  *
- * src/port/fdatasync.c
+ * src/port/win32fdatasync.c
  *
  *-------------------------------------------------------------------------
  */
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index a06dbcae4d..8d88e78f05 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -99,7 +99,7 @@ sub mkvcbuild
 	$solution = CreateSolution($vsVersion, $config);
 
 	our @pgportfiles = qw(
-	  chklocale.c explicit_bzero.c fdatasync.c
+	  chklocale.c explicit_bzero.c
 	  getpeereid.c getrusage.c inet_aton.c
 	  getaddrinfo.c gettimeofday.c inet_net_ntop.c kill.c open.c
 	  snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c
@@ -110,6 +110,7 @@ sub mkvcbuild
 	  strerror.c tar.c
 	  win32dlopen.c
 	  win32env.c win32error.c
+	  win32fdatasync.c
 	  win32link.c
 	  win32pread.c
 	  win32pwrite.c
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index bd8b755b96..d7ab6ab258 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -252,7 +252,6 @@ sub GenerateFiles
 		HAVE_EDITLINE_READLINE_H                    => undef,
 		HAVE_EXECINFO_H                             => undef,
 		HAVE_EXPLICIT_BZERO                         => undef,
-		HAVE_FDATASYNC                              => 1,
 		HAVE_FSEEKO                                 => 1,
 		HAVE_FUNCNAME__FUNC                         => undef,
 		HAVE_FUNCNAME__FUNCTION                     => 1,
-- 
2.37.1

v3-0013-Remove-disable-thread-safety.patchtext/x-patch; charset=US-ASCII; name=v3-0013-Remove-disable-thread-safety.patchDownload
From 5bda430998d502a7f8a6fe662a56b63ac374c925 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Fri, 26 Mar 2021 22:58:06 +1300
Subject: [PATCH v3 13/13] Remove --disable-thread-safety.

Threads are in SUSv2 and all targeted Unix systems have the option.
There are no known Unix systems that don't choose to implement the
threading option, and we're no longer testing such builds.

Future work to improve our use of threads will be simplified by not
having to cope with a no-threads build option.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Greg Stark <stark@mit.edu>
Reviewed-by: Robert Haas <robertmhaas@gmail.com>
Discussion: https://postgr.es/m/CA+hUKGJ3LHeP9w5Fgzdr4G8AnEtJ=z=p6hGDEm4qYGEUX5B6fQ@mail.gmail.com
---
 configure                                     | 56 ++-------------
 configure.ac                                  | 28 ++------
 doc/src/sgml/installation.sgml                | 13 ----
 doc/src/sgml/libpq.sgml                       |  3 +-
 src/Makefile.global.in                        |  1 -
 src/bin/pgbench/pgbench.c                     | 22 +-----
 src/include/pg_config.h.in                    |  4 --
 src/interfaces/ecpg/ecpglib/connect.c         | 40 -----------
 src/interfaces/ecpg/ecpglib/descriptor.c      |  9 ---
 src/interfaces/ecpg/ecpglib/ecpglib_extern.h  |  2 -
 src/interfaces/ecpg/ecpglib/execute.c         |  2 -
 src/interfaces/ecpg/ecpglib/memory.c          |  7 --
 src/interfaces/ecpg/ecpglib/misc.c            | 47 ------------
 .../ecpg/include/ecpg-pthread-win32.h         |  3 -
 src/interfaces/ecpg/include/ecpg_config.h.in  |  4 --
 src/interfaces/ecpg/include/ecpglib.h         |  2 -
 .../ecpg/test/expected/thread-alloc.c         | 43 +++++------
 .../ecpg/test/expected/thread-alloc_2.stdout  |  1 -
 .../ecpg/test/expected/thread-descriptor.c    | 22 +++---
 .../ecpg/test/expected/thread-prep.c          | 71 ++++++++-----------
 .../ecpg/test/expected/thread-prep.stdout     |  1 -
 .../ecpg/test/expected/thread-prep_2.stdout   |  0
 .../ecpg/test/expected/thread-thread.c        | 63 +++++++---------
 .../ecpg/test/expected/thread-thread.stdout   |  2 +-
 .../ecpg/test/expected/thread-thread_2.stdout |  1 -
 .../test/expected/thread-thread_implicit.c    | 63 +++++++---------
 .../expected/thread-thread_implicit.stdout    |  2 +-
 .../expected/thread-thread_implicit_2.stdout  |  1 -
 src/interfaces/ecpg/test/thread/alloc.pgc     |  9 ---
 .../ecpg/test/thread/descriptor.pgc           |  8 +--
 src/interfaces/ecpg/test/thread/prep.pgc      |  9 ---
 src/interfaces/ecpg/test/thread/thread.pgc    |  9 ---
 .../ecpg/test/thread/thread_implicit.pgc      |  9 ---
 src/interfaces/libpq/Makefile                 |  2 -
 src/interfaces/libpq/fe-auth.c                |  9 ++-
 src/interfaces/libpq/fe-connect.c             |  4 --
 src/interfaces/libpq/fe-exec.c                |  4 --
 src/interfaces/libpq/fe-print.c               | 13 +---
 src/interfaces/libpq/fe-secure-openssl.c      | 17 +----
 src/interfaces/libpq/fe-secure.c              | 26 +------
 src/interfaces/libpq/legacy-pqsignal.c        |  4 --
 src/interfaces/libpq/libpq-int.h              |  9 +--
 src/port/getaddrinfo.c                        |  2 +-
 src/tools/msvc/Solution.pm                    |  3 +-
 src/tools/msvc/ecpg_regression.proj           |  2 +-
 45 files changed, 142 insertions(+), 510 deletions(-)
 delete mode 100644 src/interfaces/ecpg/test/expected/thread-alloc_2.stdout
 delete mode 100644 src/interfaces/ecpg/test/expected/thread-prep_2.stdout
 delete mode 100644 src/interfaces/ecpg/test/expected/thread-thread_2.stdout
 delete mode 100644 src/interfaces/ecpg/test/expected/thread-thread_implicit_2.stdout

diff --git a/configure b/configure
index a70768f04e..79ece5372a 100755
--- a/configure
+++ b/configure
@@ -728,7 +728,6 @@ with_tcl
 ICU_LIBS
 ICU_CFLAGS
 with_icu
-enable_thread_safety
 INCLUDES
 autodepend
 PKG_CONFIG_LIBDIR
@@ -853,7 +852,6 @@ with_CC
 with_llvm
 enable_depend
 enable_cassert
-enable_thread_safety
 with_icu
 with_tcl
 with_tclconfig
@@ -1542,7 +1540,6 @@ Optional Features:
   --enable-tap-tests      enable TAP tests (requires Perl and IPC::Run)
   --enable-depend         turn on automatic dependency tracking
   --enable-cassert        enable assertion checks (for debugging)
-  --disable-thread-safety disable thread-safety in client libraries
   --disable-largefile     omit support for large files
 
 Optional Packages:
@@ -7972,43 +7969,6 @@ $as_echo "$as_me: WARNING: *** Library directory $dir does not exist." >&2;}
 done
 IFS=$ac_save_IFS
 
-#
-# Enable thread-safe client libraries
-#
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking allow thread-safe client libraries" >&5
-$as_echo_n "checking allow thread-safe client libraries... " >&6; }
-
-
-# Check whether --enable-thread-safety was given.
-if test "${enable_thread_safety+set}" = set; then :
-  enableval=$enable_thread_safety;
-  case $enableval in
-    yes)
-      :
-      ;;
-    no)
-      :
-      ;;
-    *)
-      as_fn_error $? "no argument expected for --enable-thread-safety option" "$LINENO" 5
-      ;;
-  esac
-
-else
-  enable_thread_safety=yes
-
-fi
-
-
-if test "$enable_thread_safety" = yes; then
-
-$as_echo "#define ENABLE_THREAD_SAFETY 1" >>confdefs.h
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_thread_safety" >&5
-$as_echo "$enable_thread_safety" >&6; }
-
-
 #
 # ICU
 #
@@ -11087,7 +11047,7 @@ fi
 done
 
 
-if test "$enable_thread_safety" = yes -a "$PORTNAME" != "win32"; then :
+if "$PORTNAME" != "win32"; then :
    # then
 
 
@@ -11746,7 +11706,7 @@ if test "x$ac_cv_header_pthread_h" = xyes; then :
 
 else
   as_fn_error $? "
-pthread.h not found;  use --disable-thread-safety to disable thread safety" "$LINENO" 5
+pthread.h not found" "$LINENO" 5
 fi
 
 
@@ -12430,8 +12390,7 @@ if test "$ac_res" != no; then :
 fi
 
 
-if test "$enable_thread_safety" = yes; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gethostbyname_r" >&5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gethostbyname_r" >&5
 $as_echo_n "checking for library containing gethostbyname_r... " >&6; }
 if ${ac_cv_search_gethostbyname_r+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -12487,7 +12446,7 @@ if test "$ac_res" != no; then :
 
 fi
 
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_barrier_wait" >&5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_barrier_wait" >&5
 $as_echo_n "checking for library containing pthread_barrier_wait... " >&6; }
 if ${ac_cv_search_pthread_barrier_wait+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -12543,7 +12502,6 @@ if test "$ac_res" != no; then :
 
 fi
 
-fi
 
 if test "$with_readline" = yes; then
 
@@ -13416,7 +13374,7 @@ else
   thread_safe_libldap=no
 fi
 
-    if test "$enable_thread_safety" = yes -a "$thread_safe_libldap" = no; then
+    if test "$thread_safe_libldap" = no; then
       # Use ldap_r for FE if available, else assume ldap is thread-safe.
       # On some platforms ldap_r fails to link without PTHREAD_LIBS.
       LIBS="$_LIBS"
@@ -16725,8 +16683,7 @@ fi
 
 
 
-if test "$enable_thread_safety" = yes; then
-  ac_fn_c_check_func "$LINENO" "pthread_barrier_wait" "ac_cv_func_pthread_barrier_wait"
+ac_fn_c_check_func "$LINENO" "pthread_barrier_wait" "ac_cv_func_pthread_barrier_wait"
 if test "x$ac_cv_func_pthread_barrier_wait" = xyes; then :
   $as_echo "#define HAVE_PTHREAD_BARRIER_WAIT 1" >>confdefs.h
 
@@ -16740,7 +16697,6 @@ esac
 fi
 
 
-fi
 
 if test "$PORTNAME" = "win32" -o "$PORTNAME" = "cygwin"; then
 	# Cygwin and (apparently, based on test results) Mingw both
diff --git a/configure.ac b/configure.ac
index 6c035d8e20..2bd26a02b6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -788,18 +788,6 @@ for dir in $LIBRARY_DIRS $SRCH_LIB; do
 done
 IFS=$ac_save_IFS
 
-#
-# Enable thread-safe client libraries
-#
-AC_MSG_CHECKING([allow thread-safe client libraries])
-PGAC_ARG_BOOL(enable, thread-safety, yes, [disable thread-safety in client libraries])
-if test "$enable_thread_safety" = yes; then
-  AC_DEFINE([ENABLE_THREAD_SAFETY], 1,
-          [Define to 1 to build client libraries as thread-safe code. (--enable-thread-safety)])
-fi
-AC_MSG_RESULT([$enable_thread_safety])
-AC_SUBST(enable_thread_safety)
-
 #
 # ICU
 #
@@ -1197,7 +1185,7 @@ dnl note: We have to use AS_IF here rather than plain if. The AC_CHECK_HEADER
 dnl invocation below is the first one in the script, and autoconf generates
 dnl additional code for that, which must not be inside the if-block. AS_IF
 dnl knows how to do that.
-AS_IF([test "$enable_thread_safety" = yes -a "$PORTNAME" != "win32"],
+AS_IF(["$PORTNAME" != "win32"],
 [ # then
 AX_PTHREAD	# set thread flags
 
@@ -1212,7 +1200,7 @@ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
 LIBS="$LIBS $PTHREAD_LIBS"
 
 AC_CHECK_HEADER(pthread.h, [], [AC_MSG_ERROR([
-pthread.h not found;  use --disable-thread-safety to disable thread safety])])
+pthread.h not found])])
 
 AC_CHECK_FUNCS([strerror_r gethostbyname_r])
 
@@ -1258,10 +1246,8 @@ AC_SEARCH_LIBS(shmget, cygipc)
 # *BSD:
 AC_SEARCH_LIBS(backtrace_symbols, execinfo)
 
-if test "$enable_thread_safety" = yes; then
-  AC_SEARCH_LIBS(gethostbyname_r, nsl)
-  AC_SEARCH_LIBS(pthread_barrier_wait, pthread)
-fi
+AC_SEARCH_LIBS(gethostbyname_r, nsl)
+AC_SEARCH_LIBS(pthread_barrier_wait, pthread)
 
 if test "$with_readline" = yes; then
   PGAC_CHECK_READLINE
@@ -1386,7 +1372,7 @@ if test "$with_ldap" = yes ; then
     AC_CHECK_FUNC([ldap_verify_credentials],
 		  [thread_safe_libldap=yes],
 		  [thread_safe_libldap=no])
-    if test "$enable_thread_safety" = yes -a "$thread_safe_libldap" = no; then
+    if test "$thread_safe_libldap" = no; then
       # Use ldap_r for FE if available, else assume ldap is thread-safe.
       # On some platforms ldap_r fails to link without PTHREAD_LIBS.
       LIBS="$_LIBS"
@@ -1876,9 +1862,7 @@ AC_REPLACE_FUNCS(m4_normalize([
 	strtof
 ]))
 
-if test "$enable_thread_safety" = yes; then
-  AC_REPLACE_FUNCS(pthread_barrier_wait)
-fi
+AC_REPLACE_FUNCS(pthread_barrier_wait)
 
 if test "$PORTNAME" = "win32" -o "$PORTNAME" = "cygwin"; then
 	# Cygwin and (apparently, based on test results) Mingw both
diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml
index 70d188e2bc..f31e1f9160 100644
--- a/doc/src/sgml/installation.sgml
+++ b/doc/src/sgml/installation.sgml
@@ -1285,19 +1285,6 @@ build-postgresql:
        </listitem>
       </varlistentry>
 
-      <varlistentry>
-       <term><option>--disable-thread-safety</option></term>
-       <listitem>
-        <para>
-         Disable the thread-safety of client libraries.  This prevents
-         concurrent threads in <application>libpq</application> and
-         <application>ECPG</application> programs from safely controlling
-         their private connection handles.  Use this only on platforms
-         with deficient threading support.
-        </para>
-       </listitem>
-      </varlistentry>
-
      </variablelist>
 
    </sect3>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 74456aa69d..655b4db31e 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -8837,7 +8837,8 @@ int PQisthreadsafe();
 
      <para>
       Returns 1 if the <application>libpq</application> is thread-safe
-      and 0 if it is not.
+      and 0 if it is not.  Since <productname>PostgreSQL</productname> version
+      16, this function always returns 1.
      </para>
     </listitem>
    </varlistentry>
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index 14fdd4ef7b..cb35cd9eba 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -202,7 +202,6 @@ enable_debug	= @enable_debug@
 enable_dtrace	= @enable_dtrace@
 enable_coverage	= @enable_coverage@
 enable_tap_tests	= @enable_tap_tests@
-enable_thread_safety	= @enable_thread_safety@
 
 python_includespec	= @python_includespec@
 python_libdir		= @python_libdir@
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 0778656794..5397bcaee6 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -140,7 +140,7 @@ typedef struct socket_set
 	EnterSynchronizationBarrier((barrier), \
 								SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY)
 #define THREAD_BARRIER_DESTROY(barrier)
-#elif defined(ENABLE_THREAD_SAFETY)
+#else
 /* Use POSIX threads */
 #include "port/pg_pthread.h"
 #define THREAD_T pthread_t
@@ -156,16 +156,6 @@ typedef struct socket_set
 	pthread_barrier_init((barrier), NULL, (n))
 #define THREAD_BARRIER_WAIT(barrier) pthread_barrier_wait((barrier))
 #define THREAD_BARRIER_DESTROY(barrier) pthread_barrier_destroy((barrier))
-#else
-/* No threads implementation, use none (-j 1) */
-#define THREAD_T void *
-#define THREAD_FUNC_RETURN_TYPE void *
-#define THREAD_FUNC_RETURN return NULL
-#define THREAD_FUNC_CC
-#define THREAD_BARRIER_T int
-#define THREAD_BARRIER_INIT(barrier, n) (*(barrier) = 0)
-#define THREAD_BARRIER_WAIT(barrier)
-#define THREAD_BARRIER_DESTROY(barrier)
 #endif
 
 
@@ -6680,10 +6670,6 @@ main(int argc, char **argv)
 				{
 					exit(1);
 				}
-#ifndef ENABLE_THREAD_SAFETY
-				if (nthreads != 1)
-					pg_fatal("threads are not supported on this platform; use -j1");
-#endif							/* !ENABLE_THREAD_SAFETY */
 				break;
 			case 'C':
 				benchmarking_option_set = true;
@@ -7197,7 +7183,6 @@ main(int argc, char **argv)
 	if (errno != 0)
 		pg_fatal("could not initialize barrier: %m");
 
-#ifdef ENABLE_THREAD_SAFETY
 	/* start all threads but thread 0 which is executed directly later */
 	for (i = 1; i < nthreads; i++)
 	{
@@ -7209,9 +7194,6 @@ main(int argc, char **argv)
 		if (errno != 0)
 			pg_fatal("could not create thread: %m");
 	}
-#else
-	Assert(nthreads == 1);
-#endif							/* ENABLE_THREAD_SAFETY */
 
 	/* compute when to stop */
 	threads[0].create_time = pg_time_now();
@@ -7229,10 +7211,8 @@ main(int argc, char **argv)
 	{
 		TState	   *thread = &threads[i];
 
-#ifdef ENABLE_THREAD_SAFETY
 		if (i > 0)
 			THREAD_JOIN(thread->thread);
-#endif							/* ENABLE_THREAD_SAFETY */
 
 		for (int j = 0; j < thread->nstate; j++)
 			if (thread->state[j].state != CSTATE_FINISHED)
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 2a0d08d10f..a4ef016c06 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -51,10 +51,6 @@
 /* Define to 1 if you want National Language Support. (--enable-nls) */
 #undef ENABLE_NLS
 
-/* Define to 1 to build client libraries as thread-safe code.
-   (--enable-thread-safety) */
-#undef ENABLE_THREAD_SAFETY
-
 /* Define to 1 if gettimeofday() takes only 1 argument. */
 #undef GETTIMEOFDAY_1ARG
 
diff --git a/src/interfaces/ecpg/ecpglib/connect.c b/src/interfaces/ecpg/ecpglib/connect.c
index db0bae1fe0..8afb1f0a26 100644
--- a/src/interfaces/ecpg/ecpglib/connect.c
+++ b/src/interfaces/ecpg/ecpglib/connect.c
@@ -14,15 +14,12 @@
 locale_t	ecpg_clocale = (locale_t) 0;
 #endif
 
-#ifdef ENABLE_THREAD_SAFETY
 static pthread_mutex_t connections_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_key_t actual_connection_key;
 static pthread_once_t actual_connection_key_once = PTHREAD_ONCE_INIT;
-#endif
 static struct connection *actual_connection = NULL;
 static struct connection *all_connections = NULL;
 
-#ifdef ENABLE_THREAD_SAFETY
 static void
 ecpg_actual_connection_init(void)
 {
@@ -34,7 +31,6 @@ ecpg_pthreads_init(void)
 {
 	pthread_once(&actual_connection_key_once, ecpg_actual_connection_init);
 }
-#endif
 
 static struct connection *
 ecpg_get_connection_nr(const char *connection_name)
@@ -43,7 +39,6 @@ ecpg_get_connection_nr(const char *connection_name)
 
 	if ((connection_name == NULL) || (strcmp(connection_name, "CURRENT") == 0))
 	{
-#ifdef ENABLE_THREAD_SAFETY
 		ecpg_pthreads_init();	/* ensure actual_connection_key is valid */
 
 		ret = pthread_getspecific(actual_connection_key);
@@ -56,9 +51,6 @@ ecpg_get_connection_nr(const char *connection_name)
 		if (ret == NULL)
 			/* no TSD connection, going for global */
 			ret = actual_connection;
-#else
-		ret = actual_connection;
-#endif
 	}
 	else
 	{
@@ -82,7 +74,6 @@ ecpg_get_connection(const char *connection_name)
 
 	if ((connection_name == NULL) || (strcmp(connection_name, "CURRENT") == 0))
 	{
-#ifdef ENABLE_THREAD_SAFETY
 		ecpg_pthreads_init();	/* ensure actual_connection_key is valid */
 
 		ret = pthread_getspecific(actual_connection_key);
@@ -95,21 +86,14 @@ ecpg_get_connection(const char *connection_name)
 		if (ret == NULL)
 			/* no TSD connection here either, using global */
 			ret = actual_connection;
-#else
-		ret = actual_connection;
-#endif
 	}
 	else
 	{
-#ifdef ENABLE_THREAD_SAFETY
 		pthread_mutex_lock(&connections_mutex);
-#endif
 
 		ret = ecpg_get_connection_nr(connection_name);
 
-#ifdef ENABLE_THREAD_SAFETY
 		pthread_mutex_unlock(&connections_mutex);
-#endif
 	}
 
 	return ret;
@@ -143,10 +127,8 @@ ecpg_finish(struct connection *act)
 				con->next = act->next;
 		}
 
-#ifdef ENABLE_THREAD_SAFETY
 		if (pthread_getspecific(actual_connection_key) == act)
 			pthread_setspecific(actual_connection_key, all_connections);
-#endif
 		if (actual_connection == act)
 			actual_connection = all_connections;
 
@@ -212,11 +194,7 @@ ECPGsetconn(int lineno, const char *connection_name)
 	if (!ecpg_init(con, connection_name, lineno))
 		return false;
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_setspecific(actual_connection_key, con);
-#else
-	actual_connection = con;
-#endif
 	return true;
 }
 
@@ -326,9 +304,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
 	if (dbname == NULL && connection_name == NULL)
 		connection_name = "DEFAULT";
 
-#if ENABLE_THREAD_SAFETY
 	ecpg_pthreads_init();
-#endif
 
 	/* check if the identifier is unique */
 	if (ecpg_get_connection(connection_name))
@@ -505,9 +481,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
 	}
 
 	/* add connection to our list */
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_lock(&connections_mutex);
-#endif
 
 	/*
 	 * ... but first, make certain we have created ecpg_clocale.  Rely on
@@ -519,9 +493,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
 		ecpg_clocale = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
 		if (!ecpg_clocale)
 		{
-#ifdef ENABLE_THREAD_SAFETY
 			pthread_mutex_unlock(&connections_mutex);
-#endif
 			ecpg_raise(lineno, ECPG_OUT_OF_MEMORY,
 					   ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
 			if (host)
@@ -558,9 +530,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
 		this->next = all_connections;
 
 	all_connections = this;
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_setspecific(actual_connection_key, all_connections);
-#endif
 	actual_connection = all_connections;
 
 	ecpg_log("ECPGconnect: opening database %s on %s port %s %s%s %s%s\n",
@@ -678,9 +648,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
 		ecpg_log("ECPGconnect: %s", errmsg);
 
 		ecpg_finish(this);
-#ifdef ENABLE_THREAD_SAFETY
 		pthread_mutex_unlock(&connections_mutex);
-#endif
 
 		ecpg_raise(lineno, ECPG_CONNECT, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, db);
 		if (realname)
@@ -692,9 +660,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
 	if (realname)
 		ecpg_free(realname);
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_unlock(&connections_mutex);
-#endif
 
 	this->autocommit = autocommit;
 
@@ -716,9 +682,7 @@ ECPGdisconnect(int lineno, const char *connection_name)
 		return false;
 	}
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_lock(&connections_mutex);
-#endif
 
 	if (strcmp(connection_name, "ALL") == 0)
 	{
@@ -737,18 +701,14 @@ ECPGdisconnect(int lineno, const char *connection_name)
 
 		if (!ecpg_init(con, connection_name, lineno))
 		{
-#ifdef ENABLE_THREAD_SAFETY
 			pthread_mutex_unlock(&connections_mutex);
-#endif
 			return false;
 		}
 		else
 			ecpg_finish(con);
 	}
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_unlock(&connections_mutex);
-#endif
 
 	return true;
 }
diff --git a/src/interfaces/ecpg/ecpglib/descriptor.c b/src/interfaces/ecpg/ecpglib/descriptor.c
index 649a71c286..b47f422d92 100644
--- a/src/interfaces/ecpg/ecpglib/descriptor.c
+++ b/src/interfaces/ecpg/ecpglib/descriptor.c
@@ -19,7 +19,6 @@
 static void descriptor_free(struct descriptor *desc);
 
 /* We manage descriptors separately for each thread. */
-#ifdef ENABLE_THREAD_SAFETY
 static pthread_key_t descriptor_key;
 static pthread_once_t descriptor_once = PTHREAD_ONCE_INIT;
 
@@ -49,12 +48,6 @@ set_descriptors(struct descriptor *value)
 {
 	pthread_setspecific(descriptor_key, value);
 }
-#else
-static struct descriptor *all_descriptors = NULL;
-
-#define get_descriptors()		(all_descriptors)
-#define set_descriptors(value)	do { all_descriptors = (value); } while(0)
-#endif
 
 /* old internal convenience function that might go away later */
 static PGresult *
@@ -782,7 +775,6 @@ ECPGdeallocate_desc(int line, const char *name)
 	return false;
 }
 
-#ifdef ENABLE_THREAD_SAFETY
 
 /* Deallocate all descriptors in the list */
 static void
@@ -796,7 +788,6 @@ descriptor_deallocate_all(struct descriptor *list)
 		list = next;
 	}
 }
-#endif							/* ENABLE_THREAD_SAFETY */
 
 bool
 ECPGallocate_desc(int line, const char *name)
diff --git a/src/interfaces/ecpg/ecpglib/ecpglib_extern.h b/src/interfaces/ecpg/ecpglib/ecpglib_extern.h
index c438cfb820..968f1211b8 100644
--- a/src/interfaces/ecpg/ecpglib/ecpglib_extern.h
+++ b/src/interfaces/ecpg/ecpglib/ecpglib_extern.h
@@ -169,9 +169,7 @@ bool		ecpg_get_data(const PGresult *, int, int, int, enum ECPGttype type,
 						  enum ECPGttype, char *, char *, long, long, long,
 						  enum ARRAY_TYPE, enum COMPAT_MODE, bool);
 
-#ifdef ENABLE_THREAD_SAFETY
 void		ecpg_pthreads_init(void);
-#endif
 struct connection *ecpg_get_connection(const char *);
 char	   *ecpg_alloc(long, int);
 char	   *ecpg_auto_alloc(long, int);
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index bd94bd4e6c..0b2716d921 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1961,9 +1961,7 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator,
 		return false;
 	}
 
-#ifdef ENABLE_THREAD_SAFETY
 	ecpg_pthreads_init();
-#endif
 
 	con = ecpg_get_connection(connection_name);
 
diff --git a/src/interfaces/ecpg/ecpglib/memory.c b/src/interfaces/ecpg/ecpglib/memory.c
index bd81251054..a83637ac75 100644
--- a/src/interfaces/ecpg/ecpglib/memory.c
+++ b/src/interfaces/ecpg/ecpglib/memory.c
@@ -68,7 +68,6 @@ struct auto_mem
 	struct auto_mem *next;
 };
 
-#ifdef ENABLE_THREAD_SAFETY
 static pthread_key_t auto_mem_key;
 static pthread_once_t auto_mem_once = PTHREAD_ONCE_INIT;
 
@@ -97,12 +96,6 @@ set_auto_allocs(struct auto_mem *am)
 {
 	pthread_setspecific(auto_mem_key, am);
 }
-#else
-static struct auto_mem *auto_allocs = NULL;
-
-#define get_auto_allocs()		(auto_allocs)
-#define set_auto_allocs(am)		do { auto_allocs = (am); } while(0)
-#endif
 
 char *
 ecpg_auto_alloc(long size, int lineno)
diff --git a/src/interfaces/ecpg/ecpglib/misc.c b/src/interfaces/ecpg/ecpglib/misc.c
index 1eef1ec044..71f07c4e4f 100644
--- a/src/interfaces/ecpg/ecpglib/misc.c
+++ b/src/interfaces/ecpg/ecpglib/misc.c
@@ -55,42 +55,11 @@ static struct sqlca_t sqlca_init =
 	}
 };
 
-#ifdef ENABLE_THREAD_SAFETY
 static pthread_key_t sqlca_key;
 static pthread_once_t sqlca_key_once = PTHREAD_ONCE_INIT;
-#else
-static struct sqlca_t sqlca =
-{
-	{
-		'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '
-	},
-	sizeof(struct sqlca_t),
-	0,
-	{
-		0,
-		{
-			0
-		}
-	},
-	{
-		'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '
-	},
-	{
-		0, 0, 0, 0, 0, 0
-	},
-	{
-		0, 0, 0, 0, 0, 0, 0, 0
-	},
-	{
-		'0', '0', '0', '0', '0'
-	}
-};
-#endif
 
-#ifdef ENABLE_THREAD_SAFETY
 static pthread_mutex_t debug_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t debug_init_mutex = PTHREAD_MUTEX_INITIALIZER;
-#endif
 static int	simple_debug = 0;
 static FILE *debugstream = NULL;
 
@@ -123,7 +92,6 @@ ecpg_init(const struct connection *con, const char *connection_name, const int l
 	return true;
 }
 
-#ifdef ENABLE_THREAD_SAFETY
 static void
 ecpg_sqlca_key_destructor(void *arg)
 {
@@ -135,12 +103,10 @@ ecpg_sqlca_key_init(void)
 {
 	pthread_key_create(&sqlca_key, ecpg_sqlca_key_destructor);
 }
-#endif
 
 struct sqlca_t *
 ECPGget_sqlca(void)
 {
-#ifdef ENABLE_THREAD_SAFETY
 	struct sqlca_t *sqlca;
 
 	pthread_once(&sqlca_key_once, ecpg_sqlca_key_init);
@@ -155,9 +121,6 @@ ECPGget_sqlca(void)
 		pthread_setspecific(sqlca_key, sqlca);
 	}
 	return sqlca;
-#else
-	return &sqlca;
-#endif
 }
 
 bool
@@ -240,9 +203,7 @@ ECPGtrans(int lineno, const char *connection_name, const char *transaction)
 void
 ECPGdebug(int n, FILE *dbgs)
 {
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_lock(&debug_init_mutex);
-#endif
 
 	if (n > 100)
 	{
@@ -256,9 +217,7 @@ ECPGdebug(int n, FILE *dbgs)
 
 	ecpg_log("ECPGdebug: set to %d\n", simple_debug);
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_unlock(&debug_init_mutex);
-#endif
 }
 
 void
@@ -290,9 +249,7 @@ ecpg_log(const char *format,...)
 	else
 		snprintf(fmt, bufsize, "[%d]: %s", (int) getpid(), intl_format);
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_lock(&debug_mutex);
-#endif
 
 	va_start(ap, format);
 	vfprintf(debugstream, fmt, ap);
@@ -307,9 +264,7 @@ ecpg_log(const char *format,...)
 
 	fflush(debugstream);
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_unlock(&debug_mutex);
-#endif
 
 	free(fmt);
 }
@@ -451,7 +406,6 @@ ECPGis_noind_null(enum ECPGttype type, const void *ptr)
 }
 
 #ifdef WIN32
-#ifdef ENABLE_THREAD_SAFETY
 
 void
 win32_pthread_mutex(volatile pthread_mutex_t *mutex)
@@ -482,7 +436,6 @@ win32_pthread_once(volatile pthread_once_t *once, void (*fn) (void))
 		pthread_mutex_unlock(&win32_pthread_once_lock);
 	}
 }
-#endif							/* ENABLE_THREAD_SAFETY */
 #endif							/* WIN32 */
 
 #ifdef ENABLE_NLS
diff --git a/src/interfaces/ecpg/include/ecpg-pthread-win32.h b/src/interfaces/ecpg/include/ecpg-pthread-win32.h
index 33c897b633..8252a17809 100644
--- a/src/interfaces/ecpg/include/ecpg-pthread-win32.h
+++ b/src/interfaces/ecpg/include/ecpg-pthread-win32.h
@@ -5,8 +5,6 @@
 #ifndef _ECPG_PTHREAD_WIN32_H
 #define _ECPG_PTHREAD_WIN32_H
 
-#ifdef ENABLE_THREAD_SAFETY
-
 #ifndef WIN32
 
 #include <pthread.h>
@@ -53,6 +51,5 @@ void		win32_pthread_once(volatile pthread_once_t *once, void (*fn) (void));
 			win32_pthread_once((once), (fn)); \
 	} while(0)
 #endif							/* WIN32 */
-#endif							/* ENABLE_THREAD_SAFETY */
 
 #endif							/* _ECPG_PTHREAD_WIN32_H */
diff --git a/src/interfaces/ecpg/include/ecpg_config.h.in b/src/interfaces/ecpg/include/ecpg_config.h.in
index cbd24f11a0..6d01608a49 100644
--- a/src/interfaces/ecpg/include/ecpg_config.h.in
+++ b/src/interfaces/ecpg/include/ecpg_config.h.in
@@ -1,7 +1,3 @@
-/* Define to 1 to build client libraries as thread-safe code.
- *    (--enable-thread-safety) */
-#undef ENABLE_THREAD_SAFETY
-
 /* Define to 1 if the system has the type `int64'. */
 #undef HAVE_INT64
 
diff --git a/src/interfaces/ecpg/include/ecpglib.h b/src/interfaces/ecpg/include/ecpglib.h
index 00240109a6..05433726ac 100644
--- a/src/interfaces/ecpg/include/ecpglib.h
+++ b/src/interfaces/ecpg/include/ecpglib.h
@@ -92,9 +92,7 @@ void	   *ECPGget_var(int number);
 /* dynamic result allocation */
 void		ECPGfree_auto_mem(void);
 
-#ifdef ENABLE_THREAD_SAFETY
 void		ecpg_pthreads_init(void);
-#endif
 
 #ifdef __cplusplus
 }
diff --git a/src/interfaces/ecpg/test/expected/thread-alloc.c b/src/interfaces/ecpg/test/expected/thread-alloc.c
index 37ef44ed94..3b31d27fd3 100644
--- a/src/interfaces/ecpg/test/expected/thread-alloc.c
+++ b/src/interfaces/ecpg/test/expected/thread-alloc.c
@@ -11,14 +11,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifdef WIN32
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
@@ -101,7 +93,7 @@ struct sqlca_t *ECPGget_sqlca(void);
 
 #endif
 
-#line 26 "alloc.pgc"
+#line 18 "alloc.pgc"
 
 
 #line 1 "regression.h"
@@ -111,14 +103,14 @@ struct sqlca_t *ECPGget_sqlca(void);
 
 
 
-#line 27 "alloc.pgc"
+#line 19 "alloc.pgc"
 
 
 /* exec sql whenever sqlerror  sqlprint ; */
-#line 29 "alloc.pgc"
+#line 21 "alloc.pgc"
 
 /* exec sql whenever not found  sqlprint ; */
-#line 30 "alloc.pgc"
+#line 22 "alloc.pgc"
 
 
 #ifdef WIN32
@@ -134,54 +126,54 @@ static void* fn(void* arg)
 	 
 	   
 	
-#line 41 "alloc.pgc"
+#line 33 "alloc.pgc"
  int value ;
  
-#line 42 "alloc.pgc"
+#line 34 "alloc.pgc"
  char name [ 100 ] ;
  
-#line 43 "alloc.pgc"
+#line 35 "alloc.pgc"
  char ** r = NULL ;
 /* exec sql end declare section */
-#line 44 "alloc.pgc"
+#line 36 "alloc.pgc"
 
 
 	value = (intptr_t) arg;
 	sprintf(name, "Connection: %d", value);
 
 	{ ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , name, 0); 
-#line 49 "alloc.pgc"
+#line 41 "alloc.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 49 "alloc.pgc"
+#line 41 "alloc.pgc"
 
 	{ ECPGsetcommit(__LINE__, "on", NULL);
-#line 50 "alloc.pgc"
+#line 42 "alloc.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 50 "alloc.pgc"
+#line 42 "alloc.pgc"
 
 	for (i = 1; i <= REPEATS; ++i)
 	{
 		{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select relname from pg_class where relname = 'pg_class'", ECPGt_EOIT, 
 	ECPGt_char,&(r),(long)0,(long)0,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
-#line 53 "alloc.pgc"
+#line 45 "alloc.pgc"
 
 if (sqlca.sqlcode == ECPG_NOT_FOUND) sqlprint();
-#line 53 "alloc.pgc"
+#line 45 "alloc.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 53 "alloc.pgc"
+#line 45 "alloc.pgc"
 
 		free(r);
 		r = NULL;
 	}
 	{ ECPGdisconnect(__LINE__, name);
-#line 57 "alloc.pgc"
+#line 49 "alloc.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 57 "alloc.pgc"
+#line 49 "alloc.pgc"
 
 
 	return 0;
@@ -215,4 +207,3 @@ int main ()
 
 	return 0;
 }
-#endif
diff --git a/src/interfaces/ecpg/test/expected/thread-alloc_2.stdout b/src/interfaces/ecpg/test/expected/thread-alloc_2.stdout
deleted file mode 100644
index 75fe16bb36..0000000000
--- a/src/interfaces/ecpg/test/expected/thread-alloc_2.stdout
+++ /dev/null
@@ -1 +0,0 @@
-No threading enabled.
diff --git a/src/interfaces/ecpg/test/expected/thread-descriptor.c b/src/interfaces/ecpg/test/expected/thread-descriptor.c
index f56cc25ab0..e34f4708d1 100644
--- a/src/interfaces/ecpg/test/expected/thread-descriptor.c
+++ b/src/interfaces/ecpg/test/expected/thread-descriptor.c
@@ -7,7 +7,6 @@
 #define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y))
 
 #line 1 "descriptor.pgc"
-#ifdef ENABLE_THREAD_SAFETY
 #ifdef WIN32
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
@@ -16,7 +15,6 @@
 #else
 #include <pthread.h>
 #endif
-#endif
 #include <stdio.h>
 
 #define THREADS		16
@@ -91,16 +89,16 @@ struct sqlca_t *ECPGget_sqlca(void);
 
 #endif
 
-#line 16 "descriptor.pgc"
+#line 14 "descriptor.pgc"
 
 /* exec sql whenever sqlerror  sqlprint ; */
-#line 17 "descriptor.pgc"
+#line 15 "descriptor.pgc"
 
 /* exec sql whenever not found  sqlprint ; */
-#line 18 "descriptor.pgc"
+#line 16 "descriptor.pgc"
 
 
-#if defined(ENABLE_THREAD_SAFETY) && defined(WIN32)
+#if defined(WIN32)
 static unsigned __stdcall fn(void* arg)
 #else
 static void* fn(void* arg)
@@ -111,16 +109,16 @@ static void* fn(void* arg)
 	for (i = 1; i <= REPEATS; ++i)
 	{
 		ECPGallocate_desc(__LINE__, "mydesc");
-#line 30 "descriptor.pgc"
+#line 28 "descriptor.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();
-#line 30 "descriptor.pgc"
+#line 28 "descriptor.pgc"
 
 		ECPGdeallocate_desc(__LINE__, "mydesc");
-#line 31 "descriptor.pgc"
+#line 29 "descriptor.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();
-#line 31 "descriptor.pgc"
+#line 29 "descriptor.pgc"
 
 	}
 
@@ -129,7 +127,6 @@ if (sqlca.sqlcode < 0) sqlprint();
 
 int main ()
 {
-#ifdef ENABLE_THREAD_SAFETY
 	int i;
 #ifdef WIN32
 	HANDLE threads[THREADS];
@@ -153,9 +150,6 @@ int main ()
 	for (i = 0; i < THREADS; ++i)
 		pthread_join(threads[i], NULL);
 #endif
-#else
-	fn(NULL);
-#endif
 
 	return 0;
 }
diff --git a/src/interfaces/ecpg/test/expected/thread-prep.c b/src/interfaces/ecpg/test/expected/thread-prep.c
index 7cdf2505d3..052e27b634 100644
--- a/src/interfaces/ecpg/test/expected/thread-prep.c
+++ b/src/interfaces/ecpg/test/expected/thread-prep.c
@@ -11,14 +11,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifdef WIN32
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
@@ -101,7 +93,7 @@ struct sqlca_t *ECPGget_sqlca(void);
 
 #endif
 
-#line 26 "prep.pgc"
+#line 18 "prep.pgc"
 
 
 #line 1 "regression.h"
@@ -111,14 +103,14 @@ struct sqlca_t *ECPGget_sqlca(void);
 
 
 
-#line 27 "prep.pgc"
+#line 19 "prep.pgc"
 
 
 /* exec sql whenever sqlerror  sqlprint ; */
-#line 29 "prep.pgc"
+#line 21 "prep.pgc"
 
 /* exec sql whenever not found  sqlprint ; */
-#line 30 "prep.pgc"
+#line 22 "prep.pgc"
 
 
 #ifdef WIN32
@@ -134,64 +126,64 @@ static void* fn(void* arg)
 	 
 	   
 	
-#line 41 "prep.pgc"
+#line 33 "prep.pgc"
  int value ;
  
-#line 42 "prep.pgc"
+#line 34 "prep.pgc"
  char name [ 100 ] ;
  
-#line 43 "prep.pgc"
+#line 35 "prep.pgc"
  char query [ 256 ] = "INSERT INTO T VALUES ( ? )" ;
 /* exec sql end declare section */
-#line 44 "prep.pgc"
+#line 36 "prep.pgc"
 
 
 	value = (intptr_t) arg;
 	sprintf(name, "Connection: %d", value);
 
 	{ ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , name, 0); 
-#line 49 "prep.pgc"
+#line 41 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 49 "prep.pgc"
+#line 41 "prep.pgc"
 
 	{ ECPGsetcommit(__LINE__, "on", NULL);
-#line 50 "prep.pgc"
+#line 42 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 50 "prep.pgc"
+#line 42 "prep.pgc"
 
 	for (i = 1; i <= REPEATS; ++i)
 	{
 		{ ECPGprepare(__LINE__, NULL, 0, "i", query);
-#line 53 "prep.pgc"
+#line 45 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 53 "prep.pgc"
+#line 45 "prep.pgc"
 
 		{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_execute, "i", 
 	ECPGt_int,&(value),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
-#line 54 "prep.pgc"
+#line 46 "prep.pgc"
 
 if (sqlca.sqlcode == ECPG_NOT_FOUND) sqlprint();
-#line 54 "prep.pgc"
+#line 46 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 54 "prep.pgc"
+#line 46 "prep.pgc"
 
 	}
 	{ ECPGdeallocate(__LINE__, 0, NULL, "i");
-#line 56 "prep.pgc"
+#line 48 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 56 "prep.pgc"
+#line 48 "prep.pgc"
 
 	{ ECPGdisconnect(__LINE__, name);
-#line 57 "prep.pgc"
+#line 49 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 57 "prep.pgc"
+#line 49 "prep.pgc"
 
 
 	return 0;
@@ -207,34 +199,34 @@ int main ()
 #endif
 
 	{ ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0); 
-#line 71 "prep.pgc"
+#line 63 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 71 "prep.pgc"
+#line 63 "prep.pgc"
 
 	{ ECPGsetcommit(__LINE__, "on", NULL);
-#line 72 "prep.pgc"
+#line 64 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 72 "prep.pgc"
+#line 64 "prep.pgc"
 
 	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table if exists T", ECPGt_EOIT, ECPGt_EORT);
-#line 73 "prep.pgc"
+#line 65 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 73 "prep.pgc"
+#line 65 "prep.pgc"
 
 	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table T ( i int )", ECPGt_EOIT, ECPGt_EORT);
-#line 74 "prep.pgc"
+#line 66 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 74 "prep.pgc"
+#line 66 "prep.pgc"
 
 	{ ECPGdisconnect(__LINE__, "CURRENT");
-#line 75 "prep.pgc"
+#line 67 "prep.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 75 "prep.pgc"
+#line 67 "prep.pgc"
 
 
 #ifdef WIN32
@@ -256,4 +248,3 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	return 0;
 }
-#endif
diff --git a/src/interfaces/ecpg/test/expected/thread-prep.stdout b/src/interfaces/ecpg/test/expected/thread-prep.stdout
index 75fe16bb36..e69de29bb2 100644
--- a/src/interfaces/ecpg/test/expected/thread-prep.stdout
+++ b/src/interfaces/ecpg/test/expected/thread-prep.stdout
@@ -1 +0,0 @@
-No threading enabled.
diff --git a/src/interfaces/ecpg/test/expected/thread-prep_2.stdout b/src/interfaces/ecpg/test/expected/thread-prep_2.stdout
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/src/interfaces/ecpg/test/expected/thread-thread.c b/src/interfaces/ecpg/test/expected/thread-thread.c
index 0e75c47fab..95faa223c2 100644
--- a/src/interfaces/ecpg/test/expected/thread-thread.c
+++ b/src/interfaces/ecpg/test/expected/thread-thread.c
@@ -15,14 +15,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifndef WIN32
 #include <pthread.h>
 #else
@@ -38,7 +30,7 @@ main(void)
 
 
 
-#line 24 "thread.pgc"
+#line 16 "thread.pgc"
 
 
 void *test_thread(void *arg);
@@ -57,10 +49,10 @@ int main()
   /* exec sql begin declare section */
    
   
-#line 40 "thread.pgc"
+#line 32 "thread.pgc"
  int l_rows ;
 /* exec sql end declare section */
-#line 41 "thread.pgc"
+#line 33 "thread.pgc"
 
 
  /* Do not switch on debug output for regression tests. The threads get executed in
@@ -69,22 +61,22 @@ int main()
 
   /* setup test_thread table */
   { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0); }
-#line 48 "thread.pgc"
+#line 40 "thread.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table test_thread", ECPGt_EOIT, ECPGt_EORT);}
-#line 49 "thread.pgc"
+#line 41 "thread.pgc"
  /* DROP might fail */
   { ECPGtrans(__LINE__, NULL, "commit");}
-#line 50 "thread.pgc"
+#line 42 "thread.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table test_thread ( tstamp timestamp not null default cast ( timeofday ( ) as timestamp ) , thread text not null , iteration integer not null , primary key ( thread , iteration ) )", ECPGt_EOIT, ECPGt_EORT);}
-#line 55 "thread.pgc"
+#line 47 "thread.pgc"
 
   { ECPGtrans(__LINE__, NULL, "commit");}
-#line 56 "thread.pgc"
+#line 48 "thread.pgc"
 
   { ECPGdisconnect(__LINE__, "CURRENT");}
-#line 57 "thread.pgc"
+#line 49 "thread.pgc"
 
 
   /* create, and start, threads */
@@ -116,18 +108,18 @@ int main()
 
   /* and check results */
   { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0); }
-#line 87 "thread.pgc"
+#line 79 "thread.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count ( * ) from test_thread", ECPGt_EOIT, 
 	ECPGt_int,&(l_rows),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
-#line 88 "thread.pgc"
+#line 80 "thread.pgc"
 
   { ECPGtrans(__LINE__, NULL, "commit");}
-#line 89 "thread.pgc"
+#line 81 "thread.pgc"
 
   { ECPGdisconnect(__LINE__, "CURRENT");}
-#line 90 "thread.pgc"
+#line 82 "thread.pgc"
 
   if( l_rows == (nthreads * iterations) )
     printf("Success.\n");
@@ -145,13 +137,13 @@ void *test_thread(void *arg)
     
    
   
-#line 104 "thread.pgc"
+#line 96 "thread.pgc"
  int l_i ;
  
-#line 105 "thread.pgc"
+#line 97 "thread.pgc"
  char l_connection [ 128 ] ;
 /* exec sql end declare section */
-#line 106 "thread.pgc"
+#line 98 "thread.pgc"
 
 
   /* build up connection name, and connect to database */
@@ -161,13 +153,13 @@ void *test_thread(void *arg)
   _snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum);
 #endif
   /* exec sql whenever sqlerror  sqlprint ; */
-#line 114 "thread.pgc"
+#line 106 "thread.pgc"
 
   { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , l_connection, 0); 
-#line 115 "thread.pgc"
+#line 107 "thread.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 115 "thread.pgc"
+#line 107 "thread.pgc"
 
   if( sqlca.sqlcode != 0 )
     {
@@ -175,10 +167,10 @@ if (sqlca.sqlcode < 0) sqlprint();}
       return NULL;
     }
   { ECPGtrans(__LINE__, l_connection, "begin");
-#line 121 "thread.pgc"
+#line 113 "thread.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 121 "thread.pgc"
+#line 113 "thread.pgc"
 
 
   /* insert into test_thread table */
@@ -189,10 +181,10 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_int,&(l_i),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
-#line 126 "thread.pgc"
+#line 118 "thread.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 126 "thread.pgc"
+#line 118 "thread.pgc"
 
       if( sqlca.sqlcode != 0 )
 	printf("%s: ERROR: insert failed!\n", l_connection);
@@ -200,17 +192,16 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
   /* all done */
   { ECPGtrans(__LINE__, l_connection, "commit");
-#line 132 "thread.pgc"
+#line 124 "thread.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 132 "thread.pgc"
+#line 124 "thread.pgc"
 
   { ECPGdisconnect(__LINE__, l_connection);
-#line 133 "thread.pgc"
+#line 125 "thread.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 133 "thread.pgc"
+#line 125 "thread.pgc"
 
   return NULL;
 }
-#endif /* ENABLE_THREAD_SAFETY */
diff --git a/src/interfaces/ecpg/test/expected/thread-thread.stdout b/src/interfaces/ecpg/test/expected/thread-thread.stdout
index 75fe16bb36..a9d787cc55 100644
--- a/src/interfaces/ecpg/test/expected/thread-thread.stdout
+++ b/src/interfaces/ecpg/test/expected/thread-thread.stdout
@@ -1 +1 @@
-No threading enabled.
+Success.
diff --git a/src/interfaces/ecpg/test/expected/thread-thread_2.stdout b/src/interfaces/ecpg/test/expected/thread-thread_2.stdout
deleted file mode 100644
index a9d787cc55..0000000000
--- a/src/interfaces/ecpg/test/expected/thread-thread_2.stdout
+++ /dev/null
@@ -1 +0,0 @@
-Success.
diff --git a/src/interfaces/ecpg/test/expected/thread-thread_implicit.c b/src/interfaces/ecpg/test/expected/thread-thread_implicit.c
index 0df2794530..7ac0297a23 100644
--- a/src/interfaces/ecpg/test/expected/thread-thread_implicit.c
+++ b/src/interfaces/ecpg/test/expected/thread-thread_implicit.c
@@ -15,14 +15,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifndef WIN32
 #include <pthread.h>
 #else
@@ -38,7 +30,7 @@ main(void)
 
 
 
-#line 24 "thread_implicit.pgc"
+#line 16 "thread_implicit.pgc"
 
 
 void *test_thread(void *arg);
@@ -57,10 +49,10 @@ int main()
   /* exec sql begin declare section */
    
   
-#line 40 "thread_implicit.pgc"
+#line 32 "thread_implicit.pgc"
  int l_rows ;
 /* exec sql end declare section */
-#line 41 "thread_implicit.pgc"
+#line 33 "thread_implicit.pgc"
 
 
  /* Do not switch on debug output for regression tests. The threads get executed in
@@ -69,22 +61,22 @@ int main()
 
   /* setup test_thread table */
   { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0); }
-#line 48 "thread_implicit.pgc"
+#line 40 "thread_implicit.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table test_thread", ECPGt_EOIT, ECPGt_EORT);}
-#line 49 "thread_implicit.pgc"
+#line 41 "thread_implicit.pgc"
  /* DROP might fail */
   { ECPGtrans(__LINE__, NULL, "commit");}
-#line 50 "thread_implicit.pgc"
+#line 42 "thread_implicit.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table test_thread ( tstamp timestamp not null default cast ( timeofday ( ) as timestamp ) , thread text not null , iteration integer not null , primary key ( thread , iteration ) )", ECPGt_EOIT, ECPGt_EORT);}
-#line 55 "thread_implicit.pgc"
+#line 47 "thread_implicit.pgc"
 
   { ECPGtrans(__LINE__, NULL, "commit");}
-#line 56 "thread_implicit.pgc"
+#line 48 "thread_implicit.pgc"
 
   { ECPGdisconnect(__LINE__, "CURRENT");}
-#line 57 "thread_implicit.pgc"
+#line 49 "thread_implicit.pgc"
 
 
   /* create, and start, threads */
@@ -116,18 +108,18 @@ int main()
 
   /* and check results */
   { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0); }
-#line 87 "thread_implicit.pgc"
+#line 79 "thread_implicit.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count ( * ) from test_thread", ECPGt_EOIT, 
 	ECPGt_int,&(l_rows),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
-#line 88 "thread_implicit.pgc"
+#line 80 "thread_implicit.pgc"
 
   { ECPGtrans(__LINE__, NULL, "commit");}
-#line 89 "thread_implicit.pgc"
+#line 81 "thread_implicit.pgc"
 
   { ECPGdisconnect(__LINE__, "CURRENT");}
-#line 90 "thread_implicit.pgc"
+#line 82 "thread_implicit.pgc"
 
   if( l_rows == (nthreads * iterations) )
     printf("Success.\n");
@@ -145,13 +137,13 @@ void *test_thread(void *arg)
     
    
   
-#line 104 "thread_implicit.pgc"
+#line 96 "thread_implicit.pgc"
  int l_i ;
  
-#line 105 "thread_implicit.pgc"
+#line 97 "thread_implicit.pgc"
  char l_connection [ 128 ] ;
 /* exec sql end declare section */
-#line 106 "thread_implicit.pgc"
+#line 98 "thread_implicit.pgc"
 
 
   /* build up connection name, and connect to database */
@@ -161,13 +153,13 @@ void *test_thread(void *arg)
   _snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum);
 #endif
   /* exec sql whenever sqlerror  sqlprint ; */
-#line 114 "thread_implicit.pgc"
+#line 106 "thread_implicit.pgc"
 
   { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , l_connection, 0); 
-#line 115 "thread_implicit.pgc"
+#line 107 "thread_implicit.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 115 "thread_implicit.pgc"
+#line 107 "thread_implicit.pgc"
 
   if( sqlca.sqlcode != 0 )
     {
@@ -175,10 +167,10 @@ if (sqlca.sqlcode < 0) sqlprint();}
       return NULL;
     }
   { ECPGtrans(__LINE__, NULL, "begin");
-#line 121 "thread_implicit.pgc"
+#line 113 "thread_implicit.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 121 "thread_implicit.pgc"
+#line 113 "thread_implicit.pgc"
 
 
   /* insert into test_thread table */
@@ -189,10 +181,10 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_int,&(l_i),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
-#line 126 "thread_implicit.pgc"
+#line 118 "thread_implicit.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 126 "thread_implicit.pgc"
+#line 118 "thread_implicit.pgc"
 
       if( sqlca.sqlcode != 0 )
 	printf("%s: ERROR: insert failed!\n", l_connection);
@@ -200,17 +192,16 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
   /* all done */
   { ECPGtrans(__LINE__, NULL, "commit");
-#line 132 "thread_implicit.pgc"
+#line 124 "thread_implicit.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 132 "thread_implicit.pgc"
+#line 124 "thread_implicit.pgc"
 
   { ECPGdisconnect(__LINE__, l_connection);
-#line 133 "thread_implicit.pgc"
+#line 125 "thread_implicit.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 133 "thread_implicit.pgc"
+#line 125 "thread_implicit.pgc"
 
   return NULL;
 }
-#endif /* ENABLE_THREAD_SAFETY */
diff --git a/src/interfaces/ecpg/test/expected/thread-thread_implicit.stdout b/src/interfaces/ecpg/test/expected/thread-thread_implicit.stdout
index 75fe16bb36..a9d787cc55 100644
--- a/src/interfaces/ecpg/test/expected/thread-thread_implicit.stdout
+++ b/src/interfaces/ecpg/test/expected/thread-thread_implicit.stdout
@@ -1 +1 @@
-No threading enabled.
+Success.
diff --git a/src/interfaces/ecpg/test/expected/thread-thread_implicit_2.stdout b/src/interfaces/ecpg/test/expected/thread-thread_implicit_2.stdout
deleted file mode 100644
index a9d787cc55..0000000000
--- a/src/interfaces/ecpg/test/expected/thread-thread_implicit_2.stdout
+++ /dev/null
@@ -1 +0,0 @@
-Success.
diff --git a/src/interfaces/ecpg/test/thread/alloc.pgc b/src/interfaces/ecpg/test/thread/alloc.pgc
index c0021a737e..d3d35493bf 100644
--- a/src/interfaces/ecpg/test/thread/alloc.pgc
+++ b/src/interfaces/ecpg/test/thread/alloc.pgc
@@ -2,14 +2,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifdef WIN32
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
@@ -87,4 +79,3 @@ int main ()
 
 	return 0;
 }
-#endif
diff --git a/src/interfaces/ecpg/test/thread/descriptor.pgc b/src/interfaces/ecpg/test/thread/descriptor.pgc
index 76a7a5dff5..30bce7c87b 100644
--- a/src/interfaces/ecpg/test/thread/descriptor.pgc
+++ b/src/interfaces/ecpg/test/thread/descriptor.pgc
@@ -1,4 +1,3 @@
-#ifdef ENABLE_THREAD_SAFETY
 #ifdef WIN32
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
@@ -7,7 +6,6 @@
 #else
 #include <pthread.h>
 #endif
-#endif
 #include <stdio.h>
 
 #define THREADS		16
@@ -17,7 +15,7 @@ EXEC SQL include sqlca;
 EXEC SQL whenever sqlerror sqlprint;
 EXEC SQL whenever not found sqlprint;
 
-#if defined(ENABLE_THREAD_SAFETY) && defined(WIN32)
+#if defined(WIN32)
 static unsigned __stdcall fn(void* arg)
 #else
 static void* fn(void* arg)
@@ -36,7 +34,6 @@ static void* fn(void* arg)
 
 int main ()
 {
-#ifdef ENABLE_THREAD_SAFETY
 	int i;
 #ifdef WIN32
 	HANDLE threads[THREADS];
@@ -60,9 +57,6 @@ int main ()
 	for (i = 0; i < THREADS; ++i)
 		pthread_join(threads[i], NULL);
 #endif
-#else
-	fn(NULL);
-#endif
 
 	return 0;
 }
diff --git a/src/interfaces/ecpg/test/thread/prep.pgc b/src/interfaces/ecpg/test/thread/prep.pgc
index d7ecfd4855..f61b31ce10 100644
--- a/src/interfaces/ecpg/test/thread/prep.pgc
+++ b/src/interfaces/ecpg/test/thread/prep.pgc
@@ -2,14 +2,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifdef WIN32
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
@@ -93,4 +85,3 @@ int main ()
 
 	return 0;
 }
-#endif
diff --git a/src/interfaces/ecpg/test/thread/thread.pgc b/src/interfaces/ecpg/test/thread/thread.pgc
index e7d8c00af6..b9b9ebb441 100644
--- a/src/interfaces/ecpg/test/thread/thread.pgc
+++ b/src/interfaces/ecpg/test/thread/thread.pgc
@@ -6,14 +6,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifndef WIN32
 #include <pthread.h>
 #else
@@ -133,4 +125,3 @@ void *test_thread(void *arg)
   EXEC SQL DISCONNECT :l_connection;
   return NULL;
 }
-#endif /* ENABLE_THREAD_SAFETY */
diff --git a/src/interfaces/ecpg/test/thread/thread_implicit.pgc b/src/interfaces/ecpg/test/thread/thread_implicit.pgc
index b4cae7e1ae..ff9b12a943 100644
--- a/src/interfaces/ecpg/test/thread/thread_implicit.pgc
+++ b/src/interfaces/ecpg/test/thread/thread_implicit.pgc
@@ -6,14 +6,6 @@
 #include <stdlib.h>
 #include "ecpg_config.h"
 
-#ifndef ENABLE_THREAD_SAFETY
-int
-main(void)
-{
-	printf("No threading enabled.\n");
-	return 0;
-}
-#else
 #ifndef WIN32
 #include <pthread.h>
 #else
@@ -133,4 +125,3 @@ void *test_thread(void *arg)
   EXEC SQL DISCONNECT :l_connection;
   return NULL;
 }
-#endif /* ENABLE_THREAD_SAFETY */
diff --git a/src/interfaces/libpq/Makefile b/src/interfaces/libpq/Makefile
index 8abdb092c2..6af1dbfe8e 100644
--- a/src/interfaces/libpq/Makefile
+++ b/src/interfaces/libpq/Makefile
@@ -71,10 +71,8 @@ ifeq ($(PORTNAME), win32)
 OBJS += \
 	win32.o
 
-ifeq ($(enable_thread_safety), yes)
 OBJS += pthread-win32.o
 endif
-endif
 
 
 # Add libraries that libpq depends (or might depend) on into the
diff --git a/src/interfaces/libpq/fe-auth.c b/src/interfaces/libpq/fe-auth.c
index 49a1c626f6..3504ab2c34 100644
--- a/src/interfaces/libpq/fe-auth.c
+++ b/src/interfaces/libpq/fe-auth.c
@@ -1116,11 +1116,10 @@ pg_fe_getusername(uid_t user_id, PQExpBuffer errorMessage)
 #endif
 
 	/*
-	 * Some users are using configure --enable-thread-safety-force, so we
-	 * might as well do the locking within our library to protect getpwuid().
-	 * In fact, application developers can use getpwuid() in their application
-	 * if they use the locking call we provide, or install their own locking
-	 * function using PQregisterThreadLock().
+	 * We do the locking within our library to protect getpwuid().  Application
+	 * developers can use getpwuid() in their application if they use the
+	 * locking call we provide, or install their own locking function using
+	 * PQregisterThreadLock().
 	 */
 	pglock_thread();
 
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index dc49387d6c..7f14026777 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -55,13 +55,11 @@
 #endif
 #endif
 
-#ifdef ENABLE_THREAD_SAFETY
 #ifdef WIN32
 #include "pthread-win32.h"
 #else
 #include <pthread.h>
 #endif
-#endif
 
 #ifdef USE_LDAP
 #ifdef WIN32
@@ -7364,7 +7362,6 @@ pqGetHomeDirectory(char *buf, int bufsize)
 static void
 default_threadlock(int acquire)
 {
-#ifdef ENABLE_THREAD_SAFETY
 #ifndef WIN32
 	static pthread_mutex_t singlethread_lock = PTHREAD_MUTEX_INITIALIZER;
 #else
@@ -7393,7 +7390,6 @@ default_threadlock(int acquire)
 		if (pthread_mutex_unlock(&singlethread_lock))
 			Assert(false);
 	}
-#endif
 }
 
 pgthreadlock_t
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index a36f5eb310..41861e6a11 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -3924,11 +3924,7 @@ PQisnonblocking(const PGconn *conn)
 int
 PQisthreadsafe(void)
 {
-#ifdef ENABLE_THREAD_SAFETY
 	return true;
-#else
-	return false;
-#endif
 }
 
 
diff --git a/src/interfaces/libpq/fe-print.c b/src/interfaces/libpq/fe-print.c
index 783cd9b756..2dc0f1afb9 100644
--- a/src/interfaces/libpq/fe-print.c
+++ b/src/interfaces/libpq/fe-print.c
@@ -88,14 +88,11 @@ PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
 		bool		usePipe = false;
 		char	   *pagerenv;
 
-#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
+#if !defined(WIN32)
 		sigset_t	osigset;
 		bool		sigpipe_masked = false;
 		bool		sigpipe_pending;
 #endif
-#if !defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
-		pqsigfunc	oldsigpipehandler = NULL;
-#endif
 
 #ifdef TIOCGWINSZ
 		struct winsize screen_size;
@@ -185,12 +182,8 @@ PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
 				{
 					usePipe = true;
 #ifndef WIN32
-#ifdef ENABLE_THREAD_SAFETY
 					if (pq_block_sigpipe(&osigset, &sigpipe_pending) == 0)
 						sigpipe_masked = true;
-#else
-					oldsigpipehandler = pqsignal(SIGPIPE, SIG_IGN);
-#endif							/* ENABLE_THREAD_SAFETY */
 #endif							/* WIN32 */
 				}
 				else
@@ -323,13 +316,9 @@ exit:
 #else
 			pclose(fout);
 
-#ifdef ENABLE_THREAD_SAFETY
 			/* we can't easily verify if EPIPE occurred, so say it did */
 			if (sigpipe_masked)
 				pq_reset_sigpipe(&osigset, sigpipe_pending, true);
-#else
-			pqsignal(SIGPIPE, oldsigpipehandler);
-#endif							/* ENABLE_THREAD_SAFETY */
 #endif							/* WIN32 */
 		}
 	}
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index 8117cbd40f..01b2494bb4 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -46,13 +46,11 @@
 
 #include <sys/stat.h>
 
-#ifdef ENABLE_THREAD_SAFETY
 #ifdef WIN32
 #include "pthread-win32.h"
 #else
 #include <pthread.h>
 #endif
-#endif
 
 /*
  * These SSL-related #includes must come after all system-provided headers.
@@ -93,7 +91,6 @@ static bool pq_init_crypto_lib = true;
 
 static bool ssl_lib_initialized = false;
 
-#ifdef ENABLE_THREAD_SAFETY
 static long crypto_open_connections = 0;
 
 #ifndef WIN32
@@ -102,7 +99,6 @@ static pthread_mutex_t ssl_config_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t ssl_config_mutex = NULL;
 static long win32_ssl_create_mutex = 0;
 #endif
-#endif							/* ENABLE_THREAD_SAFETY */
 
 static PQsslKeyPassHook_OpenSSL_type PQsslKeyPassHook = NULL;
 static int	ssl_protocol_version_to_openssl(const char *protocol);
@@ -114,15 +110,12 @@ static int	ssl_protocol_version_to_openssl(const char *protocol);
 void
 pgtls_init_library(bool do_ssl, int do_crypto)
 {
-#ifdef ENABLE_THREAD_SAFETY
-
 	/*
 	 * Disallow changing the flags while we have open connections, else we'd
 	 * get completely confused.
 	 */
 	if (crypto_open_connections != 0)
 		return;
-#endif
 
 	pq_init_ssl_lib = do_ssl;
 	pq_init_crypto_lib = do_crypto;
@@ -709,7 +702,7 @@ pgtls_verify_peer_name_matches_certificate_guts(PGconn *conn,
 	return rc;
 }
 
-#if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_CRYPTO_LOCK)
+#if defined(HAVE_CRYPTO_LOCK)
 /*
  *	Callback functions for OpenSSL internal locking.  (OpenSSL 1.1.0
  *	does its own locking, and doesn't need these anymore.  The
@@ -750,7 +743,7 @@ pq_lockingcallback(int mode, int n, const char *file, int line)
 			Assert(false);
 	}
 }
-#endif							/* ENABLE_THREAD_SAFETY && HAVE_CRYPTO_LOCK */
+#endif							/* HAVE_CRYPTO_LOCK */
 
 /*
  * Initialize SSL library.
@@ -765,7 +758,6 @@ pq_lockingcallback(int mode, int n, const char *file, int line)
 int
 pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto)
 {
-#ifdef ENABLE_THREAD_SAFETY
 #ifdef WIN32
 	/* Also see similar code in fe-connect.c, default_threadlock() */
 	if (ssl_config_mutex == NULL)
@@ -831,7 +823,6 @@ pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto)
 		}
 	}
 #endif							/* HAVE_CRYPTO_LOCK */
-#endif							/* ENABLE_THREAD_SAFETY */
 
 	if (!ssl_lib_initialized && do_ssl)
 	{
@@ -848,9 +839,7 @@ pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto)
 		ssl_lib_initialized = true;
 	}
 
-#ifdef ENABLE_THREAD_SAFETY
 	pthread_mutex_unlock(&ssl_config_mutex);
-#endif
 	return 0;
 }
 
@@ -869,7 +858,7 @@ pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto)
 static void
 destroy_ssl_system(void)
 {
-#if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_CRYPTO_LOCK)
+#if defined(HAVE_CRYPTO_LOCK)
 	/* Mutex is created in pgtls_init() */
 	if (pthread_mutex_lock(&ssl_config_mutex))
 		return;
diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c
index a1dc7b796d..88607fb65b 100644
--- a/src/interfaces/libpq/fe-secure.c
+++ b/src/interfaces/libpq/fe-secure.c
@@ -37,13 +37,11 @@
 
 #include <sys/stat.h>
 
-#ifdef ENABLE_THREAD_SAFETY
 #ifdef WIN32
 #include "pthread-win32.h"
 #else
 #include <pthread.h>
 #endif
-#endif
 
 #include "fe-auth.h"
 #include "libpq-fe.h"
@@ -58,8 +56,6 @@
 
 #define SIGPIPE_MASKED(conn)	((conn)->sigpipe_so || (conn)->sigpipe_flag)
 
-#ifdef ENABLE_THREAD_SAFETY
-
 struct sigpipe_info
 {
 	sigset_t	oldsigmask;
@@ -92,24 +88,6 @@ struct sigpipe_info
 			pq_reset_sigpipe(&(spinfo).oldsigmask, (spinfo).sigpipe_pending, \
 							 (spinfo).got_epipe); \
 	} while (0)
-#else							/* !ENABLE_THREAD_SAFETY */
-
-#define DECLARE_SIGPIPE_INFO(spinfo) pqsigfunc spinfo = NULL
-
-#define DISABLE_SIGPIPE(conn, spinfo, failaction) \
-	do { \
-		if (!SIGPIPE_MASKED(conn)) \
-			spinfo = pqsignal(SIGPIPE, SIG_IGN); \
-	} while (0)
-
-#define REMEMBER_EPIPE(spinfo, cond)
-
-#define RESTORE_SIGPIPE(conn, spinfo) \
-	do { \
-		if (!SIGPIPE_MASKED(conn)) \
-			pqsignal(SIGPIPE, spinfo); \
-	} while (0)
-#endif							/* ENABLE_THREAD_SAFETY */
 #else							/* WIN32 */
 
 #define DECLARE_SIGPIPE_INFO(spinfo)
@@ -524,7 +502,7 @@ PQgssEncInUse(PGconn *conn)
 #endif							/* ENABLE_GSS */
 
 
-#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
+#if !defined(WIN32)
 
 /*
  *	Block SIGPIPE for this thread.  This prevents send()/write() from exiting
@@ -608,4 +586,4 @@ pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, bool got_epipe)
 	SOCK_ERRNO_SET(save_errno);
 }
 
-#endif							/* ENABLE_THREAD_SAFETY && !WIN32 */
+#endif							/* !WIN32 */
diff --git a/src/interfaces/libpq/legacy-pqsignal.c b/src/interfaces/libpq/legacy-pqsignal.c
index db470df9ea..1b4424eabb 100644
--- a/src/interfaces/libpq/legacy-pqsignal.c
+++ b/src/interfaces/libpq/legacy-pqsignal.c
@@ -27,10 +27,6 @@
  * Because it is only intended for backwards compatibility, we freeze it
  * with the semantics it had in 9.2; in particular, this has different
  * behavior for SIGALRM than the version in src/port/pqsignal.c.
- *
- * libpq itself uses this only for SIGPIPE (and even then, only in
- * non-ENABLE_THREAD_SAFETY builds), so the incompatibility isn't
- * troublesome for internal references.
  */
 pqsigfunc
 pqsignal(int signo, pqsigfunc func)
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index 51ab51f9f9..99c40af8cf 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -28,14 +28,12 @@
 #include <sys/time.h>
 #endif
 
-#ifdef ENABLE_THREAD_SAFETY
 #ifdef WIN32
 #include "pthread-win32.h"
 #else
 #include <pthread.h>
 #endif
 #include <signal.h>
-#endif
 
 /* include stuff common to fe and be */
 #include "getaddrinfo.h"
@@ -649,15 +647,10 @@ extern int	pqPacketSend(PGconn *conn, char pack_type,
 						 const void *buf, size_t buf_len);
 extern bool pqGetHomeDirectory(char *buf, int bufsize);
 
-#ifdef ENABLE_THREAD_SAFETY
 extern pgthreadlock_t pg_g_threadlock;
 
 #define pglock_thread()		pg_g_threadlock(true)
 #define pgunlock_thread()	pg_g_threadlock(false)
-#else
-#define pglock_thread()		((void) 0)
-#define pgunlock_thread()	((void) 0)
-#endif
 
 /* === in fe-exec.c === */
 
@@ -732,7 +725,7 @@ extern ssize_t pqsecure_write(PGconn *, const void *ptr, size_t len);
 extern ssize_t pqsecure_raw_read(PGconn *, void *ptr, size_t len);
 extern ssize_t pqsecure_raw_write(PGconn *, const void *ptr, size_t len);
 
-#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
+#if !defined(WIN32)
 extern int	pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending);
 extern void pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending,
 							 bool got_epipe);
diff --git a/src/port/getaddrinfo.c b/src/port/getaddrinfo.c
index bea7b520f0..8cb3a4db2f 100644
--- a/src/port/getaddrinfo.c
+++ b/src/port/getaddrinfo.c
@@ -414,7 +414,7 @@ pqGethostbyname(const char *name,
 				struct hostent **result,
 				int *herrno)
 {
-#if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_GETHOSTBYNAME_R)
+#if defined(HAVE_GETHOSTBYNAME_R)
 
 	/*
 	 * broken (well early POSIX draft) gethostbyname_r() which returns 'struct
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index d7ab6ab258..33693b41b9 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -219,7 +219,6 @@ sub GenerateFiles
 		DLSUFFIX                   => '".dll"',
 		ENABLE_GSS                 => $self->{options}->{gss} ? 1 : undef,
 		ENABLE_NLS                 => $self->{options}->{nls} ? 1 : undef,
-		ENABLE_THREAD_SAFETY       => 1,
 		GETTIMEOFDAY_1ARG          => undef,
 		HAVE_APPEND_HISTORY        => undef,
 		HAVE_ASN1_STRING_GET0_DATA => undef,
@@ -1208,7 +1207,7 @@ sub GetFakeConfigure
 {
 	my $self = shift;
 
-	my $cfg = '--enable-thread-safety';
+	my $cfg = '';
 	$cfg .= ' --enable-cassert'   if ($self->{options}->{asserts});
 	$cfg .= ' --enable-nls'       if ($self->{options}->{nls});
 	$cfg .= ' --enable-tap-tests' if ($self->{options}->{tap_tests});
diff --git a/src/tools/msvc/ecpg_regression.proj b/src/tools/msvc/ecpg_regression.proj
index ec2760b1f6..0ec60a275e 100644
--- a/src/tools/msvc/ecpg_regression.proj
+++ b/src/tools/msvc/ecpg_regression.proj
@@ -54,7 +54,7 @@
 
   <!-- Run ECPG and the Visual C++ compiler on the files. Don't bother with dependency check between the steps -->
   <Exec WorkingDirectory="%(Pgc.RelativeDir)" Command="$(OUTDIR)ecpg\ecpg -I ../../include --regression $(ECPGPARAM) -o %(Pgc.Filename).c %(Pgc.Filename).pgc" />
-  <Exec WorkingDirectory="%(Pgc.RelativeDir)" Command="cl /nologo %(Pgc.FileName).c /TC /MD$(DEBUGLIB) /DENABLE_THREAD_SAFETY /DWIN32 /I. /I..\..\include /I..\..\..\libpq /I..\..\..\..\include /link /defaultlib:$(OUTDIR)libecpg\libecpg.lib /defaultlib:$(OUTDIR)libecpg_compat\libecpg_compat.lib /defaultlib:$(OUTDIR)libpgtypes\libpgtypes.lib" />
+  <Exec WorkingDirectory="%(Pgc.RelativeDir)" Command="cl /nologo %(Pgc.FileName).c /TC /MD$(DEBUGLIB) /DWIN32 /I. /I..\..\include /I..\..\..\libpq /I..\..\..\..\include /link /defaultlib:$(OUTDIR)libecpg\libecpg.lib /defaultlib:$(OUTDIR)libecpg_compat\libecpg_compat.lib /defaultlib:$(OUTDIR)libpgtypes\libpgtypes.lib" />
  </Target>
 
  <!-- Clean up all output files -->
-- 
2.37.1

#21Andres Freund
andres@anarazel.de
In reply to: Thomas Munro (#20)
Re: Cleaning up historical portability baggage

Hi,

Another potential cleanup is the fallback for strtoll/strtoull. Some of the
spellings were introduced because of "ancient HPUX":

commit 06f66cff9e0b93db81db1595156b2aff8ba1786e
Author: Tom Lane <tgl@sss.pgh.pa.us>
Date: 2018-05-19 14:22:18 -0400

Support platforms where strtoll/strtoull are spelled __strtoll/__strtoull.

Ancient HPUX, for one, does this. We hadn't noticed due to the lack
of regression tests that required a working strtoll.

(I was slightly tempted to remove the other historical spelling,
strto[u]q, since it seems we have no buildfarm members testing that case.
But I refrained.)

Discussion: /messages/by-id/151935568942.1461.14623890240535309745@wrigleys.postgresql.org

and some much longer ago:

commit 9394d391b803c55281879721ea393a50df4a0be6
Author: Peter Eisentraut <peter_e@gmx.net>
Date: 2000-11-20 15:56:14 +0000

Add configure checks for strtoll, strtoull (or strto[u]q). Disable
'long long int' portions of ecpg if the type or these functions don't
exist.

since strtoq, strtouq apparently were already obsolete in 2018, and hpux is
now obsolete...

I only noticed this because I'd ported the configure check a bit naively,
without the break in the if-found case, and was looking into why HAVE_STRTOQ,
HAVE_STRTOUQ were defined with meson, but not autoconf...
AC_CHECK_FUNCS([strtoll __strtoll strtoq], [break])
AC_CHECK_FUNCS([strtoull __strtoull strtouq], [break])

Greetings,

Andres Freund

#22Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andres Freund (#21)
Re: Cleaning up historical portability baggage

Andres Freund <andres@anarazel.de> writes:

Another potential cleanup is the fallback for strtoll/strtoull.

+1, I suspect the alternate spellings are dead.

regards, tom lane

#23Andres Freund
andres@anarazel.de
In reply to: Tom Lane (#22)
1 attachment(s)
Re: Cleaning up historical portability baggage

Hi,

On 2022-08-03 21:52:04 -0400, Tom Lane wrote:

Andres Freund <andres@anarazel.de> writes:

Another potential cleanup is the fallback for strtoll/strtoull.

+1, I suspect the alternate spellings are dead.

Looks like that includes systems where there's no declaration for strtoll,
strtoull. The test was introduced in

commit a6228128fc48c222953dfd41fd438522a184054c
Author: Tom Lane <tgl@sss.pgh.pa.us>
Date: 2018-05-18 22:42:10 -0400

Arrange to supply declarations for strtoll/strtoull if needed.

The check was introduced for animal dromedary, afaics. Looks like that stopped
reporting 2019-09-27 and transformed into florican.

A query on the bf database didn't see any runs in the last 30 days that didn't
have strtoll declared.

See attached patch.

Greetings,

Andres Freund

Attachments:

v1-0001-Remove-fallbacks-for-strtoll-strtoull.patchtext/x-diff; charset=us-asciiDownload
From 971cd9491f27b52b982b0a9735bc0e678805e14b Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Wed, 3 Aug 2022 19:21:56 -0700
Subject: [PATCH v1] Remove fallbacks for strtoll, strtoull

strtoll was backfilled with either __strtoll or strtoq on systems without
strtoll. The last such system on the buildfarm was an ancient HP-UX animal. We
don't support HP-UX anymore, so remove.

On other systems strtoll was present, but did not have a declaration. The last
known instance on the buildfarm was running an ancient OSX and shut down in
2019.

Discussion: https://postgr.es/m/20220804013546.h65najrzig764jar@awork3.anarazel.de
---
 src/include/c.h            | 29 -----------------------
 src/include/pg_config.h.in | 26 ---------------------
 configure                  | 47 --------------------------------------
 configure.ac               |  5 ----
 src/tools/msvc/Solution.pm |  8 -------
 5 files changed, 115 deletions(-)

diff --git a/src/include/c.h b/src/include/c.h
index d35405f191a..8c4baeb0ec3 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -1294,35 +1294,6 @@ typedef union PGAlignedXLogBlock
 extern int	fdatasync(int fildes);
 #endif
 
-/* Older platforms may provide strto[u]ll functionality under other names */
-#if !defined(HAVE_STRTOLL) && defined(HAVE___STRTOLL)
-#define strtoll __strtoll
-#define HAVE_STRTOLL 1
-#endif
-
-#if !defined(HAVE_STRTOLL) && defined(HAVE_STRTOQ)
-#define strtoll strtoq
-#define HAVE_STRTOLL 1
-#endif
-
-#if !defined(HAVE_STRTOULL) && defined(HAVE___STRTOULL)
-#define strtoull __strtoull
-#define HAVE_STRTOULL 1
-#endif
-
-#if !defined(HAVE_STRTOULL) && defined(HAVE_STRTOUQ)
-#define strtoull strtouq
-#define HAVE_STRTOULL 1
-#endif
-
-#if defined(HAVE_STRTOLL) && !HAVE_DECL_STRTOLL
-extern long long strtoll(const char *str, char **endptr, int base);
-#endif
-
-#if defined(HAVE_STRTOULL) && !HAVE_DECL_STRTOULL
-extern unsigned long long strtoull(const char *str, char **endptr, int base);
-#endif
-
 /*
  * Thin wrappers that convert strings to exactly 64-bit integers, matching our
  * definition of int64.  (For the naming, compare that POSIX has
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index f9618e19863..00abe62f5c6 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -161,14 +161,6 @@
    don't. */
 #undef HAVE_DECL_STRNLEN
 
-/* Define to 1 if you have the declaration of `strtoll', and to 0 if you
-   don't. */
-#undef HAVE_DECL_STRTOLL
-
-/* Define to 1 if you have the declaration of `strtoull', and to 0 if you
-   don't. */
-#undef HAVE_DECL_STRTOULL
-
 /* Define to 1 if you have the `dlopen' function. */
 #undef HAVE_DLOPEN
 
@@ -531,18 +523,6 @@
 /* Define to 1 if you have the `strtof' function. */
 #undef HAVE_STRTOF
 
-/* Define to 1 if you have the `strtoll' function. */
-#undef HAVE_STRTOLL
-
-/* Define to 1 if you have the `strtoq' function. */
-#undef HAVE_STRTOQ
-
-/* Define to 1 if you have the `strtoull' function. */
-#undef HAVE_STRTOULL
-
-/* Define to 1 if you have the `strtouq' function. */
-#undef HAVE_STRTOUQ
-
 /* Define to 1 if the system has the type `struct addrinfo'. */
 #undef HAVE_STRUCT_ADDRINFO
 
@@ -747,12 +727,6 @@
 /* Define to 1 if your compiler understands _Static_assert. */
 #undef HAVE__STATIC_ASSERT
 
-/* Define to 1 if you have the `__strtoll' function. */
-#undef HAVE___STRTOLL
-
-/* Define to 1 if you have the `__strtoull' function. */
-#undef HAVE___STRTOULL
-
 /* Define to the appropriate printf length modifier for 64-bit ints. */
 #undef INT64_MODIFIER
 
diff --git a/configure b/configure
index c5bc3823958..b9add9022b8 100755
--- a/configure
+++ b/configure
@@ -17230,53 +17230,6 @@ $as_echo "#define HAVE_INT_OPTRESET 1" >>confdefs.h
 
 fi
 
-for ac_func in strtoll __strtoll strtoq
-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"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
- break
-fi
-done
-
-for ac_func in strtoull __strtoull strtouq
-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"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
- break
-fi
-done
-
-# strto[u]ll may exist but not be declared
-ac_fn_c_check_decl "$LINENO" "strtoll" "ac_cv_have_decl_strtoll" "$ac_includes_default"
-if test "x$ac_cv_have_decl_strtoll" = xyes; then :
-  ac_have_decl=1
-else
-  ac_have_decl=0
-fi
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL_STRTOLL $ac_have_decl
-_ACEOF
-ac_fn_c_check_decl "$LINENO" "strtoull" "ac_cv_have_decl_strtoull" "$ac_includes_default"
-if test "x$ac_cv_have_decl_strtoull" = xyes; then :
-  ac_have_decl=1
-else
-  ac_have_decl=0
-fi
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL_STRTOULL $ac_have_decl
-_ACEOF
-
-
 if test "$with_icu" = yes; then
   ac_save_CPPFLAGS=$CPPFLAGS
   CPPFLAGS="$ICU_CFLAGS $CPPFLAGS"
diff --git a/configure.ac b/configure.ac
index 61d0dd5d586..982f218b30f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2009,11 +2009,6 @@ if test x"$pgac_cv_var_int_optreset" = x"yes"; then
   AC_DEFINE(HAVE_INT_OPTRESET, 1, [Define to 1 if you have the global variable 'int optreset'.])
 fi
 
-AC_CHECK_FUNCS([strtoll __strtoll strtoq], [break])
-AC_CHECK_FUNCS([strtoull __strtoull strtouq], [break])
-# strto[u]ll may exist but not be declared
-AC_CHECK_DECLS([strtoll, strtoull])
-
 if test "$with_icu" = yes; then
   ac_save_CPPFLAGS=$CPPFLAGS
   CPPFLAGS="$ICU_CFLAGS $CPPFLAGS"
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index b09872e018d..5b420ce4efd 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -249,8 +249,6 @@ sub GenerateFiles
 		HAVE_DECL_STRLCAT                           => 0,
 		HAVE_DECL_STRLCPY                           => 0,
 		HAVE_DECL_STRNLEN                           => 1,
-		HAVE_DECL_STRTOLL                           => 1,
-		HAVE_DECL_STRTOULL                          => 1,
 		HAVE_DLOPEN                                 => undef,
 		HAVE_EDITLINE_HISTORY_H                     => undef,
 		HAVE_EDITLINE_READLINE_H                    => undef,
@@ -370,10 +368,6 @@ sub GenerateFiles
 		HAVE_STRNLEN                             => 1,
 		HAVE_STRSIGNAL                           => undef,
 		HAVE_STRTOF                              => 1,
-		HAVE_STRTOLL                             => 1,
-		HAVE_STRTOQ                              => undef,
-		HAVE_STRTOULL                            => 1,
-		HAVE_STRTOUQ                             => undef,
 		HAVE_STRUCT_ADDRINFO                     => 1,
 		HAVE_STRUCT_CMSGCRED                     => undef,
 		HAVE_STRUCT_OPTION                       => undef,
@@ -442,8 +436,6 @@ sub GenerateFiles
 		HAVE__CPUID                              => 1,
 		HAVE__GET_CPUID                          => undef,
 		HAVE__STATIC_ASSERT                      => undef,
-		HAVE___STRTOLL                           => undef,
-		HAVE___STRTOULL                          => undef,
 		INT64_MODIFIER                           => qq{"ll"},
 		LOCALE_T_IN_XLOCALE                      => undef,
 		MAXIMUM_ALIGNOF                          => 8,
-- 
2.37.0.3.g30cc8d0f14

#24Andres Freund
andres@anarazel.de
In reply to: Thomas Munro (#20)
Re: Cleaning up historical portability baggage

Hi,

Can we get a few more of these committed soon? It's all tests that I need to
sync with the meson stuff, and I'd rather get it over with :). And it reduces
the set of tests that need to be compared... Or is there a blocker (leaving
the prairedog one aside)?

On 2022-08-03 14:25:01 +1200, Thomas Munro wrote:

Subject: [PATCH v3 01/13] Remove configure probe for dlopen.
Subject: [PATCH v3 02/13] Remove configure probe and extra tests for
getrlimit.

LGTM.

From 96a4935ff9480c2786634e9892b1f44782b403fb Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 23 Jul 2022 23:49:27 +1200
Subject: [PATCH v3 03/13] Remove configure probe for shm_open.

shm_open() is in SUSv2 (realtime) and all targeted Unix systems have it.

We retain a HAVE_SHM_OPEN macro, because it's clearer to readers than
something like !defined(WIN32).

I don't like these. I don't find them clearer - if we really just assume this
to be the case on windows, it's easier to understand the checks if they talk
about windows rather than having to know whether this specific check just
applies to windows or potentially an unspecified separate set of systems.

But I guess I should complain upthread...

Subject: [PATCH v3 04/13] Remove configure probe for setsid.

LGTM.

Subject: [PATCH v3 05/13] Remove configure probes for symlink/readlink, and
dead code.

Nice win.

From 143f6917bbc7d8f457d52d02a5fbc79d849744e1 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sun, 24 Jul 2022 01:19:05 +1200

Subject: [PATCH v3 06/13] Remove configure probe for link.
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -402,7 +402,8 @@ extern float pg_strtof(const char *nptr, char **endptr);
#define strtof(a,b) (pg_strtof((a),(b)))
#endif
-#ifndef HAVE_LINK
+#ifdef WIN32
+/* src/port/win32link.c */
extern int	link(const char *src, const char *dst);
#endif

It bothers me that we have all this windows crap in port.h instead of
win32_port.h. But that's not this patch's fault.

Subject: [PATCH v3 07/13] Remove dead replacement code for clock_gettime().

Nice.

XXX This can only be committed once prairedog is decommissioned, because
macOS 10.4 didn't have clock_gettime().

Maybe put it later in the queue?

Subject: [PATCH v3 08/13] Remove configure probes for poll and poll.h.

poll() and <poll.h> are in SUSv2 and all targeted Unix systems have
them.

Retain HAVE_POLL and HAVE_POLL_H macros for readability. There's an
error in latch.c that is now unreachable (since logically always have
one of WIN32 or HAVE_POLL defined), but that falls out of a decision to
keep using defined(HAVE_POLL) instead of !defined(WIN32) to guard the
poll() code.

Wonder if we instead should add an empty poll.h to src/include/port/win32?

Subject: [PATCH v3 09/13] Remove dead setenv, unsetenv replacement code.
Subject: [PATCH v3 10/13] Remove dead pread and pwrite replacement code.

LGTM.

Subject: [PATCH v3 11/13] Simplify replacement code for preadv and pwritev.

preadv() and pwritev() are not standardized by POSIX. Most targeted
Unix systems have had them for more than a decade, since they are
obvious combinations of standard p- and -v functions.

In 15, we had two replacement implementations: one based on lseek() + -v
function if available, and the other based on a loop over p- function.
They aren't used for much yet, but are heavily used in a current
proposal.

Supporting two ways of falling back, at the cost of having a
pg_preadv/pg_pwritev that could never be used in a multi-threaded
program accessing the same file descriptor from two threads without
unpleasant locking does not sound like a good trade.

Therefore, drop the lseek()-based variant, and also the pg_ prefix, now
that the file position portability hazard is gone. Previously, both
fallbacks had the file position portability hazard, because our
pread()/pwrite() replacement had the same hazard, but that problem has
been fixed for pread()/pwrite() by an earlier commit. Now the way is
clear to expunge the file position portability hazard of the
lseek()-based variants too.

At the time of writing, the following systems in our build farm lack
native preadv/pwritev and thus use fallback code:

* Solaris (but not illumos)
* macOS before release 11.0
* Windows with Cygwin
* Windows native

With this commit, all of the above systems will now use the *same*
fallback code, the one that loops over pread()/pwrite() (which is
translated to equivalent calls in Windows). Previously, all but Windows
native would use the readv()/writev()-based fallback that this commit
removes.

Given that it's just solaris and old macOS that "benefited" from writev, just
using the "full" fallback there makes sense.

Subject: [PATCH v3 12/13] Remove fdatasync configure probe.

@@ -1928,7 +1925,6 @@ if test "$PORTNAME" = "win32"; then
AC_CHECK_FUNCS(_configthreadlocale)
AC_REPLACE_FUNCS(gettimeofday)
AC_LIBOBJ(dirmod)
- AC_LIBOBJ(fdatasync)
AC_LIBOBJ(getrusage)
AC_LIBOBJ(kill)
AC_LIBOBJ(open)
@@ -1936,6 +1932,7 @@ if test "$PORTNAME" = "win32"; then
AC_LIBOBJ(win32dlopen)
AC_LIBOBJ(win32env)
AC_LIBOBJ(win32error)
+ AC_LIBOBJ(win32fdatasync)
AC_LIBOBJ(win32link)
AC_LIBOBJ(win32ntdll)
AC_LIBOBJ(win32pread)

I like that we might get away from all those "generically" named libobjs that
are hardcoded to be used only on windows...

From 5bda430998d502a7f8a6fe662a56b63ac374c925 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Fri, 26 Mar 2021 22:58:06 +1300
Subject: [PATCH v3 13/13] Remove --disable-thread-safety.

Threads are in SUSv2 and all targeted Unix systems have the option.
There are no known Unix systems that don't choose to implement the
threading option, and we're no longer testing such builds.

Future work to improve our use of threads will be simplified by not
having to cope with a no-threads build option.

Yeha.

AC_CHECK_HEADER(pthread.h, [], [AC_MSG_ERROR([
-pthread.h not found;  use --disable-thread-safety to disable thread safety])])
+pthread.h not found])])

Is this really needed after these changes? We probably can't get away from
AX_PTHREAD just yet, but we should be able to rely on pthread.h?

diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 2a0d08d10f..a4ef016c06 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -51,10 +51,6 @@
/* Define to 1 if you want National Language Support. (--enable-nls) */
#undef ENABLE_NLS

-/* Define to 1 to build client libraries as thread-safe code.
- (--enable-thread-safety) */
-#undef ENABLE_THREAD_SAFETY
-

Might be worth grepping around whether there are extensions that reference
ENABLE_THREAD_SAFETY (e.g. to then error out if not available). If common
enough we could decide to keep it, given that it's pretty reasonable for code
to want to know that across versions?

# Add libraries that libpq depends (or might depend) on into the
diff --git a/src/interfaces/libpq/fe-auth.c b/src/interfaces/libpq/fe-auth.c
index 49a1c626f6..3504ab2c34 100644
--- a/src/interfaces/libpq/fe-auth.c
+++ b/src/interfaces/libpq/fe-auth.c
@@ -1116,11 +1116,10 @@ pg_fe_getusername(uid_t user_id, PQExpBuffer errorMessage)
#endif
/*
-	 * Some users are using configure --enable-thread-safety-force, so we
-	 * might as well do the locking within our library to protect getpwuid().
-	 * In fact, application developers can use getpwuid() in their application
-	 * if they use the locking call we provide, or install their own locking
-	 * function using PQregisterThreadLock().
+	 * We do the locking within our library to protect getpwuid().  Application
+	 * developers can use getpwuid() in their application if they use the
+	 * locking call we provide, or install their own locking function using
+	 * PQregisterThreadLock().
*/
pglock_thread();

Probably worth using getpwuid_r where available - might even be everywhere
(except windows of course, but GetUserName() is threadsafe).

--- a/src/port/getaddrinfo.c
+++ b/src/port/getaddrinfo.c
@@ -414,7 +414,7 @@ pqGethostbyname(const char *name,
struct hostent **result,
int *herrno)
{
-#if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_GETHOSTBYNAME_R)
+#if defined(HAVE_GETHOSTBYNAME_R)
/*
* broken (well early POSIX draft) gethostbyname_r() which returns 'struct

Depressingly there's still plenty systems without gethostbyname_r() :(

curculio, gombessa, longfin, lorikeet, morepork, pollock, sifaka, wrasse ...

Greetings,

Andres Freund

#25Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andres Freund (#24)
Re: Cleaning up historical portability baggage

Andres Freund <andres@anarazel.de> writes:

XXX This can only be committed once prairedog is decommissioned, because
macOS 10.4 didn't have clock_gettime().

Maybe put it later in the queue?

clock_gettime is required by SUSv2 (1997), so I have to admit that
macOS 10.4 doesn't have a lot of excuse not to have it. In any case,
prairiedog is just sitting there doing its thing until I find cycles
to install a newer OS. If you want to move ahead with this, don't
let prairiedog block you.

regards, tom lane

#26Thomas Munro
thomas.munro@gmail.com
In reply to: Tom Lane (#25)
Re: Cleaning up historical portability baggage

On Thu, Aug 4, 2022 at 4:09 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Andres Freund <andres@anarazel.de> writes:

XXX This can only be committed once prairedog is decommissioned, because
macOS 10.4 didn't have clock_gettime().

Maybe put it later in the queue?

clock_gettime is required by SUSv2 (1997), so I have to admit that
macOS 10.4 doesn't have a lot of excuse not to have it. In any case,
prairiedog is just sitting there doing its thing until I find cycles
to install a newer OS. If you want to move ahead with this, don't
let prairiedog block you.

Thanks, will do. Just having an argument with MSYS about something I
seem to have messed up in the most recent version, and then I'll start
pushing these...

#27Thomas Munro
thomas.munro@gmail.com
In reply to: Andres Freund (#24)
Re: Cleaning up historical portability baggage

On Thu, Aug 4, 2022 at 3:43 PM Andres Freund <andres@anarazel.de> wrote:

We retain a HAVE_SHM_OPEN macro, because it's clearer to readers than
something like !defined(WIN32).

I don't like these. I don't find them clearer - if we really just assume this
to be the case on windows, it's easier to understand the checks if they talk
about windows rather than having to know whether this specific check just
applies to windows or potentially an unspecified separate set of systems.

But I guess I should complain upthread...

Thanks for reviewing.

For this point, I'm planning to commit with those "vestigial" macros
that Tom asked for, and then we can argue about removing them
separately later.

#28Thomas Munro
thomas.munro@gmail.com
In reply to: Thomas Munro (#27)
Re: Cleaning up historical portability baggage

I've now pushed all of these except the --disable-thread-safety one,
which I'm still contemplating. So far all green on the farm (except
known unrelated breakage). But that's just the same-day animals...

#29Thomas Munro
thomas.munro@gmail.com
In reply to: Andres Freund (#23)
Re: Cleaning up historical portability baggage

On Thu, Aug 4, 2022 at 2:30 PM Andres Freund <andres@anarazel.de> wrote:

On 2022-08-03 21:52:04 -0400, Tom Lane wrote:

Andres Freund <andres@anarazel.de> writes:

Another potential cleanup is the fallback for strtoll/strtoull.

+1, I suspect the alternate spellings are dead.

Looks like that includes systems where there's no declaration for strtoll,
strtoull. The test was introduced in

commit a6228128fc48c222953dfd41fd438522a184054c
Author: Tom Lane <tgl@sss.pgh.pa.us>
Date: 2018-05-18 22:42:10 -0400

Arrange to supply declarations for strtoll/strtoull if needed.

The check was introduced for animal dromedary, afaics. Looks like that stopped
reporting 2019-09-27 and transformed into florican.

A query on the bf database didn't see any runs in the last 30 days that didn't
have strtoll declared.

See attached patch.

LGTM. This is just C99 <stdlib.h> stuff, and my scraped config data
set agrees with your observation.

#30Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#16)
Re: Cleaning up historical portability baggage

On Sat, Jul 23, 2022 at 8:23 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:

More generally, I'm not exactly convinced that changes like
this are a readability improvement:

-#ifdef HAVE_SETSID
+#ifndef WIN32

I'd rather not have the code cluttered with a sea of
indistinguishable "#ifndef WIN32" tests when some of them could be
more specific and more mnemonic.

I can see both sides of this issue. On the one hand, if there's a
large chunk of code that's surrounded by #ifndef WIN32, then it might
not be clear to the casual observer that the block of code in question
is working around the lack of setsid() rather than some other
Windows-specific weirdness. Comments can help with that, though. On
the other hand, to me, seeing HAVE_SETSID makes me think that we're
dealing with a configure probe, and that I might have to worry about
UNIX-like systems not having support for that primitive. If it says
WIN32, then I know that's all we're talking about, and that's clearer.

Looking at a HAVE_SETSID specifically, they seem to fall into three
different categories. First, there's a couple of places that look
roughly like this:

#ifdef HAVE_SETSID
if (setsid() < 0)
elog(FATAL, "setsid() failed: %m");
#endif

I don't think that changing this to WIN32 would confuse anybody.
Surely it's obvious that the WIN32 test is about setsid(), because
that's the only code in the block.

Then there are a couple of places that look like this:

/*
* If we have setsid(), signal the backend's whole process
* group
*/
#ifdef HAVE_SETSID
(void) kill(-pid, SIGTERM);
#else
(void) kill(pid, SIGTERM);
#endif

I think it would be clear enough to adopt a WIN32 test here if we also
adjusted the comment, e.g. "All non-Windows systems supported process
groups, and on such systems, we want to signal the entire group." But
I think there might be an even better option. On Windows, kill is
anyway getting defined to pgkill, and our version of pgkill is defined
to return EINVAL if you pass it a negative number. Why don't we just
have it change a negative value into a positive one? Then we can drop
all this conditional logic in the callers, who can just do (void)
kill(-pid, SIGWHATEVER) and we should be fine. On a quick look, it
appears to me that every call site that passes non-constant second
argument to kill() would be happy with this change to pgkill().

Finally, there's this sort of thing:

static void
signal_child(pid_t pid, int signal)
{
if (kill(pid, signal) < 0)
elog(DEBUG3, "kill(%ld,%d) failed: %m", (long) pid, signal);
#ifdef HAVE_SETSID
switch (signal)
{
case SIGINT:
case SIGTERM:
case SIGQUIT:
case SIGSTOP:
case SIGKILL:
if (kill(-pid, signal) < 0)
elog(DEBUG3, "kill(%ld,%d) failed: %m", (long) (-pid), signal);
break;
default:
break;
}
#endif
}

So the logic here says that we should send the signal to the child and
then if the signal is in a certain list and HAVE_SETSID is defined,
also send the same signal to the whole process group. Here HAVE_SETSID
is really just a proxy for whether the operating system has a notion
of process groups and, again, it seems OK to change this to a WIN32
test with proper comments. However, here again, I think there might be
a better option. The comment above this function notes that signalling
the process itself (as opposed to other process group members) is
assumed to not cause any problems, which implies that it's not a
desired behavior. So with the above redefinition of pgkill(), we could
rewrite this function like this:

static void
signal_child(pid_t pid, int signal)
{
switch (signal)
{
case SIGINT:
case SIGTERM:
case SIGQUIT:
case SIGSTOP:
case SIGKILL:
pid = -pid;
break;
default:
break;
}
if (kill(pid, signal) < 0)
elog(DEBUG3, "kill(%ld,%d) failed: %m", (long) pid, signal);
}

Overall, I don't think it's a great idea to keep all of these
HAVE_WHATEVER macros around if the configure tests are gone. It might
be necessary in the short term to make sure we don't regress the
readability of the code, but I think it would be better to come up
with other techniques for keeping the code readable rather than
relying on the names of these vestigial macros as documentation.

--
Robert Haas
EDB: http://www.enterprisedb.com

#31Tom Lane
tgl@sss.pgh.pa.us
In reply to: Robert Haas (#30)
Re: Cleaning up historical portability baggage

Robert Haas <robertmhaas@gmail.com> writes:

Overall, I don't think it's a great idea to keep all of these
HAVE_WHATEVER macros around if the configure tests are gone. It might
be necessary in the short term to make sure we don't regress the
readability of the code, but I think it would be better to come up
with other techniques for keeping the code readable rather than
relying on the names of these vestigial macros as documentation.

Hmm ... I agree with you that the end result could be nicer code,
but what's making it nicer is a pretty substantial amount of human
effort for each and every call site. Is anybody stepping forward
to put in that amount of work?

My proposal is to leave the call sites alone until someone feels
like doing that sort of detail work.

regards, tom lane

#32Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#31)
Re: Cleaning up historical portability baggage

On Fri, Aug 5, 2022 at 10:48 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Hmm ... I agree with you that the end result could be nicer code,
but what's making it nicer is a pretty substantial amount of human
effort for each and every call site. Is anybody stepping forward
to put in that amount of work?

My proposal is to leave the call sites alone until someone feels
like doing that sort of detail work.

My plan was to nerd-snipe Thomas Munro into doing it.[1]https://xkcd.com/356/

--
Robert Haas
EDB: http://www.enterprisedb.com

[1]: https://xkcd.com/356/

#33Thomas Munro
thomas.munro@gmail.com
In reply to: Thomas Munro (#29)
1 attachment(s)
Re: Cleaning up historical portability baggage

On Sat, Aug 6, 2022 at 12:01 AM Thomas Munro <thomas.munro@gmail.com> wrote:

On Thu, Aug 4, 2022 at 2:30 PM Andres Freund <andres@anarazel.de> wrote:

[strtoll cleanup patch]

LGTM. This is just C99 <stdlib.h> stuff, and my scraped config data
set agrees with your observation.

I found a couple of explicit references to these macros left in
src/interfaces/ecpg/ecpglib/data.c and src/timezone/private.h.
Removed in the attached, which I'll push a bit later if no objections.

Attachments:

v2-0001-Remove-fallbacks-for-strtoll-strtoull.patchtext/x-patch; charset=US-ASCII; name=v2-0001-Remove-fallbacks-for-strtoll-strtoull.patchDownload
From cff515054ab36add9971ef9044b8558c979bebad Mon Sep 17 00:00:00 2001
From: Thomas Munro <tmunro@postgresql.org>
Date: Sat, 6 Aug 2022 08:50:21 +1200
Subject: [PATCH v2] Remove fallbacks for strtoll, strtoull.

strtoll was backfilled with either __strtoll or strtoq on systems without
strtoll. The last such system on the buildfarm was an ancient HP-UX animal. We
don't support HP-UX anymore, so remove.

On other systems strtoll was present, but did not have a declaration. The last
known instance on the buildfarm was running an ancient OSX and shut down in
2019.

Author: Andres Freund <andres@anarazel.de>
Discussion: https://postgr.es/m/20220804013546.h65najrzig764jar@awork3.anarazel.de
---
 configure                          | 47 ------------------------------
 configure.ac                       |  5 ----
 src/include/c.h                    | 29 ------------------
 src/include/pg_config.h.in         | 26 -----------------
 src/interfaces/ecpg/ecpglib/data.c |  5 +---
 src/timezone/private.h             |  4 ---
 src/tools/msvc/Solution.pm         |  8 -----
 7 files changed, 1 insertion(+), 123 deletions(-)

diff --git a/configure b/configure
index da28a6bb8b..aa7f55b33a 100755
--- a/configure
+++ b/configure
@@ -17132,53 +17132,6 @@ $as_echo "#define HAVE_INT_OPTRESET 1" >>confdefs.h
 
 fi
 
-for ac_func in strtoll __strtoll strtoq
-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"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
- break
-fi
-done
-
-for ac_func in strtoull __strtoull strtouq
-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"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
- break
-fi
-done
-
-# strto[u]ll may exist but not be declared
-ac_fn_c_check_decl "$LINENO" "strtoll" "ac_cv_have_decl_strtoll" "$ac_includes_default"
-if test "x$ac_cv_have_decl_strtoll" = xyes; then :
-  ac_have_decl=1
-else
-  ac_have_decl=0
-fi
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL_STRTOLL $ac_have_decl
-_ACEOF
-ac_fn_c_check_decl "$LINENO" "strtoull" "ac_cv_have_decl_strtoull" "$ac_includes_default"
-if test "x$ac_cv_have_decl_strtoull" = xyes; then :
-  ac_have_decl=1
-else
-  ac_have_decl=0
-fi
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL_STRTOULL $ac_have_decl
-_ACEOF
-
-
 if test "$with_icu" = yes; then
   ac_save_CPPFLAGS=$CPPFLAGS
   CPPFLAGS="$ICU_CFLAGS $CPPFLAGS"
diff --git a/configure.ac b/configure.ac
index fada092cf3..6a9463b5ae 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1981,11 +1981,6 @@ if test x"$pgac_cv_var_int_optreset" = x"yes"; then
   AC_DEFINE(HAVE_INT_OPTRESET, 1, [Define to 1 if you have the global variable 'int optreset'.])
 fi
 
-AC_CHECK_FUNCS([strtoll __strtoll strtoq], [break])
-AC_CHECK_FUNCS([strtoull __strtoull strtouq], [break])
-# strto[u]ll may exist but not be declared
-AC_CHECK_DECLS([strtoll, strtoull])
-
 if test "$with_icu" = yes; then
   ac_save_CPPFLAGS=$CPPFLAGS
   CPPFLAGS="$ICU_CFLAGS $CPPFLAGS"
diff --git a/src/include/c.h b/src/include/c.h
index d35405f191..8c4baeb0ec 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -1294,35 +1294,6 @@ typedef union PGAlignedXLogBlock
 extern int	fdatasync(int fildes);
 #endif
 
-/* Older platforms may provide strto[u]ll functionality under other names */
-#if !defined(HAVE_STRTOLL) && defined(HAVE___STRTOLL)
-#define strtoll __strtoll
-#define HAVE_STRTOLL 1
-#endif
-
-#if !defined(HAVE_STRTOLL) && defined(HAVE_STRTOQ)
-#define strtoll strtoq
-#define HAVE_STRTOLL 1
-#endif
-
-#if !defined(HAVE_STRTOULL) && defined(HAVE___STRTOULL)
-#define strtoull __strtoull
-#define HAVE_STRTOULL 1
-#endif
-
-#if !defined(HAVE_STRTOULL) && defined(HAVE_STRTOUQ)
-#define strtoull strtouq
-#define HAVE_STRTOULL 1
-#endif
-
-#if defined(HAVE_STRTOLL) && !HAVE_DECL_STRTOLL
-extern long long strtoll(const char *str, char **endptr, int base);
-#endif
-
-#if defined(HAVE_STRTOULL) && !HAVE_DECL_STRTOULL
-extern unsigned long long strtoull(const char *str, char **endptr, int base);
-#endif
-
 /*
  * Thin wrappers that convert strings to exactly 64-bit integers, matching our
  * definition of int64.  (For the naming, compare that POSIX has
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 2a0d08d10f..b584788dc0 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -150,14 +150,6 @@
    don't. */
 #undef HAVE_DECL_STRNLEN
 
-/* Define to 1 if you have the declaration of `strtoll', and to 0 if you
-   don't. */
-#undef HAVE_DECL_STRTOLL
-
-/* Define to 1 if you have the declaration of `strtoull', and to 0 if you
-   don't. */
-#undef HAVE_DECL_STRTOULL
-
 /* Define to 1 if you have the <editline/history.h> header file. */
 #undef HAVE_EDITLINE_HISTORY_H
 
@@ -481,18 +473,6 @@
 /* Define to 1 if you have the `strtof' function. */
 #undef HAVE_STRTOF
 
-/* Define to 1 if you have the `strtoll' function. */
-#undef HAVE_STRTOLL
-
-/* Define to 1 if you have the `strtoq' function. */
-#undef HAVE_STRTOQ
-
-/* Define to 1 if you have the `strtoull' function. */
-#undef HAVE_STRTOULL
-
-/* Define to 1 if you have the `strtouq' function. */
-#undef HAVE_STRTOUQ
-
 /* Define to 1 if the system has the type `struct addrinfo'. */
 #undef HAVE_STRUCT_ADDRINFO
 
@@ -688,12 +668,6 @@
 /* Define to 1 if your compiler understands _Static_assert. */
 #undef HAVE__STATIC_ASSERT
 
-/* Define to 1 if you have the `__strtoll' function. */
-#undef HAVE___STRTOLL
-
-/* Define to 1 if you have the `__strtoull' function. */
-#undef HAVE___STRTOULL
-
 /* Define to the appropriate printf length modifier for 64-bit ints. */
 #undef INT64_MODIFIER
 
diff --git a/src/interfaces/ecpg/ecpglib/data.c b/src/interfaces/ecpg/ecpglib/data.c
index a1bba42bb8..bf9b313a11 100644
--- a/src/interfaces/ecpg/ecpglib/data.c
+++ b/src/interfaces/ecpg/ecpglib/data.c
@@ -438,7 +438,6 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					}
 					break;
 
-#ifdef HAVE_STRTOLL
 				case ECPGt_long_long:
 					*((long long int *) (var + offset * act_tuple)) = strtoll(pval, &scan_length, 10);
 					if (garbage_left(isarray, &scan_length, compat))
@@ -449,8 +448,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					pval = scan_length;
 
 					break;
-#endif							/* HAVE_STRTOLL */
-#ifdef HAVE_STRTOULL
+
 				case ECPGt_unsigned_long_long:
 					*((unsigned long long int *) (var + offset * act_tuple)) = strtoull(pval, &scan_length, 10);
 					if (garbage_left(isarray, &scan_length, compat))
@@ -461,7 +459,6 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 					pval = scan_length;
 
 					break;
-#endif							/* HAVE_STRTOULL */
 
 				case ECPGt_float:
 				case ECPGt_double:
diff --git a/src/timezone/private.h b/src/timezone/private.h
index 533e3d9f4e..39d40e43a9 100644
--- a/src/timezone/private.h
+++ b/src/timezone/private.h
@@ -46,11 +46,7 @@
 
 /* PG doesn't currently rely on <inttypes.h>, so work around strtoimax() */
 #undef strtoimax
-#ifdef HAVE_STRTOLL
 #define strtoimax strtoll
-#else
-#define strtoimax strtol
-#endif
 
 
 /*
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index d7ab6ab258..9fe53bb036 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -246,8 +246,6 @@ sub GenerateFiles
 		HAVE_DECL_STRLCAT                           => 0,
 		HAVE_DECL_STRLCPY                           => 0,
 		HAVE_DECL_STRNLEN                           => 1,
-		HAVE_DECL_STRTOLL                           => 1,
-		HAVE_DECL_STRTOULL                          => 1,
 		HAVE_EDITLINE_HISTORY_H                     => undef,
 		HAVE_EDITLINE_READLINE_H                    => undef,
 		HAVE_EXECINFO_H                             => undef,
@@ -354,10 +352,6 @@ sub GenerateFiles
 		HAVE_STRNLEN                             => 1,
 		HAVE_STRSIGNAL                           => undef,
 		HAVE_STRTOF                              => 1,
-		HAVE_STRTOLL                             => 1,
-		HAVE_STRTOQ                              => undef,
-		HAVE_STRTOULL                            => 1,
-		HAVE_STRTOUQ                             => undef,
 		HAVE_STRUCT_ADDRINFO                     => 1,
 		HAVE_STRUCT_CMSGCRED                     => undef,
 		HAVE_STRUCT_OPTION                       => undef,
@@ -423,8 +417,6 @@ sub GenerateFiles
 		HAVE__CPUID                              => 1,
 		HAVE__GET_CPUID                          => undef,
 		HAVE__STATIC_ASSERT                      => undef,
-		HAVE___STRTOLL                           => undef,
-		HAVE___STRTOULL                          => undef,
 		INT64_MODIFIER                           => qq{"ll"},
 		LOCALE_T_IN_XLOCALE                      => undef,
 		MAXIMUM_ALIGNOF                          => 8,
-- 
2.37.1

#34Andres Freund
andres@anarazel.de
In reply to: Thomas Munro (#33)
Re: Cleaning up historical portability baggage

Hi,

On 2022-08-06 09:02:32 +1200, Thomas Munro wrote:

On Sat, Aug 6, 2022 at 12:01 AM Thomas Munro <thomas.munro@gmail.com> wrote:

On Thu, Aug 4, 2022 at 2:30 PM Andres Freund <andres@anarazel.de> wrote:

[strtoll cleanup patch]

LGTM. This is just C99 <stdlib.h> stuff, and my scraped config data
set agrees with your observation.

I found a couple of explicit references to these macros left in
src/interfaces/ecpg/ecpglib/data.c and src/timezone/private.h.
Removed in the attached, which I'll push a bit later if no objections.

Hah, I was about to push it. Thanks for catching these. Happy for you to push
this soon!

Greetings,

Andres Freund

#35Andres Freund
andres@anarazel.de
In reply to: Andres Freund (#34)
1 attachment(s)
Re: Cleaning up historical portability baggage

Hi,

On 2022-08-05 14:08:23 -0700, Andres Freund wrote:

Hah, I was about to push it. Thanks for catching these. Happy for you to push
this soon!

Thanks. Next in my quest for reducing autoconf vs meson pg_config.h
differences is GETTIMEOFDAY stuff.

HAVE_GETTIMEOFDAY currently is only defined for mingw as the configure test is
gated to windows - that's somewhat weird imo. mingw has had it since at least
2007. The attached patch makes the gettimeofday() fallback specific to msvc.

I've renamed the file to win32gettimeofday now. I wonder if we should rename
files that are specific to msvc to indicate that? But that's for later.

1-arg gettimeofday() hasn't been around in a *long* while from what I can
see. So I've removed that configure test.

Greetings,

Andres Freund

Attachments:

0001-Simplify-gettimeofday-fallback-logic.patchtext/x-diff; charset=us-asciiDownload
From 0a2e2c82b2f099dcec16a43261c9077db4426dcf Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Fri, 5 Aug 2022 16:28:59 -0700
Subject: [PATCH] Simplify gettimeofday() fallback logic.

There's no known system needing 1 argument gettimeofday() support. The test
for it was added a long time ago (92c6bf9775b). Remove.

Until now we tested whether a gettimeofday() fallback is needed when
targetting windows. Which lead to the odd result that HAVE_GETTIMEOFDAY only
being defined when targetting MinGW. MinGW has had gettimeofday() since at
least 2007. As the fallback is specific to msvc, remove the configure code and
rename src/port/gettimeofday.c to src/port/win32gettimeofday.c.

While at it, also remove the definition of struct timezone, a forward
declaration of the struct is sufficient.
---
 src/include/pg_config.h.in                    | 10 ----
 src/include/port.h                            |  5 --
 src/include/port/win32_port.h                 | 15 ++----
 .../{gettimeofday.c => win32gettimeofday.c}   |  0
 config/c-library.m4                           | 24 ----------
 configure                                     | 47 -------------------
 configure.ac                                  |  2 -
 src/tools/msvc/Mkvcbuild.pm                   |  3 +-
 src/tools/msvc/Solution.pm                    |  2 -
 9 files changed, 7 insertions(+), 101 deletions(-)
 rename src/port/{gettimeofday.c => win32gettimeofday.c} (100%)

diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index b584788dc08..2d9a1cdc8ab 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -55,13 +55,6 @@
    (--enable-thread-safety) */
 #undef ENABLE_THREAD_SAFETY
 
-/* Define to 1 if gettimeofday() takes only 1 argument. */
-#undef GETTIMEOFDAY_1ARG
-
-#ifdef GETTIMEOFDAY_1ARG
-# define gettimeofday(a,b) gettimeofday(a)
-#endif
-
 /* Define to 1 if you have the `append_history' function. */
 #undef HAVE_APPEND_HISTORY
 
@@ -215,9 +208,6 @@
 /* Define to 1 if you have the `getpeerucred' function. */
 #undef HAVE_GETPEERUCRED
 
-/* Define to 1 if you have the `gettimeofday' function. */
-#undef HAVE_GETTIMEOFDAY
-
 /* Define to 1 if you have the <gssapi/gssapi.h> header file. */
 #undef HAVE_GSSAPI_GSSAPI_H
 
diff --git a/src/include/port.h b/src/include/port.h
index 14b640fe33e..56986b67cd1 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -328,11 +328,6 @@ extern FILE *pgwin32_popen(const char *command, const char *type);
 #define popen(a,b) pgwin32_popen(a,b)
 #define pclose(a) _pclose(a)
 
-/* New versions of MingW have gettimeofday, old mingw and msvc don't */
-#ifndef HAVE_GETTIMEOFDAY
-/* Last parameter not used */
-extern int	gettimeofday(struct timeval *tp, struct timezone *tzp);
-#endif
 #else							/* !WIN32 */
 
 /*
diff --git a/src/include/port/win32_port.h b/src/include/port/win32_port.h
index 0eaa97561a0..640f3d0ae62 100644
--- a/src/include/port/win32_port.h
+++ b/src/include/port/win32_port.h
@@ -179,16 +179,11 @@
 #define SIGUSR1				30
 #define SIGUSR2				31
 
-/*
- * New versions of MinGW have gettimeofday() and also declare
- * struct timezone to support it.
- */
-#ifndef HAVE_GETTIMEOFDAY
-struct timezone
-{
-	int			tz_minuteswest; /* Minutes west of GMT.  */
-	int			tz_dsttime;		/* Nonzero if DST is ever in effect.  */
-};
+/* MinW has gettimeofday(), but MSVC doesn't */
+#ifdef _MSC_VER
+struct timezone;
+/* Last parameter not used */
+extern int	gettimeofday(struct timeval *tp, struct timezone *tzp);
 #endif
 
 /* for setitimer in backend/port/win32/timer.c */
diff --git a/src/port/gettimeofday.c b/src/port/win32gettimeofday.c
similarity index 100%
rename from src/port/gettimeofday.c
rename to src/port/win32gettimeofday.c
diff --git a/config/c-library.m4 b/config/c-library.m4
index 163ad5742d8..35fdc63afee 100644
--- a/config/c-library.m4
+++ b/config/c-library.m4
@@ -37,30 +37,6 @@ AC_DEFUN([PGAC_STRUCT_TIMEZONE],
 ])# PGAC_STRUCT_TIMEZONE
 
 
-# PGAC_FUNC_GETTIMEOFDAY_1ARG
-# ---------------------------
-# Check if gettimeofday() has only one arguments. (Normal is two.)
-# If so, define GETTIMEOFDAY_1ARG.
-AC_DEFUN([PGAC_FUNC_GETTIMEOFDAY_1ARG],
-[AC_CACHE_CHECK(whether gettimeofday takes only one argument,
-pgac_cv_func_gettimeofday_1arg,
-[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <sys/time.h>],
-[struct timeval *tp;
-struct timezone *tzp;
-gettimeofday(tp,tzp);])],
-[pgac_cv_func_gettimeofday_1arg=no],
-[pgac_cv_func_gettimeofday_1arg=yes])])
-if test x"$pgac_cv_func_gettimeofday_1arg" = xyes ; then
-  AC_DEFINE(GETTIMEOFDAY_1ARG, 1,
-            [Define to 1 if gettimeofday() takes only 1 argument.])
-fi
-AH_VERBATIM(GETTIMEOFDAY_1ARG_,
-[@%:@ifdef GETTIMEOFDAY_1ARG
-@%:@ define gettimeofday(a,b) gettimeofday(a)
-@%:@endif])dnl
-])# PGAC_FUNC_GETTIMEOFDAY_1ARG
-
-
 # PGAC_FUNC_STRERROR_R_INT
 # ---------------------------
 # Check if strerror_r() returns int (POSIX) rather than char * (GNU libc).
diff --git a/configure b/configure
index aa7f55b33a6..0e73edb9ffa 100755
--- a/configure
+++ b/configure
@@ -15945,39 +15945,6 @@ if test x"$pgac_cv_var_int_timezone" = xyes ; then
 $as_echo "#define HAVE_INT_TIMEZONE 1" >>confdefs.h
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gettimeofday takes only one argument" >&5
-$as_echo_n "checking whether gettimeofday takes only one argument... " >&6; }
-if ${pgac_cv_func_gettimeofday_1arg+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <sys/time.h>
-int
-main ()
-{
-struct timeval *tp;
-struct timezone *tzp;
-gettimeofday(tp,tzp);
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  pgac_cv_func_gettimeofday_1arg=no
-else
-  pgac_cv_func_gettimeofday_1arg=yes
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_func_gettimeofday_1arg" >&5
-$as_echo "$pgac_cv_func_gettimeofday_1arg" >&6; }
-if test x"$pgac_cv_func_gettimeofday_1arg" = xyes ; then
-
-$as_echo "#define GETTIMEOFDAY_1ARG 1" >>confdefs.h
-
-fi
-
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wcstombs_l declaration" >&5
 $as_echo_n "checking for wcstombs_l declaration... " >&6; }
 if ${pgac_cv_func_wcstombs_l+:} false; then :
@@ -16909,20 +16876,6 @@ _ACEOF
 fi
 done
 
-  ac_fn_c_check_func "$LINENO" "gettimeofday" "ac_cv_func_gettimeofday"
-if test "x$ac_cv_func_gettimeofday" = xyes; then :
-  $as_echo "#define HAVE_GETTIMEOFDAY 1" >>confdefs.h
-
-else
-  case " $LIBOBJS " in
-  *" gettimeofday.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS gettimeofday.$ac_objext"
- ;;
-esac
-
-fi
-
-
   case " $LIBOBJS " in
   *" dirmod.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS dirmod.$ac_objext"
diff --git a/configure.ac b/configure.ac
index 6a9463b5ae2..efd3be91cd4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1779,7 +1779,6 @@ fi
 ##
 
 PGAC_VAR_INT_TIMEZONE
-PGAC_FUNC_GETTIMEOFDAY_1ARG
 PGAC_FUNC_WCSTOMBS_L
 
 # Some versions of libedit contain strlcpy(), setproctitle(), and other
@@ -1925,7 +1924,6 @@ fi
 # Win32 (really MinGW) support
 if test "$PORTNAME" = "win32"; then
   AC_CHECK_FUNCS(_configthreadlocale)
-  AC_REPLACE_FUNCS(gettimeofday)
   AC_LIBOBJ(dirmod)
   AC_LIBOBJ(getrusage)
   AC_LIBOBJ(kill)
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index 8d88e78f051..bacc9207581 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -101,7 +101,7 @@ sub mkvcbuild
 	our @pgportfiles = qw(
 	  chklocale.c explicit_bzero.c
 	  getpeereid.c getrusage.c inet_aton.c
-	  getaddrinfo.c gettimeofday.c inet_net_ntop.c kill.c open.c
+	  getaddrinfo.c inet_net_ntop.c kill.c open.c
 	  snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c
 	  dirent.c getopt.c getopt_long.c
 	  preadv.c pwritev.c pg_bitutils.c
@@ -111,6 +111,7 @@ sub mkvcbuild
 	  win32dlopen.c
 	  win32env.c win32error.c
 	  win32fdatasync.c
+	  win32gettimeofday.c
 	  win32link.c
 	  win32pread.c
 	  win32pwrite.c
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 9fe53bb036e..4916a86f5cf 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -220,7 +220,6 @@ sub GenerateFiles
 		ENABLE_GSS                 => $self->{options}->{gss} ? 1 : undef,
 		ENABLE_NLS                 => $self->{options}->{nls} ? 1 : undef,
 		ENABLE_THREAD_SAFETY       => 1,
-		GETTIMEOFDAY_1ARG          => undef,
 		HAVE_APPEND_HISTORY        => undef,
 		HAVE_ASN1_STRING_GET0_DATA => undef,
 		HAVE_ATOMICS               => 1,
@@ -267,7 +266,6 @@ sub GenerateFiles
 		HAVE_GETOPT_LONG                            => undef,
 		HAVE_GETPEEREID                             => undef,
 		HAVE_GETPEERUCRED                           => undef,
-		HAVE_GETTIMEOFDAY                           => undef,
 		HAVE_GSSAPI_GSSAPI_H                        => undef,
 		HAVE_GSSAPI_H                               => undef,
 		HAVE_HMAC_CTX_FREE                          => undef,
-- 
2.37.0.3.g30cc8d0f14

#36Andres Freund
andres@anarazel.de
In reply to: Thomas Munro (#20)
Re: Cleaning up historical portability baggage

Hi,

On 2022-08-03 14:25:01 +1200, Thomas Munro wrote:

It'd be good to find a new home for pg_get_user_name() and
pg_get_user_home_dir(), which really shouldn't be left in the now
bogusly named src/port/thread.c. Any suggestions?

Leaving the name aside, the win32 handling of these functions is
embarassing. Both are inside an #ifndef WIN32.

The only caller (in fe-auth.c) of pg_get_user_name() has:
#ifdef WIN32
if (GetUserName(username, &namesize))
name = username;
else if (errorMessage)
appendPQExpBuffer(errorMessage,
libpq_gettext("user name lookup failure: error code %lu\n"),
GetLastError());
#else
if (pg_get_user_name(user_id, pwdbuf, sizeof(pwdbuf)))
name = pwdbuf;
else if (errorMessage)
appendPQExpBuffer(errorMessage, "%s\n", pwdbuf);

the only caller of pg_get_user_home_dir() (path.c) has:

bool
get_home_path(char *ret_path)
{
#ifndef WIN32
/*
* We first consult $HOME. If that's unset, try to get the info from
* <pwd.h>.
*/
const char *home;

home = getenv("HOME");
if (home == NULL || home[0] == '\0')
return pg_get_user_home_dir(geteuid(), ret_path, MAXPGPATH);
strlcpy(ret_path, home, MAXPGPATH);
return true;
#else
char *tmppath;

/*
* Note: We use getenv() here because the more modern SHGetFolderPath()
* would force the backend to link with shell32.lib, which eats valuable
* desktop heap. XXX This function is used only in psql, which already
* brings in shell32 via libpq. Moving this function to its own file
* would keep it out of the backend, freeing it from this concern.
*/
tmppath = getenv("APPDATA");
if (!tmppath)
return false;
snprintf(ret_path, MAXPGPATH, "%s/postgresql", tmppath);
return true;
#endif
}

How does this make any sort of sense?

Greetings,

Andres Freund

#37Thomas Munro
thomas.munro@gmail.com
In reply to: Andres Freund (#35)
Re: Cleaning up historical portability baggage

On Sat, Aug 6, 2022 at 12:03 PM Andres Freund <andres@anarazel.de> wrote:

HAVE_GETTIMEOFDAY currently is only defined for mingw as the configure test is
gated to windows - that's somewhat weird imo. mingw has had it since at least
2007. The attached patch makes the gettimeofday() fallback specific to msvc.

+1

I've renamed the file to win32gettimeofday now. I wonder if we should rename
files that are specific to msvc to indicate that? But that's for later.

+1, I was thinking the same.

1-arg gettimeofday() hasn't been around in a *long* while from what I can
see. So I've removed that configure test.

+1

LGTM.

#38Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andres Freund (#35)
Re: Cleaning up historical portability baggage

Andres Freund <andres@anarazel.de> writes:

I've renamed the file to win32gettimeofday now. I wonder if we should rename
files that are specific to msvc to indicate that? But that's for later.

+1, but you didn't change the file's own comments containing its name.

regards, tom lane

#39Thomas Munro
thomas.munro@gmail.com
In reply to: Robert Haas (#32)
1 attachment(s)
Re: Cleaning up historical portability baggage

On Sat, Aug 6, 2022 at 2:54 AM Robert Haas <robertmhaas@gmail.com> wrote:

On Fri, Aug 5, 2022 at 10:48 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Hmm ... I agree with you that the end result could be nicer code,
but what's making it nicer is a pretty substantial amount of human
effort for each and every call site. Is anybody stepping forward
to put in that amount of work?

My proposal is to leave the call sites alone until someone feels
like doing that sort of detail work.

My plan was to nerd-snipe Thomas Munro into doing it.[1]

Alright, well here's a patch for the setsid() stuff following Robert's
plan, which I think is a pretty good plan.

Did I understand correctly that the places that do kill(-pid) followed
by kill(pid) really only need the kill(-pid)?

I checked that user processes should never have pid 0 (that's a
special system idle process) or 1 (because they're always even,
actually it looks like they're pointers in kernel space or something
like that), since those wouldn't play nice with the coding I used
here.

I note that Windows actually *does* have process groups (in one of the
CI threads, we learned that there were at least two concepts like
that). Some of our fake signals turn into messages to pipes, and
others turn into process termination, and in theory we could probably
also take advantage of Windows' support for its native "control C" and
"control break" signals here. It's possible that someone could do
something to make all but the pipe ones propagate to real Windows
process groups. That might be good for things like nuking archiver
subprocesses and the like when taking out the backend, or something
like that, but I'm not planning to look into that myself.

Attachments:

0001-Simplify-conditional-code-for-process-groups.patchtext/x-patch; charset=US-ASCII; name=0001-Simplify-conditional-code-for-process-groups.patchDownload
From f3c224082736605f373b4c34e661b6a8d26846c0 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sun, 7 Aug 2022 09:37:34 +1200
Subject: [PATCH] Simplify conditional code for process groups.

Teach our replacement kill() function for Windows to ignore process
groups and send directly to a single pid instead.  Now we can drop a
bunch of conditional code at call sites, and the vestigial HAVE_SETSID
macro.

While here, rename src/port/kill.c to win32kill.c, following our
convention for Windows-only fallback code.

Suggested-by: Robert Haas <robertmhaas@gmail.com>
Discussion: https://postgr.es/m/CA%2BTgmob_5AUNCzyFGJX6quYSnQnKCHW6DGGJa1noofJqSu%2Bweg%40mail.gmail.com
---
 configure                             | 12 ++++++------
 configure.ac                          |  2 +-
 src/backend/postmaster/postmaster.c   |  9 +++------
 src/backend/storage/ipc/procarray.c   |  9 +--------
 src/backend/storage/ipc/signalfuncs.c |  6 +-----
 src/backend/utils/init/miscinit.c     |  2 +-
 src/backend/utils/init/postinit.c     |  6 ------
 src/bin/pg_ctl/pg_ctl.c               |  2 +-
 src/include/port.h                    |  1 -
 src/port/{kill.c => win32kill.c}      | 16 +++++++++-------
 src/tools/msvc/Mkvcbuild.pm           |  3 ++-
 11 files changed, 25 insertions(+), 43 deletions(-)
 rename src/port/{kill.c => win32kill.c} (88%)

diff --git a/configure b/configure
index 0e73edb9ff..6ea8051c9c 100755
--- a/configure
+++ b/configure
@@ -16888,12 +16888,6 @@ esac
  ;;
 esac
 
-  case " $LIBOBJS " in
-  *" kill.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS kill.$ac_objext"
- ;;
-esac
-
   case " $LIBOBJS " in
   *" open.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS open.$ac_objext"
@@ -16930,6 +16924,12 @@ esac
  ;;
 esac
 
+  case " $LIBOBJS " in
+  *" win32kill.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS win32kill.$ac_objext"
+ ;;
+esac
+
   case " $LIBOBJS " in
   *" win32link.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS win32link.$ac_objext"
diff --git a/configure.ac b/configure.ac
index efd3be91cd..127e4ce925 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1926,13 +1926,13 @@ if test "$PORTNAME" = "win32"; then
   AC_CHECK_FUNCS(_configthreadlocale)
   AC_LIBOBJ(dirmod)
   AC_LIBOBJ(getrusage)
-  AC_LIBOBJ(kill)
   AC_LIBOBJ(open)
   AC_LIBOBJ(system)
   AC_LIBOBJ(win32dlopen)
   AC_LIBOBJ(win32env)
   AC_LIBOBJ(win32error)
   AC_LIBOBJ(win32fdatasync)
+  AC_LIBOBJ(win32kill)
   AC_LIBOBJ(win32link)
   AC_LIBOBJ(win32ntdll)
   AC_LIBOBJ(win32pread)
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 81cb585891..c50e07bf2b 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -4041,9 +4041,6 @@ PostmasterStateMachine(void)
 static void
 signal_child(pid_t pid, int signal)
 {
-	if (kill(pid, signal) < 0)
-		elog(DEBUG3, "kill(%ld,%d) failed: %m", (long) pid, signal);
-#ifdef HAVE_SETSID
 	switch (signal)
 	{
 		case SIGINT:
@@ -4051,13 +4048,13 @@ signal_child(pid_t pid, int signal)
 		case SIGQUIT:
 		case SIGSTOP:
 		case SIGKILL:
-			if (kill(-pid, signal) < 0)
-				elog(DEBUG3, "kill(%ld,%d) failed: %m", (long) (-pid), signal);
+			pid = -pid;
 			break;
 		default:
 			break;
 	}
-#endif
+	if (kill(pid, signal) < 0)
+		elog(DEBUG3, "kill(%ld,%d) failed: %m", (long) pid, signal);
 }
 
 /*
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index 0555b02a8d..1ec4359c92 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -3865,15 +3865,8 @@ TerminateOtherDBBackends(Oid databaseId)
 
 			if (proc != NULL)
 			{
-				/*
-				 * If we have setsid(), signal the backend's whole process
-				 * group
-				 */
-#ifdef HAVE_SETSID
+				/* Signal the backend's whole process group */
 				(void) kill(-pid, SIGTERM);
-#else
-				(void) kill(pid, SIGTERM);
-#endif
 			}
 		}
 	}
diff --git a/src/backend/storage/ipc/signalfuncs.c b/src/backend/storage/ipc/signalfuncs.c
index 6e310b14eb..13e691ec92 100644
--- a/src/backend/storage/ipc/signalfuncs.c
+++ b/src/backend/storage/ipc/signalfuncs.c
@@ -92,12 +92,8 @@ pg_signal_backend(int pid, int sig)
 	 * too unlikely to worry about.
 	 */
 
-	/* If we have setsid(), signal the backend's whole process group */
-#ifdef HAVE_SETSID
+	/* Signal the backend's whole process group */
 	if (kill(-pid, sig))
-#else
-	if (kill(pid, sig))
-#endif
 	{
 		/* Again, just a warning to allow loops */
 		ereport(WARNING,
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index bd973ba613..c65b596d1b 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -145,7 +145,7 @@ InitPostmasterChild(void)
 	 * children, but for consistency we make all postmaster child processes do
 	 * this.
 	 */
-#ifdef HAVE_SETSID
+#ifndef WIN32
 	if (setsid() < 0)
 		elog(FATAL, "setsid() failed: %m");
 #endif
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 0d557a8684..da248b3665 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -1279,11 +1279,8 @@ StatementTimeoutHandler(void)
 	if (ClientAuthInProgress)
 		sig = SIGTERM;
 
-#ifdef HAVE_SETSID
 	/* try to signal whole process group */
 	kill(-MyProcPid, sig);
-#endif
-	kill(MyProcPid, sig);
 }
 
 /*
@@ -1292,11 +1289,8 @@ StatementTimeoutHandler(void)
 static void
 LockTimeoutHandler(void)
 {
-#ifdef HAVE_SETSID
 	/* try to signal whole process group */
 	kill(-MyProcPid, SIGINT);
-#endif
-	kill(MyProcPid, SIGINT);
 }
 
 static void
diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
index 2762e8590d..17c1c16b4f 100644
--- a/src/bin/pg_ctl/pg_ctl.c
+++ b/src/bin/pg_ctl/pg_ctl.c
@@ -478,7 +478,7 @@ start_postmaster(void)
 	 * group and make it a group leader, so that it doesn't get signaled along
 	 * with the current group that launched it.
 	 */
-#ifdef HAVE_SETSID
+#ifndef WIN32
 	if (setsid() < 0)
 	{
 		write_stderr(_("%s: could not start server due to setsid() failure: %s\n"),
diff --git a/src/include/port.h b/src/include/port.h
index ad76384fb1..aa9bcb7966 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -502,7 +502,6 @@ extern bool wait_result_is_any_signal(int exit_status, bool include_command_not_
 #define HAVE_POLL 1
 #define HAVE_POLL_H 1
 #define HAVE_READLINK 1
-#define HAVE_SETSID 1
 #define HAVE_SHM_OPEN 1
 #define HAVE_SYMLINK 1
 #endif
diff --git a/src/port/kill.c b/src/port/win32kill.c
similarity index 88%
rename from src/port/kill.c
rename to src/port/win32kill.c
index ff0862683c..794468405a 100644
--- a/src/port/kill.c
+++ b/src/port/win32kill.c
@@ -1,6 +1,6 @@
 /*-------------------------------------------------------------------------
  *
- * kill.c
+ * win32kill.c
  *	  kill()
  *
  * Copyright (c) 1996-2022, PostgreSQL Global Development Group
@@ -9,14 +9,13 @@
  *	signals that the backend can recognize.
  *
  * IDENTIFICATION
- *	  src/port/kill.c
+ *	  src/port/win32kill.c
  *
  *-------------------------------------------------------------------------
  */
 
 #include "c.h"
 
-#ifdef WIN32
 /* signal sending */
 int
 pgkill(int pid, int sig)
@@ -32,12 +31,17 @@ pgkill(int pid, int sig)
 		errno = EINVAL;
 		return -1;
 	}
-	if (pid <= 0)
+	if (pid == 0 || pid == -1)
 	{
-		/* No support for process groups */
+		/* No support for special process group values */
 		errno = EINVAL;
 		return -1;
 	}
+	else if (pid < -1)
+	{
+		/* No support for process groups: just send to one process instead */
+		pid = -pid;
+	}
 
 	/* special case for SIGKILL: just ask the system to terminate the target */
 	if (sig == SIGKILL)
@@ -93,5 +97,3 @@ pgkill(int pid, int sig)
 			return -1;
 	}
 }
-
-#endif
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index bacc920758..016456ca37 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -101,7 +101,7 @@ sub mkvcbuild
 	our @pgportfiles = qw(
 	  chklocale.c explicit_bzero.c
 	  getpeereid.c getrusage.c inet_aton.c
-	  getaddrinfo.c inet_net_ntop.c kill.c open.c
+	  getaddrinfo.c inet_net_ntop.c open.c
 	  snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c
 	  dirent.c getopt.c getopt_long.c
 	  preadv.c pwritev.c pg_bitutils.c
@@ -112,6 +112,7 @@ sub mkvcbuild
 	  win32env.c win32error.c
 	  win32fdatasync.c
 	  win32gettimeofday.c
+	  win32kill.c
 	  win32link.c
 	  win32pread.c
 	  win32pwrite.c
-- 
2.37.1

#40Tom Lane
tgl@sss.pgh.pa.us
In reply to: Thomas Munro (#39)
Re: Cleaning up historical portability baggage

Thomas Munro <thomas.munro@gmail.com> writes:

Did I understand correctly that the places that do kill(-pid) followed
by kill(pid) really only need the kill(-pid)?

Uh ... did you read the comment right above signal_child?

* There is a race condition for recently-forked children: they might not
* have executed setsid() yet. So we signal the child directly as well as
* the group. We assume such a child will handle the signal before trying
* to spawn any grandchild processes. We also assume that signaling the
* child twice will not cause any problems.

It might be that this is wrong and signaling -pid will work even if
the child hasn't yet done setsid(), but I doubt it: the kill(2) man
page is pretty clear that it'll fail if "the process group doesn't
exist".

Perhaps we could finesse that by signaling -pid first, and then
signaling pid if that fails, but offhand it seems like that has
the described race condition w.r.t. grandchild processes.

regards, tom lane

#41Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andres Freund (#35)
Re: Cleaning up historical portability baggage

Andres Freund <andres@anarazel.de> writes:

Thanks. Next in my quest for reducing autoconf vs meson pg_config.h
differences is GETTIMEOFDAY stuff.

I just noticed that this could be simplified:

#ifdef _MSC_VER
struct timezone;
/* Last parameter not used */
extern int gettimeofday(struct timeval *tp, struct timezone *tzp);
#endif

because what POSIX actually says is

int gettimeofday(struct timeval *restrict tp, void *restrict tzp);

and

If tzp is not a null pointer, the behavior is unspecified.

Indeed, we never call it with anything but a null tzp value,
nor does our Windows fallback implementation do anything with tzp.

So ISTM we should drop the bogus "struct timezone;" and declare
this parameter as "void *tzp".

regards, tom lane

#42Thomas Munro
thomas.munro@gmail.com
In reply to: Tom Lane (#41)
Re: Cleaning up historical portability baggage

On Sun, Aug 7, 2022 at 11:08 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Andres Freund <andres@anarazel.de> writes:

Thanks. Next in my quest for reducing autoconf vs meson pg_config.h
differences is GETTIMEOFDAY stuff.

I just noticed that this could be simplified:

#ifdef _MSC_VER
struct timezone;
/* Last parameter not used */
extern int gettimeofday(struct timeval *tp, struct timezone *tzp);
#endif

because what POSIX actually says is

int gettimeofday(struct timeval *restrict tp, void *restrict tzp);

and

If tzp is not a null pointer, the behavior is unspecified.

Indeed, we never call it with anything but a null tzp value,
nor does our Windows fallback implementation do anything with tzp.

So ISTM we should drop the bogus "struct timezone;" and declare
this parameter as "void *tzp".

I also wonder if half the stuff in win32gettimeofday.c can be deleted.
From some light googling, it looks like
GetSystemTimePreciseAsFileTime() can just be called directly on
Windows 8+ (and we now require 10+), and that kernel32.dll malarky was
for older systems?

#43Tom Lane
tgl@sss.pgh.pa.us
In reply to: Thomas Munro (#42)
Re: Cleaning up historical portability baggage

Thomas Munro <thomas.munro@gmail.com> writes:

I also wonder if half the stuff in win32gettimeofday.c can be deleted.
From some light googling, it looks like
GetSystemTimePreciseAsFileTime() can just be called directly on
Windows 8+ (and we now require 10+), and that kernel32.dll malarky was
for older systems?

Yeah, Microsoft's man page for it just says to include sysinfoapi.h
(which we aren't) and then it should work on supported versions.

regards, tom lane

#44Thomas Munro
thomas.munro@gmail.com
In reply to: Tom Lane (#40)
1 attachment(s)
Re: Cleaning up historical portability baggage

On Sun, Aug 7, 2022 at 10:42 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Thomas Munro <thomas.munro@gmail.com> writes:

Did I understand correctly that the places that do kill(-pid) followed
by kill(pid) really only need the kill(-pid)?

Uh ... did you read the comment right above signal_child?

* There is a race condition for recently-forked children: they might not
* have executed setsid() yet. So we signal the child directly as well as
* the group. We assume such a child will handle the signal before trying
* to spawn any grandchild processes. We also assume that signaling the
* child twice will not cause any problems.

Oof. Fixed.

Attachments:

v2-0001-Simplify-conditional-code-for-process-groups.patchtext/x-patch; charset=US-ASCII; name=v2-0001-Simplify-conditional-code-for-process-groups.patchDownload
From 7ec1aa38f30e32734eb77a6dc6448d332179dfa3 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sun, 7 Aug 2022 09:37:34 +1200
Subject: [PATCH v2] Simplify conditional code for process groups.

Teach our replacement kill() function for Windows to ignore process
groups and send directly to a single pid instead.  Now we can drop a
bunch of conditional code at call sites, and the vestigial HAVE_SETSID
macro.

While here, rename src/port/kill.c to win32kill.c, following our
convention for Windows-only fallback code.

Suggested-by: Robert Haas <robertmhaas@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CA%2BTgmob_5AUNCzyFGJX6quYSnQnKCHW6DGGJa1noofJqSu%2Bweg%40mail.gmail.com
---
 configure                             | 12 ++++++------
 configure.ac                          |  2 +-
 src/backend/postmaster/postmaster.c   |  2 --
 src/backend/storage/ipc/procarray.c   |  9 +--------
 src/backend/storage/ipc/signalfuncs.c |  6 +-----
 src/backend/utils/init/miscinit.c     |  2 +-
 src/backend/utils/init/postinit.c     |  4 ----
 src/bin/pg_ctl/pg_ctl.c               |  2 +-
 src/include/port.h                    |  1 -
 src/include/port/win32_port.h         |  2 +-
 src/port/{kill.c => win32kill.c}      | 16 +++++++++-------
 src/tools/msvc/Mkvcbuild.pm           |  3 ++-
 12 files changed, 23 insertions(+), 38 deletions(-)
 rename src/port/{kill.c => win32kill.c} (88%)

diff --git a/configure b/configure
index 0e73edb9ff..6ea8051c9c 100755
--- a/configure
+++ b/configure
@@ -16888,12 +16888,6 @@ esac
  ;;
 esac
 
-  case " $LIBOBJS " in
-  *" kill.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS kill.$ac_objext"
- ;;
-esac
-
   case " $LIBOBJS " in
   *" open.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS open.$ac_objext"
@@ -16930,6 +16924,12 @@ esac
  ;;
 esac
 
+  case " $LIBOBJS " in
+  *" win32kill.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS win32kill.$ac_objext"
+ ;;
+esac
+
   case " $LIBOBJS " in
   *" win32link.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS win32link.$ac_objext"
diff --git a/configure.ac b/configure.ac
index efd3be91cd..127e4ce925 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1926,13 +1926,13 @@ if test "$PORTNAME" = "win32"; then
   AC_CHECK_FUNCS(_configthreadlocale)
   AC_LIBOBJ(dirmod)
   AC_LIBOBJ(getrusage)
-  AC_LIBOBJ(kill)
   AC_LIBOBJ(open)
   AC_LIBOBJ(system)
   AC_LIBOBJ(win32dlopen)
   AC_LIBOBJ(win32env)
   AC_LIBOBJ(win32error)
   AC_LIBOBJ(win32fdatasync)
+  AC_LIBOBJ(win32kill)
   AC_LIBOBJ(win32link)
   AC_LIBOBJ(win32ntdll)
   AC_LIBOBJ(win32pread)
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 81cb585891..f8bd6285b8 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -4043,7 +4043,6 @@ signal_child(pid_t pid, int signal)
 {
 	if (kill(pid, signal) < 0)
 		elog(DEBUG3, "kill(%ld,%d) failed: %m", (long) pid, signal);
-#ifdef HAVE_SETSID
 	switch (signal)
 	{
 		case SIGINT:
@@ -4057,7 +4056,6 @@ signal_child(pid_t pid, int signal)
 		default:
 			break;
 	}
-#endif
 }
 
 /*
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index 0555b02a8d..950ecc764b 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -3865,15 +3865,8 @@ TerminateOtherDBBackends(Oid databaseId)
 
 			if (proc != NULL)
 			{
-				/*
-				 * If we have setsid(), signal the backend's whole process
-				 * group
-				 */
-#ifdef HAVE_SETSID
+				/* Signal the backend's whole process group. */
 				(void) kill(-pid, SIGTERM);
-#else
-				(void) kill(pid, SIGTERM);
-#endif
 			}
 		}
 	}
diff --git a/src/backend/storage/ipc/signalfuncs.c b/src/backend/storage/ipc/signalfuncs.c
index 6e310b14eb..13e691ec92 100644
--- a/src/backend/storage/ipc/signalfuncs.c
+++ b/src/backend/storage/ipc/signalfuncs.c
@@ -92,12 +92,8 @@ pg_signal_backend(int pid, int sig)
 	 * too unlikely to worry about.
 	 */
 
-	/* If we have setsid(), signal the backend's whole process group */
-#ifdef HAVE_SETSID
+	/* Signal the backend's whole process group */
 	if (kill(-pid, sig))
-#else
-	if (kill(pid, sig))
-#endif
 	{
 		/* Again, just a warning to allow loops */
 		ereport(WARNING,
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index bd973ba613..c65b596d1b 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -145,7 +145,7 @@ InitPostmasterChild(void)
 	 * children, but for consistency we make all postmaster child processes do
 	 * this.
 	 */
-#ifdef HAVE_SETSID
+#ifndef WIN32
 	if (setsid() < 0)
 		elog(FATAL, "setsid() failed: %m");
 #endif
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 0d557a8684..5a8d5f9c38 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -1279,10 +1279,8 @@ StatementTimeoutHandler(void)
 	if (ClientAuthInProgress)
 		sig = SIGTERM;
 
-#ifdef HAVE_SETSID
 	/* try to signal whole process group */
 	kill(-MyProcPid, sig);
-#endif
 	kill(MyProcPid, sig);
 }
 
@@ -1292,10 +1290,8 @@ StatementTimeoutHandler(void)
 static void
 LockTimeoutHandler(void)
 {
-#ifdef HAVE_SETSID
 	/* try to signal whole process group */
 	kill(-MyProcPid, SIGINT);
-#endif
 	kill(MyProcPid, SIGINT);
 }
 
diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
index 2762e8590d..17c1c16b4f 100644
--- a/src/bin/pg_ctl/pg_ctl.c
+++ b/src/bin/pg_ctl/pg_ctl.c
@@ -478,7 +478,7 @@ start_postmaster(void)
 	 * group and make it a group leader, so that it doesn't get signaled along
 	 * with the current group that launched it.
 	 */
-#ifdef HAVE_SETSID
+#ifndef WIN32
 	if (setsid() < 0)
 	{
 		write_stderr(_("%s: could not start server due to setsid() failure: %s\n"),
diff --git a/src/include/port.h b/src/include/port.h
index ad76384fb1..aa9bcb7966 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -502,7 +502,6 @@ extern bool wait_result_is_any_signal(int exit_status, bool include_command_not_
 #define HAVE_POLL 1
 #define HAVE_POLL_H 1
 #define HAVE_READLINK 1
-#define HAVE_SETSID 1
 #define HAVE_SHM_OPEN 1
 #define HAVE_SYMLINK 1
 #endif
diff --git a/src/include/port/win32_port.h b/src/include/port/win32_port.h
index 79451a00f9..ea94bb3dac 100644
--- a/src/include/port/win32_port.h
+++ b/src/include/port/win32_port.h
@@ -470,7 +470,7 @@ extern HANDLE pgwin32_create_signal_listener(pid_t pid);
 extern void pgwin32_dispatch_queued_signals(void);
 extern void pg_queue_signal(int signum);
 
-/* In src/port/kill.c */
+/* In src/port/win32kill.c */
 #define kill(pid,sig)	pgkill(pid,sig)
 extern int	pgkill(int pid, int sig);
 
diff --git a/src/port/kill.c b/src/port/win32kill.c
similarity index 88%
rename from src/port/kill.c
rename to src/port/win32kill.c
index ff0862683c..794468405a 100644
--- a/src/port/kill.c
+++ b/src/port/win32kill.c
@@ -1,6 +1,6 @@
 /*-------------------------------------------------------------------------
  *
- * kill.c
+ * win32kill.c
  *	  kill()
  *
  * Copyright (c) 1996-2022, PostgreSQL Global Development Group
@@ -9,14 +9,13 @@
  *	signals that the backend can recognize.
  *
  * IDENTIFICATION
- *	  src/port/kill.c
+ *	  src/port/win32kill.c
  *
  *-------------------------------------------------------------------------
  */
 
 #include "c.h"
 
-#ifdef WIN32
 /* signal sending */
 int
 pgkill(int pid, int sig)
@@ -32,12 +31,17 @@ pgkill(int pid, int sig)
 		errno = EINVAL;
 		return -1;
 	}
-	if (pid <= 0)
+	if (pid == 0 || pid == -1)
 	{
-		/* No support for process groups */
+		/* No support for special process group values */
 		errno = EINVAL;
 		return -1;
 	}
+	else if (pid < -1)
+	{
+		/* No support for process groups: just send to one process instead */
+		pid = -pid;
+	}
 
 	/* special case for SIGKILL: just ask the system to terminate the target */
 	if (sig == SIGKILL)
@@ -93,5 +97,3 @@ pgkill(int pid, int sig)
 			return -1;
 	}
 }
-
-#endif
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index bacc920758..016456ca37 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -101,7 +101,7 @@ sub mkvcbuild
 	our @pgportfiles = qw(
 	  chklocale.c explicit_bzero.c
 	  getpeereid.c getrusage.c inet_aton.c
-	  getaddrinfo.c inet_net_ntop.c kill.c open.c
+	  getaddrinfo.c inet_net_ntop.c open.c
 	  snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c
 	  dirent.c getopt.c getopt_long.c
 	  preadv.c pwritev.c pg_bitutils.c
@@ -112,6 +112,7 @@ sub mkvcbuild
 	  win32env.c win32error.c
 	  win32fdatasync.c
 	  win32gettimeofday.c
+	  win32kill.c
 	  win32link.c
 	  win32pread.c
 	  win32pwrite.c
-- 
2.37.1

#45Thomas Munro
thomas.munro@gmail.com
In reply to: Andres Freund (#34)
1 attachment(s)
Re: Cleaning up historical portability baggage

On Sat, Aug 6, 2022 at 9:08 AM Andres Freund <andres@anarazel.de> wrote:

[stuff about strtoll, strtoull]

So what about strtof? That's gotta be dead code too. I gather we
still need commit 72880ac1's HAVE_BUGGY_STRTOF. From a cursory glance
at MinGW's implementation, it still has the complained-about
behaviour, if I've understood the complaint, and if I'm looking at the
right C runtime[1]https://github.com/mirror/mingw-w64/blob/master/mingw-w64-crt/stdio/strtof.c. But then our code says:

* Test results on Mingw suggest that it has the same problem, though looking
* at the code I can't figure out why.

... so which code was that referring to then? I'm not up to speed on
how many C runtime libraries there are and how they are selected on
MSYS (I mean, the closest I've ever got to this system is flinging
patches at it on CI using Melih's patch, which, incidentally, I just
tested the attached with and it passed[2]https://github.com/macdice/postgres/runs/7708082971).

[1]: https://github.com/mirror/mingw-w64/blob/master/mingw-w64-crt/stdio/strtof.c
[2]: https://github.com/macdice/postgres/runs/7708082971

Attachments:

0001-Simplify-replacement-code-for-strtof.patchtext/x-patch; charset=US-ASCII; name=0001-Simplify-replacement-code-for-strtof.patchDownload
From 6bab84477090951ad0553c16069406718770d6a4 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sun, 7 Aug 2022 10:51:39 +1200
Subject: [PATCH] Simplify replacement code for strtof.

strtof() is in C99 and all targeted systems have it.  We can remove the
configure probe and some dead code, but we still need replacement code
for a couple of systems that have known buggy implementations selected
via platform template.

diff --git a/configure b/configure
index 0e73edb9ff..5ee7c2c1a2 100755
--- a/configure
+++ b/configure
@@ -16734,19 +16734,6 @@ esac
 
 fi
 
-ac_fn_c_check_func "$LINENO" "strtof" "ac_cv_func_strtof"
-if test "x$ac_cv_func_strtof" = xyes; then :
-  $as_echo "#define HAVE_STRTOF 1" >>confdefs.h
-
-else
-  case " $LIBOBJS " in
-  *" strtof.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS strtof.$ac_objext"
- ;;
-esac
-
-fi
-
 
 
 if test "$enable_thread_safety" = yes; then
@@ -16770,8 +16757,7 @@ if test "$PORTNAME" = "win32" -o "$PORTNAME" = "cygwin"; then
 	# Cygwin and (apparently, based on test results) Mingw both
 	# have a broken strtof(), so substitute its implementation.
 	# That's not a perfect fix, since it doesn't avoid double-rounding,
-	# but we have no better options. To get that, though, we have to
-	# force the file to be compiled despite HAVE_STRTOF.
+	# but we have no better options.
 	case " $LIBOBJS " in
   *" strtof.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS strtof.$ac_objext"
diff --git a/configure.ac b/configure.ac
index efd3be91cd..be52e17ea7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1874,7 +1874,6 @@ AC_REPLACE_FUNCS(m4_normalize([
 	strlcat
 	strlcpy
 	strnlen
-	strtof
 ]))
 
 if test "$enable_thread_safety" = yes; then
@@ -1885,8 +1884,7 @@ if test "$PORTNAME" = "win32" -o "$PORTNAME" = "cygwin"; then
 	# Cygwin and (apparently, based on test results) Mingw both
 	# have a broken strtof(), so substitute its implementation.
 	# That's not a perfect fix, since it doesn't avoid double-rounding,
-	# but we have no better options. To get that, though, we have to
-	# force the file to be compiled despite HAVE_STRTOF.
+	# but we have no better options.
 	AC_LIBOBJ([strtof])
 	AC_MSG_NOTICE([On $host_os we will use our strtof wrapper.])
 fi
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 2d9a1cdc8a..c243a906c9 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -460,9 +460,6 @@
 /* Define to 1 if you have the `strsignal' function. */
 #undef HAVE_STRSIGNAL
 
-/* Define to 1 if you have the `strtof' function. */
-#undef HAVE_STRTOF
-
 /* Define to 1 if the system has the type `struct addrinfo'. */
 #undef HAVE_STRUCT_ADDRINFO
 
diff --git a/src/include/port.h b/src/include/port.h
index ad76384fb1..cec41eae71 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -387,10 +387,6 @@ extern int	getpeereid(int sock, uid_t *uid, gid_t *gid);
 extern void explicit_bzero(void *buf, size_t len);
 #endif
 
-#ifndef HAVE_STRTOF
-extern float strtof(const char *nptr, char **endptr);
-#endif
-
 #ifdef HAVE_BUGGY_STRTOF
 extern float pg_strtof(const char *nptr, char **endptr);
 #define strtof(a,b) (pg_strtof((a),(b)))
diff --git a/src/port/strtof.c b/src/port/strtof.c
index 314fcc9851..21b3f8f712 100644
--- a/src/port/strtof.c
+++ b/src/port/strtof.c
@@ -16,43 +16,7 @@
 #include <float.h>
 #include <math.h>
 
-#ifndef HAVE_STRTOF
-/*
- * strtof() is part of C99; this version is only for the benefit of obsolete
- * platforms. As such, it is known to return incorrect values for edge cases,
- * which have to be allowed for in variant files for regression test results
- * for any such platform.
- */
-
-float
-strtof(const char *nptr, char **endptr)
-{
-	int			caller_errno = errno;
-	double		dresult;
-	float		fresult;
-
-	errno = 0;
-	dresult = strtod(nptr, endptr);
-	fresult = (float) dresult;
 
-	if (errno == 0)
-	{
-		/*
-		 * Value might be in-range for double but not float.
-		 */
-		if (dresult != 0 && fresult == 0)
-			caller_errno = ERANGE;	/* underflow */
-		if (!isinf(dresult) && isinf(fresult))
-			caller_errno = ERANGE;	/* overflow */
-	}
-	else
-		caller_errno = errno;
-
-	errno = caller_errno;
-	return fresult;
-}
-
-#elif HAVE_BUGGY_STRTOF
 /*
  * Cygwin has a strtof() which is literally just (float)strtod(), which means
  * we can't avoid the double-rounding problem; but using this wrapper does get
@@ -119,5 +83,3 @@ pg_strtof(const char *nptr, char **endptr)
 		}
 	}
 }
-
-#endif
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 4916a86f5c..caacb965bb 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -349,7 +349,6 @@ sub GenerateFiles
 		HAVE_STRLCPY                             => undef,
 		HAVE_STRNLEN                             => 1,
 		HAVE_STRSIGNAL                           => undef,
-		HAVE_STRTOF                              => 1,
 		HAVE_STRUCT_ADDRINFO                     => 1,
 		HAVE_STRUCT_CMSGCRED                     => undef,
 		HAVE_STRUCT_OPTION                       => undef,
-- 
2.37.1

#46Tom Lane
tgl@sss.pgh.pa.us
In reply to: Thomas Munro (#44)
Re: Cleaning up historical portability baggage

Thomas Munro <thomas.munro@gmail.com> writes:

On Sun, Aug 7, 2022 at 10:42 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

* There is a race condition for recently-forked children: they might not
* have executed setsid() yet. So we signal the child directly as well as
* the group. We assume such a child will handle the signal before trying
* to spawn any grandchild processes. We also assume that signaling the
* child twice will not cause any problems.

Oof. Fixed.

Hmm ... it seems like these other callers have the same race condition.
StatementTimeoutHandler and LockTimeoutHandler account for that
correctly by issuing two kill()s, so how is it OK for pg_signal_backend
and TerminateOtherDBBackends not to?

It would likely be a good idea for all these places to mention that
they're doing that to avoid a race condition, and cross-reference
signal_child for details. Or maybe we should promote signal_child
into a more widely used function?

regards, tom lane

#47Tom Lane
tgl@sss.pgh.pa.us
In reply to: Thomas Munro (#45)
Re: Cleaning up historical portability baggage

Thomas Munro <thomas.munro@gmail.com> writes:

So what about strtof? That's gotta be dead code too. I gather we
still need commit 72880ac1's HAVE_BUGGY_STRTOF. From a cursory glance
at MinGW's implementation, it still has the complained-about
behaviour, if I've understood the complaint, and if I'm looking at the
right C runtime[1].

Looks plausible from here.

regards, tom lane

#48Thomas Munro
thomas.munro@gmail.com
In reply to: Tom Lane (#43)
1 attachment(s)
Re: Cleaning up historical portability baggage

On Sun, Aug 7, 2022 at 11:22 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Thomas Munro <thomas.munro@gmail.com> writes:

I also wonder if half the stuff in win32gettimeofday.c can be deleted.
From some light googling, it looks like
GetSystemTimePreciseAsFileTime() can just be called directly on
Windows 8+ (and we now require 10+), and that kernel32.dll malarky was
for older systems?

Yeah, Microsoft's man page for it just says to include sysinfoapi.h
(which we aren't) and then it should work on supported versions.

This looks good on CI (well I haven't waited for it to finish yet, but
MSVC compiles it without warning and we're most of the way through the
tests...).

Attachments:

0001-Simplify-gettimeofday-for-Windows.patchtext/x-patch; charset=US-ASCII; name=0001-Simplify-gettimeofday-for-Windows.patchDownload
From 6498faf80f5f2859e9228baf85f7e7974a29f4dc Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sun, 7 Aug 2022 11:57:23 +1200
Subject: [PATCH] Simplify gettimeofday for Windows.

Previously we bothered to forward-declare a struct timezone, following
man pages on typical systems, but POSIX actually says the argument
(which we ignore anyway) is void *.  Drop a line.

Previously we did extra work to select between Windows APIs needed on
older releases, but now we can just use the higher resolution function
directly.

Discussion: https://postgr.es/m/CA%2BhUKGKwRpvGfcfq2qNVAQS2Wg1B9eA9QRhAmVSyJt1zsCN2sQ%40mail.gmail.com
---
 src/include/port/win32_port.h |  3 +-
 src/port/win32gettimeofday.c  | 59 +++--------------------------------
 2 files changed, 5 insertions(+), 57 deletions(-)

diff --git a/src/include/port/win32_port.h b/src/include/port/win32_port.h
index 79451a00f9..12b4cf6cdb 100644
--- a/src/include/port/win32_port.h
+++ b/src/include/port/win32_port.h
@@ -181,9 +181,8 @@
 
 /* MinW has gettimeofday(), but MSVC doesn't */
 #ifdef _MSC_VER
-struct timezone;
 /* Last parameter not used */
-extern int	gettimeofday(struct timeval *tp, struct timezone *tzp);
+extern int	gettimeofday(struct timeval *tp, void *tzp);
 #endif
 
 /* for setitimer in backend/port/win32/timer.c */
diff --git a/src/port/win32gettimeofday.c b/src/port/win32gettimeofday.c
index 0464548758..a7eddddaad 100644
--- a/src/port/win32gettimeofday.c
+++ b/src/port/win32gettimeofday.c
@@ -28,6 +28,8 @@
 
 #include "c.h"
 
+#include <sysinfoapi.h>
+
 #include <sys/time.h>
 
 /* FILETIME of Jan 1 1970 00:00:00, the PostgreSQL epoch */
@@ -40,59 +42,6 @@ static const unsigned __int64 epoch = UINT64CONST(116444736000000000);
 #define FILETIME_UNITS_PER_SEC	10000000L
 #define FILETIME_UNITS_PER_USEC 10
 
-/*
- * Both GetSystemTimeAsFileTime and GetSystemTimePreciseAsFileTime share a
- * signature, so we can just store a pointer to whichever we find. This
- * is the pointer's type.
- */
-typedef VOID(WINAPI * PgGetSystemTimeFn) (LPFILETIME);
-
-/* One-time initializer function, must match that signature. */
-static void WINAPI init_gettimeofday(LPFILETIME lpSystemTimeAsFileTime);
-
-/* Storage for the function we pick at runtime */
-static PgGetSystemTimeFn pg_get_system_time = &init_gettimeofday;
-
-/*
- * One time initializer.  Determine whether GetSystemTimePreciseAsFileTime
- * is available and if so, plan to use it; if not, fall back to
- * GetSystemTimeAsFileTime.
- */
-static void WINAPI
-init_gettimeofday(LPFILETIME lpSystemTimeAsFileTime)
-{
-	/*
-	 * Because it's guaranteed that kernel32.dll will be linked into our
-	 * address space already, we don't need to LoadLibrary it and worry about
-	 * closing it afterwards, so we're not using Pg's dlopen/dlsym() wrapper.
-	 *
-	 * We'll just look up the address of GetSystemTimePreciseAsFileTime if
-	 * present.
-	 *
-	 * While we could look up the Windows version and skip this on Windows
-	 * versions below Windows 8 / Windows Server 2012 there isn't much point,
-	 * and determining the windows version is its self somewhat Windows
-	 * version and development SDK specific...
-	 */
-	pg_get_system_time = (PgGetSystemTimeFn) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),
-															"GetSystemTimePreciseAsFileTime");
-	if (pg_get_system_time == NULL)
-	{
-		/*
-		 * The expected error from GetLastError() is ERROR_PROC_NOT_FOUND, if
-		 * the function isn't present. No other error should occur.
-		 *
-		 * We can't report an error here because this might be running in
-		 * frontend code; and even if we're in the backend, it's too early to
-		 * elog(...) if we get some unexpected error.  Also, it's not a
-		 * serious problem, so just silently fall back to
-		 * GetSystemTimeAsFileTime irrespective of why the failure occurred.
-		 */
-		pg_get_system_time = &GetSystemTimeAsFileTime;
-	}
-
-	(*pg_get_system_time) (lpSystemTimeAsFileTime);
-}
 
 /*
  * timezone information is stored outside the kernel so tzp isn't used anymore.
@@ -101,12 +50,12 @@ init_gettimeofday(LPFILETIME lpSystemTimeAsFileTime)
  * elapsed_time().
  */
 int
-gettimeofday(struct timeval *tp, struct timezone *tzp)
+gettimeofday(struct timeval *tp, void *tzp)
 {
 	FILETIME	file_time;
 	ULARGE_INTEGER ularge;
 
-	(*pg_get_system_time) (&file_time);
+	GetSystemTimePreciseAsFileTime(&file_time);
 	ularge.LowPart = file_time.dwLowDateTime;
 	ularge.HighPart = file_time.dwHighDateTime;
 
-- 
2.37.1

#49Tom Lane
tgl@sss.pgh.pa.us
In reply to: Thomas Munro (#48)
Re: Cleaning up historical portability baggage

Thomas Munro <thomas.munro@gmail.com> writes:

On Sun, Aug 7, 2022 at 11:22 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Thomas Munro <thomas.munro@gmail.com> writes:

I also wonder if half the stuff in win32gettimeofday.c can be deleted.

This looks good on CI (well I haven't waited for it to finish yet, but
MSVC compiles it without warning and we're most of the way through the
tests...).

Looks plausible from here. A couple other thoughts:

* While you're at it you could fix the "MinW" typo just above
the extern for gettimeofday.

* I'm half tempted to add something like this to gettimeofday:

/*
* POSIX declines to define what tzp points to, saying
* "If tzp is not a null pointer, the behavior is unspecified".
* Let's take this opportunity to verify that noplace in
* Postgres tries to use any unportable behavior.
*/
Assert(tzp == NULL);

regards, tom lane

#50Andres Freund
andres@anarazel.de
In reply to: Thomas Munro (#1)
5 attachment(s)
Re: Cleaning up historical portability baggage

Hi,

Here's another set patches for cruft I discovered going line-by-line through
the autoconf vs meson test differences. They'd all be simple to port to meson
too, but I think it's better to clean them up.

0001: __func__ is C99, so we don't need to support fallbacks

0002: windows: We've unconditionally defined HAVE_MINIDUMP_TYPE for msvc forever, we
can rely on it for mingw too

0003: aix: aix3.2.5, aix4.1 are not even of historical interest at this point
- 4.1 was released before the first commit in our commit history

0004: solaris: these gcc & gnu ld vs sun stuff differences seem unnecessary or
outdated

I started this because I wanted to get rid of with_gnu_ld, but there's still
a necessary reference left unfortunately. But it still seems worth doing?

I checked and the relevant options (-shared, -Wl,-Bsymbolic, -Wl,-soname)
work even on solaris 10 with developerstudio12.5 (not the latest)

0005: those broken system headers look to have been repaired a good while ago,
or, in the case of irix, we don't support the platform anymore

Greetings,

Andres Freund

Attachments:

0003-aix-Remove-checks-for-very-old-OS-versions.patchtext/x-diff; charset=us-asciiDownload
From ad73df7c9779cdb7e68fccd78bf79f445ae7059f Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Sat, 6 Aug 2022 13:22:49 -0700
Subject: [PATCH 3/5] aix: Remove checks for very old OS versions

---
 src/makefiles/Makefile.aix | 14 ++------------
 src/template/aix           |  3 ---
 src/backend/Makefile       |  8 --------
 3 files changed, 2 insertions(+), 23 deletions(-)

diff --git a/src/makefiles/Makefile.aix b/src/makefiles/Makefile.aix
index 84f26b49b87..4cf2cc52d45 100644
--- a/src/makefiles/Makefile.aix
+++ b/src/makefiles/Makefile.aix
@@ -8,19 +8,9 @@ AROPT = crs
 # -blibpath must contain ALL directories where we should look for libraries
 libpath := $(shell echo $(subst -L,:,$(filter -L/%,$(LDFLAGS))) | sed -e's/ //g'):/usr/lib:/lib
 
-ifeq ($(host_os), aix3.2.5)
-	rpath = -L'$(rpathdir)'
-else
-	rpath = -Wl,-blibpath:'$(rpathdir)$(libpath)'
-endif
+rpath = -Wl,-blibpath:'$(rpathdir)$(libpath)'
 
-ifeq ($(host_os), aix3.2.5)
-ifneq ($(GCC), yes)
-	LDFLAGS_SL += -e _nostart -H512 -bM:SRE
-endif
-else
-	LDFLAGS_SL += -Wl,-bnoentry -Wl,-H512 -Wl,-bM:SRE
-endif
+LDFLAGS_SL += -Wl,-bnoentry -Wl,-H512 -Wl,-bM:SRE
 
 # env var name to use in place of LD_LIBRARY_PATH
 ld_library_path_var = LIBPATH
diff --git a/src/template/aix b/src/template/aix
index cec240d27b9..47fa8990a7c 100644
--- a/src/template/aix
+++ b/src/template/aix
@@ -6,9 +6,6 @@
 # non-default CFLAGS setting.
 if test "$GCC" != yes ; then
   case $host_os in
-    aix3.2.5 | aix4.1*)
-      CFLAGS="-O -qmaxmem=16384"
-      ;;
     *)
       CFLAGS="-O2 -qmaxmem=16384"
       ;;
diff --git a/src/backend/Makefile b/src/backend/Makefile
index 953c80db5ab..7262861b12a 100644
--- a/src/backend/Makefile
+++ b/src/backend/Makefile
@@ -101,15 +101,7 @@ postgres: $(POSTGRES_IMP)
 
 $(POSTGRES_IMP): $(OBJS)
 	$(LD) $(LDREL) $(LDOUT) SUBSYS.o $(call expand_subsys,$^)
-ifeq ($(host_os), aix3.2.5)
 	$(MKLDEXPORT) SUBSYS.o $(bindir)/postgres > $@
-else
-ifneq (,$(findstring aix4.1, $(host_os)))
-	$(MKLDEXPORT) SUBSYS.o $(bindir)/postgres > $@
-else
-	$(MKLDEXPORT) SUBSYS.o . > $@
-endif
-endif
 	@rm -f SUBSYS.o
 
 endif # aix
-- 
2.37.0.3.g30cc8d0f14

0004-solaris-Remove-unnecessary-gcc-gnu-ld-vs-sun-studio-.patchtext/x-diff; charset=us-asciiDownload
From d6582d4aed8779fcb903f5eb3ad5d802289a0cf5 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Sat, 6 Aug 2022 13:23:43 -0700
Subject: [PATCH 4/5] solaris: Remove unnecessary gcc / gnu ld vs sun studio
 differences

Unfortunately one with_gnu_ld reference remains, otherwise we could remove the
configure support for determining with_gnu_ld.
---
 src/makefiles/Makefile.solaris |  9 +--------
 src/Makefile.shlib             | 12 ++----------
 2 files changed, 3 insertions(+), 18 deletions(-)

diff --git a/src/makefiles/Makefile.solaris b/src/makefiles/Makefile.solaris
index 5496edcafc1..acdf44cc0f2 100644
--- a/src/makefiles/Makefile.solaris
+++ b/src/makefiles/Makefile.solaris
@@ -1,21 +1,14 @@
 # src/makefiles/Makefile.solaris
 
 AROPT = crs
+rpath = -Wl,-rpath,'$(rpathdir)'
 
 ifeq ($(with_gnu_ld), yes)
 export_dynamic = -Wl,-E
-rpath = -Wl,-rpath,'$(rpathdir)'
-else
-rpath = -Wl,-R'$(rpathdir)'
 endif
 
-
 # Rule for building a shared library from a single .o file
 %.so: %.o
-ifeq ($(GCC), yes)
 	$(CC) $(CFLAGS) $< $(LDFLAGS) $(LDFLAGS_SL) -shared -o $@
-else
-	$(CC) $(CFLAGS) $< $(LDFLAGS) $(LDFLAGS_SL) -G -o $@
-endif
 
 sqlmansect = 5sql
diff --git a/src/Makefile.shlib b/src/Makefile.shlib
index 2396bc247e5..2af6192f0f3 100644
--- a/src/Makefile.shlib
+++ b/src/Makefile.shlib
@@ -188,17 +188,9 @@ ifeq ($(PORTNAME), linux)
 endif
 
 ifeq ($(PORTNAME), solaris)
-  ifeq ($(GCC), yes)
-    LINK.shared		= $(COMPILER) -shared -Wl,-Bsymbolic
-  else
-    LINK.shared		= $(COMPILER) -G -Bsymbolic
-  endif
+  LINK.shared		= $(COMPILER) -shared -Wl,-Bsymbolic
   ifdef soname
-    ifeq ($(with_gnu_ld), yes)
-      LINK.shared	+= -Wl,-soname,$(soname)
-    else
-      LINK.shared	+= -h $(soname)
-    endif
+    LINK.shared	+= -Wl,-soname,$(soname)
   endif
 endif
 
-- 
2.37.0.3.g30cc8d0f14

0001-Rely-on-__func__-being-supported.patchtext/x-diff; charset=us-asciiDownload
From f69c4e34d82c9441402d939e39575fa0afc949e8 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Fri, 5 Aug 2022 17:25:49 -0700
Subject: [PATCH 1/5] Rely on __func__ being supported

Previously we fell back to __FUNCTION__ and then NULL. As __func__ is in C99
that shouldn't be necessary anymore.

For some reason Solution.pm defined HAVE_FUNCNAME__FUNCTION instead of
HAVE_FUNCNAME__FUNC (originating in 4164e6636e2), there doesn't seem to be a
reason to continue with that as __func__ is supported by msvc.
---
 src/include/c.h                   | 11 ------
 src/include/pg_config.h.in        |  6 ---
 src/include/storage/s_lock.h      |  4 +-
 src/include/utils/elog.h          |  4 +-
 config/c-compiler.m4              | 26 -------------
 src/backend/storage/lmgr/s_lock.c |  2 +-
 configure                         | 61 -------------------------------
 configure.ac                      |  1 -
 src/tools/msvc/Solution.pm        |  2 -
 9 files changed, 5 insertions(+), 112 deletions(-)

diff --git a/src/include/c.h b/src/include/c.h
index 8c4baeb0ec3..de9ec04d494 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -360,17 +360,6 @@ typedef void (*pg_funcptr_t) (void);
  */
 #define FLEXIBLE_ARRAY_MEMBER	/* empty */
 
-/* Which __func__ symbol do we have, if any? */
-#ifdef HAVE_FUNCNAME__FUNC
-#define PG_FUNCNAME_MACRO	__func__
-#else
-#ifdef HAVE_FUNCNAME__FUNCTION
-#define PG_FUNCNAME_MACRO	__FUNCTION__
-#else
-#define PG_FUNCNAME_MACRO	NULL
-#endif
-#endif
-
 
 /* ----------------------------------------------------------------
  *				Section 2:	bool, true, false
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 2d9a1cdc8ab..5ec31e532e3 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -158,12 +158,6 @@
 /* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
 #undef HAVE_FSEEKO
 
-/* Define to 1 if your compiler understands __func__. */
-#undef HAVE_FUNCNAME__FUNC
-
-/* Define to 1 if your compiler understands __FUNCTION__. */
-#undef HAVE_FUNCNAME__FUNCTION
-
 /* Define to 1 if you have __atomic_compare_exchange_n(int *, int *, int). */
 #undef HAVE_GCC__ATOMIC_INT32_CAS
 
diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h
index 1c9f6f08954..0877cf65b0b 100644
--- a/src/include/storage/s_lock.h
+++ b/src/include/storage/s_lock.h
@@ -768,7 +768,7 @@ extern int	tas_sema(volatile slock_t *lock);
 
 #if !defined(S_LOCK)
 #define S_LOCK(lock) \
-	(TAS(lock) ? s_lock((lock), __FILE__, __LINE__, PG_FUNCNAME_MACRO) : 0)
+	(TAS(lock) ? s_lock((lock), __FILE__, __LINE__, __func__) : 0)
 #endif	 /* S_LOCK */
 
 #if !defined(S_LOCK_FREE)
@@ -855,7 +855,7 @@ init_spin_delay(SpinDelayStatus *status,
 	status->func = func;
 }
 
-#define init_local_spin_delay(status) init_spin_delay(status, __FILE__, __LINE__, PG_FUNCNAME_MACRO)
+#define init_local_spin_delay(status) init_spin_delay(status, __FILE__, __LINE__, __func__)
 extern void perform_spin_delay(SpinDelayStatus *status);
 extern void finish_spin_delay(SpinDelayStatus *status);
 
diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h
index 68ead8e8736..56398176901 100644
--- a/src/include/utils/elog.h
+++ b/src/include/utils/elog.h
@@ -140,7 +140,7 @@
 		if (__builtin_constant_p(elevel) && (elevel) >= ERROR ? \
 			errstart_cold(elevel, domain) : \
 			errstart(elevel, domain)) \
-			__VA_ARGS__, errfinish(__FILE__, __LINE__, PG_FUNCNAME_MACRO); \
+			__VA_ARGS__, errfinish(__FILE__, __LINE__, __func__); \
 		if (__builtin_constant_p(elevel) && (elevel) >= ERROR) \
 			pg_unreachable(); \
 	} while(0)
@@ -150,7 +150,7 @@
 		const int elevel_ = (elevel); \
 		pg_prevent_errno_in_scope(); \
 		if (errstart(elevel_, domain)) \
-			__VA_ARGS__, errfinish(__FILE__, __LINE__, PG_FUNCNAME_MACRO); \
+			__VA_ARGS__, errfinish(__FILE__, __LINE__, __func__); \
 		if (elevel_ >= ERROR) \
 			pg_unreachable(); \
 	} while(0)
diff --git a/config/c-compiler.m4 b/config/c-compiler.m4
index d3562d6feee..69efc5bb10a 100644
--- a/config/c-compiler.m4
+++ b/config/c-compiler.m4
@@ -165,32 +165,6 @@ if (q != holder)
 fi])# PGAC_TYPE_128BIT_INT
 
 
-# PGAC_C_FUNCNAME_SUPPORT
-# -----------------------
-# Check if the C compiler understands __func__ (C99) or __FUNCTION__ (gcc).
-# Define HAVE_FUNCNAME__FUNC or HAVE_FUNCNAME__FUNCTION accordingly.
-AC_DEFUN([PGAC_C_FUNCNAME_SUPPORT],
-[AC_CACHE_CHECK(for __func__, pgac_cv_funcname_func_support,
-[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <stdio.h>],
-[printf("%s\n", __func__);])],
-[pgac_cv_funcname_func_support=yes],
-[pgac_cv_funcname_func_support=no])])
-if test x"$pgac_cv_funcname_func_support" = xyes ; then
-AC_DEFINE(HAVE_FUNCNAME__FUNC, 1,
-          [Define to 1 if your compiler understands __func__.])
-else
-AC_CACHE_CHECK(for __FUNCTION__, pgac_cv_funcname_function_support,
-[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <stdio.h>],
-[printf("%s\n", __FUNCTION__);])],
-[pgac_cv_funcname_function_support=yes],
-[pgac_cv_funcname_function_support=no])])
-if test x"$pgac_cv_funcname_function_support" = xyes ; then
-AC_DEFINE(HAVE_FUNCNAME__FUNCTION, 1,
-          [Define to 1 if your compiler understands __FUNCTION__.])
-fi
-fi])# PGAC_C_FUNCNAME_SUPPORT
-
-
 
 # PGAC_C_STATIC_ASSERT
 # --------------------
diff --git a/src/backend/storage/lmgr/s_lock.c b/src/backend/storage/lmgr/s_lock.c
index 2a658ff594c..4e473ec27ec 100644
--- a/src/backend/storage/lmgr/s_lock.c
+++ b/src/backend/storage/lmgr/s_lock.c
@@ -304,7 +304,7 @@ main()
 	printf("             if S_LOCK() and TAS() are working.\n");
 	fflush(stdout);
 
-	s_lock(&test_lock.lock, __FILE__, __LINE__, PG_FUNCNAME_MACRO);
+	s_lock(&test_lock.lock, __FILE__, __LINE__, __func__);
 
 	printf("S_LOCK_TEST: failed, lock not locked\n");
 	return 1;
diff --git a/configure b/configure
index 0e73edb9ffa..3891ae61d31 100755
--- a/configure
+++ b/configure
@@ -14937,67 +14937,6 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __func__" >&5
-$as_echo_n "checking for __func__... " >&6; }
-if ${pgac_cv_funcname_func_support+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdio.h>
-int
-main ()
-{
-printf("%s\n", __func__);
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  pgac_cv_funcname_func_support=yes
-else
-  pgac_cv_funcname_func_support=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_funcname_func_support" >&5
-$as_echo "$pgac_cv_funcname_func_support" >&6; }
-if test x"$pgac_cv_funcname_func_support" = xyes ; then
-
-$as_echo "#define HAVE_FUNCNAME__FUNC 1" >>confdefs.h
-
-else
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __FUNCTION__" >&5
-$as_echo_n "checking for __FUNCTION__... " >&6; }
-if ${pgac_cv_funcname_function_support+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdio.h>
-int
-main ()
-{
-printf("%s\n", __FUNCTION__);
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  pgac_cv_funcname_function_support=yes
-else
-  pgac_cv_funcname_function_support=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_funcname_function_support" >&5
-$as_echo "$pgac_cv_funcname_function_support" >&6; }
-if test x"$pgac_cv_funcname_function_support" = xyes ; then
-
-$as_echo "#define HAVE_FUNCNAME__FUNCTION 1" >>confdefs.h
-
-fi
-fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _Static_assert" >&5
 $as_echo_n "checking for _Static_assert... " >&6; }
 if ${pgac_cv__static_assert+:} false; then :
diff --git a/configure.ac b/configure.ac
index efd3be91cd4..d96066e3803 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1635,7 +1635,6 @@ m4_defun([AC_PROG_CC_STDC], []) dnl We don't want that.
 AC_C_BIGENDIAN
 AC_C_INLINE
 PGAC_PRINTF_ARCHETYPE
-PGAC_C_FUNCNAME_SUPPORT
 PGAC_C_STATIC_ASSERT
 PGAC_C_TYPEOF
 PGAC_C_TYPES_COMPATIBLE
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 4916a86f5cf..7615a228aa9 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -250,8 +250,6 @@ sub GenerateFiles
 		HAVE_EXECINFO_H                             => undef,
 		HAVE_EXPLICIT_BZERO                         => undef,
 		HAVE_FSEEKO                                 => 1,
-		HAVE_FUNCNAME__FUNC                         => undef,
-		HAVE_FUNCNAME__FUNCTION                     => 1,
 		HAVE_GCC__ATOMIC_INT32_CAS                  => undef,
 		HAVE_GCC__ATOMIC_INT64_CAS                  => undef,
 		HAVE_GCC__SYNC_CHAR_TAS                     => undef,
-- 
2.37.0.3.g30cc8d0f14

0002-windows-Remove-HAVE_MINIDUMP_TYPE-test.patchtext/x-diff; charset=us-asciiDownload
From fd0b114540cbd5950a4c6e01131d8b73e1e01c98 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Fri, 5 Aug 2022 17:35:47 -0700
Subject: [PATCH 2/5] windows: Remove HAVE_MINIDUMP_TYPE test

We've relied on it being present for msvc for ages...
---
 src/include/pg_config.h.in      |  3 ---
 src/backend/main/main.c         |  2 +-
 src/backend/port/win32/Makefile |  4 +---
 configure                       | 26 --------------------------
 configure.ac                    | 11 -----------
 src/Makefile.global.in          |  3 ---
 src/tools/msvc/Solution.pm      |  1 -
 7 files changed, 2 insertions(+), 48 deletions(-)

diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 5ec31e532e3..63c17c77a5c 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -325,9 +325,6 @@
 /* Define to 1 if you have the `memset_s' function. */
 #undef HAVE_MEMSET_S
 
-/* Define to 1 if the system has the type `MINIDUMP_TYPE'. */
-#undef HAVE_MINIDUMP_TYPE
-
 /* Define to 1 if you have the `mkdtemp' function. */
 #undef HAVE_MKDTEMP
 
diff --git a/src/backend/main/main.c b/src/backend/main/main.c
index bb782fa1ec6..5a964a0db67 100644
--- a/src/backend/main/main.c
+++ b/src/backend/main/main.c
@@ -63,7 +63,7 @@ main(int argc, char *argv[])
 	 * If supported on the current platform, set up a handler to be called if
 	 * the backend/postmaster crashes with a fatal signal or exception.
 	 */
-#if defined(WIN32) && defined(HAVE_MINIDUMP_TYPE)
+#if defined(WIN32)
 	pgwin32_install_crashdump_handler();
 #endif
 
diff --git a/src/backend/port/win32/Makefile b/src/backend/port/win32/Makefile
index 90126f634ac..61e0369d621 100644
--- a/src/backend/port/win32/Makefile
+++ b/src/backend/port/win32/Makefile
@@ -13,11 +13,9 @@ top_builddir = ../../../..
 include $(top_builddir)/src/Makefile.global
 
 OBJS = \
+	crashdump.o \
 	signal.o \
 	socket.o \
 	timer.o
-ifeq ($(have_win32_dbghelp), yes)
-OBJS += crashdump.o
-endif
 
 include $(top_srcdir)/src/backend/common.mk
diff --git a/configure b/configure
index 3891ae61d31..c60c827a3c8 100755
--- a/configure
+++ b/configure
@@ -648,7 +648,6 @@ MSGFMT
 PG_CRC32C_OBJS
 CFLAGS_ARMV8_CRC32C
 CFLAGS_SSE42
-have_win32_dbghelp
 LIBOBJS
 ZSTD
 LZ4
@@ -16911,32 +16910,7 @@ esac
  ;;
 esac
 
-  ac_fn_c_check_type "$LINENO" "MINIDUMP_TYPE" "ac_cv_type_MINIDUMP_TYPE" "
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <string.h>
-#include <dbghelp.h>
-"
-if test "x$ac_cv_type_MINIDUMP_TYPE" = xyes; then :
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_MINIDUMP_TYPE 1
-_ACEOF
-
-pgac_minidump_type=yes
-else
-  pgac_minidump_type=no
 fi
-
-fi
-if test x"$pgac_minidump_type" = x"yes" ; then
-  have_win32_dbghelp=yes
-
-else
-  have_win32_dbghelp=no
-
-fi
-
 # Cygwin needs only a bit of that
 if test "$PORTNAME" = "cygwin"; then
   case " $LIBOBJS " in
diff --git a/configure.ac b/configure.ac
index d96066e3803..8593c50575f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1939,18 +1939,7 @@ if test "$PORTNAME" = "win32"; then
   AC_LIBOBJ(win32security)
   AC_LIBOBJ(win32setlocale)
   AC_LIBOBJ(win32stat)
-  AC_CHECK_TYPES(MINIDUMP_TYPE, [pgac_minidump_type=yes], [pgac_minidump_type=no], [
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <string.h>
-#include <dbghelp.h>])
 fi
-if test x"$pgac_minidump_type" = x"yes" ; then
-  AC_SUBST(have_win32_dbghelp,yes)
-else
-  AC_SUBST(have_win32_dbghelp,no)
-fi
-
 # Cygwin needs only a bit of that
 if test "$PORTNAME" = "cygwin"; then
   AC_LIBOBJ(dirmod)
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index 14fdd4ef7b1..0625b60c434 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -547,9 +547,6 @@ host_cpu = @host_cpu@
 # Backend stack size limit has to be hard-wired on Windows (it's in bytes)
 WIN32_STACK_RLIMIT=4194304
 
-# Set if we have a working win32 crashdump header
-have_win32_dbghelp = @have_win32_dbghelp@
-
 DLSUFFIX = @DLSUFFIX@
 
 # Pull in platform-specific magic
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 7615a228aa9..ab8f4b24dba 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -305,7 +305,6 @@ sub GenerateFiles
 		HAVE_MBSTOWCS_L             => 1,
 		HAVE_MEMORY_H               => 1,
 		HAVE_MEMSET_S               => undef,
-		HAVE_MINIDUMP_TYPE          => 1,
 		HAVE_MKDTEMP                => undef,
 		HAVE_NETINET_TCP_H          => undef,
 		HAVE_NET_IF_H               => undef,
-- 
2.37.0.3.g30cc8d0f14

0005-Trust-a-few-system-headers-to-stand-on-their-own.patchtext/x-diff; charset=us-asciiDownload
From d886e115887fa7e30a40d9265caae1cba32bd747 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Sat, 6 Aug 2022 17:04:56 -0700
Subject: [PATCH 5/5] Trust a few system headers to stand on their own

At some point in the past some headers (net/if.h on some BSDs in 2009,
netinet/tcp.h on IRIX in 2000, sys/ucred.h in 2013 on then older openbsd),
only compiled if other heades were included first, complicating configure
tests. More recent tests indicate that that's not required anymore.

Discussion: https://postgr.es/m/
---
 configure    | 56 +---------------------------------------------------
 configure.ac | 24 +++-------------------
 2 files changed, 4 insertions(+), 76 deletions(-)

diff --git a/configure b/configure
index c60c827a3c8..e71c0c4c2d5 100755
--- a/configure
+++ b/configure
@@ -13874,7 +13874,7 @@ $as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h
 fi
 
 
-for ac_header in atomic.h copyfile.h execinfo.h getopt.h ifaddrs.h langinfo.h mbarrier.h sys/epoll.h sys/event.h sys/ipc.h sys/personality.h sys/prctl.h sys/procctl.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/signalfd.h sys/sockio.h sys/uio.h sys/un.h termios.h ucred.h
+for ac_header in atomic.h copyfile.h execinfo.h getopt.h ifaddrs.h langinfo.h mbarrier.h net/if.h netinet/tcp.h sys/epoll.h sys/event.h sys/ipc.h sys/personality.h sys/prctl.h sys/procctl.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/signalfd.h sys/sockio.h sys/ucred.h sys/uio.h sys/un.h termios.h ucred.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@@ -13888,60 +13888,6 @@ fi
 done
 
 
-# On BSD, test for net/if.h will fail unless sys/socket.h
-# is included first.
-for ac_header in net/if.h
-do :
-  ac_fn_c_check_header_compile "$LINENO" "net/if.h" "ac_cv_header_net_if_h" "$ac_includes_default
-#include <sys/socket.h>
-
-"
-if test "x$ac_cv_header_net_if_h" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_NET_IF_H 1
-_ACEOF
-
-fi
-
-done
-
-
-# On OpenBSD, test for sys/ucred.h will fail unless sys/param.h
-# is included first.
-for ac_header in sys/ucred.h
-do :
-  ac_fn_c_check_header_compile "$LINENO" "sys/ucred.h" "ac_cv_header_sys_ucred_h" "$ac_includes_default
-#include <sys/param.h>
-
-"
-if test "x$ac_cv_header_sys_ucred_h" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_SYS_UCRED_H 1
-_ACEOF
-
-fi
-
-done
-
-
-# At least on IRIX, test for netinet/tcp.h will fail unless
-# netinet/in.h is included first.
-for ac_header in netinet/tcp.h
-do :
-  ac_fn_c_check_header_compile "$LINENO" "netinet/tcp.h" "ac_cv_header_netinet_tcp_h" "$ac_includes_default
-#include <netinet/in.h>
-
-"
-if test "x$ac_cv_header_netinet_tcp_h" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_NETINET_TCP_H 1
-_ACEOF
-
-fi
-
-done
-
-
 if expr x"$pgac_cv_check_readline" : 'x-lreadline' >/dev/null ; then
   for ac_header in readline/readline.h
 do :
diff --git a/configure.ac b/configure.ac
index 8593c50575f..c4590c9e674 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1452,6 +1452,8 @@ AC_CHECK_HEADERS(m4_normalize([
 	ifaddrs.h
 	langinfo.h
 	mbarrier.h
+	net/if.h
+	netinet/tcp.h
 	sys/epoll.h
 	sys/event.h
 	sys/ipc.h
@@ -1464,33 +1466,13 @@ AC_CHECK_HEADERS(m4_normalize([
 	sys/shm.h
 	sys/signalfd.h
 	sys/sockio.h
+	sys/ucred.h
 	sys/uio.h
 	sys/un.h
 	termios.h
 	ucred.h
 ]))
 
-# On BSD, test for net/if.h will fail unless sys/socket.h
-# is included first.
-AC_CHECK_HEADERS(net/if.h, [], [],
-[AC_INCLUDES_DEFAULT
-#include <sys/socket.h>
-])
-
-# On OpenBSD, test for sys/ucred.h will fail unless sys/param.h
-# is included first.
-AC_CHECK_HEADERS(sys/ucred.h, [], [],
-[AC_INCLUDES_DEFAULT
-#include <sys/param.h>
-])
-
-# At least on IRIX, test for netinet/tcp.h will fail unless
-# netinet/in.h is included first.
-AC_CHECK_HEADERS(netinet/tcp.h, [], [],
-[AC_INCLUDES_DEFAULT
-#include <netinet/in.h>
-])
-
 if expr x"$pgac_cv_check_readline" : 'x-lreadline' >/dev/null ; then
   AC_CHECK_HEADERS(readline/readline.h, [],
         [AC_CHECK_HEADERS(readline.h, [],
-- 
2.37.0.3.g30cc8d0f14

#51Thomas Munro
thomas.munro@gmail.com
In reply to: Andres Freund (#50)
Re: Cleaning up historical portability baggage

On Sun, Aug 7, 2022 at 1:29 PM Andres Freund <andres@anarazel.de> wrote:

0001: __func__ is C99, so we don't need to support fallbacks

+1, and my scraped data agrees.

I believe our minimum MSVC is current 2015, and this says it has it
(it doesn't let you select older versions in the version drop-down,
but we don't care about older versions):

https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=msvc-140

0002: windows: We've unconditionally defined HAVE_MINIDUMP_TYPE for msvc forever, we
can rely on it for mingw too

      * If supported on the current platform, set up a handler to be called if
      * the backend/postmaster crashes with a fatal signal or exception.
      */
-#if defined(WIN32) && defined(HAVE_MINIDUMP_TYPE)
+#if defined(WIN32)

Personally I'd remove "If supported on the current platform, " and
shove the rest of the comment inside the #if defined(WIN32), but
that's just me...

0003: aix: aix3.2.5, aix4.1 are not even of historical interest at this point
- 4.1 was released before the first commit in our commit history

Wow.

0004: solaris: these gcc & gnu ld vs sun stuff differences seem unnecessary or
outdated

LGTM from a look at the current man page.

I checked and the relevant options (-shared, -Wl,-Bsymbolic, -Wl,-soname)
work even on solaris 10 with developerstudio12.5 (not the latest)

FWIW I'd call Solaris 10 EOL'd (it's in some
sure-pay-us-but-we-aren't-really-going-to-fix-it phase with a lifetime
similar to the actual sun).

0005: those broken system headers look to have been repaired a good while ago,
or, in the case of irix, we don't support the platform anymore

Nice archeology.

#52Andres Freund
andres@anarazel.de
In reply to: Thomas Munro (#45)
Re: Cleaning up historical portability baggage

Hi,

On 2022-08-07 11:47:31 +1200, Thomas Munro wrote:

So what about strtof? That's gotta be dead code too. I gather we
still need commit 72880ac1's HAVE_BUGGY_STRTOF.

From a cursory glance at MinGW's implementation, it still has the
complained-about behaviour, if I've understood the complaint, and if I'm
looking at the right C runtime[1].

Well, right now we don't refuse to build against the "wrong" runtimes, so it's
hard to say whether you're looking at the right runtime. I don't think we need
this if we're (as we should imo) only using the ucrt - that's microsoft's,
which IIUC is ok?

-/*
- * strtof() is part of C99; this version is only for the benefit of obsolete
- * platforms. As such, it is known to return incorrect values for edge cases,
- * which have to be allowed for in variant files for regression test results
- * for any such platform.
- */

We can't remove the result files referenced here yet, due to the double
rounding behaviour?

Greetings,

Andres Freund

#53Andres Freund
andres@anarazel.de
In reply to: Thomas Munro (#51)
Re: Cleaning up historical portability baggage

Hi,

On 2022-08-07 14:29:20 +1200, Thomas Munro wrote:

On Sun, Aug 7, 2022 at 1:29 PM Andres Freund <andres@anarazel.de> wrote:

0001: __func__ is C99, so we don't need to support fallbacks

+1, and my scraped data agrees.

I believe our minimum MSVC is current 2015, and this says it has it
(it doesn't let you select older versions in the version drop-down,
but we don't care about older versions):

Thanks for checking.

0002: windows: We've unconditionally defined HAVE_MINIDUMP_TYPE for msvc forever, we
can rely on it for mingw too

* If supported on the current platform, set up a handler to be called if
* the backend/postmaster crashes with a fatal signal or exception.
*/
-#if defined(WIN32) && defined(HAVE_MINIDUMP_TYPE)
+#if defined(WIN32)

Personally I'd remove "If supported on the current platform, " and
shove the rest of the comment inside the #if defined(WIN32), but
that's just me...

I started out that way as well, but it'd actually be nice to do this on other
platforms too, and we just don't support it yet :)

I checked and the relevant options (-shared, -Wl,-Bsymbolic, -Wl,-soname)
work even on solaris 10 with developerstudio12.5 (not the latest)

FWIW I'd call Solaris 10 EOL'd (it's in some
sure-pay-us-but-we-aren't-really-going-to-fix-it phase with a lifetime
similar to the actual sun).

I'd agree - but checked so that couldn't even be an argument against :)

Greetings,

Andres Freund

#54Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andres Freund (#52)
Re: Cleaning up historical portability baggage

Andres Freund <andres@anarazel.de> writes:

On 2022-08-07 11:47:31 +1200, Thomas Munro wrote:

So what about strtof? That's gotta be dead code too. I gather we
still need commit 72880ac1's HAVE_BUGGY_STRTOF.

Well, right now we don't refuse to build against the "wrong" runtimes, so it's
hard to say whether you're looking at the right runtime. I don't think we need
this if we're (as we should imo) only using the ucrt - that's microsoft's,
which IIUC is ok?

You could pull it out and see if the buildfarm breaks, but my money
is on it breaking. That HAVE_BUGGY_STRTOF stuff isn't very old.

regards, tom lane

#55Andres Freund
andres@anarazel.de
In reply to: Tom Lane (#54)
Re: Cleaning up historical portability baggage

Hi,

On 2022-08-06 22:58:12 -0400, Tom Lane wrote:

You could pull it out and see if the buildfarm breaks, but my money
is on it breaking. That HAVE_BUGGY_STRTOF stuff isn't very old.

We only recently figured out that we should use the ucrt runtime (and that it
exists, I guess).
fairywren and jacan's first runs with ucrt are from mid February:
https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=fairywren&amp;dt=2022-02-13%2007%3A11%3A46
https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=jacana&amp;dt=2022-02-17%2016%3A15%3A24

We probably should just throw an error if msvcrt is used. That's the old, pre
C99, microsoft C runtime, with some mingw replacement functions ontop. I
think our tests already don't pass when it's used. See [1]https://www.msys2.org/docs/environments/ for more info.

Not entirely sure how to best detect ucrt use - we could just check MSYSTEM,
but that's not determinative because one also can specify the compiler via the
prefix...

That'd still leave us with the alternative output files due to cygwin, I
think.

Greetings,

Andres Freund

[1]: https://www.msys2.org/docs/environments/

#56Andres Freund
andres@anarazel.de
In reply to: Andres Freund (#55)
Re: Cleaning up historical portability baggage

Hi,

On 2022-08-06 20:39:48 -0700, Andres Freund wrote:

On 2022-08-06 22:58:12 -0400, Tom Lane wrote:

You could pull it out and see if the buildfarm breaks, but my money
is on it breaking. That HAVE_BUGGY_STRTOF stuff isn't very old.

We only recently figured out that we should use the ucrt runtime (and that it
exists, I guess).
fairywren and jacan's first runs with ucrt are from mid February:
https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=fairywren&amp;dt=2022-02-13%2007%3A11%3A46
https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=jacana&amp;dt=2022-02-17%2016%3A15%3A24

Well, bad news and good news. The bad: We get the wrong results when just
removing HAVE_BUGGY_STRTOF. The good: That is just because we haven't applied
enough, or the right, magic. To have mingw to not interfere with things one
also has to pass -D_UCRT and -lucrt - then the tests pass, even without
HAVE_BUGGY_STRTOF.

I think this might also explain (and fix) some other oddity we had with mingw
that I was getting confused about a while back, but I forgot too much of the
details...

Greetings,

Andres Freund

#57Andres Freund
andres@anarazel.de
In reply to: Andres Freund (#56)
Re: Cleaning up historical portability baggage

Hi,

On 2022-08-06 23:20:26 -0700, Andres Freund wrote:

The good: That is just because we haven't applied enough, or the right,
magic. To have mingw to not interfere with things one also has to pass
-D_UCRT and -lucrt - then the tests pass, even without HAVE_BUGGY_STRTOF.

Looks like only -lucrt is required, not -D_UCRT.

Asked on the mingw irc channel - it's not expected that such magic is
required. Opened https://github.com/msys2/MINGW-packages/issues/12472

Greetings,

Andres Freund

#58Andres Freund
andres@anarazel.de
In reply to: Andres Freund (#50)
Re: Cleaning up historical portability baggage

Hi,

On 2022-08-06 18:29:14 -0700, Andres Freund wrote:

0003: aix: aix3.2.5, aix4.1 are not even of historical interest at this point
- 4.1 was released before the first commit in our commit history

hoverfly clearly doesn't like this:
https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=hoverfly&amp;dt=2022-08-07%2017%3A06%3A15

Oh, I may see the problem I think I misread the comma in the ifneq

--- a/src/backend/Makefile
+++ b/src/backend/Makefile
@@ -101,15 +101,7 @@ postgres: $(POSTGRES_IMP)

$(POSTGRES_IMP): $(OBJS)
$(LD) $(LDREL) $(LDOUT) SUBSYS.o $(call expand_subsys,$^)
-ifeq ($(host_os), aix3.2.5)
$(MKLDEXPORT) SUBSYS.o $(bindir)/postgres > $@
-else
-ifneq (,$(findstring aix4.1, $(host_os)))
- $(MKLDEXPORT) SUBSYS.o $(bindir)/postgres > $@
-else
- $(MKLDEXPORT) SUBSYS.o . > $@
-endif
-endif
@rm -f SUBSYS.o

i.e. it should be "$(MKLDEXPORT) SUBSYS.o . > $@" after removing the
conditionals rather than "$(MKLDEXPORT) SUBSYS.o $(bindir)/postgres > $@".

Greetings,

Andres Freund

#59Tom Lane
tgl@sss.pgh.pa.us
In reply to: Thomas Munro (#26)
Re: Cleaning up historical portability baggage

Thomas Munro <thomas.munro@gmail.com> writes:

On Thu, Aug 4, 2022 at 4:09 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:

clock_gettime is required by SUSv2 (1997), so I have to admit that
macOS 10.4 doesn't have a lot of excuse not to have it. In any case,
prairiedog is just sitting there doing its thing until I find cycles
to install a newer OS. If you want to move ahead with this, don't
let prairiedog block you.

Thanks, will do.

BTW, that commit really should have updated the explanation at the top of
instr_time.h:

* This file provides an abstraction layer to hide portability issues in
* interval timing. On Unix we use clock_gettime() if available, else
* gettimeofday(). On Windows, gettimeofday() gives a low-precision result
* so we must use QueryPerformanceCounter() instead. These macros also give
* some breathing room to use other high-precision-timing APIs.

Updating the second sentence is easy enough, but as for the third,
I wonder if it's still true in view of 24c3ce8f1. Should we revisit
whether to use gettimeofday vs. QueryPerformanceCounter? At the very
least I suspect it's no longer about "low precision", but about which
API is faster.

regards, tom lane

#60Thomas Munro
thomas.munro@gmail.com
In reply to: Tom Lane (#59)
Re: Cleaning up historical portability baggage

On Mon, Aug 8, 2022 at 12:27 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:

BTW, that commit really should have updated the explanation at the top of
instr_time.h:

* This file provides an abstraction layer to hide portability issues in
* interval timing. On Unix we use clock_gettime() if available, else
* gettimeofday(). On Windows, gettimeofday() gives a low-precision result
* so we must use QueryPerformanceCounter() instead. These macros also give
* some breathing room to use other high-precision-timing APIs.

Updating the second sentence is easy enough, but as for the third,
I wonder if it's still true in view of 24c3ce8f1. Should we revisit
whether to use gettimeofday vs. QueryPerformanceCounter? At the very
least I suspect it's no longer about "low precision", but about which
API is faster.

Yeah, that's not true anymore, and QueryPerformanceCounter() is faster
than Get­System­Time­Precise­As­File­Time()[1]https://devblogs.microsoft.com/oldnewthing/20170921-00/?p=97057, but there doesn't
really seem to be any point in mentioning that or gettimeofday() at
all here. I propose to cut it down to just:

  * This file provides an abstraction layer to hide portability issues in
- * interval timing.  On Unix we use clock_gettime() if available, else
- * gettimeofday().  On Windows, gettimeofday() gives a low-precision result
- * so we must use QueryPerformanceCounter() instead.  These macros also give
- * some breathing room to use other high-precision-timing APIs.
+ * interval timing.  On Unix we use clock_gettime(), and on Windows we use
+ * QueryPerformanceCounter().  These macros also give some breathing room to
+ * use other high-precision-timing APIs.

FWIW I expect this stuff to get whacked around some more for v16[2]https://commitfest.postgresql.org/39/3751/.

[1]: https://devblogs.microsoft.com/oldnewthing/20170921-00/?p=97057
[2]: https://commitfest.postgresql.org/39/3751/

#61Tom Lane
tgl@sss.pgh.pa.us
In reply to: Thomas Munro (#60)
Re: Cleaning up historical portability baggage

Thomas Munro <thomas.munro@gmail.com> writes:

Yeah, that's not true anymore, and QueryPerformanceCounter() is faster
than Get­System­Time­Precise­As­File­Time()[1], but there doesn't
really seem to be any point in mentioning that or gettimeofday() at
all here. I propose to cut it down to just:

* This file provides an abstraction layer to hide portability issues in
- * interval timing.  On Unix we use clock_gettime() if available, else
- * gettimeofday().  On Windows, gettimeofday() gives a low-precision result
- * so we must use QueryPerformanceCounter() instead.  These macros also give
- * some breathing room to use other high-precision-timing APIs.
+ * interval timing.  On Unix we use clock_gettime(), and on Windows we use
+ * QueryPerformanceCounter().  These macros also give some breathing room to
+ * use other high-precision-timing APIs.

WFM.

FWIW I expect this stuff to get whacked around some more for v16[2].
[2] https://commitfest.postgresql.org/39/3751/

Meh. I think trying to use rdtsc is a fool's errand; you'll be fighting
CPU quirks forever.

regards, tom lane

#62Thomas Munro
thomas.munro@gmail.com
In reply to: Tom Lane (#61)
6 attachment(s)
Re: Cleaning up historical portability baggage

Here's a new batch of these:

Remove configure probe for sys/uio.h.
Remove configure probes for sys/un.h and struct sockaddr_un.
Remove configure probe for sys/select.h.
Remove configure probes for sys/ipc.h, sys/sem.h, sys/shm.h.
Remove configure probe for sys/resource.h and refactor.
Remove configure probe for shl_load library.

The most interesting things to say about these ones are:
* The concept of a no-Unix-socket build is removed. We should be
able to do that now, right? Peter E seemed to say approximately that
in the commit message for 797129e5. Or is there a thought that a new
operating system might show up that doesn't have 'em and we'd wish
we'd kept this stuff well marked out?
* Instead of eg HAVE_SYS_RESOURCE_H I supplied <sys/resource.h> and
moved the relevant declarations there from the big random-win2-stuff
header, and likewise for <sys/un.h>

(I still plan to get rid of no-threads-builds soon, but I got stuck
figuring out how to make sure I don't break the recent magic ldap
library detection... more soon.)

Attachments:

0001-Remove-configure-probe-for-sys-uio.h.patchapplication/octet-stream; name=0001-Remove-configure-probe-for-sys-uio.h.patchDownload
From 85584131bc1fcde2e54984f853b79b23a5331a43 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Thu, 11 Aug 2022 14:19:38 +1200
Subject: [PATCH 1/7] Remove configure probe for sys/uio.h.

<sys/uio.h> is in SUSv2, and all targeted Unix system have it, so we
might as well drop the probe (in fact we never really needed this one,
as even HP-UX 10.20 had it).  It's where struct iovec is defined, and as
a common extension, it's also where non-standard preadv() and pwritev()
are declared on systems that have it.

It's a little confusing so let's spell what our pg_iovec.h header does
for the OSes in the build farm today:

Windows: defines our own struct and declares our own functions
Solaris: includes sys/uio.h for the struct and declares our own functions
Every other targeted Unix: includes sys/uio.h for the struct and the functions
---
 configure                   |  2 +-
 configure.ac                |  1 -
 src/include/pg_config.h.in  |  3 ---
 src/include/port/pg_iovec.h | 20 ++++++++------------
 src/tools/msvc/Solution.pm  |  1 -
 5 files changed, 9 insertions(+), 18 deletions(-)

diff --git a/configure b/configure
index cf2c4b85fe..ef5334a12d 100755
--- a/configure
+++ b/configure
@@ -13874,7 +13874,7 @@ $as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h
 fi
 
 
-for ac_header in atomic.h copyfile.h execinfo.h getopt.h ifaddrs.h langinfo.h mbarrier.h net/if.h netinet/tcp.h sys/epoll.h sys/event.h sys/ipc.h sys/personality.h sys/prctl.h sys/procctl.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/signalfd.h sys/sockio.h sys/ucred.h sys/uio.h sys/un.h termios.h ucred.h
+for ac_header in atomic.h copyfile.h execinfo.h getopt.h ifaddrs.h langinfo.h mbarrier.h net/if.h netinet/tcp.h sys/epoll.h sys/event.h sys/ipc.h sys/personality.h sys/prctl.h sys/procctl.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/signalfd.h sys/sockio.h sys/ucred.h sys/un.h termios.h ucred.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
diff --git a/configure.ac b/configure.ac
index b5798bcb0a..c1b75e0f34 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1467,7 +1467,6 @@ AC_CHECK_HEADERS(m4_normalize([
 	sys/signalfd.h
 	sys/sockio.h
 	sys/ucred.h
-	sys/uio.h
 	sys/un.h
 	termios.h
 	ucred.h
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index fc5ad5fd65..ed6185343e 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -538,9 +538,6 @@
 /* Define to 1 if you have the <sys/ucred.h> header file. */
 #undef HAVE_SYS_UCRED_H
 
-/* Define to 1 if you have the <sys/uio.h> header file. */
-#undef HAVE_SYS_UIO_H
-
 /* Define to 1 if you have the <sys/un.h> header file. */
 #undef HAVE_SYS_UN_H
 
diff --git a/src/include/port/pg_iovec.h b/src/include/port/pg_iovec.h
index f0a50c0e01..ecdddba7fc 100644
--- a/src/include/port/pg_iovec.h
+++ b/src/include/port/pg_iovec.h
@@ -13,27 +13,23 @@
 #ifndef PG_IOVEC_H
 #define PG_IOVEC_H
 
-#include <limits.h>
+#ifndef WIN32
 
-#ifdef HAVE_SYS_UIO_H
+#include <limits.h>
 #include <sys/uio.h>
-#endif
 
-/* If <sys/uio.h> is missing, define our own POSIX-compatible iovec struct. */
-#ifndef HAVE_SYS_UIO_H
+#else
+
+/* POSIX requires at least 16 as a maximum iovcnt. */
+#define IOV_MAX 16
+
+/* Define our own POSIX-compatible iovec struct. */
 struct iovec
 {
 	void	   *iov_base;
 	size_t		iov_len;
 };
-#endif
 
-/*
- * If <limits.h> didn't define IOV_MAX, define our own.  POSIX requires at
- * least 16.
- */
-#ifndef IOV_MAX
-#define IOV_MAX 16
 #endif
 
 /* Define a reasonable maximum that is safe to use on the stack. */
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index cc82668457..741998a103 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -375,7 +375,6 @@ sub GenerateFiles
 		HAVE_SYS_STAT_H                          => 1,
 		HAVE_SYS_TYPES_H                         => 1,
 		HAVE_SYS_UCRED_H                         => undef,
-		HAVE_SYS_UIO_H                           => undef,
 		HAVE_SYS_UN_H                            => undef,
 		HAVE_TERMIOS_H                           => undef,
 		HAVE_TYPEOF                              => undef,
-- 
2.32.1 (Apple Git-133)

0002-Remove-configure-probes-for-sys-un.h-and-struct-sock.patchapplication/octet-stream; name=0002-Remove-configure-probes-for-sys-un.h-and-struct-sock.patchDownload
From df84d3160c2917981c62dc3a6f3fd6cde5486b7e Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Thu, 11 Aug 2022 15:30:38 +1200
Subject: [PATCH 2/7] Remove configure probes for sys/un.h and struct
 sockaddr_un.

<sys/un.h> and the struct it defines are in SUSv2 and every targeted
Unix has it.  Windows doesn't, you have to define it yourself, but we do
that.  To avoid the need to make the #include conditional, move our
definition into src/include/port/win32/sys/un.h.

This implies that we can also get rid of HAVE_UNIX_SOCKETS, since we
always have them, even on Windows.  We can therefore drop some
conditional branches and a small amount of dead code.
---
 config/c-library.m4                 | 14 ----------
 configure                           | 17 +-----------
 configure.ac                        |  2 --
 src/backend/libpq/hba.c             | 10 -------
 src/backend/libpq/pqcomm.c          | 18 -------------
 src/backend/postmaster/postmaster.c |  2 --
 src/backend/utils/misc/guc.c        |  4 ---
 src/bin/initdb/initdb.c             | 41 -----------------------------
 src/bin/pg_upgrade/option.c         |  4 +--
 src/bin/pg_upgrade/server.c         |  2 +-
 src/common/ip.c                     | 11 --------
 src/include/c.h                     |  4 ---
 src/include/libpq/pqcomm.h          |  4 +--
 src/include/pg_config.h.in          |  6 -----
 src/include/port/win32.h            | 11 --------
 src/include/port/win32/sys/un.h     | 17 ++++++++++++
 src/interfaces/libpq/fe-connect.c   | 12 ---------
 src/port/getpeereid.c               |  4 +--
 src/test/regress/pg_regress.c       | 19 ++-----------
 src/tools/msvc/Solution.pm          |  2 --
 20 files changed, 25 insertions(+), 179 deletions(-)
 create mode 100644 src/include/port/win32/sys/un.h

diff --git a/config/c-library.m4 b/config/c-library.m4
index 35fdc63afe..76552ac6ed 100644
--- a/config/c-library.m4
+++ b/config/c-library.m4
@@ -76,20 +76,6 @@ AC_DEFUN([PGAC_UNION_SEMUN],
 #endif])])# PGAC_UNION_SEMUN
 
 
-# PGAC_STRUCT_SOCKADDR_UN
-# -----------------------
-# If `struct sockaddr_un' exists, define HAVE_STRUCT_SOCKADDR_UN.
-# If it is missing then one could define it.
-# (Requires test for <sys/un.h>!)
-AC_DEFUN([PGAC_STRUCT_SOCKADDR_UN],
-[AC_CHECK_TYPES([struct sockaddr_un], [], [],
-[#include <sys/types.h>
-#ifdef HAVE_SYS_UN_H
-#include <sys/un.h>
-#endif
-])])# PGAC_STRUCT_SOCKADDR_UN
-
-
 # PGAC_STRUCT_SOCKADDR_STORAGE
 # ----------------------------
 # If `struct sockaddr_storage' exists, define HAVE_STRUCT_SOCKADDR_STORAGE.
diff --git a/configure b/configure
index ef5334a12d..b0bc818af8 100755
--- a/configure
+++ b/configure
@@ -13874,7 +13874,7 @@ $as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h
 fi
 
 
-for ac_header in atomic.h copyfile.h execinfo.h getopt.h ifaddrs.h langinfo.h mbarrier.h net/if.h netinet/tcp.h sys/epoll.h sys/event.h sys/ipc.h sys/personality.h sys/prctl.h sys/procctl.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/signalfd.h sys/sockio.h sys/ucred.h sys/un.h termios.h ucred.h
+for ac_header in atomic.h copyfile.h execinfo.h getopt.h ifaddrs.h langinfo.h mbarrier.h net/if.h netinet/tcp.h sys/epoll.h sys/event.h sys/ipc.h sys/personality.h sys/prctl.h sys/procctl.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/signalfd.h sys/sockio.h sys/ucred.h termios.h ucred.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@@ -15117,21 +15117,6 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
-fi
-
-ac_fn_c_check_type "$LINENO" "struct sockaddr_un" "ac_cv_type_struct_sockaddr_un" "#include <sys/types.h>
-#ifdef HAVE_SYS_UN_H
-#include <sys/un.h>
-#endif
-
-"
-if test "x$ac_cv_type_struct_sockaddr_un" = xyes; then :
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_STRUCT_SOCKADDR_UN 1
-_ACEOF
-
-
 fi
 
 ac_fn_c_check_type "$LINENO" "struct sockaddr_storage" "ac_cv_type_struct_sockaddr_storage" "#include <sys/types.h>
diff --git a/configure.ac b/configure.ac
index c1b75e0f34..666ad7dbcb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1467,7 +1467,6 @@ AC_CHECK_HEADERS(m4_normalize([
 	sys/signalfd.h
 	sys/sockio.h
 	sys/ucred.h
-	sys/un.h
 	termios.h
 	ucred.h
 ]))
@@ -1625,7 +1624,6 @@ PGAC_C_COMPUTED_GOTO
 PGAC_STRUCT_TIMEZONE
 PGAC_UNION_SEMUN
 AC_CHECK_TYPES(socklen_t, [], [], [#include <sys/socket.h>])
-PGAC_STRUCT_SOCKADDR_UN
 PGAC_STRUCT_SOCKADDR_STORAGE
 PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS
 PGAC_STRUCT_ADDRINFO
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index deee05c197..66f2156cde 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -973,17 +973,7 @@ parse_hba_line(TokenizedAuthLine *tok_line, int elevel)
 	token = linitial(tokens);
 	if (strcmp(token->string, "local") == 0)
 	{
-#ifdef HAVE_UNIX_SOCKETS
 		parsedline->conntype = ctLocal;
-#else
-		ereport(elevel,
-				(errcode(ERRCODE_CONFIG_FILE_ERROR),
-				 errmsg("local connections are not supported by this build"),
-				 errcontext("line %d of configuration file \"%s\"",
-							line_num, HbaFileName)));
-		*err_msg = "local connections are not supported by this build";
-		return NULL;
-#endif
 	}
 	else if (strcmp(token->string, "host") == 0 ||
 			 strcmp(token->string, "hostssl") == 0 ||
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 75392a8bb7..3ec4328613 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -149,10 +149,8 @@ static void socket_putmessage_noblock(char msgtype, const char *s, size_t len);
 static int	internal_putbytes(const char *s, size_t len);
 static int	internal_flush(void);
 
-#ifdef HAVE_UNIX_SOCKETS
 static int	Lock_AF_UNIX(const char *unixSocketDir, const char *unixSocketPath);
 static int	Setup_AF_UNIX(const char *sock_path);
-#endif							/* HAVE_UNIX_SOCKETS */
 
 static const PQcommMethods PqCommSocketMethods = {
 	socket_comm_reset,
@@ -334,10 +332,7 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
 	struct addrinfo hint;
 	int			listen_index = 0;
 	int			added = 0;
-
-#ifdef HAVE_UNIX_SOCKETS
 	char		unixSocketPath[MAXPGPATH];
-#endif
 #if !defined(WIN32) || defined(IPV6_V6ONLY)
 	int			one = 1;
 #endif
@@ -348,7 +343,6 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
 	hint.ai_flags = AI_PASSIVE;
 	hint.ai_socktype = SOCK_STREAM;
 
-#ifdef HAVE_UNIX_SOCKETS
 	if (family == AF_UNIX)
 	{
 		/*
@@ -369,7 +363,6 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
 		service = unixSocketPath;
 	}
 	else
-#endif							/* HAVE_UNIX_SOCKETS */
 	{
 		snprintf(portNumberStr, sizeof(portNumberStr), "%d", portNumber);
 		service = portNumberStr;
@@ -427,11 +420,9 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
 				familyDesc = _("IPv6");
 				break;
 #endif
-#ifdef HAVE_UNIX_SOCKETS
 			case AF_UNIX:
 				familyDesc = _("Unix");
 				break;
-#endif
 			default:
 				snprintf(familyDescBuf, sizeof(familyDescBuf),
 						 _("unrecognized address family %d"),
@@ -441,11 +432,9 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
 		}
 
 		/* set up text form of address for log messages */
-#ifdef HAVE_UNIX_SOCKETS
 		if (addr->ai_family == AF_UNIX)
 			addrDesc = unixSocketPath;
 		else
-#endif
 		{
 			pg_getnameinfo_all((const struct sockaddr_storage *) addr->ai_addr,
 							   addr->ai_addrlen,
@@ -540,7 +529,6 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
 			continue;
 		}
 
-#ifdef HAVE_UNIX_SOCKETS
 		if (addr->ai_family == AF_UNIX)
 		{
 			if (Setup_AF_UNIX(service) != STATUS_OK)
@@ -549,7 +537,6 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
 				break;
 			}
 		}
-#endif
 
 		/*
 		 * Select appropriate accept-queue length limit.  PG_SOMAXCONN is only
@@ -572,13 +559,11 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
 			continue;
 		}
 
-#ifdef HAVE_UNIX_SOCKETS
 		if (addr->ai_family == AF_UNIX)
 			ereport(LOG,
 					(errmsg("listening on Unix socket \"%s\"",
 							addrDesc)));
 		else
-#endif
 			ereport(LOG,
 			/* translator: first %s is IPv4 or IPv6 */
 					(errmsg("listening on %s address \"%s\", port %d",
@@ -597,8 +582,6 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
 }
 
 
-#ifdef HAVE_UNIX_SOCKETS
-
 /*
  * Lock_AF_UNIX -- configure unix socket file path
  */
@@ -699,7 +682,6 @@ Setup_AF_UNIX(const char *sock_path)
 	}
 	return STATUS_OK;
 }
-#endif							/* HAVE_UNIX_SOCKETS */
 
 
 /*
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 81cb585891..a85b32db69 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -1300,7 +1300,6 @@ PostmasterMain(int argc, char *argv[])
 	}
 #endif
 
-#ifdef HAVE_UNIX_SOCKETS
 	if (Unix_socket_directories)
 	{
 		char	   *rawstring;
@@ -1350,7 +1349,6 @@ PostmasterMain(int argc, char *argv[])
 		list_free_deep(elemlist);
 		pfree(rawstring);
 	}
-#endif
 
 	/*
 	 * check that we have some socket to listen on
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 5db5df6285..9fbbfb1be5 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -4452,11 +4452,7 @@ static struct config_string ConfigureNamesString[] =
 			GUC_LIST_INPUT | GUC_LIST_QUOTE | GUC_SUPERUSER_ONLY
 		},
 		&Unix_socket_directories,
-#ifdef HAVE_UNIX_SOCKETS
 		DEFAULT_PGSOCKET_DIR,
-#else
-		"",
-#endif
 		NULL, NULL, NULL
 	},
 
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 2c93ffe811..4feb5db3fa 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -242,9 +242,6 @@ static char backend_exec[MAXPGPATH];
 static char **replace_token(char **lines,
 							const char *token, const char *replacement);
 
-#ifndef HAVE_UNIX_SOCKETS
-static char **filter_lines_with_token(char **lines, const char *token);
-#endif
 static char **readfile(const char *path);
 static void writefile(char *path, char **lines);
 static FILE *popen_check(const char *command, const char *mode);
@@ -418,36 +415,6 @@ replace_token(char **lines, const char *token, const char *replacement)
 	return result;
 }
 
-/*
- * make a copy of lines without any that contain the token
- *
- * a sort of poor man's grep -v
- */
-#ifndef HAVE_UNIX_SOCKETS
-static char **
-filter_lines_with_token(char **lines, const char *token)
-{
-	int			numlines = 1;
-	int			i,
-				src,
-				dst;
-	char	  **result;
-
-	for (i = 0; lines[i]; i++)
-		numlines++;
-
-	result = (char **) pg_malloc(numlines * sizeof(char *));
-
-	for (src = 0, dst = 0; src < numlines; src++)
-	{
-		if (lines[src] == NULL || strstr(lines[src], token) == NULL)
-			result[dst++] = lines[src];
-	}
-
-	return result;
-}
-#endif
-
 /*
  * get the lines from a text file
  */
@@ -1045,12 +1012,8 @@ setup_config(void)
 				 n_buffers * (BLCKSZ / 1024));
 	conflines = replace_token(conflines, "#shared_buffers = 128MB", repltok);
 
-#ifdef HAVE_UNIX_SOCKETS
 	snprintf(repltok, sizeof(repltok), "#unix_socket_directories = '%s'",
 			 DEFAULT_PGSOCKET_DIR);
-#else
-	snprintf(repltok, sizeof(repltok), "#unix_socket_directories = ''");
-#endif
 	conflines = replace_token(conflines, "#unix_socket_directories = '/tmp'",
 							  repltok);
 
@@ -1210,11 +1173,7 @@ setup_config(void)
 
 	conflines = readfile(hba_file);
 
-#ifndef HAVE_UNIX_SOCKETS
-	conflines = filter_lines_with_token(conflines, "@remove-line-for-nolocal@");
-#else
 	conflines = replace_token(conflines, "@remove-line-for-nolocal@", "");
-#endif
 
 #ifdef HAVE_IPV6
 
diff --git a/src/bin/pg_upgrade/option.c b/src/bin/pg_upgrade/option.c
index 0954b75ec0..fbab1c4fb7 100644
--- a/src/bin/pg_upgrade/option.c
+++ b/src/bin/pg_upgrade/option.c
@@ -444,7 +444,7 @@ adjust_data_dir(ClusterInfo *cluster)
 void
 get_sock_dir(ClusterInfo *cluster, bool live_check)
 {
-#if defined(HAVE_UNIX_SOCKETS) && !defined(WIN32)
+#if !defined(WIN32)
 	if (!live_check)
 		cluster->sockdir = user_opts.socketdir;
 	else
@@ -490,7 +490,7 @@ get_sock_dir(ClusterInfo *cluster, bool live_check)
 			pg_log(PG_WARNING, "user-supplied old port number %hu corrected to %hu",
 				   orig_port, cluster->port);
 	}
-#else							/* !HAVE_UNIX_SOCKETS || WIN32 */
+#else							/* WIN32 */
 	cluster->sockdir = NULL;
 #endif
 }
diff --git a/src/bin/pg_upgrade/server.c b/src/bin/pg_upgrade/server.c
index 79479edc0e..9a1a20fb27 100644
--- a/src/bin/pg_upgrade/server.c
+++ b/src/bin/pg_upgrade/server.c
@@ -212,7 +212,7 @@ start_postmaster(ClusterInfo *cluster, bool report_and_exit_on_error)
 
 	socket_string[0] = '\0';
 
-#if defined(HAVE_UNIX_SOCKETS) && !defined(WIN32)
+#if !defined(WIN32)
 	/* prevent TCP/IP connections, restrict socket access */
 	strcat(socket_string,
 		   " -c listen_addresses='' -c unix_socket_permissions=0700");
diff --git a/src/common/ip.c b/src/common/ip.c
index 267103efb9..dd9193feb1 100644
--- a/src/common/ip.c
+++ b/src/common/ip.c
@@ -38,7 +38,6 @@
 
 
 
-#ifdef	HAVE_UNIX_SOCKETS
 static int	getaddrinfo_unix(const char *path,
 							 const struct addrinfo *hintsp,
 							 struct addrinfo **result);
@@ -47,7 +46,6 @@ static int	getnameinfo_unix(const struct sockaddr_un *sa, int salen,
 							 char *node, int nodelen,
 							 char *service, int servicelen,
 							 int flags);
-#endif
 
 
 /*
@@ -62,10 +60,8 @@ pg_getaddrinfo_all(const char *hostname, const char *servname,
 	/* not all versions of getaddrinfo() zero *result on failure */
 	*result = NULL;
 
-#ifdef HAVE_UNIX_SOCKETS
 	if (hintp->ai_family == AF_UNIX)
 		return getaddrinfo_unix(servname, hintp, result);
-#endif
 
 	/* NULL has special meaning to getaddrinfo(). */
 	rc = getaddrinfo((!hostname || hostname[0] == '\0') ? NULL : hostname,
@@ -87,7 +83,6 @@ pg_getaddrinfo_all(const char *hostname, const char *servname,
 void
 pg_freeaddrinfo_all(int hint_ai_family, struct addrinfo *ai)
 {
-#ifdef HAVE_UNIX_SOCKETS
 	if (hint_ai_family == AF_UNIX)
 	{
 		/* struct was built by getaddrinfo_unix (see pg_getaddrinfo_all) */
@@ -101,7 +96,6 @@ pg_freeaddrinfo_all(int hint_ai_family, struct addrinfo *ai)
 		}
 	}
 	else
-#endif							/* HAVE_UNIX_SOCKETS */
 	{
 		/* struct was built by getaddrinfo() */
 		if (ai != NULL)
@@ -126,14 +120,12 @@ pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen,
 {
 	int			rc;
 
-#ifdef HAVE_UNIX_SOCKETS
 	if (addr && addr->ss_family == AF_UNIX)
 		rc = getnameinfo_unix((const struct sockaddr_un *) addr, salen,
 							  node, nodelen,
 							  service, servicelen,
 							  flags);
 	else
-#endif
 		rc = getnameinfo((const struct sockaddr *) addr, salen,
 						 node, nodelen,
 						 service, servicelen,
@@ -151,8 +143,6 @@ pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen,
 }
 
 
-#if defined(HAVE_UNIX_SOCKETS)
-
 /* -------
  *	getaddrinfo_unix - get unix socket info using IPv6-compatible API
  *
@@ -286,4 +276,3 @@ getnameinfo_unix(const struct sockaddr_un *sa, int salen,
 
 	return 0;
 }
-#endif							/* HAVE_UNIX_SOCKETS */
diff --git a/src/include/c.h b/src/include/c.h
index de9ec04d49..65e91a6b89 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -1113,10 +1113,6 @@ extern void ExceptionalCondition(const char *conditionName,
  * ----------------------------------------------------------------
  */
 
-#ifdef HAVE_STRUCT_SOCKADDR_UN
-#define HAVE_UNIX_SOCKETS 1
-#endif
-
 /*
  * Invert the sign of a qsort-style comparison result, ie, exchange negative
  * and positive integer values, being careful not to get the wrong answer
diff --git a/src/include/libpq/pqcomm.h b/src/include/libpq/pqcomm.h
index b418283d5f..3bcc06b2d6 100644
--- a/src/include/libpq/pqcomm.h
+++ b/src/include/libpq/pqcomm.h
@@ -17,10 +17,8 @@
 #define PQCOMM_H
 
 #include <sys/socket.h>
-#include <netdb.h>
-#ifdef HAVE_SYS_UN_H
 #include <sys/un.h>
-#endif
+#include <netdb.h>
 #include <netinet/in.h>
 
 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index ed6185343e..b6c73ccd71 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -478,9 +478,6 @@
 /* Define to 1 if `__ss_len' is a member of `struct sockaddr_storage'. */
 #undef HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN
 
-/* Define to 1 if the system has the type `struct sockaddr_un'. */
-#undef HAVE_STRUCT_SOCKADDR_UN
-
 /* Define to 1 if `tm_zone' is a member of `struct tm'. */
 #undef HAVE_STRUCT_TM_TM_ZONE
 
@@ -538,9 +535,6 @@
 /* Define to 1 if you have the <sys/ucred.h> header file. */
 #undef HAVE_SYS_UCRED_H
 
-/* Define to 1 if you have the <sys/un.h> header file. */
-#undef HAVE_SYS_UN_H
-
 /* Define to 1 if you have the <termios.h> header file. */
 #undef HAVE_TERMIOS_H
 
diff --git a/src/include/port/win32.h b/src/include/port/win32.h
index 5f3b17a500..67755aadc4 100644
--- a/src/include/port/win32.h
+++ b/src/include/port/win32.h
@@ -55,14 +55,3 @@
 #ifdef _MSC_VER
 #define PGDLLEXPORT __declspec (dllexport)
 #endif
-
-/*
- * Windows headers don't define this structure, but you can define it yourself
- * to use the functionality.
- */
-struct sockaddr_un
-{
-	unsigned short sun_family;
-	char		sun_path[108];
-};
-#define HAVE_STRUCT_SOCKADDR_UN 1
diff --git a/src/include/port/win32/sys/un.h b/src/include/port/win32/sys/un.h
new file mode 100644
index 0000000000..aec0c4a1a7
--- /dev/null
+++ b/src/include/port/win32/sys/un.h
@@ -0,0 +1,17 @@
+/*
+ * src/include/port/win32/sys/un.h
+ */
+#ifndef WIN32_SYS_UN_H
+#define WIN32_SYS_UN_H
+
+/*
+ * Windows headers don't define this structure, but you can define it yourself
+ * to use the functionality.
+ */
+struct sockaddr_un
+{
+	unsigned short sun_family;
+	char		sun_path[108];
+};
+
+#endif
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index dc49387d6c..730e79a31d 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -1102,10 +1102,8 @@ connectOptions2(PGconn *conn)
 		else if (ch->host != NULL && ch->host[0] != '\0')
 		{
 			ch->type = CHT_HOST_NAME;
-#ifdef HAVE_UNIX_SOCKETS
 			if (is_unixsock_path(ch->host))
 				ch->type = CHT_UNIX_SOCKET;
-#endif
 		}
 		else
 		{
@@ -1115,14 +1113,12 @@ connectOptions2(PGconn *conn)
 			 * This bit selects the default host location.  If you change
 			 * this, see also pg_regress.
 			 */
-#ifdef HAVE_UNIX_SOCKETS
 			if (DEFAULT_PGSOCKET_DIR[0])
 			{
 				ch->host = strdup(DEFAULT_PGSOCKET_DIR);
 				ch->type = CHT_UNIX_SOCKET;
 			}
 			else
-#endif
 			{
 				ch->host = strdup(DefaultHost);
 				ch->type = CHT_HOST_NAME;
@@ -1684,7 +1680,6 @@ getHostaddr(PGconn *conn, char *host_addr, int host_addr_len)
 static void
 emitHostIdentityInfo(PGconn *conn, const char *host_addr)
 {
-#ifdef HAVE_UNIX_SOCKETS
 	if (conn->raddr.addr.ss_family == AF_UNIX)
 	{
 		char		service[NI_MAXHOST];
@@ -1698,7 +1693,6 @@ emitHostIdentityInfo(PGconn *conn, const char *host_addr)
 						  service);
 	}
 	else
-#endif							/* HAVE_UNIX_SOCKETS */
 	{
 		const char *displayed_host;
 		const char *displayed_port;
@@ -1748,12 +1742,10 @@ connectFailureMessage(PGconn *conn, int errorno)
 					  "%s\n",
 					  SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)));
 
-#ifdef HAVE_UNIX_SOCKETS
 	if (conn->raddr.addr.ss_family == AF_UNIX)
 		appendPQExpBufferStr(&conn->errorMessage,
 							 libpq_gettext("\tIs the server running locally and accepting connections on that socket?\n"));
 	else
-#endif
 		appendPQExpBufferStr(&conn->errorMessage,
 							 libpq_gettext("\tIs the server running on that host and accepting TCP/IP connections?\n"));
 }
@@ -2415,7 +2407,6 @@ keep_going:						/* We will come back to here until there is
 				break;
 
 			case CHT_UNIX_SOCKET:
-#ifdef HAVE_UNIX_SOCKETS
 				conn->addrlist_family = hint.ai_family = AF_UNIX;
 				UNIXSOCK_PATH(portstr, thisport, ch->host);
 				if (strlen(portstr) >= UNIXSOCK_PATH_BUFLEN)
@@ -2440,9 +2431,6 @@ keep_going:						/* We will come back to here until there is
 									  portstr, gai_strerror(ret));
 					goto keep_going;
 				}
-#else
-				Assert(false);
-#endif
 				break;
 		}
 
diff --git a/src/port/getpeereid.c b/src/port/getpeereid.c
index 56ae141040..0bb07782ba 100644
--- a/src/port/getpeereid.c
+++ b/src/port/getpeereid.c
@@ -16,10 +16,8 @@
 
 #include <sys/param.h>
 #include <sys/socket.h>
-#include <unistd.h>
-#ifdef HAVE_SYS_UN_H
 #include <sys/un.h>
-#endif
+#include <unistd.h>
 #ifdef HAVE_UCRED_H
 #include <ucred.h>
 #endif
diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c
index 04ab513b7c..b7aa5752f4 100644
--- a/src/test/regress/pg_regress.c
+++ b/src/test/regress/pg_regress.c
@@ -102,11 +102,9 @@ static char *logfilename;
 static FILE *logfile;
 static char *difffilename;
 static const char *sockdir;
-#ifdef HAVE_UNIX_SOCKETS
 static const char *temp_sockdir;
 static char sockself[MAXPGPATH];
 static char socklock[MAXPGPATH];
-#endif
 
 static _resultmap *resultmap = NULL;
 
@@ -288,7 +286,6 @@ stop_postmaster(void)
 	}
 }
 
-#ifdef HAVE_UNIX_SOCKETS
 /*
  * Remove the socket temporary directory.  pg_regress never waits for a
  * postmaster exit, so it is indeterminate whether the postmaster has yet to
@@ -363,7 +360,6 @@ make_temp_sockdir(void)
 
 	return temp_sockdir;
 }
-#endif							/* HAVE_UNIX_SOCKETS */
 
 /*
  * Check whether string matches pattern
@@ -686,7 +682,6 @@ initialize_environment(void)
 		/* PGPORT, see below */
 		/* PGHOST, see below */
 
-#ifdef HAVE_UNIX_SOCKETS
 		if (hostname != NULL)
 			setenv("PGHOST", hostname, 1);
 		else
@@ -696,10 +691,6 @@ initialize_environment(void)
 				sockdir = make_temp_sockdir();
 			setenv("PGHOST", sockdir, 1);
 		}
-#else
-		Assert(hostname != NULL);
-		setenv("PGHOST", hostname, 1);
-#endif
 		unsetenv("PGHOSTADDR");
 		if (port != -1)
 		{
@@ -749,11 +740,9 @@ initialize_environment(void)
 		if (!pghost)
 		{
 			/* Keep this bit in sync with libpq's default host location: */
-#ifdef HAVE_UNIX_SOCKETS
 			if (DEFAULT_PGSOCKET_DIR[0])
 				 /* do nothing, we'll print "Unix socket" below */ ;
 			else
-#endif
 				pghost = "localhost";	/* DefaultHost in fe-connect.c */
 		}
 
@@ -2071,9 +2060,7 @@ regression_main(int argc, char *argv[],
 
 	atexit(stop_postmaster);
 
-#if !defined(HAVE_UNIX_SOCKETS)
-	use_unix_sockets = false;
-#elif defined(WIN32)
+#if defined(WIN32)
 
 	/*
 	 * We don't use Unix-domain sockets on Windows by default, even if the
@@ -2212,7 +2199,7 @@ regression_main(int argc, char *argv[],
 		/*
 		 * To reduce chances of interference with parallel installations, use
 		 * a port number starting in the private range (49152-65535)
-		 * calculated from the version number.  This aids !HAVE_UNIX_SOCKETS
+		 * calculated from the version number.  This aids non-Unix socket mode
 		 * systems; elsewhere, the use of a private socket directory already
 		 * prevents interference.
 		 */
@@ -2332,8 +2319,6 @@ regression_main(int argc, char *argv[],
 			snprintf(buf, sizeof(buf), "%s/data", temp_instance);
 			config_sspi_auth(buf, NULL);
 		}
-#elif !defined(HAVE_UNIX_SOCKETS)
-#error Platform has no means to secure the test installation.
 #endif
 
 		/*
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 741998a103..ed437ce084 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -355,7 +355,6 @@ sub GenerateFiles
 		HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN      => undef,
 		HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY => undef,
 		HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN    => undef,
-		HAVE_STRUCT_SOCKADDR_UN                  => undef,
 		HAVE_STRUCT_TM_TM_ZONE                   => undef,
 		HAVE_SYNC_FILE_RANGE                     => undef,
 		HAVE_SYNCFS                              => undef,
@@ -375,7 +374,6 @@ sub GenerateFiles
 		HAVE_SYS_STAT_H                          => 1,
 		HAVE_SYS_TYPES_H                         => 1,
 		HAVE_SYS_UCRED_H                         => undef,
-		HAVE_SYS_UN_H                            => undef,
 		HAVE_TERMIOS_H                           => undef,
 		HAVE_TYPEOF                              => undef,
 		HAVE_UCRED_H                             => undef,
-- 
2.32.1 (Apple Git-133)

0003-Remove-configure-probe-for-sys-select.h.patchapplication/octet-stream; name=0003-Remove-configure-probe-for-sys-select.h.patchDownload
From d823b15b43a73a0ef99449daeb9b167264702feb Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Thu, 11 Aug 2022 15:59:48 +1200
Subject: [PATCH 3/7] Remove configure probe for sys/select.h.

<sys/select.h> is in SUSv3 (POSIX.1-2001) and every targeted Unix
system has it.  Provide an empty header in src/include/port/win32 so
that we can #include it unguarded even on Windows.
---
 configure                                        | 2 +-
 configure.ac                                     | 1 -
 doc/src/sgml/libpq.sgml                          | 4 +---
 src/backend/libpq/auth.c                         | 4 +---
 src/backend/postmaster/postmaster.c              | 5 +----
 src/backend/tcop/postgres.c                      | 4 +---
 src/bin/pg_basebackup/pg_basebackup.c            | 4 +---
 src/bin/pg_basebackup/pg_recvlogical.c           | 4 +---
 src/bin/pg_basebackup/receivelog.c               | 4 +---
 src/bin/pg_dump/parallel.c                       | 4 +---
 src/bin/pgbench/pgbench.c                        | 2 --
 src/fe_utils/parallel_slot.c                     | 2 --
 src/include/pg_config.h.in                       | 3 ---
 src/include/port/win32/sys/select.h              | 3 +++
 src/interfaces/libpq/fe-misc.c                   | 4 +---
 src/port/pgsleep.c                               | 4 +---
 src/test/examples/testlibpq2.c                   | 4 +---
 src/test/isolation/isolationtester.c             | 4 +---
 src/test/modules/libpq_pipeline/libpq_pipeline.c | 4 +---
 src/tools/msvc/Solution.pm                       | 1 -
 20 files changed, 17 insertions(+), 50 deletions(-)
 create mode 100644 src/include/port/win32/sys/select.h

diff --git a/configure b/configure
index b0bc818af8..804162e873 100755
--- a/configure
+++ b/configure
@@ -13874,7 +13874,7 @@ $as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h
 fi
 
 
-for ac_header in atomic.h copyfile.h execinfo.h getopt.h ifaddrs.h langinfo.h mbarrier.h net/if.h netinet/tcp.h sys/epoll.h sys/event.h sys/ipc.h sys/personality.h sys/prctl.h sys/procctl.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/signalfd.h sys/sockio.h sys/ucred.h termios.h ucred.h
+for ac_header in atomic.h copyfile.h execinfo.h getopt.h ifaddrs.h langinfo.h mbarrier.h net/if.h netinet/tcp.h sys/epoll.h sys/event.h sys/ipc.h sys/personality.h sys/prctl.h sys/procctl.h sys/resource.h sys/sem.h sys/shm.h sys/signalfd.h sys/sockio.h sys/ucred.h termios.h ucred.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
diff --git a/configure.ac b/configure.ac
index 666ad7dbcb..a9474fd8f3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1461,7 +1461,6 @@ AC_CHECK_HEADERS(m4_normalize([
 	sys/prctl.h
 	sys/procctl.h
 	sys/resource.h
-	sys/select.h
 	sys/sem.h
 	sys/shm.h
 	sys/signalfd.h
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 74456aa69d..fab602b37e 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -9211,11 +9211,9 @@ main(int argc, char **argv)
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
+#include <sys/select.h>
 #include <sys/time.h>
 #include <sys/types.h>
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
 
 #include "libpq-fe.h"
 
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index 2d9ab7edce..41d60e06d0 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -16,13 +16,11 @@
 #include "postgres.h"
 
 #include <sys/param.h>
+#include <sys/select.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <pwd.h>
 #include <unistd.h>
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
 
 #include "commands/user.h"
 #include "common/ip.h"
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index a85b32db69..8a038d1b2a 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -70,6 +70,7 @@
 #include <time.h>
 #include <sys/wait.h>
 #include <ctype.h>
+#include <sys/select.h>
 #include <sys/stat.h>
 #include <sys/socket.h>
 #include <fcntl.h>
@@ -77,10 +78,6 @@
 #include <netdb.h>
 #include <limits.h>
 
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-
 #ifdef USE_BONJOUR
 #include <dns_sd.h>
 #endif
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 11e802eba9..671edcb3c7 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -23,10 +23,8 @@
 #include <limits.h>
 #include <signal.h>
 #include <unistd.h>
-#include <sys/socket.h>
-#ifdef HAVE_SYS_SELECT_H
 #include <sys/select.h>
-#endif
+#include <sys/socket.h>
 #ifdef HAVE_SYS_RESOURCE_H
 #include <sys/time.h>
 #include <sys/resource.h>
diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c
index 49fcabbd2c..9ce30d43a4 100644
--- a/src/bin/pg_basebackup/pg_basebackup.c
+++ b/src/bin/pg_basebackup/pg_basebackup.c
@@ -16,13 +16,11 @@
 #include <unistd.h>
 #include <dirent.h>
 #include <limits.h>
+#include <sys/select.h>
 #include <sys/stat.h>
 #include <sys/wait.h>
 #include <signal.h>
 #include <time.h>
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
 #ifdef HAVE_LIBZ
 #include <zlib.h>
 #endif
diff --git a/src/bin/pg_basebackup/pg_recvlogical.c b/src/bin/pg_basebackup/pg_recvlogical.c
index b59ff23f61..2a4c8b130a 100644
--- a/src/bin/pg_basebackup/pg_recvlogical.c
+++ b/src/bin/pg_basebackup/pg_recvlogical.c
@@ -14,11 +14,9 @@
 
 #include <dirent.h>
 #include <limits.h>
+#include <sys/select.h>
 #include <sys/stat.h>
 #include <unistd.h>
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
 
 #include "access/xlog_internal.h"
 #include "common/fe_memutils.h"
diff --git a/src/bin/pg_basebackup/receivelog.c b/src/bin/pg_basebackup/receivelog.c
index ad866a7602..976d1e73b1 100644
--- a/src/bin/pg_basebackup/receivelog.c
+++ b/src/bin/pg_basebackup/receivelog.c
@@ -14,11 +14,9 @@
 
 #include "postgres_fe.h"
 
+#include <sys/select.h>
 #include <sys/stat.h>
 #include <unistd.h>
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
 
 #include "access/xlog_internal.h"
 #include "common/file_utils.h"
diff --git a/src/bin/pg_dump/parallel.c b/src/bin/pg_dump/parallel.c
index c9f6b86bb0..c8a70d9bc1 100644
--- a/src/bin/pg_dump/parallel.c
+++ b/src/bin/pg_dump/parallel.c
@@ -53,14 +53,12 @@
 #include "postgres_fe.h"
 
 #ifndef WIN32
+#include <sys/select.h>
 #include <sys/wait.h>
 #include <signal.h>
 #include <unistd.h>
 #include <fcntl.h>
 #endif
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
 
 #include "fe_utils/string_utils.h"
 #include "parallel.h"
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 0778656794..45606e944d 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -52,10 +52,8 @@
 #endif
 #else							/* no ppoll(), so use select() */
 #define POLL_USING_SELECT
-#ifdef HAVE_SYS_SELECT_H
 #include <sys/select.h>
 #endif
-#endif
 
 #include "common/int.h"
 #include "common/logging.h"
diff --git a/src/fe_utils/parallel_slot.c b/src/fe_utils/parallel_slot.c
index 684327885d..8bce8ca366 100644
--- a/src/fe_utils/parallel_slot.c
+++ b/src/fe_utils/parallel_slot.c
@@ -18,9 +18,7 @@
 
 #include "postgres_fe.h"
 
-#ifdef HAVE_SYS_SELECT_H
 #include <sys/select.h>
-#endif
 
 #include "common/logging.h"
 #include "fe_utils/cancel.h"
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index b6c73ccd71..f666b4173b 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -511,9 +511,6 @@
 /* Define to 1 if you have the <sys/resource.h> header file. */
 #undef HAVE_SYS_RESOURCE_H
 
-/* Define to 1 if you have the <sys/select.h> header file. */
-#undef HAVE_SYS_SELECT_H
-
 /* Define to 1 if you have the <sys/sem.h> header file. */
 #undef HAVE_SYS_SEM_H
 
diff --git a/src/include/port/win32/sys/select.h b/src/include/port/win32/sys/select.h
new file mode 100644
index 0000000000..f8a877accd
--- /dev/null
+++ b/src/include/port/win32/sys/select.h
@@ -0,0 +1,3 @@
+/*
+ * src/include/port/win32/sys/select.h
+ */
diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c
index d76bb3957a..795500c593 100644
--- a/src/interfaces/libpq/fe-misc.c
+++ b/src/interfaces/libpq/fe-misc.c
@@ -37,15 +37,13 @@
 #include "win32.h"
 #else
 #include <unistd.h>
+#include <sys/select.h>
 #include <sys/time.h>
 #endif
 
 #ifdef HAVE_POLL_H
 #include <poll.h>
 #endif
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
 
 #include "libpq-fe.h"
 #include "libpq-int.h"
diff --git a/src/port/pgsleep.c b/src/port/pgsleep.c
index a84e6ccb38..03f0fac07b 100644
--- a/src/port/pgsleep.c
+++ b/src/port/pgsleep.c
@@ -13,10 +13,8 @@
 #include "c.h"
 
 #include <unistd.h>
-#include <sys/time.h>
-#ifdef HAVE_SYS_SELECT_H
 #include <sys/select.h>
-#endif
+#include <sys/time.h>
 
 /*
  * In a Windows backend, we don't use this implementation, but rather
diff --git a/src/test/examples/testlibpq2.c b/src/test/examples/testlibpq2.c
index 6337b315a4..05ce8c3f13 100644
--- a/src/test/examples/testlibpq2.c
+++ b/src/test/examples/testlibpq2.c
@@ -32,11 +32,9 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
+#include <sys/select.h>
 #include <sys/time.h>
 #include <sys/types.h>
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
 
 #include "libpq-fe.h"
 
diff --git a/src/test/isolation/isolationtester.c b/src/test/isolation/isolationtester.c
index 095db8f35c..0a66235153 100644
--- a/src/test/isolation/isolationtester.c
+++ b/src/test/isolation/isolationtester.c
@@ -7,10 +7,8 @@
 
 #include "postgres_fe.h"
 
-#include <sys/time.h>
-#ifdef HAVE_SYS_SELECT_H
 #include <sys/select.h>
-#endif
+#include <sys/time.h>
 
 #include "datatype/timestamp.h"
 #include "isolationtester.h"
diff --git a/src/test/modules/libpq_pipeline/libpq_pipeline.c b/src/test/modules/libpq_pipeline/libpq_pipeline.c
index dc17898a61..0407c4a8c0 100644
--- a/src/test/modules/libpq_pipeline/libpq_pipeline.c
+++ b/src/test/modules/libpq_pipeline/libpq_pipeline.c
@@ -15,10 +15,8 @@
 
 #include "postgres_fe.h"
 
-#include <sys/time.h>
-#ifdef HAVE_SYS_SELECT_H
 #include <sys/select.h>
-#endif
+#include <sys/time.h>
 
 #include "catalog/pg_type_d.h"
 #include "common/fe_memutils.h"
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index ed437ce084..b552f439cc 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -366,7 +366,6 @@ sub GenerateFiles
 		HAVE_SYS_PRCTL_H                         => undef,
 		HAVE_SYS_PROCCTL_H                       => undef,
 		HAVE_SYS_RESOURCE_H                      => undef,
-		HAVE_SYS_SELECT_H                        => undef,
 		HAVE_SYS_SEM_H                           => undef,
 		HAVE_SYS_SHM_H                           => undef,
 		HAVE_SYS_SIGNALFD_H                      => undef,
-- 
2.32.1 (Apple Git-133)

0004-Remove-configure-probes-for-sys-ipc.h-sys-sem.h-sys-.patchapplication/octet-stream; name=0004-Remove-configure-probes-for-sys-ipc.h-sys-sem.h-sys-.patchDownload
From 3d1bde246a781b3533d5dc5476d7efadea960f5a Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Thu, 11 Aug 2022 16:10:07 +1200
Subject: [PATCH 4/7] Remove configure probes for sys/ipc.h, sys/sem.h,
 sys/shm.h.

These so called System V IPC facilities are in SUSv2 and every targeted
Unix system has them.  It's easy to avoid including them on Windows
system because they're mostly used in platform-specific translation
units.
---
 config/c-library.m4                | 5 +----
 configure                          | 7 ++-----
 configure.ac                       | 3 ---
 src/backend/port/sysv_sema.c       | 6 +-----
 src/backend/port/sysv_shmem.c      | 8 ++------
 src/backend/storage/ipc/dsm_impl.c | 6 +-----
 src/include/pg_config.h.in         | 9 ---------
 src/tools/msvc/Solution.pm         | 3 ---
 8 files changed, 7 insertions(+), 40 deletions(-)

diff --git a/config/c-library.m4 b/config/c-library.m4
index 76552ac6ed..f6b171d923 100644
--- a/config/c-library.m4
+++ b/config/c-library.m4
@@ -68,12 +68,9 @@ fi
 AC_DEFUN([PGAC_UNION_SEMUN],
 [AC_CHECK_TYPES([union semun], [], [],
 [#include <sys/types.h>
-#ifdef HAVE_SYS_IPC_H
 #include <sys/ipc.h>
-#endif
-#ifdef HAVE_SYS_SEM_H
 #include <sys/sem.h>
-#endif])])# PGAC_UNION_SEMUN
+])])# PGAC_UNION_SEMUN
 
 
 # PGAC_STRUCT_SOCKADDR_STORAGE
diff --git a/configure b/configure
index 804162e873..9ea343c9a1 100755
--- a/configure
+++ b/configure
@@ -13874,7 +13874,7 @@ $as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h
 fi
 
 
-for ac_header in atomic.h copyfile.h execinfo.h getopt.h ifaddrs.h langinfo.h mbarrier.h net/if.h netinet/tcp.h sys/epoll.h sys/event.h sys/ipc.h sys/personality.h sys/prctl.h sys/procctl.h sys/resource.h sys/sem.h sys/shm.h sys/signalfd.h sys/sockio.h sys/ucred.h termios.h ucred.h
+for ac_header in atomic.h copyfile.h execinfo.h getopt.h ifaddrs.h langinfo.h mbarrier.h net/if.h netinet/tcp.h sys/epoll.h sys/event.h sys/personality.h sys/prctl.h sys/procctl.h sys/resource.h sys/signalfd.h sys/sockio.h sys/ucred.h termios.h ucred.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@@ -15092,12 +15092,9 @@ fi
 
 
 ac_fn_c_check_type "$LINENO" "union semun" "ac_cv_type_union_semun" "#include <sys/types.h>
-#ifdef HAVE_SYS_IPC_H
 #include <sys/ipc.h>
-#endif
-#ifdef HAVE_SYS_SEM_H
 #include <sys/sem.h>
-#endif
+
 "
 if test "x$ac_cv_type_union_semun" = xyes; then :
 
diff --git a/configure.ac b/configure.ac
index a9474fd8f3..8da9fc614d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1456,13 +1456,10 @@ AC_CHECK_HEADERS(m4_normalize([
 	netinet/tcp.h
 	sys/epoll.h
 	sys/event.h
-	sys/ipc.h
 	sys/personality.h
 	sys/prctl.h
 	sys/procctl.h
 	sys/resource.h
-	sys/sem.h
-	sys/shm.h
 	sys/signalfd.h
 	sys/sockio.h
 	sys/ucred.h
diff --git a/src/backend/port/sysv_sema.c b/src/backend/port/sysv_sema.c
index ea3ad6da1c..08a97616d6 100644
--- a/src/backend/port/sysv_sema.c
+++ b/src/backend/port/sysv_sema.c
@@ -17,13 +17,9 @@
 #include <signal.h>
 #include <unistd.h>
 #include <sys/file.h>
-#include <sys/stat.h>
-#ifdef HAVE_SYS_IPC_H
 #include <sys/ipc.h>
-#endif
-#ifdef HAVE_SYS_SEM_H
 #include <sys/sem.h>
-#endif
+#include <sys/stat.h>
 
 #include "miscadmin.h"
 #include "storage/ipc.h"
diff --git a/src/backend/port/sysv_shmem.c b/src/backend/port/sysv_shmem.c
index ea287c733d..e62d4a618e 100644
--- a/src/backend/port/sysv_shmem.c
+++ b/src/backend/port/sysv_shmem.c
@@ -22,14 +22,10 @@
 #include <signal.h>
 #include <unistd.h>
 #include <sys/file.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#ifdef HAVE_SYS_IPC_H
 #include <sys/ipc.h>
-#endif
-#ifdef HAVE_SYS_SHM_H
+#include <sys/mman.h>
 #include <sys/shm.h>
-#endif
+#include <sys/stat.h>
 
 #include "miscadmin.h"
 #include "port/pg_bitutils.h"
diff --git a/src/backend/storage/ipc/dsm_impl.c b/src/backend/storage/ipc/dsm_impl.c
index 69c6df75b4..e1b90c5de4 100644
--- a/src/backend/storage/ipc/dsm_impl.c
+++ b/src/backend/storage/ipc/dsm_impl.c
@@ -53,13 +53,9 @@
 #include <unistd.h>
 #ifndef WIN32
 #include <sys/mman.h>
-#endif
-#include <sys/stat.h>
-#ifdef HAVE_SYS_IPC_H
 #include <sys/ipc.h>
-#endif
-#ifdef HAVE_SYS_SHM_H
 #include <sys/shm.h>
+#include <sys/stat.h>
 #endif
 
 #include "common/file_perm.h"
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index f666b4173b..5f96f71896 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -496,9 +496,6 @@
 /* Define to 1 if you have the <sys/event.h> header file. */
 #undef HAVE_SYS_EVENT_H
 
-/* Define to 1 if you have the <sys/ipc.h> header file. */
-#undef HAVE_SYS_IPC_H
-
 /* Define to 1 if you have the <sys/personality.h> header file. */
 #undef HAVE_SYS_PERSONALITY_H
 
@@ -511,12 +508,6 @@
 /* Define to 1 if you have the <sys/resource.h> header file. */
 #undef HAVE_SYS_RESOURCE_H
 
-/* Define to 1 if you have the <sys/sem.h> header file. */
-#undef HAVE_SYS_SEM_H
-
-/* Define to 1 if you have the <sys/shm.h> header file. */
-#undef HAVE_SYS_SHM_H
-
 /* Define to 1 if you have the <sys/signalfd.h> header file. */
 #undef HAVE_SYS_SIGNALFD_H
 
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index b552f439cc..3f69618c4a 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -361,13 +361,10 @@ sub GenerateFiles
 		HAVE_SYSLOG                              => undef,
 		HAVE_SYS_EPOLL_H                         => undef,
 		HAVE_SYS_EVENT_H                         => undef,
-		HAVE_SYS_IPC_H                           => undef,
 		HAVE_SYS_PERSONALITY_H                   => undef,
 		HAVE_SYS_PRCTL_H                         => undef,
 		HAVE_SYS_PROCCTL_H                       => undef,
 		HAVE_SYS_RESOURCE_H                      => undef,
-		HAVE_SYS_SEM_H                           => undef,
-		HAVE_SYS_SHM_H                           => undef,
 		HAVE_SYS_SIGNALFD_H                      => undef,
 		HAVE_SYS_SOCKIO_H                        => undef,
 		HAVE_SYS_STAT_H                          => 1,
-- 
2.32.1 (Apple Git-133)

0005-Remove-configure-probe-for-sys-resource.h-and-refact.patchapplication/octet-stream; name=0005-Remove-configure-probe-for-sys-resource.h-and-refact.patchDownload
From ebc039c010ee0b47f0c0c2216dbb4bca5e2c96c3 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Thu, 11 Aug 2022 16:23:55 +1200
Subject: [PATCH 5/7] Remove configure probe for sys/resource.h and refactor.

<sys/resource.h> is in SUSv2 and is on all targeted Unix systems.  We
have a replacement implementation for just getrusage() on Windows, so
let's just move its declarations into
src/include/port/win32/sys/resource.h so that we can use a
standard-looking #include.  Also rename src/port/getrusage.c to
win32getrusage.c following the convention for Windows-only fallback
code.
---
 configure                                  | 14 +++++-----
 configure.ac                               |  3 +--
 src/backend/storage/file/fd.c              |  4 +--
 src/backend/tcop/postgres.c                | 10 ++-----
 src/bin/pg_ctl/pg_ctl.c                    |  6 ++---
 src/bin/pgbench/pgbench.c                  |  2 --
 src/include/pg_config.h.in                 |  3 ---
 src/include/port/win32/sys/resource.h      | 21 +++++++++++++++
 src/include/rusagestub.h                   | 31 ----------------------
 src/include/utils/pg_rusage.h              |  7 +----
 src/port/{getrusage.c => win32getrusage.c} | 11 +++-----
 src/test/regress/pg_regress.c              |  7 ++---
 src/tools/msvc/Mkvcbuild.pm                |  3 ++-
 src/tools/msvc/Solution.pm                 |  1 -
 src/tools/pginclude/cpluspluscheck         |  5 +---
 15 files changed, 43 insertions(+), 85 deletions(-)
 create mode 100644 src/include/port/win32/sys/resource.h
 delete mode 100644 src/include/rusagestub.h
 rename src/port/{getrusage.c => win32getrusage.c} (88%)

diff --git a/configure b/configure
index 9ea343c9a1..3306741cfc 100755
--- a/configure
+++ b/configure
@@ -13874,7 +13874,7 @@ $as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h
 fi
 
 
-for ac_header in atomic.h copyfile.h execinfo.h getopt.h ifaddrs.h langinfo.h mbarrier.h net/if.h netinet/tcp.h sys/epoll.h sys/event.h sys/personality.h sys/prctl.h sys/procctl.h sys/resource.h sys/signalfd.h sys/sockio.h sys/ucred.h termios.h ucred.h
+for ac_header in atomic.h copyfile.h execinfo.h getopt.h ifaddrs.h langinfo.h mbarrier.h net/if.h netinet/tcp.h sys/epoll.h sys/event.h sys/personality.h sys/prctl.h sys/procctl.h sys/signalfd.h sys/sockio.h sys/ucred.h termios.h ucred.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@@ -16734,12 +16734,6 @@ done
  ;;
 esac
 
-  case " $LIBOBJS " in
-  *" getrusage.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS getrusage.$ac_objext"
- ;;
-esac
-
   case " $LIBOBJS " in
   *" kill.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS kill.$ac_objext"
@@ -16782,6 +16776,12 @@ esac
  ;;
 esac
 
+  case " $LIBOBJS " in
+  *" win32getrusage.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS win32getrusage.$ac_objext"
+ ;;
+esac
+
   case " $LIBOBJS " in
   *" win32link.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS win32link.$ac_objext"
diff --git a/configure.ac b/configure.ac
index 8da9fc614d..19fe78339c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1459,7 +1459,6 @@ AC_CHECK_HEADERS(m4_normalize([
 	sys/personality.h
 	sys/prctl.h
 	sys/procctl.h
-	sys/resource.h
 	sys/signalfd.h
 	sys/sockio.h
 	sys/ucred.h
@@ -1897,7 +1896,6 @@ fi
 if test "$PORTNAME" = "win32"; then
   AC_CHECK_FUNCS(_configthreadlocale)
   AC_LIBOBJ(dirmod)
-  AC_LIBOBJ(getrusage)
   AC_LIBOBJ(kill)
   AC_LIBOBJ(open)
   AC_LIBOBJ(system)
@@ -1905,6 +1903,7 @@ if test "$PORTNAME" = "win32"; then
   AC_LIBOBJ(win32env)
   AC_LIBOBJ(win32error)
   AC_LIBOBJ(win32fdatasync)
+  AC_LIBOBJ(win32getrusage)
   AC_LIBOBJ(win32link)
   AC_LIBOBJ(win32ntdll)
   AC_LIBOBJ(win32pread)
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index efb34d4dcb..e3b19ca1ed 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -75,6 +75,7 @@
 #include <dirent.h>
 #include <sys/file.h>
 #include <sys/param.h>
+#include <sys/resource.h>		/* for getrlimit */
 #include <sys/stat.h>
 #include <sys/types.h>
 #ifndef WIN32
@@ -83,9 +84,6 @@
 #include <limits.h>
 #include <unistd.h>
 #include <fcntl.h>
-#ifdef HAVE_SYS_RESOURCE_H
-#include <sys/resource.h>		/* for getrlimit */
-#endif
 
 #include "access/xact.h"
 #include "access/xlog.h"
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 671edcb3c7..7bec4e4ff5 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -23,16 +23,10 @@
 #include <limits.h>
 #include <signal.h>
 #include <unistd.h>
+#include <sys/resource.h>
 #include <sys/select.h>
 #include <sys/socket.h>
-#ifdef HAVE_SYS_RESOURCE_H
 #include <sys/time.h>
-#include <sys/resource.h>
-#endif
-
-#ifdef WIN32
-#include "rusagestub.h"
-#endif
 
 #include "access/parallel.h"
 #include "access/printtup.h"
@@ -4860,7 +4854,7 @@ ShowUsage(const char *title)
 	 * The following rusage fields are not defined by POSIX, but they're
 	 * present on all current Unix-like systems so we use them without any
 	 * special checks.  Some of these could be provided in our Windows
-	 * emulation in src/port/getrusage.c with more work.
+	 * emulation in src/port/win32getrusage.c with more work.
 	 */
 	appendStringInfo(&str,
 					 "!\t%ld kB max resident size\n",
diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
index 2762e8590d..73e20081d1 100644
--- a/src/bin/pg_ctl/pg_ctl.c
+++ b/src/bin/pg_ctl/pg_ctl.c
@@ -14,14 +14,12 @@
 #include <fcntl.h>
 #include <signal.h>
 #include <time.h>
+#include <sys/resource.h>
 #include <sys/stat.h>
+#include <sys/time.h>
 #include <sys/wait.h>
 #include <unistd.h>
 
-#ifdef HAVE_SYS_RESOURCE_H
-#include <sys/time.h>
-#include <sys/resource.h>
-#endif
 
 #include "catalog/pg_control.h"
 #include "common/controldata_utils.h"
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 45606e944d..c0e907d437 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -40,9 +40,7 @@
 #include <signal.h>
 #include <time.h>
 #include <sys/time.h>
-#ifdef HAVE_SYS_RESOURCE_H
 #include <sys/resource.h>		/* for getrlimit */
-#endif
 
 /* For testing, PGBENCH_USE_SELECT can be defined to force use of that code */
 #if defined(HAVE_PPOLL) && !defined(PGBENCH_USE_SELECT)
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 5f96f71896..45faf05121 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -505,9 +505,6 @@
 /* Define to 1 if you have the <sys/procctl.h> header file. */
 #undef HAVE_SYS_PROCCTL_H
 
-/* Define to 1 if you have the <sys/resource.h> header file. */
-#undef HAVE_SYS_RESOURCE_H
-
 /* Define to 1 if you have the <sys/signalfd.h> header file. */
 #undef HAVE_SYS_SIGNALFD_H
 
diff --git a/src/include/port/win32/sys/resource.h b/src/include/port/win32/sys/resource.h
new file mode 100644
index 0000000000..53a6e7eea0
--- /dev/null
+++ b/src/include/port/win32/sys/resource.h
@@ -0,0 +1,21 @@
+/*
+ * Replacement for <sys/resource.h> for Windows.
+ */
+#ifndef WIN32_SYS_RESOURCE_H
+#define WIN32_SYS_RESOURCE_H
+
+#include <sys/time.h>			/* for struct timeval */
+#include <limits.h>				/* for CLK_TCK */
+
+#define RUSAGE_SELF		0
+#define RUSAGE_CHILDREN (-1)
+
+struct rusage
+{
+	struct timeval ru_utime;	/* user time used */
+	struct timeval ru_stime;	/* system time used */
+};
+
+extern int	getrusage(int who, struct rusage *rusage);
+
+#endif							/* WIN32_SYS_RESOURCE_H */
diff --git a/src/include/rusagestub.h b/src/include/rusagestub.h
deleted file mode 100644
index be26f849a5..0000000000
--- a/src/include/rusagestub.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * rusagestub.h
- *	  Stubs for getrusage(3).
- *
- *
- * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- * src/include/rusagestub.h
- *
- *-------------------------------------------------------------------------
- */
-#ifndef RUSAGESTUB_H
-#define RUSAGESTUB_H
-
-#include <sys/time.h>			/* for struct timeval */
-#include <limits.h>				/* for CLK_TCK */
-
-#define RUSAGE_SELF		0
-#define RUSAGE_CHILDREN (-1)
-
-struct rusage
-{
-	struct timeval ru_utime;	/* user time used */
-	struct timeval ru_stime;	/* system time used */
-};
-
-extern int	getrusage(int who, struct rusage *rusage);
-
-#endif							/* RUSAGESTUB_H */
diff --git a/src/include/utils/pg_rusage.h b/src/include/utils/pg_rusage.h
index a6344abd10..b2c4d36ced 100644
--- a/src/include/utils/pg_rusage.h
+++ b/src/include/utils/pg_rusage.h
@@ -14,13 +14,8 @@
 #ifndef PG_RUSAGE_H
 #define PG_RUSAGE_H
 
-#include <sys/time.h>
-
-#ifdef HAVE_SYS_RESOURCE_H
 #include <sys/resource.h>
-#else
-#include "rusagestub.h"
-#endif
+#include <sys/time.h>
 
 
 /* State structure for pg_rusage_init/pg_rusage_show */
diff --git a/src/port/getrusage.c b/src/port/win32getrusage.c
similarity index 88%
rename from src/port/getrusage.c
rename to src/port/win32getrusage.c
index 2ba59ade2c..8f3556f63b 100644
--- a/src/port/getrusage.c
+++ b/src/port/win32getrusage.c
@@ -1,6 +1,6 @@
 /*-------------------------------------------------------------------------
  *
- * getrusage.c
+ * win32getrusage.c
  *	  get information about resource utilisation
  *
  * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
@@ -8,19 +8,14 @@
  *
  *
  * IDENTIFICATION
- *	  src/port/getrusage.c
+ *	  src/port/win32getrusage.c
  *
  *-------------------------------------------------------------------------
  */
 
 #include "c.h"
 
-#include "rusagestub.h"
-
-/*
- * This code works on Windows, which is the only supported platform without a
- * native version of getrusage().
- */
+#include <sys/resource.h>
 
 int
 getrusage(int who, struct rusage *rusage)
diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c
index b7aa5752f4..cd5a5fd5dd 100644
--- a/src/test/regress/pg_regress.c
+++ b/src/test/regress/pg_regress.c
@@ -19,16 +19,13 @@
 #include "postgres_fe.h"
 
 #include <ctype.h>
+#include <sys/resource.h>
 #include <sys/stat.h>
+#include <sys/time.h>
 #include <sys/wait.h>
 #include <signal.h>
 #include <unistd.h>
 
-#ifdef HAVE_SYS_RESOURCE_H
-#include <sys/time.h>
-#include <sys/resource.h>
-#endif
-
 #include "common/logging.h"
 #include "common/restricted_token.h"
 #include "common/string.h"
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index bacc920758..0a4f0d2eaa 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -100,7 +100,7 @@ sub mkvcbuild
 
 	our @pgportfiles = qw(
 	  chklocale.c explicit_bzero.c
-	  getpeereid.c getrusage.c inet_aton.c
+	  getpeereid.c inet_aton.c
 	  getaddrinfo.c inet_net_ntop.c kill.c open.c
 	  snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c
 	  dirent.c getopt.c getopt_long.c
@@ -111,6 +111,7 @@ sub mkvcbuild
 	  win32dlopen.c
 	  win32env.c win32error.c
 	  win32fdatasync.c
+	  win32getrusage.c
 	  win32gettimeofday.c
 	  win32link.c
 	  win32pread.c
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 3f69618c4a..df594b2fe7 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -364,7 +364,6 @@ sub GenerateFiles
 		HAVE_SYS_PERSONALITY_H                   => undef,
 		HAVE_SYS_PRCTL_H                         => undef,
 		HAVE_SYS_PROCCTL_H                       => undef,
-		HAVE_SYS_RESOURCE_H                      => undef,
 		HAVE_SYS_SIGNALFD_H                      => undef,
 		HAVE_SYS_SOCKIO_H                        => undef,
 		HAVE_SYS_STAT_H                          => 1,
diff --git a/src/tools/pginclude/cpluspluscheck b/src/tools/pginclude/cpluspluscheck
index 6f336deae8..a212059480 100755
--- a/src/tools/pginclude/cpluspluscheck
+++ b/src/tools/pginclude/cpluspluscheck
@@ -71,6 +71,7 @@ do
 
 	# Additional Windows-specific headers.
 	test "$f" = src/include/port/win32_port.h && continue
+	test "$f" = src/include/port/win32/sys/resource.h && continue
 	test "$f" = src/include/port/win32/sys/socket.h && continue
 	test "$f" = src/include/port/win32_msvc/dirent.h && continue
 	test "$f" = src/include/port/win32_msvc/utime.h && continue
@@ -90,10 +91,6 @@ do
 	test "$f" = src/include/port/atomics/generic-msvc.h && continue
 	test "$f" = src/include/port/atomics/generic-sunpro.h && continue
 
-	# rusagestub.h is also platform-specific, and will be included
-	# by utils/pg_rusage.h if necessary.
-	test "$f" = src/include/rusagestub.h && continue
-
 	# sepgsql.h depends on headers that aren't there on most platforms.
 	test "$f" = contrib/sepgsql/sepgsql.h && continue
 
-- 
2.32.1 (Apple Git-133)

0006-Remove-configure-probe-for-shl_load-library.patchapplication/octet-stream; name=0006-Remove-configure-probe-for-shl_load-library.patchDownload
From 67580cde73d33d6cff5185db1d732308f9d20961 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Thu, 11 Aug 2022 20:20:45 +1200
Subject: [PATCH 6/7] Remove configure probe for shl_load library.

This was needed only by HP-UX 10, so became redundant with commit
9db300ce.
---
 configure    | 56 ----------------------------------------------------
 configure.ac |  1 -
 2 files changed, 57 deletions(-)

diff --git a/configure b/configure
index 3306741cfc..c6300a9a54 100755
--- a/configure
+++ b/configure
@@ -12034,62 +12034,6 @@ if test "$ac_res" != no; then :
 
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing shl_load" >&5
-$as_echo_n "checking for library containing shl_load... " >&6; }
-if ${ac_cv_search_shl_load+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_func_search_save_LIBS=$LIBS
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char shl_load ();
-int
-main ()
-{
-return shl_load ();
-  ;
-  return 0;
-}
-_ACEOF
-for ac_lib in '' dld; do
-  if test -z "$ac_lib"; then
-    ac_res="none required"
-  else
-    ac_res=-l$ac_lib
-    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
-  fi
-  if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_search_shl_load=$ac_res
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext
-  if ${ac_cv_search_shl_load+:} false; then :
-  break
-fi
-done
-if ${ac_cv_search_shl_load+:} false; then :
-
-else
-  ac_cv_search_shl_load=no
-fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_shl_load" >&5
-$as_echo "$ac_cv_search_shl_load" >&6; }
-ac_res=$ac_cv_search_shl_load
-if test "$ac_res" != no; then :
-  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-
-fi
-
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing getopt_long" >&5
 $as_echo_n "checking for library containing getopt_long... " >&6; }
 if ${ac_cv_search_getopt_long+:} false; then :
diff --git a/configure.ac b/configure.ac
index 19fe78339c..010c8e6a25 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1248,7 +1248,6 @@ AC_SEARCH_LIBS(setproctitle, util)
 # required. Just checking for dlsym() ought to suffice.
 AC_SEARCH_LIBS(dlsym, dl)
 AC_SEARCH_LIBS(socket, [socket ws2_32])
-AC_SEARCH_LIBS(shl_load, dld)
 AC_SEARCH_LIBS(getopt_long, [getopt gnugetopt])
 AC_SEARCH_LIBS(shm_open, rt)
 AC_SEARCH_LIBS(shm_unlink, rt)
-- 
2.32.1 (Apple Git-133)

#63Tom Lane
tgl@sss.pgh.pa.us
In reply to: Thomas Munro (#62)
Re: Cleaning up historical portability baggage

Thomas Munro <thomas.munro@gmail.com> writes:

The most interesting things to say about these ones are:
* The concept of a no-Unix-socket build is removed. We should be
able to do that now, right? Peter E seemed to say approximately that
in the commit message for 797129e5. Or is there a thought that a new
operating system might show up that doesn't have 'em and we'd wish
we'd kept this stuff well marked out?

I'm kind of down on removing that. I certainly think it's premature
to do so today, when we haven't even yet shipped a release that
assumes we can always define it on Windows -- I won't be too surprised
if we get pushback on that after 15.0 is out. But in general, Unix
sockets seem like kind of an obvious thing that might not be there
on some future platform.

Instead of what you did in 0002, I propose putting
"#define HAVE_UNIX_SOCKETS 1" in pg_config_manual.h, and keeping
the #if's that reference it as-is.

All the rest of this seems fine on a cursory readthrough. Even if
we discover that header foo.h is less universal than we thought,
putting back one or two configure tests won't be hard.

regards, tom lane

#64Andres Freund
andres@anarazel.de
In reply to: Tom Lane (#63)
Re: Cleaning up historical portability baggage

Hi,

On 2022-08-11 10:52:51 -0400, Tom Lane wrote:

Thomas Munro <thomas.munro@gmail.com> writes:

The most interesting things to say about these ones are:
* The concept of a no-Unix-socket build is removed. We should be
able to do that now, right? Peter E seemed to say approximately that
in the commit message for 797129e5. Or is there a thought that a new
operating system might show up that doesn't have 'em and we'd wish
we'd kept this stuff well marked out?

I'm kind of down on removing that. I certainly think it's premature
to do so today, when we haven't even yet shipped a release that
assumes we can always define it on Windows

I think what might be good next step is to have tests default to using unix
sockets on windows, rather than requiring PG_TEST_USE_UNIX_SOCKETS. The
pg_regress.c and Utils.pm hunks disabling it by default on windows don't
really make sense anymore.

#if !defined(HAVE_UNIX_SOCKETS)
use_unix_sockets = false;
#elif defined(WIN32)

/*
* We don't use Unix-domain sockets on Windows by default, even if the
* build supports them. (See comment at remove_temp() for a reason.)
* Override at your own risk.
*/
use_unix_sockets = getenv("PG_TEST_USE_UNIX_SOCKETS") ? true : false;
#else
use_unix_sockets = true;
#endif

and

# Specifies whether to use Unix sockets for test setups. On
# Windows we don't use them by default since it's not universally
# supported, but it can be overridden if desired.
$use_unix_sockets =
(!$windows_os || defined $ENV{PG_TEST_USE_UNIX_SOCKETS});

Tests don't reliably run on windows without PG_TEST_USE_UNIX_SOCKETS, due to
the port conflict detection being incredibly racy. I see occasional failures
even without test concurrency, and with test concurrency it reliably fails.

I don't really know what to do about the warnings around remove_temp() and
trapsig(). I think we actually may be overreading the restrictions. To me the
documented restrictions read more like a high-level-ish explanation of what's
safe in a signal handler and what not. And it seems to not have caused a
problem on windows on several thousand CI cycles, including plenty failures.

Alternatively we could just default to putting the socketdir inside the data
directory on windows - I *think* windows doesn't have strict path length
limits for the socket location. If the socket dir isn't in some global temp
directory, we don't really need signal_remove_temp, given that we're ok with
leaving the much bigger data directory around. The socket directory
determination doesn't really work on windows right now anyway, one manually
has to set a temp directory as TMPDIR isn't normally set on windows, and /tmp
doesn't exist.

char *template = psprintf("%s/pg_regress-XXXXXX",
getenv("TMPDIR") ? getenv("TMPDIR") : "/tmp");

both TEMP and TMP would exist though...

-- I won't be too surprised if we get pushback on that after 15.0 is out.

From what angle? I think our default behaviour doesn't change because
DEFAULT_PGSOCKET_DIR is "". And OS compatibility wise we apparently are good
as well?

But in general, Unix sockets seem like kind of an obvious thing that might
not be there on some future platform.

Maybe not with the precise API, but I can't imagine a new platform not having
something very similar. It serves a pretty obvious need, and I think the
security benefits have become more important over time...

Greetings,

Andres Freund

#65Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andres Freund (#64)
Re: Cleaning up historical portability baggage

Andres Freund <andres@anarazel.de> writes:

On 2022-08-11 10:52:51 -0400, Tom Lane wrote:

-- I won't be too surprised if we get pushback on that after 15.0 is out.

From what angle?

If I knew that, it'd be because we'd already received the pushback.
I'm just suspicious that very little beta testing happens on Windows,
and what does is probably mostly people running up-to-date Windows.
So I think there's plenty of chance for "hey, this no longer works"
complaints later. Maybe we'll be able to reject it all with "sorry,
we desupported that version of Windows", but I dunno.

regards, tom lane

#66Peter Eisentraut
peter.eisentraut@enterprisedb.com
In reply to: Tom Lane (#65)
Re: Cleaning up historical portability baggage

On 11.08.22 19:19, Tom Lane wrote:

Andres Freund <andres@anarazel.de> writes:

On 2022-08-11 10:52:51 -0400, Tom Lane wrote:

-- I won't be too surprised if we get pushback on that after 15.0 is out.

From what angle?

If I knew that, it'd be because we'd already received the pushback.
I'm just suspicious that very little beta testing happens on Windows,
and what does is probably mostly people running up-to-date Windows.
So I think there's plenty of chance for "hey, this no longer works"
complaints later. Maybe we'll be able to reject it all with "sorry,
we desupported that version of Windows", but I dunno.

What is changing in PG15 about this? Unix-domain sockets on Windows are
supported as of PG13.

#67John Naylor
john.naylor@enterprisedb.com
In reply to: Tom Lane (#25)
1 attachment(s)
Re: Cleaning up historical portability baggage

On Thu, Aug 4, 2022 at 11:09 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

clock_gettime is required by SUSv2 (1997), so I have to admit that
macOS 10.4 doesn't have a lot of excuse not to have it. In any case,
prairiedog is just sitting there doing its thing until I find cycles
to install a newer OS. If you want to move ahead with this, don't
let prairiedog block you.

Now that prairiedog is offline, it seems the oldest Bison in the
buildfarm is 2.3, as the vendor-supplied version for MacOS. Since
earlier versions are now untested, it seems we should now make that
the minimum, as in the attached. I took a quick look to see if that
would enable anything useful, but nothing stuck out.

Aside: The MSVC builds don't report the Bison version that I can see,
but otherwise it seems now the only non-Apple pre-3.0 animals are
prion (2.7) and the three Sparc animals on Debian 7 (2.5).

--
John Naylor
EDB: http://www.enterprisedb.com

Attachments:

v1-0001-Require-at-least-Bison-2.3-to-match-the-buildfarm.patchapplication/x-patch; name=v1-0001-Require-at-least-Bison-2.3-to-match-the-buildfarm.patchDownload
From 6e1022bae4a8d45783fa0d678d51eec03383d0de Mon Sep 17 00:00:00 2001
From: John Naylor <john.naylor@postgresql.org>
Date: Sun, 7 Aug 2022 18:32:57 +0700
Subject: [PATCH v1] Require at least Bison 2.3 to match the buildfarm

---
 config/programs.m4                     | 6 +++---
 configure                              | 6 +++---
 contrib/cube/cubeparse.y               | 5 +----
 contrib/seg/segparse.y                 | 5 +----
 doc/src/sgml/install-windows.sgml      | 2 +-
 doc/src/sgml/installation.sgml         | 2 +-
 src/backend/bootstrap/bootparse.y      | 5 +----
 src/backend/parser/gram.y              | 5 +----
 src/backend/replication/repl_gram.y    | 5 +----
 src/backend/replication/syncrep_gram.y | 5 +----
 src/backend/utils/adt/jsonpath_gram.y  | 5 +----
 src/pl/plpgsql/src/pl_gram.y           | 5 +----
 src/tools/msvc/pgbison.pl              | 2 +-
 13 files changed, 17 insertions(+), 41 deletions(-)

diff --git a/config/programs.m4 b/config/programs.m4
index e7908d8793..cf432cb62c 100644
--- a/config/programs.m4
+++ b/config/programs.m4
@@ -22,7 +22,7 @@ fi
 # PGAC_PATH_BISON
 # ---------------
 # Look for Bison, set the output variable BISON to its path if found.
-# Reject versions before 1.875 (they have bugs or capacity limits).
+# Reject versions before 2.3.
 # Note we do not accept other implementations of yacc.
 
 AC_DEFUN([PGAC_PATH_BISON],
@@ -31,11 +31,11 @@ AC_DEFUN([PGAC_PATH_BISON],
 if test "$BISON"; then
   pgac_bison_version=`$BISON --version 2>/dev/null | sed q`
   AC_MSG_NOTICE([using $pgac_bison_version])
-  if echo "$pgac_bison_version" | $AWK '{ if ([$]4 < 1.875) exit 0; else exit 1;}'
+  if echo "$pgac_bison_version" | $AWK '{ if ([$]4 < 2.3) exit 0; else exit 1;}'
   then
     AC_MSG_WARN([
 *** The installed version of Bison, $BISON, is too old to use with PostgreSQL.
-*** Bison version 1.875 or later is required, but this is $pgac_bison_version.])
+*** Bison version 2.3 or later is required, but this is $pgac_bison_version.])
     BISON=""
   fi
   # Bison >=3.0 issues warnings about %name-prefix="base_yy", instead
diff --git a/configure b/configure
index cf2c4b85fe..c3c7c1b39b 100755
--- a/configure
+++ b/configure
@@ -10219,14 +10219,14 @@ if test "$BISON"; then
   pgac_bison_version=`$BISON --version 2>/dev/null | sed q`
   { $as_echo "$as_me:${as_lineno-$LINENO}: using $pgac_bison_version" >&5
 $as_echo "$as_me: using $pgac_bison_version" >&6;}
-  if echo "$pgac_bison_version" | $AWK '{ if ($4 < 1.875) exit 0; else exit 1;}'
+  if echo "$pgac_bison_version" | $AWK '{ if ($4 < 2.3) exit 0; else exit 1;}'
   then
     { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
 *** The installed version of Bison, $BISON, is too old to use with PostgreSQL.
-*** Bison version 1.875 or later is required, but this is $pgac_bison_version." >&5
+*** Bison version 2.3 or later is required, but this is $pgac_bison_version." >&5
 $as_echo "$as_me: WARNING:
 *** The installed version of Bison, $BISON, is too old to use with PostgreSQL.
-*** Bison version 1.875 or later is required, but this is $pgac_bison_version." >&2;}
+*** Bison version 2.3 or later is required, but this is $pgac_bison_version." >&2;}
     BISON=""
   fi
   # Bison >=3.0 issues warnings about %name-prefix="base_yy", instead
diff --git a/contrib/cube/cubeparse.y b/contrib/cube/cubeparse.y
index 7577c4515c..9bfd7a0df6 100644
--- a/contrib/cube/cubeparse.y
+++ b/contrib/cube/cubeparse.y
@@ -15,10 +15,7 @@
 /*
  * Bison doesn't allocate anything that needs to live across parser calls,
  * so we can easily have it use palloc instead of malloc.  This prevents
- * memory leaks if we error out during parsing.  Note this only works with
- * bison >= 2.0.  However, in bison 1.875 the default is to use alloca()
- * if possible, so there's not really much problem anyhow, at least if
- * you're building with gcc.
+ * memory leaks if we error out during parsing.
  */
 #define YYMALLOC palloc
 #define YYFREE   pfree
diff --git a/contrib/seg/segparse.y b/contrib/seg/segparse.y
index 33e3a9f35f..7a0010f659 100644
--- a/contrib/seg/segparse.y
+++ b/contrib/seg/segparse.y
@@ -13,10 +13,7 @@
 /*
  * Bison doesn't allocate anything that needs to live across parser calls,
  * so we can easily have it use palloc instead of malloc.  This prevents
- * memory leaks if we error out during parsing.  Note this only works with
- * bison >= 2.0.  However, in bison 1.875 the default is to use alloca()
- * if possible, so there's not really much problem anyhow, at least if
- * you're building with gcc.
+ * memory leaks if we error out during parsing.
  */
 #define YYMALLOC palloc
 #define YYFREE   pfree
diff --git a/doc/src/sgml/install-windows.sgml b/doc/src/sgml/install-windows.sgml
index afb004b5cf..46d2896072 100644
--- a/doc/src/sgml/install-windows.sgml
+++ b/doc/src/sgml/install-windows.sgml
@@ -219,7 +219,7 @@ $ENV{MSBFLAGS}="/m";
      <para>
       <productname>Bison</productname> and <productname>Flex</productname> are
       required to build from Git, but not required when building from a release
-      file. Only <productname>Bison</productname> 1.875 or versions 2.2 and later
+      file. Only <productname>Bison</productname> versions 2.3 and later
       will work. <productname>Flex</productname> must be version 2.5.31 or later.
      </para>
 
diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml
index 70d188e2bc..7f7f8428e1 100644
--- a/doc/src/sgml/installation.sgml
+++ b/doc/src/sgml/installation.sgml
@@ -315,7 +315,7 @@ su - postgres
       are needed to build from a Git checkout, or if you changed the actual
       scanner and parser definition files. If you need them, be sure
       to get <application>Flex</application> 2.5.31 or later and
-      <application>Bison</application> 1.875 or later. Other <application>lex</application>
+      <application>Bison</application> 2.3 or later. Other <application>lex</application>
       and <application>yacc</application> programs cannot be used.
      </para>
     </listitem>
diff --git a/src/backend/bootstrap/bootparse.y b/src/backend/bootstrap/bootparse.y
index 7d7655d295..fdc6d17b6f 100644
--- a/src/backend/bootstrap/bootparse.y
+++ b/src/backend/bootstrap/bootparse.y
@@ -36,10 +36,7 @@
 /*
  * Bison doesn't allocate anything that needs to live across parser calls,
  * so we can easily have it use palloc instead of malloc.  This prevents
- * memory leaks if we error out during parsing.  Note this only works with
- * bison >= 2.0.  However, in bison 1.875 the default is to use alloca()
- * if possible, so there's not really much problem anyhow, at least if
- * you're building with gcc.
+ * memory leaks if we error out during parsing.
  */
 #define YYMALLOC palloc
 #define YYFREE   pfree
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index f9037761f9..e3c4c00db6 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -103,10 +103,7 @@
 /*
  * Bison doesn't allocate anything that needs to live across parser calls,
  * so we can easily have it use palloc instead of malloc.  This prevents
- * memory leaks if we error out during parsing.  Note this only works with
- * bison >= 2.0.  However, in bison 1.875 the default is to use alloca()
- * if possible, so there's not really much problem anyhow, at least if
- * you're building with gcc.
+ * memory leaks if we error out during parsing.
  */
 #define YYMALLOC palloc
 #define YYFREE   pfree
diff --git a/src/backend/replication/repl_gram.y b/src/backend/replication/repl_gram.y
index 4cf087e602..cb23fed079 100644
--- a/src/backend/replication/repl_gram.y
+++ b/src/backend/replication/repl_gram.y
@@ -29,10 +29,7 @@ Node *replication_parse_result;
 /*
  * Bison doesn't allocate anything that needs to live across parser calls,
  * so we can easily have it use palloc instead of malloc.  This prevents
- * memory leaks if we error out during parsing.  Note this only works with
- * bison >= 2.0.  However, in bison 1.875 the default is to use alloca()
- * if possible, so there's not really much problem anyhow, at least if
- * you're building with gcc.
+ * memory leaks if we error out during parsing.
  */
 #define YYMALLOC palloc
 #define YYFREE   pfree
diff --git a/src/backend/replication/syncrep_gram.y b/src/backend/replication/syncrep_gram.y
index d932f2cda3..bbdf20acc2 100644
--- a/src/backend/replication/syncrep_gram.y
+++ b/src/backend/replication/syncrep_gram.y
@@ -26,10 +26,7 @@ static SyncRepConfigData *create_syncrep_config(const char *num_sync,
 /*
  * Bison doesn't allocate anything that needs to live across parser calls,
  * so we can easily have it use palloc instead of malloc.  This prevents
- * memory leaks if we error out during parsing.  Note this only works with
- * bison >= 2.0.  However, in bison 1.875 the default is to use alloca()
- * if possible, so there's not really much problem anyhow, at least if
- * you're building with gcc.
+ * memory leaks if we error out during parsing.
  */
 #define YYMALLOC palloc
 #define YYFREE   pfree
diff --git a/src/backend/utils/adt/jsonpath_gram.y b/src/backend/utils/adt/jsonpath_gram.y
index f903dba3e3..5d81aefddc 100644
--- a/src/backend/utils/adt/jsonpath_gram.y
+++ b/src/backend/utils/adt/jsonpath_gram.y
@@ -60,10 +60,7 @@ static JsonPathParseItem *makeItemLikeRegex(JsonPathParseItem *expr,
 /*
  * Bison doesn't allocate anything that needs to live across parser calls,
  * so we can easily have it use palloc instead of malloc.  This prevents
- * memory leaks if we error out during parsing.  Note this only works with
- * bison >= 2.0.  However, in bison 1.875 the default is to use alloca()
- * if possible, so there's not really much problem anyhow, at least if
- * you're building with gcc.
+ * memory leaks if we error out during parsing.
  */
 #define YYMALLOC palloc
 #define YYFREE   pfree
diff --git a/src/pl/plpgsql/src/pl_gram.y b/src/pl/plpgsql/src/pl_gram.y
index 0b8aea9504..f7cf2b4b89 100644
--- a/src/pl/plpgsql/src/pl_gram.y
+++ b/src/pl/plpgsql/src/pl_gram.y
@@ -39,10 +39,7 @@
 /*
  * Bison doesn't allocate anything that needs to live across parser calls,
  * so we can easily have it use palloc instead of malloc.  This prevents
- * memory leaks if we error out during parsing.  Note this only works with
- * bison >= 2.0.  However, in bison 1.875 the default is to use alloca()
- * if possible, so there's not really much problem anyhow, at least if
- * you're building with gcc.
+ * memory leaks if we error out during parsing.
  */
 #define YYMALLOC palloc
 #define YYFREE   pfree
diff --git a/src/tools/msvc/pgbison.pl b/src/tools/msvc/pgbison.pl
index 3974c30d96..60935adbaa 100644
--- a/src/tools/msvc/pgbison.pl
+++ b/src/tools/msvc/pgbison.pl
@@ -16,7 +16,7 @@ do './src/tools/msvc/buildenv.pl' if -e 'src/tools/msvc/buildenv.pl';
 my ($bisonver) = `bison -V`;    # grab first line
 $bisonver = (split(/\s+/, $bisonver))[3];    # grab version number
 
-unless ($bisonver eq '1.875' || $bisonver ge '2.2')
+unless ($bisonver ge '2.3')
 {
 	print "WARNING! Bison install not found, or unsupported Bison version.\n";
 	print "echo Attempting to build without.\n";
-- 
2.36.1

#68Peter Eisentraut
peter.eisentraut@enterprisedb.com
In reply to: Thomas Munro (#62)
Re: Cleaning up historical portability baggage

On 11.08.22 12:02, Thomas Munro wrote:

* The concept of a no-Unix-socket build is removed. We should be
able to do that now, right? Peter E seemed to say approximately that
in the commit message for 797129e5. Or is there a thought that a new
operating system might show up that doesn't have 'em and we'd wish
we'd kept this stuff well marked out?

Most uses of HAVE_UNIX_SOCKETS are not useful independent of that
question. For example, you patch has

@@ -348,7 +343,6 @@ StreamServerPort(int family, const char *hostName,
unsigned short portNumber,
hint.ai_flags = AI_PASSIVE;
hint.ai_socktype = SOCK_STREAM;

-#ifdef HAVE_UNIX_SOCKETS
if (family == AF_UNIX)
{
/*

But on a platform without support for Unix sockets, family just won't be
AF_UNIX at run time, so there is no need to hide that if branch.

Note that we already require that AF_UNIX is defined on all platforms,
even if the kernel doesn't support Unix sockets.

But maybe it would be better to make that a separate patch from the
sys/un.h configure changes, just so there is more clarity around it.

#69Thomas Munro
thomas.munro@gmail.com
In reply to: Andres Freund (#64)
Re: Cleaning up historical portability baggage

On Fri, Aug 12, 2022 at 5:14 AM Andres Freund <andres@anarazel.de> wrote:

On 2022-08-11 10:52:51 -0400, Tom Lane wrote:

Thomas Munro <thomas.munro@gmail.com> writes:

The most interesting things to say about these ones are:
* The concept of a no-Unix-socket build is removed. We should be
able to do that now, right? Peter E seemed to say approximately that
in the commit message for 797129e5. Or is there a thought that a new
operating system might show up that doesn't have 'em and we'd wish
we'd kept this stuff well marked out?

I'm kind of down on removing that. I certainly think it's premature
to do so today, when we haven't even yet shipped a release that
assumes we can always define it on Windows

We already do assume that on Windows though. I assume it just bombs
out with an address-family-not-recognized or similar error if you try
to use it on old Windows? It compiles fine because there aren't
any new APIs, and winsock.h has always had the AF_UNIX macro (and many
others probably copied-and-pasted from BSD sys/socket.h, the numbers
seem to match for the first 16 AF_XXXs), and we supply our own
sockaddr_un.

About that struct, some versions of Visual Studio and MinGW didn't
have the header for it when this went in[1]/messages/by-id/88ae9594-6177-fa3c-0061-5bf8f8044b21@2ndquadrant.com. MingGW 10, released in
April 2022, has gained it[2]https://github.com/mingw-w64/mingw-w64/blob/v10.0.0/mingw-w64-headers/include/afunix.h. I think it's reasonable to support only
the "current" MinGW (it's just too niche to have a support window
wider than "right now" IMHO), so it'd be OK to rely on that for PG16?
That would leave Visual Studio. Does anyone know if our recent
de-cluttering efforts have fixed that problem yet? If that turns out
to be true, I'd propose to keep the <sys/un.h> header I added here,
but change it to simply #include <afunix.h>. But that's probably too
hopeful... If we could find out which MSVC
version/SDK/whatever-you-call-it is the first not to need it, it'd be
great to put that in a comment at least, for future garbage collection
work...

(As for why we ever had a configure check for something as basic as
Unix sockets, it looks like QNX and very old Cygwin didn't have them?
Perhaps one or both also didn't even define AF_UNIX, explaining the
IS_AF_UNIX() macro we used to have?)

(Thinking about the standard... I wonder if Windows would have got
this facility sooner if POSIX's attempt to rename AF_UNIX to the more
portable-sounding AF_LOCAL had succeeded... I noticed the Stevens
networking book has a note that POSIX had just decided on AF_LOCAL,
but current POSIX standards make no mention of it, so something went
wrong somewhere along the way there...)

I think what might be good next step is to have tests default to using unix
sockets on windows, rather than requiring PG_TEST_USE_UNIX_SOCKETS. The
pg_regress.c and Utils.pm hunks disabling it by default on windows don't
really make sense anymore.

+1, obviously separate from this cleanup stuff, but, yeah, from PG16
onwards it seems to be legit to assume that they're available AFAIK.

I don't really know what to do about the warnings around remove_temp() and
trapsig(). I think we actually may be overreading the restrictions. To me the
documented restrictions read more like a high-level-ish explanation of what's
safe in a signal handler and what not. And it seems to not have caused a
problem on windows on several thousand CI cycles, including plenty failures.

Alternatively we could just default to putting the socketdir inside the data
directory on windows - I *think* windows doesn't have strict path length
limits for the socket location. If the socket dir isn't in some global temp
directory, we don't really need signal_remove_temp, given that we're ok with
leaving the much bigger data directory around. The socket directory
determination doesn't really work on windows right now anyway, one manually
has to set a temp directory as TMPDIR isn't normally set on windows, and /tmp
doesn't exist.

Re: length: No Windows here but I spent some time today playing ping
pong with little stand-alone test programs on CI, and determined that
it chomps paths at 108 despite succeeding with longer paths. I could
successfully bind(), but directory listings showed the truncation, and
if I tried to make and bind two sockets with the same 108-character
prefix, the second would fail with address-in-use. Is that enough to
be practical?

One thing I noticed is that it is implemented as reparse points. We
might need to tweak some of our stat/dirent stuff to be more careful
if we start putting sockets in places that might be encountered by
that stuff. (The old pgwin32_is_junction() I recently removed would
have returned true for a socket; the newer get_dirent_type() would
return PGFILETYPE_REG right now because it examines reparse points
slightly more carefully, but that's still the wrong answer; for
comparison, on Unix you'd get PGFILETYPE_UNKNOWN for a DT_SOCK because
we didn't handle it).

There seems to be conflicting information out there about whether
"abstract" sockets work (the Linux extension to AF_UNIX where sun_path
starts with a NUL byte and they don't appear in the filesystem, and
they automatically go away when all descriptors are closed). I
couldn't get it to work but I might be doing it wrong... information
is scant.

[1]: /messages/by-id/88ae9594-6177-fa3c-0061-5bf8f8044b21@2ndquadrant.com
[2]: https://github.com/mingw-w64/mingw-w64/blob/v10.0.0/mingw-w64-headers/include/afunix.h

#70Thomas Munro
thomas.munro@gmail.com
In reply to: Peter Eisentraut (#68)
Re: Cleaning up historical portability baggage

On Fri, Aug 12, 2022 at 7:15 PM Peter Eisentraut
<peter.eisentraut@enterprisedb.com> wrote:

On 11.08.22 12:02, Thomas Munro wrote:

* The concept of a no-Unix-socket build is removed. We should be
able to do that now, right? Peter E seemed to say approximately that
in the commit message for 797129e5. Or is there a thought that a new
operating system might show up that doesn't have 'em and we'd wish
we'd kept this stuff well marked out?

Most uses of HAVE_UNIX_SOCKETS are not useful independent of that
question. For example, you patch has

@@ -348,7 +343,6 @@ StreamServerPort(int family, const char *hostName,
unsigned short portNumber,
hint.ai_flags = AI_PASSIVE;
hint.ai_socktype = SOCK_STREAM;

-#ifdef HAVE_UNIX_SOCKETS
if (family == AF_UNIX)
{
/*

But on a platform without support for Unix sockets, family just won't be
AF_UNIX at run time, so there is no need to hide that if branch.

Good point.

Note that we already require that AF_UNIX is defined on all platforms,
even if the kernel doesn't support Unix sockets.

POSIX requires the macro too. I think this would count as SUSv3 (AKA
issue 6?). (IIUC it existed in much older POSIX form as 1g, it's all
very confusing...)

https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html

But maybe it would be better to make that a separate patch from the
sys/un.h configure changes, just so there is more clarity around it.

Cool, I'll do that.

#71Tom Lane
tgl@sss.pgh.pa.us
In reply to: Thomas Munro (#70)
1 attachment(s)
Re: Cleaning up historical portability baggage

Continuing the project of removing dead configure tests ...
I see that prairiedog was the only buildfarm animal failing the
HAVE_PPC_LWARX_MUTEX_HINT test, and it seems pretty unlikely that
there are any assemblers remaining in the wild that can't parse that.
(I've confirmed that son-of-prairiedog, the NetBSD 9.3 installation
I'm cranking up on that hardware, is okay with it.)

So, PFA a little patch to remove that test.

It doesn't look like we can remove the adjacent test about "i"
syntax, unfortunately, because the AIX animals still fail that.

regards, tom lane

Attachments:

drop-lwarx-hint-test.patchtext/x-diff; charset=us-ascii; name=drop-lwarx-hint-test.patchDownload
diff --git a/configure b/configure
index cf2c4b85fe..35dcfbb709 100755
--- a/configure
+++ b/configure
@@ -15423,39 +15423,7 @@ $as_echo "#define HAVE_X86_64_POPCNTQ 1" >>confdefs.h
     fi
   ;;
   ppc*|powerpc*)
-    # On PPC, check if assembler supports LWARX instruction's mutex hint bit
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether assembler supports lwarx hint bit" >&5
-$as_echo_n "checking whether assembler supports lwarx hint bit... " >&6; }
-if ${pgac_cv_have_ppc_mutex_hint+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-int a = 0; int *p = &a; int r;
-	 __asm__ __volatile__ (" lwarx %0,0,%1,1\n" : "=&r"(r) : "r"(p));
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  pgac_cv_have_ppc_mutex_hint=yes
-else
-  pgac_cv_have_ppc_mutex_hint=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_have_ppc_mutex_hint" >&5
-$as_echo "$pgac_cv_have_ppc_mutex_hint" >&6; }
-    if test x"$pgac_cv_have_ppc_mutex_hint" = xyes ; then
-
-$as_echo "#define HAVE_PPC_LWARX_MUTEX_HINT 1" >>confdefs.h
-
-    fi
-    # Check if compiler accepts "i"(x) when __builtin_constant_p(x).
+    # On PPC, check if compiler accepts "i"(x) when __builtin_constant_p(x).
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether __builtin_constant_p(x) implies \"i\"(x) acceptance" >&5
 $as_echo_n "checking whether __builtin_constant_p(x) implies \"i\"(x) acceptance... " >&6; }
 if ${pgac_cv_have_i_constraint__builtin_constant_p+:} false; then :
diff --git a/configure.ac b/configure.ac
index b5798bcb0a..a2aa725455 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1687,18 +1687,7 @@ case $host_cpu in
     fi
   ;;
   ppc*|powerpc*)
-    # On PPC, check if assembler supports LWARX instruction's mutex hint bit
-    AC_CACHE_CHECK([whether assembler supports lwarx hint bit],
-                   [pgac_cv_have_ppc_mutex_hint],
-    [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],
-	[int a = 0; int *p = &a; int r;
-	 __asm__ __volatile__ (" lwarx %0,0,%1,1\n" : "=&r"(r) : "r"(p));])],
-	[pgac_cv_have_ppc_mutex_hint=yes],
-	[pgac_cv_have_ppc_mutex_hint=no])])
-    if test x"$pgac_cv_have_ppc_mutex_hint" = xyes ; then
-	AC_DEFINE(HAVE_PPC_LWARX_MUTEX_HINT, 1, [Define to 1 if the assembler supports PPC's LWARX mutex hint bit.])
-    fi
-    # Check if compiler accepts "i"(x) when __builtin_constant_p(x).
+    # On PPC, check if compiler accepts "i"(x) when __builtin_constant_p(x).
     AC_CACHE_CHECK([whether __builtin_constant_p(x) implies "i"(x) acceptance],
                    [pgac_cv_have_i_constraint__builtin_constant_p],
     [AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index fc5ad5fd65..049c2d204f 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -349,9 +349,6 @@
 /* Define to 1 if you have the `posix_fallocate' function. */
 #undef HAVE_POSIX_FALLOCATE
 
-/* Define to 1 if the assembler supports PPC's LWARX mutex hint bit. */
-#undef HAVE_PPC_LWARX_MUTEX_HINT
-
 /* Define to 1 if you have the `ppoll' function. */
 #undef HAVE_PPOLL
 
diff --git a/src/include/pg_config_manual.h b/src/include/pg_config_manual.h
index 5ee2c46267..ffd385765c 100644
--- a/src/include/pg_config_manual.h
+++ b/src/include/pg_config_manual.h
@@ -236,11 +236,9 @@
  * which should be safe in nearly all cases.  You might want to override
  * this if you are building 32-bit code for a known-recent PPC machine.
  */
-#ifdef HAVE_PPC_LWARX_MUTEX_HINT	/* must have assembler support in any case */
 #if defined(__ppc64__) || defined(__powerpc64__)
 #define USE_PPC_LWARX_MUTEX_HINT
 #endif
-#endif
 
 /*
  * On PPC machines, decide whether to use LWSYNC instructions in place of
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index cc82668457..243c5fa824 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -313,7 +313,6 @@ sub GenerateFiles
 		HAVE_PAM_PAM_APPL_H         => undef,
 		HAVE_POSIX_FADVISE          => undef,
 		HAVE_POSIX_FALLOCATE        => undef,
-		HAVE_PPC_LWARX_MUTEX_HINT   => undef,
 		HAVE_PPOLL                  => undef,
 		HAVE_PS_STRINGS             => undef,
 		HAVE_PTHREAD                => undef,
#72Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tom Lane (#71)
1 attachment(s)
Re: Cleaning up historical portability baggage

I wrote:

I see that prairiedog was the only buildfarm animal failing the
HAVE_PPC_LWARX_MUTEX_HINT test, and it seems pretty unlikely that
there are any assemblers remaining in the wild that can't parse that.

Actually, after further investigation and testing, I think we could
drop the conditionality around PPC spinlock sequences altogether.
The commentary in pg_config_manual.h claims that "some pre-POWER4
machines" will fail on LWSYNC or LWARX with hint, but I've now
confirmed that the oldest PPC chips in my possession (prairiedog's
ppc7400, as well as a couple of ppc7450 machines) are all fine with
both. Indeed, prairiedog would have been failing for some time now
if it didn't like LWSYNC, because port/atomics/arch-ppc.h is using
that unconditionally in some places :-(. I think we can safely
assume that such machines no longer exist in the wild, or at least
are not going to be used to run Postgres v16.

The attached, expanded patch hard-wires USE_PPC_LWARX_MUTEX_HINT
and USE_PPC_LWSYNC as true, and syncs the assembler sequences in
arch-ppc.h with that decision. I've checked this lightly on
tern's host as well as my own machines.

regards, tom lane

Attachments:

remove-conditionality-in-ppc-spinlock-code.patchtext/x-diff; charset=us-ascii; name=remove-conditionality-in-ppc-spinlock-code.patchDownload
diff --git a/configure b/configure
index cf2c4b85fe..35dcfbb709 100755
--- a/configure
+++ b/configure
@@ -15423,39 +15423,7 @@ $as_echo "#define HAVE_X86_64_POPCNTQ 1" >>confdefs.h
     fi
   ;;
   ppc*|powerpc*)
-    # On PPC, check if assembler supports LWARX instruction's mutex hint bit
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether assembler supports lwarx hint bit" >&5
-$as_echo_n "checking whether assembler supports lwarx hint bit... " >&6; }
-if ${pgac_cv_have_ppc_mutex_hint+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-int a = 0; int *p = &a; int r;
-	 __asm__ __volatile__ (" lwarx %0,0,%1,1\n" : "=&r"(r) : "r"(p));
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  pgac_cv_have_ppc_mutex_hint=yes
-else
-  pgac_cv_have_ppc_mutex_hint=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_have_ppc_mutex_hint" >&5
-$as_echo "$pgac_cv_have_ppc_mutex_hint" >&6; }
-    if test x"$pgac_cv_have_ppc_mutex_hint" = xyes ; then
-
-$as_echo "#define HAVE_PPC_LWARX_MUTEX_HINT 1" >>confdefs.h
-
-    fi
-    # Check if compiler accepts "i"(x) when __builtin_constant_p(x).
+    # On PPC, check if compiler accepts "i"(x) when __builtin_constant_p(x).
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether __builtin_constant_p(x) implies \"i\"(x) acceptance" >&5
 $as_echo_n "checking whether __builtin_constant_p(x) implies \"i\"(x) acceptance... " >&6; }
 if ${pgac_cv_have_i_constraint__builtin_constant_p+:} false; then :
diff --git a/configure.ac b/configure.ac
index b5798bcb0a..a2aa725455 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1687,18 +1687,7 @@ case $host_cpu in
     fi
   ;;
   ppc*|powerpc*)
-    # On PPC, check if assembler supports LWARX instruction's mutex hint bit
-    AC_CACHE_CHECK([whether assembler supports lwarx hint bit],
-                   [pgac_cv_have_ppc_mutex_hint],
-    [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],
-	[int a = 0; int *p = &a; int r;
-	 __asm__ __volatile__ (" lwarx %0,0,%1,1\n" : "=&r"(r) : "r"(p));])],
-	[pgac_cv_have_ppc_mutex_hint=yes],
-	[pgac_cv_have_ppc_mutex_hint=no])])
-    if test x"$pgac_cv_have_ppc_mutex_hint" = xyes ; then
-	AC_DEFINE(HAVE_PPC_LWARX_MUTEX_HINT, 1, [Define to 1 if the assembler supports PPC's LWARX mutex hint bit.])
-    fi
-    # Check if compiler accepts "i"(x) when __builtin_constant_p(x).
+    # On PPC, check if compiler accepts "i"(x) when __builtin_constant_p(x).
     AC_CACHE_CHECK([whether __builtin_constant_p(x) implies "i"(x) acceptance],
                    [pgac_cv_have_i_constraint__builtin_constant_p],
     [AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index fc5ad5fd65..049c2d204f 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -349,9 +349,6 @@
 /* Define to 1 if you have the `posix_fallocate' function. */
 #undef HAVE_POSIX_FALLOCATE
 
-/* Define to 1 if the assembler supports PPC's LWARX mutex hint bit. */
-#undef HAVE_PPC_LWARX_MUTEX_HINT
-
 /* Define to 1 if you have the `ppoll' function. */
 #undef HAVE_PPOLL
 
diff --git a/src/include/pg_config_manual.h b/src/include/pg_config_manual.h
index 5ee2c46267..844c3e0f09 100644
--- a/src/include/pg_config_manual.h
+++ b/src/include/pg_config_manual.h
@@ -227,32 +227,6 @@
  */
 #define DEFAULT_EVENT_SOURCE  "PostgreSQL"
 
-/*
- * On PPC machines, decide whether to use the mutex hint bit in LWARX
- * instructions.  Setting the hint bit will slightly improve spinlock
- * performance on POWER6 and later machines, but does nothing before that,
- * and will result in illegal-instruction failures on some pre-POWER4
- * machines.  By default we use the hint bit when building for 64-bit PPC,
- * which should be safe in nearly all cases.  You might want to override
- * this if you are building 32-bit code for a known-recent PPC machine.
- */
-#ifdef HAVE_PPC_LWARX_MUTEX_HINT	/* must have assembler support in any case */
-#if defined(__ppc64__) || defined(__powerpc64__)
-#define USE_PPC_LWARX_MUTEX_HINT
-#endif
-#endif
-
-/*
- * On PPC machines, decide whether to use LWSYNC instructions in place of
- * ISYNC and SYNC.  This provides slightly better performance, but will
- * result in illegal-instruction failures on some pre-POWER4 machines.
- * By default we use LWSYNC when building for 64-bit PPC, which should be
- * safe in nearly all cases.
- */
-#if defined(__ppc64__) || defined(__powerpc64__)
-#define USE_PPC_LWSYNC
-#endif
-
 /*
  * Assumed cache line size. This doesn't affect correctness, but can be used
  * for low-level optimizations. Currently, this is used to pad some data
diff --git a/src/include/port/atomics/arch-ppc.h b/src/include/port/atomics/arch-ppc.h
index eb64513626..35a79042c0 100644
--- a/src/include/port/atomics/arch-ppc.h
+++ b/src/include/port/atomics/arch-ppc.h
@@ -90,12 +90,12 @@ pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr,
 		(int32) *expected >= PG_INT16_MIN)
 		__asm__ __volatile__(
 			"	sync				\n"
-			"	lwarx   %0,0,%5		\n"
+			"	lwarx   %0,0,%5,1	\n"
 			"	cmpwi   %0,%3		\n"
-			"	bne     $+12		\n"		/* branch to isync */
+			"	bne     $+12		\n"		/* branch to lwsync */
 			"	stwcx.  %4,0,%5		\n"
 			"	bne     $-16		\n"		/* branch to lwarx */
-			"	isync				\n"
+			"	lwsync				\n"
 			"	mfcr    %1          \n"
 :			"=&r"(found), "=r"(condition_register), "+m"(ptr->value)
 :			"i"(*expected), "r"(newval), "r"(&ptr->value)
@@ -104,12 +104,12 @@ pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr,
 #endif
 		__asm__ __volatile__(
 			"	sync				\n"
-			"	lwarx   %0,0,%5		\n"
+			"	lwarx   %0,0,%5,1	\n"
 			"	cmpw    %0,%3		\n"
-			"	bne     $+12		\n"		/* branch to isync */
+			"	bne     $+12		\n"		/* branch to lwsync */
 			"	stwcx.  %4,0,%5		\n"
 			"	bne     $-16		\n"		/* branch to lwarx */
-			"	isync				\n"
+			"	lwsync				\n"
 			"	mfcr    %1          \n"
 :			"=&r"(found), "=r"(condition_register), "+m"(ptr->value)
 :			"r"(*expected), "r"(newval), "r"(&ptr->value)
@@ -138,11 +138,11 @@ pg_atomic_fetch_add_u32_impl(volatile pg_atomic_uint32 *ptr, int32 add_)
 		add_ <= PG_INT16_MAX && add_ >= PG_INT16_MIN)
 		__asm__ __volatile__(
 			"	sync				\n"
-			"	lwarx   %1,0,%4		\n"
+			"	lwarx   %1,0,%4,1	\n"
 			"	addi    %0,%1,%3	\n"
 			"	stwcx.  %0,0,%4		\n"
 			"	bne     $-12		\n"		/* branch to lwarx */
-			"	isync				\n"
+			"	lwsync				\n"
 :			"=&r"(_t), "=&b"(res), "+m"(ptr->value)
 :			"i"(add_), "r"(&ptr->value)
 :			"memory", "cc");
@@ -150,11 +150,11 @@ pg_atomic_fetch_add_u32_impl(volatile pg_atomic_uint32 *ptr, int32 add_)
 #endif
 		__asm__ __volatile__(
 			"	sync				\n"
-			"	lwarx   %1,0,%4		\n"
+			"	lwarx   %1,0,%4,1	\n"
 			"	add     %0,%1,%3	\n"
 			"	stwcx.  %0,0,%4		\n"
 			"	bne     $-12		\n"		/* branch to lwarx */
-			"	isync				\n"
+			"	lwsync				\n"
 :			"=&r"(_t), "=&r"(res), "+m"(ptr->value)
 :			"r"(add_), "r"(&ptr->value)
 :			"memory", "cc");
@@ -180,12 +180,12 @@ pg_atomic_compare_exchange_u64_impl(volatile pg_atomic_uint64 *ptr,
 		(int64) *expected >= PG_INT16_MIN)
 		__asm__ __volatile__(
 			"	sync				\n"
-			"	ldarx   %0,0,%5		\n"
+			"	ldarx   %0,0,%5,1	\n"
 			"	cmpdi   %0,%3		\n"
-			"	bne     $+12		\n"		/* branch to isync */
+			"	bne     $+12		\n"		/* branch to lwsync */
 			"	stdcx.  %4,0,%5		\n"
 			"	bne     $-16		\n"		/* branch to ldarx */
-			"	isync				\n"
+			"	lwsync				\n"
 			"	mfcr    %1          \n"
 :			"=&r"(found), "=r"(condition_register), "+m"(ptr->value)
 :			"i"(*expected), "r"(newval), "r"(&ptr->value)
@@ -194,12 +194,12 @@ pg_atomic_compare_exchange_u64_impl(volatile pg_atomic_uint64 *ptr,
 #endif
 		__asm__ __volatile__(
 			"	sync				\n"
-			"	ldarx   %0,0,%5		\n"
+			"	ldarx   %0,0,%5,1	\n"
 			"	cmpd    %0,%3		\n"
-			"	bne     $+12		\n"		/* branch to isync */
+			"	bne     $+12		\n"		/* branch to lwsync */
 			"	stdcx.  %4,0,%5		\n"
 			"	bne     $-16		\n"		/* branch to ldarx */
-			"	isync				\n"
+			"	lwsync				\n"
 			"	mfcr    %1          \n"
 :			"=&r"(found), "=r"(condition_register), "+m"(ptr->value)
 :			"r"(*expected), "r"(newval), "r"(&ptr->value)
@@ -224,11 +224,11 @@ pg_atomic_fetch_add_u64_impl(volatile pg_atomic_uint64 *ptr, int64 add_)
 		add_ <= PG_INT16_MAX && add_ >= PG_INT16_MIN)
 		__asm__ __volatile__(
 			"	sync				\n"
-			"	ldarx   %1,0,%4		\n"
+			"	ldarx   %1,0,%4,1	\n"
 			"	addi    %0,%1,%3	\n"
 			"	stdcx.  %0,0,%4		\n"
 			"	bne     $-12		\n"		/* branch to ldarx */
-			"	isync				\n"
+			"	lwsync				\n"
 :			"=&r"(_t), "=&b"(res), "+m"(ptr->value)
 :			"i"(add_), "r"(&ptr->value)
 :			"memory", "cc");
@@ -236,11 +236,11 @@ pg_atomic_fetch_add_u64_impl(volatile pg_atomic_uint64 *ptr, int64 add_)
 #endif
 		__asm__ __volatile__(
 			"	sync				\n"
-			"	ldarx   %1,0,%4		\n"
+			"	ldarx   %1,0,%4,1	\n"
 			"	add     %0,%1,%3	\n"
 			"	stdcx.  %0,0,%4		\n"
 			"	bne     $-12		\n"		/* branch to ldarx */
-			"	isync				\n"
+			"	lwsync				\n"
 :			"=&r"(_t), "=&r"(res), "+m"(ptr->value)
 :			"r"(add_), "r"(&ptr->value)
 :			"memory", "cc");
diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h
index 0877cf65b0..cc83d561b2 100644
--- a/src/include/storage/s_lock.h
+++ b/src/include/storage/s_lock.h
@@ -435,7 +435,8 @@ typedef unsigned int slock_t;
  *
  * NOTE: per the Enhanced PowerPC Architecture manual, v1.0 dated 7-May-2002,
  * an isync is a sufficient synchronization barrier after a lwarx/stwcx loop.
- * On newer machines, we can use lwsync instead for better performance.
+ * But if the spinlock is in ordinary memory, we can use lwsync instead for
+ * better performance.
  *
  * Ordinarily, we'd code the branches here using GNU-style local symbols, that
  * is "1f" referencing "1:" and so on.  But some people run gcc on AIX with
@@ -450,23 +451,15 @@ tas(volatile slock_t *lock)
 	int _res;
 
 	__asm__ __volatile__(
-#ifdef USE_PPC_LWARX_MUTEX_HINT
 "	lwarx   %0,0,%3,1	\n"
-#else
-"	lwarx   %0,0,%3		\n"
-#endif
 "	cmpwi   %0,0		\n"
 "	bne     $+16		\n"		/* branch to li %1,1 */
 "	addi    %0,%0,1		\n"
 "	stwcx.  %0,0,%3		\n"
-"	beq     $+12		\n"		/* branch to lwsync/isync */
+"	beq     $+12		\n"		/* branch to lwsync */
 "	li      %1,1		\n"
 "	b       $+12		\n"		/* branch to end of asm sequence */
-#ifdef USE_PPC_LWSYNC
 "	lwsync				\n"
-#else
-"	isync				\n"
-#endif
 "	li      %1,0		\n"
 
 :	"=&b"(_t), "=r"(_res), "+m"(*lock)
@@ -477,23 +470,14 @@ tas(volatile slock_t *lock)
 
 /*
  * PowerPC S_UNLOCK is almost standard but requires a "sync" instruction.
- * On newer machines, we can use lwsync instead for better performance.
+ * But we can use lwsync instead for better performance.
  */
-#ifdef USE_PPC_LWSYNC
 #define S_UNLOCK(lock)	\
 do \
 { \
 	__asm__ __volatile__ ("	lwsync \n" ::: "memory"); \
 	*((volatile slock_t *) (lock)) = 0; \
 } while (0)
-#else
-#define S_UNLOCK(lock)	\
-do \
-{ \
-	__asm__ __volatile__ ("	sync \n" ::: "memory"); \
-	*((volatile slock_t *) (lock)) = 0; \
-} while (0)
-#endif /* USE_PPC_LWSYNC */
 
 #endif /* powerpc */
 
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index cc82668457..243c5fa824 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -313,7 +313,6 @@ sub GenerateFiles
 		HAVE_PAM_PAM_APPL_H         => undef,
 		HAVE_POSIX_FADVISE          => undef,
 		HAVE_POSIX_FALLOCATE        => undef,
-		HAVE_PPC_LWARX_MUTEX_HINT   => undef,
 		HAVE_PPOLL                  => undef,
 		HAVE_PS_STRINGS             => undef,
 		HAVE_PTHREAD                => undef,
#73Thomas Munro
thomas.munro@gmail.com
In reply to: Tom Lane (#72)
Re: Cleaning up historical portability baggage

On Sat, Aug 13, 2022 at 8:08 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

I wrote:

I see that prairiedog was the only buildfarm animal failing the
HAVE_PPC_LWARX_MUTEX_HINT test, and it seems pretty unlikely that
there are any assemblers remaining in the wild that can't parse that.

Actually, after further investigation and testing, I think we could
drop the conditionality around PPC spinlock sequences altogether.
The commentary in pg_config_manual.h claims that "some pre-POWER4
machines" will fail on LWSYNC or LWARX with hint, but I've now
confirmed that the oldest PPC chips in my possession (prairiedog's
ppc7400, as well as a couple of ppc7450 machines) are all fine with
both. Indeed, prairiedog would have been failing for some time now
if it didn't like LWSYNC, because port/atomics/arch-ppc.h is using
that unconditionally in some places :-(. I think we can safely
assume that such machines no longer exist in the wild, or at least
are not going to be used to run Postgres v16.

Yeah, POWER3 was superseded in 2001. Looking around, Linux distros
that someone might seriously run a database on already require much
more recent POWER generations to even boot up, and although there is
(for example) a separate unofficial powerpc port for Debian and of
course NetBSD and others that can target older Macs and IBM servers
etc, apparently no one has run our test suite on 21+ year old hardware
and reported that it (presumably) SIGILLs already, per that
observation (I think ports/packages that fail to work probably just
get marked broken). As for vintage Apple hardware, clearly the G4
cube was far more collectable than those weird slightly inflated
looking G3 machines :-)

I'm curious, though... if we used compiler builtins, would
-march/-mcpu etc know about this kind of thing, for people who wanted
to compile on ancient hardware, or, I guess more interestingly, newer
tricks that we haven't got around to learning about yet?

#74Tom Lane
tgl@sss.pgh.pa.us
In reply to: Thomas Munro (#73)
Re: Cleaning up historical portability baggage

Thomas Munro <thomas.munro@gmail.com> writes:

I'm curious, though... if we used compiler builtins, would
-march/-mcpu etc know about this kind of thing, for people who wanted
to compile on ancient hardware, or, I guess more interestingly, newer
tricks that we haven't got around to learning about yet?

No idea, but I could run some tests if you have something
specific in mind.

regards, tom lane

#75Thomas Munro
thomas.munro@gmail.com
In reply to: Thomas Munro (#70)
3 attachment(s)
Re: Cleaning up historical portability baggage

On Fri, Aug 12, 2022 at 8:03 PM Thomas Munro <thomas.munro@gmail.com> wrote:

On Fri, Aug 12, 2022 at 7:15 PM Peter Eisentraut
<peter.eisentraut@enterprisedb.com> wrote:

But maybe it would be better to make that a separate patch from the
sys/un.h configure changes, just so there is more clarity around it.

Cool, I'll do that.

I pushed these, except I chopped out the HAVE_UNIX_SOCKETS part as
requested. Here it is in a separate patch, with a commit message that
explains the rationale (essentially, what you said, it's basically a
runtime matter for a hypothetical AF_UNIX-less system to complain
about). Tom, does this argument persuade you? Also, a couple of
nearby things:

Remove HAVE_UNIX_SOCKETS.
Remove configure probe for struct sockaddr_storage.
Remove configure probe for getaddrinfo, and replacement code.

If I'm reading comments and scraped configure data right, it looks
like those last two things were there only for HP-UX 10 and Windows <
8.1.

I tried to figure out how to get rid of
PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS, but there we're into genuine
non-standard cross-platform differences. At best maybe you could
maybe skip the test for ss_family (POSIX says you have to have that,
but I haven't read RFC 2553 to see why it claims someone should spell
it differently). Didn't seem worth changing.

bfbot=> select name, value, count(*) from macro where name like
'%SOCKADDR_%' group by 1, 2;
name | value | count
----------------------------------------+-------+-------
HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN | 1 | 13 <-- BSDish
HAVE_STRUCT_SOCKADDR_STORAGE | 1 | 108 <-- everyone
HAVE_STRUCT_SOCKADDR_SA_LEN | 1 | 18 <-- BSDish + AIX
HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY | 1 | 108 <-- everyone
HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN | 1 | 5 <-- AIX
HAVE_STRUCT_SOCKADDR_UN | 1 | 106 <-- everyone
except mingw
(6 rows)

Attachments:

0002-Remove-configure-probe-for-struct-sockaddr_storage.patchtext/x-patch; charset=US-ASCII; name=0002-Remove-configure-probe-for-struct-sockaddr_storage.patchDownload
From 05f16ae2e21704cea6c560c4f333bff555222fa0 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 13 Aug 2022 21:10:39 +1200
Subject: [PATCH 2/3] Remove configure probe for struct sockaddr_storage.

<sys/socket.h> provides sockaddr_storage in SUSv3.  Windows has it too.
---
 config/c-library.m4        | 14 +-------------
 configure                  | 13 -------------
 configure.ac               |  1 -
 src/include/libpq/pqcomm.h | 23 -----------------------
 src/include/pg_config.h.in |  3 ---
 src/tools/msvc/Solution.pm |  1 -
 6 files changed, 1 insertion(+), 54 deletions(-)

diff --git a/config/c-library.m4 b/config/c-library.m4
index f6b171d923..7a79033730 100644
--- a/config/c-library.m4
+++ b/config/c-library.m4
@@ -73,23 +73,11 @@ AC_DEFUN([PGAC_UNION_SEMUN],
 ])])# PGAC_UNION_SEMUN
 
 
-# PGAC_STRUCT_SOCKADDR_STORAGE
-# ----------------------------
-# If `struct sockaddr_storage' exists, define HAVE_STRUCT_SOCKADDR_STORAGE.
-# If it is missing then one could define it.
-AC_DEFUN([PGAC_STRUCT_SOCKADDR_STORAGE],
-[AC_CHECK_TYPES([struct sockaddr_storage], [], [],
-[#include <sys/types.h>
-#include <sys/socket.h>
-])])# PGAC_STRUCT_SOCKADDR_STORAGE
-
 # PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS
 # --------------------------------------
 # Check the members of `struct sockaddr_storage'.  We need to know about
 # ss_family and ss_len.  (Some platforms follow RFC 2553 and call them
-# __ss_family and __ss_len.)  We also check struct sockaddr's sa_len;
-# if we have to define our own `struct sockaddr_storage', this tells us
-# whether we need to provide an ss_len field.
+# __ss_family and __ss_len.)  We also check struct sockaddr's sa_len.
 AC_DEFUN([PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS],
 [AC_CHECK_MEMBERS([struct sockaddr_storage.ss_family,
 		   struct sockaddr_storage.__ss_family,
diff --git a/configure b/configure
index c6300a9a54..7c10905dfd 100755
--- a/configure
+++ b/configure
@@ -15058,19 +15058,6 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
-fi
-
-ac_fn_c_check_type "$LINENO" "struct sockaddr_storage" "ac_cv_type_struct_sockaddr_storage" "#include <sys/types.h>
-#include <sys/socket.h>
-
-"
-if test "x$ac_cv_type_struct_sockaddr_storage" = xyes; then :
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_STRUCT_SOCKADDR_STORAGE 1
-_ACEOF
-
-
 fi
 
 ac_fn_c_check_member "$LINENO" "struct sockaddr_storage" "ss_family" "ac_cv_member_struct_sockaddr_storage_ss_family" "#include <sys/types.h>
diff --git a/configure.ac b/configure.ac
index 010c8e6a25..d3e402dfc0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1618,7 +1618,6 @@ PGAC_C_COMPUTED_GOTO
 PGAC_STRUCT_TIMEZONE
 PGAC_UNION_SEMUN
 AC_CHECK_TYPES(socklen_t, [], [], [#include <sys/socket.h>])
-PGAC_STRUCT_SOCKADDR_STORAGE
 PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS
 PGAC_STRUCT_ADDRINFO
 
diff --git a/src/include/libpq/pqcomm.h b/src/include/libpq/pqcomm.h
index 3bcc06b2d6..7e2f1495f3 100644
--- a/src/include/libpq/pqcomm.h
+++ b/src/include/libpq/pqcomm.h
@@ -21,8 +21,6 @@
 #include <netdb.h>
 #include <netinet/in.h>
 
-#ifdef HAVE_STRUCT_SOCKADDR_STORAGE
-
 #ifndef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY
 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY
 #define ss_family __ss_family
@@ -35,27 +33,6 @@
 #define ss_len __ss_len
 #define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1
 #endif
-#else							/* !HAVE_STRUCT_SOCKADDR_STORAGE */
-
-/* Define a struct sockaddr_storage if we don't have one. */
-
-struct sockaddr_storage
-{
-	union
-	{
-		struct sockaddr sa;		/* get the system-dependent fields */
-		int64		ss_align;	/* ensures struct is properly aligned */
-		char		ss_pad[128];	/* ensures struct has desired size */
-	}			ss_stuff;
-};
-
-#define ss_family	ss_stuff.sa.sa_family
-/* It should have an ss_len field if sockaddr has sa_len. */
-#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
-#define ss_len		ss_stuff.sa.sa_len
-#define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1
-#endif
-#endif							/* HAVE_STRUCT_SOCKADDR_STORAGE */
 
 typedef struct
 {
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 45faf05121..31674bde4e 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -463,9 +463,6 @@
 /* Define to 1 if `sa_len' is a member of `struct sockaddr'. */
 #undef HAVE_STRUCT_SOCKADDR_SA_LEN
 
-/* Define to 1 if the system has the type `struct sockaddr_storage'. */
-#undef HAVE_STRUCT_SOCKADDR_STORAGE
-
 /* Define to 1 if `ss_family' is a member of `struct sockaddr_storage'. */
 #undef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY
 
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index df594b2fe7..1632931840 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -350,7 +350,6 @@ sub GenerateFiles
 		HAVE_STRUCT_CMSGCRED                     => undef,
 		HAVE_STRUCT_OPTION                       => undef,
 		HAVE_STRUCT_SOCKADDR_SA_LEN              => undef,
-		HAVE_STRUCT_SOCKADDR_STORAGE             => 1,
 		HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY   => 1,
 		HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN      => undef,
 		HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY => undef,
-- 
2.30.2

0003-Remove-configure-probe-for-getaddrinfo-and-replaceme.patchtext/x-patch; charset=US-ASCII; name=0003-Remove-configure-probe-for-getaddrinfo-and-replaceme.patchDownload
From d11c344a0cc59d6e657073d243358be16347907c Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 13 Aug 2022 21:35:18 +1200
Subject: [PATCH 3/3] Remove configure probe for getaddrinfo, and replacement
 code.

SUSv3 and modern Windows have getaddrinfo() and related interfaces.
Drop the replacement implementation, and adjust some headers slightly to
make sure that the OS APIs are visible on both OSes using POSIX header
names.
---
 config/c-library.m4                   |  11 -
 configure                             |  42 ---
 configure.ac                          |  11 -
 src/backend/libpq/auth.c              |   1 +
 src/backend/libpq/hba.c               |   1 +
 src/bin/initdb/initdb.c               |   3 +-
 src/include/common/ip.h               |   4 +-
 src/include/getaddrinfo.h             | 162 ----------
 src/include/libpq/libpq-be.h          |   8 -
 src/include/pg_config.h.in            |   6 -
 src/include/port/win32/netdb.h        |   8 +
 src/include/replication/walreceiver.h |   4 +-
 src/interfaces/libpq/fe-connect.c     |   1 +
 src/interfaces/libpq/libpq-int.h      |   3 +-
 src/port/Makefile                     |   4 -
 src/port/getaddrinfo.c                | 439 --------------------------
 src/tools/msvc/Mkvcbuild.pm           |   2 +-
 src/tools/msvc/Solution.pm            |   2 -
 18 files changed, 22 insertions(+), 690 deletions(-)
 delete mode 100644 src/include/getaddrinfo.h
 delete mode 100644 src/port/getaddrinfo.c

diff --git a/config/c-library.m4 b/config/c-library.m4
index 7a79033730..58453c4f76 100644
--- a/config/c-library.m4
+++ b/config/c-library.m4
@@ -89,17 +89,6 @@ AC_DEFUN([PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS],
 ])])# PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS
 
 
-# PGAC_STRUCT_ADDRINFO
-# -----------------------
-# If `struct addrinfo' exists, define HAVE_STRUCT_ADDRINFO.
-AC_DEFUN([PGAC_STRUCT_ADDRINFO],
-[AC_CHECK_TYPES([struct addrinfo], [], [],
-[#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-])])# PGAC_STRUCT_ADDRINFO
-
-
 # PGAC_TYPE_LOCALE_T
 # ------------------
 # Check for the locale_t type and find the right header file.  macOS
diff --git a/configure b/configure
index 7c10905dfd..c1daab15d6 100755
--- a/configure
+++ b/configure
@@ -15119,20 +15119,6 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
-fi
-
-ac_fn_c_check_type "$LINENO" "struct addrinfo" "ac_cv_type_struct_addrinfo" "#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-
-"
-if test "x$ac_cv_type_struct_addrinfo" = xyes; then :
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_STRUCT_ADDRINFO 1
-_ACEOF
-
-
 fi
 
 
@@ -16565,34 +16551,6 @@ esac
 $as_echo "$as_me: On $host_os we will use our strtof wrapper." >&6;}
 fi
 
-# System's version of getaddrinfo(), if any, may be used only if we found
-# a definition for struct addrinfo; see notes in src/include/getaddrinfo.h.
-# We use only our own getaddrinfo.c on Windows, but it's time to revisit that.
-if test x"$ac_cv_type_struct_addrinfo" = xyes && \
-   test "$PORTNAME" != "win32"; then
-  ac_fn_c_check_func "$LINENO" "getaddrinfo" "ac_cv_func_getaddrinfo"
-if test "x$ac_cv_func_getaddrinfo" = xyes; then :
-  $as_echo "#define HAVE_GETADDRINFO 1" >>confdefs.h
-
-else
-  case " $LIBOBJS " in
-  *" getaddrinfo.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS getaddrinfo.$ac_objext"
- ;;
-esac
-
-fi
-
-
-else
-  case " $LIBOBJS " in
-  *" getaddrinfo.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS getaddrinfo.$ac_objext"
- ;;
-esac
-
-fi
-
 # Similarly, use system's getopt_long() only if system provides struct option.
 if test x"$ac_cv_type_struct_option" = xyes ; then
   ac_fn_c_check_func "$LINENO" "getopt_long" "ac_cv_func_getopt_long"
diff --git a/configure.ac b/configure.ac
index d3e402dfc0..1ce9766a31 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1619,7 +1619,6 @@ PGAC_STRUCT_TIMEZONE
 PGAC_UNION_SEMUN
 AC_CHECK_TYPES(socklen_t, [], [], [#include <sys/socket.h>])
 PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS
-PGAC_STRUCT_ADDRINFO
 
 PGAC_TYPE_LOCALE_T
 
@@ -1860,16 +1859,6 @@ if test "$PORTNAME" = "win32" -o "$PORTNAME" = "cygwin"; then
 	AC_MSG_NOTICE([On $host_os we will use our strtof wrapper.])
 fi
 
-# System's version of getaddrinfo(), if any, may be used only if we found
-# a definition for struct addrinfo; see notes in src/include/getaddrinfo.h.
-# We use only our own getaddrinfo.c on Windows, but it's time to revisit that.
-if test x"$ac_cv_type_struct_addrinfo" = xyes && \
-   test "$PORTNAME" != "win32"; then
-  AC_REPLACE_FUNCS([getaddrinfo])
-else
-  AC_LIBOBJ(getaddrinfo)
-fi
-
 # Similarly, use system's getopt_long() only if system provides struct option.
 if test x"$ac_cv_type_struct_option" = xyes ; then
   AC_REPLACE_FUNCS([getopt_long])
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index 41d60e06d0..290eb17325 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -19,6 +19,7 @@
 #include <sys/select.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
+#include <netdb.h>
 #include <pwd.h>
 #include <unistd.h>
 
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index 66f2156cde..857b9e5eb2 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -21,6 +21,7 @@
 #include <fcntl.h>
 #include <sys/param.h>
 #include <sys/socket.h>
+#include <netdb.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <unistd.h>
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 4feb5db3fa..6f56d3f703 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -50,7 +50,9 @@
 
 #include <dirent.h>
 #include <fcntl.h>
+#include <netdb.h>
 #include <sys/stat.h>
+#include <sys/socket.h>
 #include <unistd.h>
 #include <signal.h>
 #include <time.h>
@@ -72,7 +74,6 @@
 #include "common/string.h"
 #include "common/username.h"
 #include "fe_utils/string_utils.h"
-#include "getaddrinfo.h"
 #include "getopt_long.h"
 #include "mb/pg_wchar.h"
 #include "miscadmin.h"
diff --git a/src/include/common/ip.h b/src/include/common/ip.h
index 8414520989..6c044f7fa2 100644
--- a/src/include/common/ip.h
+++ b/src/include/common/ip.h
@@ -14,7 +14,9 @@
 #ifndef IP_H
 #define IP_H
 
-#include "getaddrinfo.h"		/* pgrminclude ignore */
+#include <netdb.h>
+#include <sys/socket.h>
+
 #include "libpq/pqcomm.h"		/* pgrminclude ignore */
 
 
diff --git a/src/include/getaddrinfo.h b/src/include/getaddrinfo.h
deleted file mode 100644
index 2042c2d303..0000000000
--- a/src/include/getaddrinfo.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * getaddrinfo.h
- *	  Support getaddrinfo() on platforms that don't have it.
- *
- * Note: we use our own routines on platforms that don't HAVE_STRUCT_ADDRINFO,
- * whether or not the library routine getaddrinfo() can be found.  This
- * policy is needed because on some platforms a manually installed libbind.a
- * may provide getaddrinfo(), yet the system headers may not provide the
- * struct definitions needed to call it.  To avoid conflict with the libbind
- * definition in such cases, we rename our routines to pg_xxx() via macros.
- *
- * This code will also work on platforms where struct addrinfo is defined
- * in the system headers but no getaddrinfo() can be located.
- *
- * Copyright (c) 2003-2022, PostgreSQL Global Development Group
- *
- * src/include/getaddrinfo.h
- *
- *-------------------------------------------------------------------------
- */
-#ifndef GETADDRINFO_H
-#define GETADDRINFO_H
-
-#include <sys/socket.h>
-#include <netdb.h>
-
-
-/* Various macros that ought to be in <netdb.h>, but might not be */
-
-#ifndef EAI_FAIL
-#ifndef WIN32
-#define EAI_BADFLAGS	(-1)
-#define EAI_NONAME		(-2)
-#define EAI_AGAIN		(-3)
-#define EAI_FAIL		(-4)
-#define EAI_FAMILY		(-6)
-#define EAI_SOCKTYPE	(-7)
-#define EAI_SERVICE		(-8)
-#define EAI_MEMORY		(-10)
-#define EAI_SYSTEM		(-11)
-#else							/* WIN32 */
-#ifdef _MSC_VER
-#ifndef WSA_NOT_ENOUGH_MEMORY
-#define WSA_NOT_ENOUGH_MEMORY	(WSAENOBUFS)
-#endif
-#define WSATYPE_NOT_FOUND		(WSABASEERR+109)
-#endif
-#define EAI_AGAIN		WSATRY_AGAIN
-#define EAI_BADFLAGS	WSAEINVAL
-#define EAI_FAIL		WSANO_RECOVERY
-#define EAI_FAMILY		WSAEAFNOSUPPORT
-#define EAI_MEMORY		WSA_NOT_ENOUGH_MEMORY
-#define EAI_NODATA		WSANO_DATA
-#define EAI_NONAME		WSAHOST_NOT_FOUND
-#define EAI_SERVICE		WSATYPE_NOT_FOUND
-#define EAI_SOCKTYPE	WSAESOCKTNOSUPPORT
-#endif							/* !WIN32 */
-#endif							/* !EAI_FAIL */
-
-#ifndef AI_PASSIVE
-#define AI_PASSIVE		0x0001
-#endif
-
-#ifndef AI_NUMERICHOST
-/*
- * some platforms don't support AI_NUMERICHOST; define as zero if using
- * the system version of getaddrinfo...
- */
-#if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO)
-#define AI_NUMERICHOST	0
-#else
-#define AI_NUMERICHOST	0x0004
-#endif
-#endif
-
-#ifndef NI_NUMERICHOST
-#define NI_NUMERICHOST	1
-#endif
-#ifndef NI_NUMERICSERV
-#define NI_NUMERICSERV	2
-#endif
-#ifndef NI_NAMEREQD
-#define NI_NAMEREQD		4
-#endif
-
-#ifndef NI_MAXHOST
-#define NI_MAXHOST	1025
-#endif
-#ifndef NI_MAXSERV
-#define NI_MAXSERV	32
-#endif
-
-
-#ifndef HAVE_STRUCT_ADDRINFO
-
-#ifndef WIN32
-struct addrinfo
-{
-	int			ai_flags;
-	int			ai_family;
-	int			ai_socktype;
-	int			ai_protocol;
-	size_t		ai_addrlen;
-	struct sockaddr *ai_addr;
-	char	   *ai_canonname;
-	struct addrinfo *ai_next;
-};
-#else
-/*
- *	The order of the structure elements on Win32 doesn't match the
- *	order specified in the standard, but we have to match it for
- *	IPv6 to work.
- */
-struct addrinfo
-{
-	int			ai_flags;
-	int			ai_family;
-	int			ai_socktype;
-	int			ai_protocol;
-	size_t		ai_addrlen;
-	char	   *ai_canonname;
-	struct sockaddr *ai_addr;
-	struct addrinfo *ai_next;
-};
-#endif
-#endif							/* HAVE_STRUCT_ADDRINFO */
-
-
-#ifndef HAVE_GETADDRINFO
-
-/* Rename private copies per comments above */
-#ifdef getaddrinfo
-#undef getaddrinfo
-#endif
-#define getaddrinfo pg_getaddrinfo
-
-#ifdef freeaddrinfo
-#undef freeaddrinfo
-#endif
-#define freeaddrinfo pg_freeaddrinfo
-
-#ifdef gai_strerror
-#undef gai_strerror
-#endif
-#define gai_strerror pg_gai_strerror
-
-#ifdef getnameinfo
-#undef getnameinfo
-#endif
-#define getnameinfo pg_getnameinfo
-
-extern int	getaddrinfo(const char *node, const char *service,
-						const struct addrinfo *hints, struct addrinfo **res);
-extern void freeaddrinfo(struct addrinfo *res);
-extern const char *gai_strerror(int errcode);
-extern int	getnameinfo(const struct sockaddr *sa, int salen,
-						char *node, int nodelen,
-						char *service, int servicelen, int flags);
-#endif							/* HAVE_GETADDRINFO */
-
-#endif							/* GETADDRINFO_H */
diff --git a/src/include/libpq/libpq-be.h b/src/include/libpq/libpq-be.h
index 90c20da22b..fa2fd03009 100644
--- a/src/include/libpq/libpq-be.h
+++ b/src/include/libpq/libpq-be.h
@@ -33,14 +33,6 @@
 #else
 #include <gssapi/gssapi.h>
 #endif							/* HAVE_GSSAPI_H */
-/*
- * GSSAPI brings in headers that set a lot of things in the global namespace on win32,
- * that doesn't match the msvc build. It gives a bunch of compiler warnings that we ignore,
- * but also defines a symbol that simply does not exist. Undefine it again.
- */
-#ifdef _MSC_VER
-#undef HAVE_GETADDRINFO
-#endif
 #endif							/* ENABLE_GSS */
 
 #ifdef ENABLE_SSPI
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 31674bde4e..e5e68fac03 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -178,9 +178,6 @@
    */
 #undef HAVE_GCC__SYNC_INT64_CAS
 
-/* Define to 1 if you have the `getaddrinfo' function. */
-#undef HAVE_GETADDRINFO
-
 /* Define to 1 if you have the `gethostbyname_r' function. */
 #undef HAVE_GETHOSTBYNAME_R
 
@@ -451,9 +448,6 @@
 /* Define to 1 if you have the `strsignal' function. */
 #undef HAVE_STRSIGNAL
 
-/* Define to 1 if the system has the type `struct addrinfo'. */
-#undef HAVE_STRUCT_ADDRINFO
-
 /* Define to 1 if the system has the type `struct cmsgcred'. */
 #undef HAVE_STRUCT_CMSGCRED
 
diff --git a/src/include/port/win32/netdb.h b/src/include/port/win32/netdb.h
index ad0627e986..f0cc2c2367 100644
--- a/src/include/port/win32/netdb.h
+++ b/src/include/port/win32/netdb.h
@@ -1 +1,9 @@
 /* src/include/port/win32/netdb.h */
+#ifndef WIN32_NETDB_H
+#define WIN32_NETDB_H
+
+#include <ws2tcpip.h>
+
+#define gai_strerror gai_strerrorA
+
+#endif
diff --git a/src/include/replication/walreceiver.h b/src/include/replication/walreceiver.h
index bd8398de0b..9339f29303 100644
--- a/src/include/replication/walreceiver.h
+++ b/src/include/replication/walreceiver.h
@@ -12,9 +12,11 @@
 #ifndef _WALRECEIVER_H
 #define _WALRECEIVER_H
 
+#include <netdb.h>
+#include <sys/socket.h>
+
 #include "access/xlog.h"
 #include "access/xlogdefs.h"
-#include "getaddrinfo.h"		/* for NI_MAXHOST */
 #include "pgtime.h"
 #include "port/atomics.h"
 #include "replication/logicalproto.h"
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 730e79a31d..0b8fabc7e8 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -18,6 +18,7 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <ctype.h>
+#include <netdb.h>
 #include <time.h>
 #include <unistd.h>
 
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index 51ab51f9f9..1eb752a82d 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -23,6 +23,8 @@
 /* We assume libpq-fe.h has already been included. */
 #include "libpq-events.h"
 
+#include <netdb.h>
+#include <sys/socket.h>
 #include <time.h>
 #ifndef WIN32
 #include <sys/time.h>
@@ -38,7 +40,6 @@
 #endif
 
 /* include stuff common to fe and be */
-#include "getaddrinfo.h"
 #include "libpq/pqcomm.h"
 /* include stuff found in fe only */
 #include "fe-auth-sasl.h"
diff --git a/src/port/Makefile b/src/port/Makefile
index bfe1feb0d4..b3754d8940 100644
--- a/src/port/Makefile
+++ b/src/port/Makefile
@@ -84,10 +84,6 @@ libpgport.a: $(OBJS)
 	rm -f $@
 	$(AR) $(AROPT) $@ $^
 
-# getaddrinfo.o and getaddrinfo_shlib.o need PTHREAD_CFLAGS (but getaddrinfo_srv.o does not)
-getaddrinfo.o: CFLAGS+=$(PTHREAD_CFLAGS)
-getaddrinfo_shlib.o: CFLAGS+=$(PTHREAD_CFLAGS)
-
 # thread.o and thread_shlib.o need PTHREAD_CFLAGS (but thread_srv.o does not)
 thread.o: CFLAGS+=$(PTHREAD_CFLAGS)
 thread_shlib.o: CFLAGS+=$(PTHREAD_CFLAGS)
diff --git a/src/port/getaddrinfo.c b/src/port/getaddrinfo.c
deleted file mode 100644
index bea7b520f0..0000000000
--- a/src/port/getaddrinfo.c
+++ /dev/null
@@ -1,439 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * getaddrinfo.c
- *	  Support getaddrinfo() on platforms that don't have it.
- *
- * We also supply getnameinfo() here, assuming that the platform will have
- * it if and only if it has getaddrinfo().  If this proves false on some
- * platform, we'll need to split this file and provide a separate configure
- * test for getnameinfo().
- *
- * Windows may or may not have these routines, so we handle Windows specially
- * by dynamically checking for their existence.  If they already exist, we
- * use the Windows native routines, but if not, we use our own.
- *
- *
- * Copyright (c) 2003-2022, PostgreSQL Global Development Group
- *
- * IDENTIFICATION
- *	  src/port/getaddrinfo.c
- *
- *-------------------------------------------------------------------------
- */
-
-/* This is intended to be used in both frontend and backend, so use c.h */
-#include "c.h"
-
-#include <sys/socket.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include "getaddrinfo.h"
-#include "libpq/pqcomm.h"		/* needed for struct sockaddr_storage */
-#include "port/pg_bswap.h"
-
-
-#ifdef FRONTEND
-static int	pqGethostbyname(const char *name,
-							struct hostent *resultbuf,
-							char *buffer, size_t buflen,
-							struct hostent **result,
-							int *herrno);
-#endif
-
-#ifdef WIN32
-/*
- * The native routines may or may not exist on the Windows platform we are on,
- * so we dynamically look up the routines, and call them via function pointers.
- * Here we need to declare what the function pointers look like
- */
-typedef int (__stdcall * getaddrinfo_ptr_t) (const char *nodename,
-											 const char *servname,
-											 const struct addrinfo *hints,
-											 struct addrinfo **res);
-
-typedef void (__stdcall * freeaddrinfo_ptr_t) (struct addrinfo *ai);
-
-typedef int (__stdcall * getnameinfo_ptr_t) (const struct sockaddr *sa,
-											 int salen,
-											 char *node, int nodelen,
-											 char *service, int servicelen,
-											 int flags);
-
-/* static pointers to the native routines, so we only do the lookup once. */
-static getaddrinfo_ptr_t getaddrinfo_ptr = NULL;
-static freeaddrinfo_ptr_t freeaddrinfo_ptr = NULL;
-static getnameinfo_ptr_t getnameinfo_ptr = NULL;
-
-
-static bool
-haveNativeWindowsIPv6routines(void)
-{
-	void	   *hLibrary = NULL;
-	static bool alreadyLookedForIpv6routines = false;
-
-	if (alreadyLookedForIpv6routines)
-		return (getaddrinfo_ptr != NULL);
-
-	/*
-	 * For Windows XP and later versions, the IPv6 routines are present in the
-	 * WinSock 2 library (ws2_32.dll).
-	 */
-	hLibrary = LoadLibraryA("ws2_32");
-
-	/* If hLibrary is null, we couldn't find a dll with functions */
-	if (hLibrary != NULL)
-	{
-		/* We found a dll, so now get the addresses of the routines */
-
-		getaddrinfo_ptr = (getaddrinfo_ptr_t) (pg_funcptr_t) GetProcAddress(hLibrary,
-																			"getaddrinfo");
-		freeaddrinfo_ptr = (freeaddrinfo_ptr_t) (pg_funcptr_t) GetProcAddress(hLibrary,
-																			  "freeaddrinfo");
-		getnameinfo_ptr = (getnameinfo_ptr_t) (pg_funcptr_t) GetProcAddress(hLibrary,
-																			"getnameinfo");
-
-		/*
-		 * If any one of the routines is missing, let's play it safe and
-		 * ignore them all
-		 */
-		if (getaddrinfo_ptr == NULL ||
-			freeaddrinfo_ptr == NULL ||
-			getnameinfo_ptr == NULL)
-		{
-			FreeLibrary(hLibrary);
-			hLibrary = NULL;
-			getaddrinfo_ptr = NULL;
-			freeaddrinfo_ptr = NULL;
-			getnameinfo_ptr = NULL;
-		}
-	}
-
-	alreadyLookedForIpv6routines = true;
-	return (getaddrinfo_ptr != NULL);
-}
-#endif
-
-
-/*
- * get address info for ipv4 sockets.
- *
- *	Bugs:	- only one addrinfo is set even though hintp is NULL or
- *		  ai_socktype is 0
- *		- AI_CANONNAME is not supported.
- *		- servname can only be a number, not text.
- */
-int
-getaddrinfo(const char *node, const char *service,
-			const struct addrinfo *hintp,
-			struct addrinfo **res)
-{
-	struct addrinfo *ai;
-	struct sockaddr_in sin,
-			   *psin;
-	struct addrinfo hints;
-
-#ifdef WIN32
-
-	/*
-	 * If Windows has native IPv6 support, use the native Windows routine.
-	 * Otherwise, fall through and use our own code.
-	 */
-	if (haveNativeWindowsIPv6routines())
-		return (*getaddrinfo_ptr) (node, service, hintp, res);
-#endif
-
-	if (hintp == NULL)
-	{
-		memset(&hints, 0, sizeof(hints));
-		hints.ai_family = AF_INET;
-		hints.ai_socktype = SOCK_STREAM;
-	}
-	else
-		memcpy(&hints, hintp, sizeof(hints));
-
-	if (hints.ai_family != AF_INET && hints.ai_family != AF_UNSPEC)
-		return EAI_FAMILY;
-
-	if (hints.ai_socktype == 0)
-		hints.ai_socktype = SOCK_STREAM;
-
-	if (!node && !service)
-		return EAI_NONAME;
-
-	memset(&sin, 0, sizeof(sin));
-
-	sin.sin_family = AF_INET;
-
-	if (node)
-	{
-		if (node[0] == '\0')
-			sin.sin_addr.s_addr = pg_hton32(INADDR_ANY);
-		else if (hints.ai_flags & AI_NUMERICHOST)
-		{
-			if (!inet_aton(node, &sin.sin_addr))
-				return EAI_NONAME;
-		}
-		else
-		{
-			struct hostent *hp;
-
-#ifdef FRONTEND
-			struct hostent hpstr;
-			char		buf[BUFSIZ];
-			int			herrno = 0;
-
-			pqGethostbyname(node, &hpstr, buf, sizeof(buf),
-							&hp, &herrno);
-#else
-			hp = gethostbyname(node);
-#endif
-			if (hp == NULL)
-			{
-				switch (h_errno)
-				{
-					case HOST_NOT_FOUND:
-					case NO_DATA:
-						return EAI_NONAME;
-					case TRY_AGAIN:
-						return EAI_AGAIN;
-					case NO_RECOVERY:
-					default:
-						return EAI_FAIL;
-				}
-			}
-			if (hp->h_addrtype != AF_INET)
-				return EAI_FAIL;
-
-			memcpy(&(sin.sin_addr), hp->h_addr, hp->h_length);
-		}
-	}
-	else
-	{
-		if (hints.ai_flags & AI_PASSIVE)
-			sin.sin_addr.s_addr = pg_hton32(INADDR_ANY);
-		else
-			sin.sin_addr.s_addr = pg_hton32(INADDR_LOOPBACK);
-	}
-
-	if (service)
-		sin.sin_port = pg_hton16((unsigned short) atoi(service));
-
-#ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN
-	sin.sin_len = sizeof(sin);
-#endif
-
-	ai = malloc(sizeof(*ai));
-	if (!ai)
-		return EAI_MEMORY;
-
-	psin = malloc(sizeof(*psin));
-	if (!psin)
-	{
-		free(ai);
-		return EAI_MEMORY;
-	}
-
-	memcpy(psin, &sin, sizeof(*psin));
-
-	ai->ai_flags = 0;
-	ai->ai_family = AF_INET;
-	ai->ai_socktype = hints.ai_socktype;
-	ai->ai_protocol = hints.ai_protocol;
-	ai->ai_addrlen = sizeof(*psin);
-	ai->ai_addr = (struct sockaddr *) psin;
-	ai->ai_canonname = NULL;
-	ai->ai_next = NULL;
-
-	*res = ai;
-
-	return 0;
-}
-
-
-void
-freeaddrinfo(struct addrinfo *res)
-{
-	if (res)
-	{
-#ifdef WIN32
-
-		/*
-		 * If Windows has native IPv6 support, use the native Windows routine.
-		 * Otherwise, fall through and use our own code.
-		 */
-		if (haveNativeWindowsIPv6routines())
-		{
-			(*freeaddrinfo_ptr) (res);
-			return;
-		}
-#endif
-
-		free(res->ai_addr);
-		free(res);
-	}
-}
-
-
-const char *
-gai_strerror(int errcode)
-{
-#ifdef HAVE_HSTRERROR
-	int			hcode;
-
-	switch (errcode)
-	{
-		case EAI_NONAME:
-			hcode = HOST_NOT_FOUND;
-			break;
-		case EAI_AGAIN:
-			hcode = TRY_AGAIN;
-			break;
-		case EAI_FAIL:
-		default:
-			hcode = NO_RECOVERY;
-			break;
-	}
-
-	return hstrerror(hcode);
-#else							/* !HAVE_HSTRERROR */
-
-	switch (errcode)
-	{
-		case EAI_NONAME:
-			return "Unknown host";
-		case EAI_AGAIN:
-			return "Host name lookup failure";
-			/* Errors below are probably WIN32 only */
-#ifdef EAI_BADFLAGS
-		case EAI_BADFLAGS:
-			return "Invalid argument";
-#endif
-#ifdef EAI_FAMILY
-		case EAI_FAMILY:
-			return "Address family not supported";
-#endif
-#ifdef EAI_MEMORY
-		case EAI_MEMORY:
-			return "Not enough memory";
-#endif
-#if defined(EAI_NODATA) && EAI_NODATA != EAI_NONAME /* MSVC/WIN64 duplicate */
-		case EAI_NODATA:
-			return "No host data of that type was found";
-#endif
-#ifdef EAI_SERVICE
-		case EAI_SERVICE:
-			return "Class type not found";
-#endif
-#ifdef EAI_SOCKTYPE
-		case EAI_SOCKTYPE:
-			return "Socket type not supported";
-#endif
-		default:
-			return "Unknown server error";
-	}
-#endif							/* HAVE_HSTRERROR */
-}
-
-/*
- * Convert an ipv4 address to a hostname.
- *
- * Bugs:	- Only supports NI_NUMERICHOST and NI_NUMERICSERV behavior.
- *		  It will never resolve a hostname.
- *		- No IPv6 support.
- */
-int
-getnameinfo(const struct sockaddr *sa, int salen,
-			char *node, int nodelen,
-			char *service, int servicelen, int flags)
-{
-#ifdef WIN32
-
-	/*
-	 * If Windows has native IPv6 support, use the native Windows routine.
-	 * Otherwise, fall through and use our own code.
-	 */
-	if (haveNativeWindowsIPv6routines())
-		return (*getnameinfo_ptr) (sa, salen, node, nodelen,
-								   service, servicelen, flags);
-#endif
-
-	/* Invalid arguments. */
-	if (sa == NULL || (node == NULL && service == NULL))
-		return EAI_FAIL;
-
-#ifdef	HAVE_IPV6
-	if (sa->sa_family == AF_INET6)
-		return EAI_FAMILY;
-#endif
-
-	/* Unsupported flags. */
-	if (flags & NI_NAMEREQD)
-		return EAI_AGAIN;
-
-	if (node)
-	{
-		if (sa->sa_family == AF_INET)
-		{
-			if (pg_inet_net_ntop(AF_INET,
-								 &((struct sockaddr_in *) sa)->sin_addr,
-								 sa->sa_family == AF_INET ? 32 : 128,
-								 node, nodelen) == NULL)
-				return EAI_MEMORY;
-		}
-		else
-			return EAI_MEMORY;
-	}
-
-	if (service)
-	{
-		int			ret = -1;
-
-		if (sa->sa_family == AF_INET)
-		{
-			ret = snprintf(service, servicelen, "%d",
-						   pg_ntoh16(((struct sockaddr_in *) sa)->sin_port));
-		}
-		if (ret < 0 || ret >= servicelen)
-			return EAI_MEMORY;
-	}
-
-	return 0;
-}
-
-/*
- * Wrapper around gethostbyname() or gethostbyname_r() to mimic
- * POSIX gethostbyname_r() behaviour, if it is not available or required.
- */
-#ifdef FRONTEND
-static int
-pqGethostbyname(const char *name,
-				struct hostent *resultbuf,
-				char *buffer, size_t buflen,
-				struct hostent **result,
-				int *herrno)
-{
-#if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_GETHOSTBYNAME_R)
-
-	/*
-	 * broken (well early POSIX draft) gethostbyname_r() which returns 'struct
-	 * hostent *'
-	 */
-	*result = gethostbyname_r(name, resultbuf, buffer, buflen, herrno);
-	return (*result == NULL) ? -1 : 0;
-#else
-
-	/* no gethostbyname_r(), just use gethostbyname() */
-	*result = gethostbyname(name);
-
-	if (*result != NULL)
-		*herrno = h_errno;
-
-	if (*result != NULL)
-		return 0;
-	else
-		return -1;
-#endif
-}
-#endif							/* FRONTEND */
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index 0a4f0d2eaa..85d03372a5 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -101,7 +101,7 @@ sub mkvcbuild
 	our @pgportfiles = qw(
 	  chklocale.c explicit_bzero.c
 	  getpeereid.c inet_aton.c
-	  getaddrinfo.c inet_net_ntop.c kill.c open.c
+	  inet_net_ntop.c kill.c open.c
 	  snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c
 	  dirent.c getopt.c getopt_long.c
 	  preadv.c pwritev.c pg_bitutils.c
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 1632931840..09ad8489a6 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -256,7 +256,6 @@ sub GenerateFiles
 		HAVE_GCC__SYNC_INT32_CAS                    => undef,
 		HAVE_GCC__SYNC_INT32_TAS                    => undef,
 		HAVE_GCC__SYNC_INT64_CAS                    => undef,
-		HAVE_GETADDRINFO                            => undef,
 		HAVE_GETHOSTBYNAME_R                        => undef,
 		HAVE_GETIFADDRS                             => undef,
 		HAVE_GETOPT                                 => undef,
@@ -346,7 +345,6 @@ sub GenerateFiles
 		HAVE_STRLCPY                             => undef,
 		HAVE_STRNLEN                             => 1,
 		HAVE_STRSIGNAL                           => undef,
-		HAVE_STRUCT_ADDRINFO                     => 1,
 		HAVE_STRUCT_CMSGCRED                     => undef,
 		HAVE_STRUCT_OPTION                       => undef,
 		HAVE_STRUCT_SOCKADDR_SA_LEN              => undef,
-- 
2.30.2

0001-Remove-HAVE_UNIX_SOCKETS.patchtext/x-patch; charset=US-ASCII; name=0001-Remove-HAVE_UNIX_SOCKETS.patchDownload
From 87c1b8dff6dea44f6ef920b0b02386e5e2b68be4 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Thu, 11 Aug 2022 15:30:38 +1200
Subject: [PATCH 1/3] Remove HAVE_UNIX_SOCKETS.

Since HAVE_UNIX_SOCKETS is now defined unconditionally, remove the macro
and drop a small amount of dead code.

The last known systems not to have them (as far as I know at least) were
QNX, which we de-supported years ago, and Windows, which now has them.

If a hypothetical new OS shows up with the POSIX sockets API but without
working AF_UNIX, it'll presumably still be able to compile the code, and
fail at runtime with unsupported address family.  We might want to
consider adding a HINT that you should turn it off if your OS doesn't
support it at that point, but it doesn't seem worth making the relevant
code compile-time conditional.

Reviewed-by: Peter Eisentraut <peter.eisentraut@enterprisedb.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Andres Freund <andres@anarazel.de>
Discussion: https://postgr.es/m/CA%2BhUKG%2BL_3brvh%3D8e0BW_VfX9h7MtwgN%3DnFHP5o7X2oZucY9dg%40mail.gmail.com
---
 src/backend/libpq/hba.c             | 10 -------
 src/backend/libpq/pqcomm.c          | 18 -------------
 src/backend/postmaster/postmaster.c |  2 --
 src/backend/utils/misc/guc.c        |  4 ---
 src/bin/initdb/initdb.c             | 41 -----------------------------
 src/bin/pg_upgrade/option.c         |  4 +--
 src/bin/pg_upgrade/server.c         |  2 +-
 src/common/ip.c                     | 11 --------
 src/include/port.h                  |  3 ---
 src/interfaces/libpq/fe-connect.c   | 12 ---------
 src/test/regress/pg_regress.c       | 19 ++-----------
 11 files changed, 5 insertions(+), 121 deletions(-)

diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index deee05c197..66f2156cde 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -973,17 +973,7 @@ parse_hba_line(TokenizedAuthLine *tok_line, int elevel)
 	token = linitial(tokens);
 	if (strcmp(token->string, "local") == 0)
 	{
-#ifdef HAVE_UNIX_SOCKETS
 		parsedline->conntype = ctLocal;
-#else
-		ereport(elevel,
-				(errcode(ERRCODE_CONFIG_FILE_ERROR),
-				 errmsg("local connections are not supported by this build"),
-				 errcontext("line %d of configuration file \"%s\"",
-							line_num, HbaFileName)));
-		*err_msg = "local connections are not supported by this build";
-		return NULL;
-#endif
 	}
 	else if (strcmp(token->string, "host") == 0 ||
 			 strcmp(token->string, "hostssl") == 0 ||
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 75392a8bb7..3ec4328613 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -149,10 +149,8 @@ static void socket_putmessage_noblock(char msgtype, const char *s, size_t len);
 static int	internal_putbytes(const char *s, size_t len);
 static int	internal_flush(void);
 
-#ifdef HAVE_UNIX_SOCKETS
 static int	Lock_AF_UNIX(const char *unixSocketDir, const char *unixSocketPath);
 static int	Setup_AF_UNIX(const char *sock_path);
-#endif							/* HAVE_UNIX_SOCKETS */
 
 static const PQcommMethods PqCommSocketMethods = {
 	socket_comm_reset,
@@ -334,10 +332,7 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
 	struct addrinfo hint;
 	int			listen_index = 0;
 	int			added = 0;
-
-#ifdef HAVE_UNIX_SOCKETS
 	char		unixSocketPath[MAXPGPATH];
-#endif
 #if !defined(WIN32) || defined(IPV6_V6ONLY)
 	int			one = 1;
 #endif
@@ -348,7 +343,6 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
 	hint.ai_flags = AI_PASSIVE;
 	hint.ai_socktype = SOCK_STREAM;
 
-#ifdef HAVE_UNIX_SOCKETS
 	if (family == AF_UNIX)
 	{
 		/*
@@ -369,7 +363,6 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
 		service = unixSocketPath;
 	}
 	else
-#endif							/* HAVE_UNIX_SOCKETS */
 	{
 		snprintf(portNumberStr, sizeof(portNumberStr), "%d", portNumber);
 		service = portNumberStr;
@@ -427,11 +420,9 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
 				familyDesc = _("IPv6");
 				break;
 #endif
-#ifdef HAVE_UNIX_SOCKETS
 			case AF_UNIX:
 				familyDesc = _("Unix");
 				break;
-#endif
 			default:
 				snprintf(familyDescBuf, sizeof(familyDescBuf),
 						 _("unrecognized address family %d"),
@@ -441,11 +432,9 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
 		}
 
 		/* set up text form of address for log messages */
-#ifdef HAVE_UNIX_SOCKETS
 		if (addr->ai_family == AF_UNIX)
 			addrDesc = unixSocketPath;
 		else
-#endif
 		{
 			pg_getnameinfo_all((const struct sockaddr_storage *) addr->ai_addr,
 							   addr->ai_addrlen,
@@ -540,7 +529,6 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
 			continue;
 		}
 
-#ifdef HAVE_UNIX_SOCKETS
 		if (addr->ai_family == AF_UNIX)
 		{
 			if (Setup_AF_UNIX(service) != STATUS_OK)
@@ -549,7 +537,6 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
 				break;
 			}
 		}
-#endif
 
 		/*
 		 * Select appropriate accept-queue length limit.  PG_SOMAXCONN is only
@@ -572,13 +559,11 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
 			continue;
 		}
 
-#ifdef HAVE_UNIX_SOCKETS
 		if (addr->ai_family == AF_UNIX)
 			ereport(LOG,
 					(errmsg("listening on Unix socket \"%s\"",
 							addrDesc)));
 		else
-#endif
 			ereport(LOG,
 			/* translator: first %s is IPv4 or IPv6 */
 					(errmsg("listening on %s address \"%s\", port %d",
@@ -597,8 +582,6 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
 }
 
 
-#ifdef HAVE_UNIX_SOCKETS
-
 /*
  * Lock_AF_UNIX -- configure unix socket file path
  */
@@ -699,7 +682,6 @@ Setup_AF_UNIX(const char *sock_path)
 	}
 	return STATUS_OK;
 }
-#endif							/* HAVE_UNIX_SOCKETS */
 
 
 /*
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 227bd9891e..8a038d1b2a 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -1297,7 +1297,6 @@ PostmasterMain(int argc, char *argv[])
 	}
 #endif
 
-#ifdef HAVE_UNIX_SOCKETS
 	if (Unix_socket_directories)
 	{
 		char	   *rawstring;
@@ -1347,7 +1346,6 @@ PostmasterMain(int argc, char *argv[])
 		list_free_deep(elemlist);
 		pfree(rawstring);
 	}
-#endif
 
 	/*
 	 * check that we have some socket to listen on
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 5db5df6285..9fbbfb1be5 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -4452,11 +4452,7 @@ static struct config_string ConfigureNamesString[] =
 			GUC_LIST_INPUT | GUC_LIST_QUOTE | GUC_SUPERUSER_ONLY
 		},
 		&Unix_socket_directories,
-#ifdef HAVE_UNIX_SOCKETS
 		DEFAULT_PGSOCKET_DIR,
-#else
-		"",
-#endif
 		NULL, NULL, NULL
 	},
 
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 2c93ffe811..4feb5db3fa 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -242,9 +242,6 @@ static char backend_exec[MAXPGPATH];
 static char **replace_token(char **lines,
 							const char *token, const char *replacement);
 
-#ifndef HAVE_UNIX_SOCKETS
-static char **filter_lines_with_token(char **lines, const char *token);
-#endif
 static char **readfile(const char *path);
 static void writefile(char *path, char **lines);
 static FILE *popen_check(const char *command, const char *mode);
@@ -418,36 +415,6 @@ replace_token(char **lines, const char *token, const char *replacement)
 	return result;
 }
 
-/*
- * make a copy of lines without any that contain the token
- *
- * a sort of poor man's grep -v
- */
-#ifndef HAVE_UNIX_SOCKETS
-static char **
-filter_lines_with_token(char **lines, const char *token)
-{
-	int			numlines = 1;
-	int			i,
-				src,
-				dst;
-	char	  **result;
-
-	for (i = 0; lines[i]; i++)
-		numlines++;
-
-	result = (char **) pg_malloc(numlines * sizeof(char *));
-
-	for (src = 0, dst = 0; src < numlines; src++)
-	{
-		if (lines[src] == NULL || strstr(lines[src], token) == NULL)
-			result[dst++] = lines[src];
-	}
-
-	return result;
-}
-#endif
-
 /*
  * get the lines from a text file
  */
@@ -1045,12 +1012,8 @@ setup_config(void)
 				 n_buffers * (BLCKSZ / 1024));
 	conflines = replace_token(conflines, "#shared_buffers = 128MB", repltok);
 
-#ifdef HAVE_UNIX_SOCKETS
 	snprintf(repltok, sizeof(repltok), "#unix_socket_directories = '%s'",
 			 DEFAULT_PGSOCKET_DIR);
-#else
-	snprintf(repltok, sizeof(repltok), "#unix_socket_directories = ''");
-#endif
 	conflines = replace_token(conflines, "#unix_socket_directories = '/tmp'",
 							  repltok);
 
@@ -1210,11 +1173,7 @@ setup_config(void)
 
 	conflines = readfile(hba_file);
 
-#ifndef HAVE_UNIX_SOCKETS
-	conflines = filter_lines_with_token(conflines, "@remove-line-for-nolocal@");
-#else
 	conflines = replace_token(conflines, "@remove-line-for-nolocal@", "");
-#endif
 
 #ifdef HAVE_IPV6
 
diff --git a/src/bin/pg_upgrade/option.c b/src/bin/pg_upgrade/option.c
index 0954b75ec0..fbab1c4fb7 100644
--- a/src/bin/pg_upgrade/option.c
+++ b/src/bin/pg_upgrade/option.c
@@ -444,7 +444,7 @@ adjust_data_dir(ClusterInfo *cluster)
 void
 get_sock_dir(ClusterInfo *cluster, bool live_check)
 {
-#if defined(HAVE_UNIX_SOCKETS) && !defined(WIN32)
+#if !defined(WIN32)
 	if (!live_check)
 		cluster->sockdir = user_opts.socketdir;
 	else
@@ -490,7 +490,7 @@ get_sock_dir(ClusterInfo *cluster, bool live_check)
 			pg_log(PG_WARNING, "user-supplied old port number %hu corrected to %hu",
 				   orig_port, cluster->port);
 	}
-#else							/* !HAVE_UNIX_SOCKETS || WIN32 */
+#else							/* WIN32 */
 	cluster->sockdir = NULL;
 #endif
 }
diff --git a/src/bin/pg_upgrade/server.c b/src/bin/pg_upgrade/server.c
index 79479edc0e..9a1a20fb27 100644
--- a/src/bin/pg_upgrade/server.c
+++ b/src/bin/pg_upgrade/server.c
@@ -212,7 +212,7 @@ start_postmaster(ClusterInfo *cluster, bool report_and_exit_on_error)
 
 	socket_string[0] = '\0';
 
-#if defined(HAVE_UNIX_SOCKETS) && !defined(WIN32)
+#if !defined(WIN32)
 	/* prevent TCP/IP connections, restrict socket access */
 	strcat(socket_string,
 		   " -c listen_addresses='' -c unix_socket_permissions=0700");
diff --git a/src/common/ip.c b/src/common/ip.c
index 267103efb9..dd9193feb1 100644
--- a/src/common/ip.c
+++ b/src/common/ip.c
@@ -38,7 +38,6 @@
 
 
 
-#ifdef	HAVE_UNIX_SOCKETS
 static int	getaddrinfo_unix(const char *path,
 							 const struct addrinfo *hintsp,
 							 struct addrinfo **result);
@@ -47,7 +46,6 @@ static int	getnameinfo_unix(const struct sockaddr_un *sa, int salen,
 							 char *node, int nodelen,
 							 char *service, int servicelen,
 							 int flags);
-#endif
 
 
 /*
@@ -62,10 +60,8 @@ pg_getaddrinfo_all(const char *hostname, const char *servname,
 	/* not all versions of getaddrinfo() zero *result on failure */
 	*result = NULL;
 
-#ifdef HAVE_UNIX_SOCKETS
 	if (hintp->ai_family == AF_UNIX)
 		return getaddrinfo_unix(servname, hintp, result);
-#endif
 
 	/* NULL has special meaning to getaddrinfo(). */
 	rc = getaddrinfo((!hostname || hostname[0] == '\0') ? NULL : hostname,
@@ -87,7 +83,6 @@ pg_getaddrinfo_all(const char *hostname, const char *servname,
 void
 pg_freeaddrinfo_all(int hint_ai_family, struct addrinfo *ai)
 {
-#ifdef HAVE_UNIX_SOCKETS
 	if (hint_ai_family == AF_UNIX)
 	{
 		/* struct was built by getaddrinfo_unix (see pg_getaddrinfo_all) */
@@ -101,7 +96,6 @@ pg_freeaddrinfo_all(int hint_ai_family, struct addrinfo *ai)
 		}
 	}
 	else
-#endif							/* HAVE_UNIX_SOCKETS */
 	{
 		/* struct was built by getaddrinfo() */
 		if (ai != NULL)
@@ -126,14 +120,12 @@ pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen,
 {
 	int			rc;
 
-#ifdef HAVE_UNIX_SOCKETS
 	if (addr && addr->ss_family == AF_UNIX)
 		rc = getnameinfo_unix((const struct sockaddr_un *) addr, salen,
 							  node, nodelen,
 							  service, servicelen,
 							  flags);
 	else
-#endif
 		rc = getnameinfo((const struct sockaddr *) addr, salen,
 						 node, nodelen,
 						 service, servicelen,
@@ -151,8 +143,6 @@ pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen,
 }
 
 
-#if defined(HAVE_UNIX_SOCKETS)
-
 /* -------
  *	getaddrinfo_unix - get unix socket info using IPv6-compatible API
  *
@@ -286,4 +276,3 @@ getnameinfo_unix(const struct sockaddr_un *sa, int salen,
 
 	return 0;
 }
-#endif							/* HAVE_UNIX_SOCKETS */
diff --git a/src/include/port.h b/src/include/port.h
index 80dcfb7dfe..cec41eae71 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -503,7 +503,4 @@ extern bool wait_result_is_any_signal(int exit_status, bool include_command_not_
 #define HAVE_SYMLINK 1
 #endif
 
-/* Interfaces that we assume that all systems have. */
-#define HAVE_UNIX_SOCKETS 1
-
 #endif							/* PG_PORT_H */
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index dc49387d6c..730e79a31d 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -1102,10 +1102,8 @@ connectOptions2(PGconn *conn)
 		else if (ch->host != NULL && ch->host[0] != '\0')
 		{
 			ch->type = CHT_HOST_NAME;
-#ifdef HAVE_UNIX_SOCKETS
 			if (is_unixsock_path(ch->host))
 				ch->type = CHT_UNIX_SOCKET;
-#endif
 		}
 		else
 		{
@@ -1115,14 +1113,12 @@ connectOptions2(PGconn *conn)
 			 * This bit selects the default host location.  If you change
 			 * this, see also pg_regress.
 			 */
-#ifdef HAVE_UNIX_SOCKETS
 			if (DEFAULT_PGSOCKET_DIR[0])
 			{
 				ch->host = strdup(DEFAULT_PGSOCKET_DIR);
 				ch->type = CHT_UNIX_SOCKET;
 			}
 			else
-#endif
 			{
 				ch->host = strdup(DefaultHost);
 				ch->type = CHT_HOST_NAME;
@@ -1684,7 +1680,6 @@ getHostaddr(PGconn *conn, char *host_addr, int host_addr_len)
 static void
 emitHostIdentityInfo(PGconn *conn, const char *host_addr)
 {
-#ifdef HAVE_UNIX_SOCKETS
 	if (conn->raddr.addr.ss_family == AF_UNIX)
 	{
 		char		service[NI_MAXHOST];
@@ -1698,7 +1693,6 @@ emitHostIdentityInfo(PGconn *conn, const char *host_addr)
 						  service);
 	}
 	else
-#endif							/* HAVE_UNIX_SOCKETS */
 	{
 		const char *displayed_host;
 		const char *displayed_port;
@@ -1748,12 +1742,10 @@ connectFailureMessage(PGconn *conn, int errorno)
 					  "%s\n",
 					  SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)));
 
-#ifdef HAVE_UNIX_SOCKETS
 	if (conn->raddr.addr.ss_family == AF_UNIX)
 		appendPQExpBufferStr(&conn->errorMessage,
 							 libpq_gettext("\tIs the server running locally and accepting connections on that socket?\n"));
 	else
-#endif
 		appendPQExpBufferStr(&conn->errorMessage,
 							 libpq_gettext("\tIs the server running on that host and accepting TCP/IP connections?\n"));
 }
@@ -2415,7 +2407,6 @@ keep_going:						/* We will come back to here until there is
 				break;
 
 			case CHT_UNIX_SOCKET:
-#ifdef HAVE_UNIX_SOCKETS
 				conn->addrlist_family = hint.ai_family = AF_UNIX;
 				UNIXSOCK_PATH(portstr, thisport, ch->host);
 				if (strlen(portstr) >= UNIXSOCK_PATH_BUFLEN)
@@ -2440,9 +2431,6 @@ keep_going:						/* We will come back to here until there is
 									  portstr, gai_strerror(ret));
 					goto keep_going;
 				}
-#else
-				Assert(false);
-#endif
 				break;
 		}
 
diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c
index e015a11c21..cd5a5fd5dd 100644
--- a/src/test/regress/pg_regress.c
+++ b/src/test/regress/pg_regress.c
@@ -99,11 +99,9 @@ static char *logfilename;
 static FILE *logfile;
 static char *difffilename;
 static const char *sockdir;
-#ifdef HAVE_UNIX_SOCKETS
 static const char *temp_sockdir;
 static char sockself[MAXPGPATH];
 static char socklock[MAXPGPATH];
-#endif
 
 static _resultmap *resultmap = NULL;
 
@@ -285,7 +283,6 @@ stop_postmaster(void)
 	}
 }
 
-#ifdef HAVE_UNIX_SOCKETS
 /*
  * Remove the socket temporary directory.  pg_regress never waits for a
  * postmaster exit, so it is indeterminate whether the postmaster has yet to
@@ -360,7 +357,6 @@ make_temp_sockdir(void)
 
 	return temp_sockdir;
 }
-#endif							/* HAVE_UNIX_SOCKETS */
 
 /*
  * Check whether string matches pattern
@@ -683,7 +679,6 @@ initialize_environment(void)
 		/* PGPORT, see below */
 		/* PGHOST, see below */
 
-#ifdef HAVE_UNIX_SOCKETS
 		if (hostname != NULL)
 			setenv("PGHOST", hostname, 1);
 		else
@@ -693,10 +688,6 @@ initialize_environment(void)
 				sockdir = make_temp_sockdir();
 			setenv("PGHOST", sockdir, 1);
 		}
-#else
-		Assert(hostname != NULL);
-		setenv("PGHOST", hostname, 1);
-#endif
 		unsetenv("PGHOSTADDR");
 		if (port != -1)
 		{
@@ -746,11 +737,9 @@ initialize_environment(void)
 		if (!pghost)
 		{
 			/* Keep this bit in sync with libpq's default host location: */
-#ifdef HAVE_UNIX_SOCKETS
 			if (DEFAULT_PGSOCKET_DIR[0])
 				 /* do nothing, we'll print "Unix socket" below */ ;
 			else
-#endif
 				pghost = "localhost";	/* DefaultHost in fe-connect.c */
 		}
 
@@ -2068,9 +2057,7 @@ regression_main(int argc, char *argv[],
 
 	atexit(stop_postmaster);
 
-#if !defined(HAVE_UNIX_SOCKETS)
-	use_unix_sockets = false;
-#elif defined(WIN32)
+#if defined(WIN32)
 
 	/*
 	 * We don't use Unix-domain sockets on Windows by default, even if the
@@ -2209,7 +2196,7 @@ regression_main(int argc, char *argv[],
 		/*
 		 * To reduce chances of interference with parallel installations, use
 		 * a port number starting in the private range (49152-65535)
-		 * calculated from the version number.  This aids !HAVE_UNIX_SOCKETS
+		 * calculated from the version number.  This aids non-Unix socket mode
 		 * systems; elsewhere, the use of a private socket directory already
 		 * prevents interference.
 		 */
@@ -2329,8 +2316,6 @@ regression_main(int argc, char *argv[],
 			snprintf(buf, sizeof(buf), "%s/data", temp_instance);
 			config_sspi_auth(buf, NULL);
 		}
-#elif !defined(HAVE_UNIX_SOCKETS)
-#error Platform has no means to secure the test installation.
 #endif
 
 		/*
-- 
2.30.2

#76Thomas Munro
thomas.munro@gmail.com
In reply to: Thomas Munro (#75)
4 attachment(s)
Re: Cleaning up historical portability baggage

On Sun, Aug 14, 2022 at 12:23 AM Thomas Munro <thomas.munro@gmail.com> wrote:

Remove HAVE_UNIX_SOCKETS.
Remove configure probe for struct sockaddr_storage.
Remove configure probe for getaddrinfo, and replacement code.

Plus one more that falls out of the above (it was only used by
src/port/getaddrinfo.c):

Remove configure probe for gethostbyname_r.

Attachments:

0001-Remove-HAVE_UNIX_SOCKETS.patchtext/x-patch; charset=US-ASCII; name=0001-Remove-HAVE_UNIX_SOCKETS.patchDownload
From 87c1b8dff6dea44f6ef920b0b02386e5e2b68be4 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Thu, 11 Aug 2022 15:30:38 +1200
Subject: [PATCH 1/4] Remove HAVE_UNIX_SOCKETS.

Since HAVE_UNIX_SOCKETS is now defined unconditionally, remove the macro
and drop a small amount of dead code.

The last known systems not to have them (as far as I know at least) were
QNX, which we de-supported years ago, and Windows, which now has them.

If a hypothetical new OS shows up with the POSIX sockets API but without
working AF_UNIX, it'll presumably still be able to compile the code, and
fail at runtime with unsupported address family.  We might want to
consider adding a HINT that you should turn it off if your OS doesn't
support it at that point, but it doesn't seem worth making the relevant
code compile-time conditional.

Reviewed-by: Peter Eisentraut <peter.eisentraut@enterprisedb.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Andres Freund <andres@anarazel.de>
Discussion: https://postgr.es/m/CA%2BhUKG%2BL_3brvh%3D8e0BW_VfX9h7MtwgN%3DnFHP5o7X2oZucY9dg%40mail.gmail.com
---
 src/backend/libpq/hba.c             | 10 -------
 src/backend/libpq/pqcomm.c          | 18 -------------
 src/backend/postmaster/postmaster.c |  2 --
 src/backend/utils/misc/guc.c        |  4 ---
 src/bin/initdb/initdb.c             | 41 -----------------------------
 src/bin/pg_upgrade/option.c         |  4 +--
 src/bin/pg_upgrade/server.c         |  2 +-
 src/common/ip.c                     | 11 --------
 src/include/port.h                  |  3 ---
 src/interfaces/libpq/fe-connect.c   | 12 ---------
 src/test/regress/pg_regress.c       | 19 ++-----------
 11 files changed, 5 insertions(+), 121 deletions(-)

diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index deee05c197..66f2156cde 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -973,17 +973,7 @@ parse_hba_line(TokenizedAuthLine *tok_line, int elevel)
 	token = linitial(tokens);
 	if (strcmp(token->string, "local") == 0)
 	{
-#ifdef HAVE_UNIX_SOCKETS
 		parsedline->conntype = ctLocal;
-#else
-		ereport(elevel,
-				(errcode(ERRCODE_CONFIG_FILE_ERROR),
-				 errmsg("local connections are not supported by this build"),
-				 errcontext("line %d of configuration file \"%s\"",
-							line_num, HbaFileName)));
-		*err_msg = "local connections are not supported by this build";
-		return NULL;
-#endif
 	}
 	else if (strcmp(token->string, "host") == 0 ||
 			 strcmp(token->string, "hostssl") == 0 ||
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 75392a8bb7..3ec4328613 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -149,10 +149,8 @@ static void socket_putmessage_noblock(char msgtype, const char *s, size_t len);
 static int	internal_putbytes(const char *s, size_t len);
 static int	internal_flush(void);
 
-#ifdef HAVE_UNIX_SOCKETS
 static int	Lock_AF_UNIX(const char *unixSocketDir, const char *unixSocketPath);
 static int	Setup_AF_UNIX(const char *sock_path);
-#endif							/* HAVE_UNIX_SOCKETS */
 
 static const PQcommMethods PqCommSocketMethods = {
 	socket_comm_reset,
@@ -334,10 +332,7 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
 	struct addrinfo hint;
 	int			listen_index = 0;
 	int			added = 0;
-
-#ifdef HAVE_UNIX_SOCKETS
 	char		unixSocketPath[MAXPGPATH];
-#endif
 #if !defined(WIN32) || defined(IPV6_V6ONLY)
 	int			one = 1;
 #endif
@@ -348,7 +343,6 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
 	hint.ai_flags = AI_PASSIVE;
 	hint.ai_socktype = SOCK_STREAM;
 
-#ifdef HAVE_UNIX_SOCKETS
 	if (family == AF_UNIX)
 	{
 		/*
@@ -369,7 +363,6 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
 		service = unixSocketPath;
 	}
 	else
-#endif							/* HAVE_UNIX_SOCKETS */
 	{
 		snprintf(portNumberStr, sizeof(portNumberStr), "%d", portNumber);
 		service = portNumberStr;
@@ -427,11 +420,9 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
 				familyDesc = _("IPv6");
 				break;
 #endif
-#ifdef HAVE_UNIX_SOCKETS
 			case AF_UNIX:
 				familyDesc = _("Unix");
 				break;
-#endif
 			default:
 				snprintf(familyDescBuf, sizeof(familyDescBuf),
 						 _("unrecognized address family %d"),
@@ -441,11 +432,9 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
 		}
 
 		/* set up text form of address for log messages */
-#ifdef HAVE_UNIX_SOCKETS
 		if (addr->ai_family == AF_UNIX)
 			addrDesc = unixSocketPath;
 		else
-#endif
 		{
 			pg_getnameinfo_all((const struct sockaddr_storage *) addr->ai_addr,
 							   addr->ai_addrlen,
@@ -540,7 +529,6 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
 			continue;
 		}
 
-#ifdef HAVE_UNIX_SOCKETS
 		if (addr->ai_family == AF_UNIX)
 		{
 			if (Setup_AF_UNIX(service) != STATUS_OK)
@@ -549,7 +537,6 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
 				break;
 			}
 		}
-#endif
 
 		/*
 		 * Select appropriate accept-queue length limit.  PG_SOMAXCONN is only
@@ -572,13 +559,11 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
 			continue;
 		}
 
-#ifdef HAVE_UNIX_SOCKETS
 		if (addr->ai_family == AF_UNIX)
 			ereport(LOG,
 					(errmsg("listening on Unix socket \"%s\"",
 							addrDesc)));
 		else
-#endif
 			ereport(LOG,
 			/* translator: first %s is IPv4 or IPv6 */
 					(errmsg("listening on %s address \"%s\", port %d",
@@ -597,8 +582,6 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
 }
 
 
-#ifdef HAVE_UNIX_SOCKETS
-
 /*
  * Lock_AF_UNIX -- configure unix socket file path
  */
@@ -699,7 +682,6 @@ Setup_AF_UNIX(const char *sock_path)
 	}
 	return STATUS_OK;
 }
-#endif							/* HAVE_UNIX_SOCKETS */
 
 
 /*
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 227bd9891e..8a038d1b2a 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -1297,7 +1297,6 @@ PostmasterMain(int argc, char *argv[])
 	}
 #endif
 
-#ifdef HAVE_UNIX_SOCKETS
 	if (Unix_socket_directories)
 	{
 		char	   *rawstring;
@@ -1347,7 +1346,6 @@ PostmasterMain(int argc, char *argv[])
 		list_free_deep(elemlist);
 		pfree(rawstring);
 	}
-#endif
 
 	/*
 	 * check that we have some socket to listen on
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 5db5df6285..9fbbfb1be5 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -4452,11 +4452,7 @@ static struct config_string ConfigureNamesString[] =
 			GUC_LIST_INPUT | GUC_LIST_QUOTE | GUC_SUPERUSER_ONLY
 		},
 		&Unix_socket_directories,
-#ifdef HAVE_UNIX_SOCKETS
 		DEFAULT_PGSOCKET_DIR,
-#else
-		"",
-#endif
 		NULL, NULL, NULL
 	},
 
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 2c93ffe811..4feb5db3fa 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -242,9 +242,6 @@ static char backend_exec[MAXPGPATH];
 static char **replace_token(char **lines,
 							const char *token, const char *replacement);
 
-#ifndef HAVE_UNIX_SOCKETS
-static char **filter_lines_with_token(char **lines, const char *token);
-#endif
 static char **readfile(const char *path);
 static void writefile(char *path, char **lines);
 static FILE *popen_check(const char *command, const char *mode);
@@ -418,36 +415,6 @@ replace_token(char **lines, const char *token, const char *replacement)
 	return result;
 }
 
-/*
- * make a copy of lines without any that contain the token
- *
- * a sort of poor man's grep -v
- */
-#ifndef HAVE_UNIX_SOCKETS
-static char **
-filter_lines_with_token(char **lines, const char *token)
-{
-	int			numlines = 1;
-	int			i,
-				src,
-				dst;
-	char	  **result;
-
-	for (i = 0; lines[i]; i++)
-		numlines++;
-
-	result = (char **) pg_malloc(numlines * sizeof(char *));
-
-	for (src = 0, dst = 0; src < numlines; src++)
-	{
-		if (lines[src] == NULL || strstr(lines[src], token) == NULL)
-			result[dst++] = lines[src];
-	}
-
-	return result;
-}
-#endif
-
 /*
  * get the lines from a text file
  */
@@ -1045,12 +1012,8 @@ setup_config(void)
 				 n_buffers * (BLCKSZ / 1024));
 	conflines = replace_token(conflines, "#shared_buffers = 128MB", repltok);
 
-#ifdef HAVE_UNIX_SOCKETS
 	snprintf(repltok, sizeof(repltok), "#unix_socket_directories = '%s'",
 			 DEFAULT_PGSOCKET_DIR);
-#else
-	snprintf(repltok, sizeof(repltok), "#unix_socket_directories = ''");
-#endif
 	conflines = replace_token(conflines, "#unix_socket_directories = '/tmp'",
 							  repltok);
 
@@ -1210,11 +1173,7 @@ setup_config(void)
 
 	conflines = readfile(hba_file);
 
-#ifndef HAVE_UNIX_SOCKETS
-	conflines = filter_lines_with_token(conflines, "@remove-line-for-nolocal@");
-#else
 	conflines = replace_token(conflines, "@remove-line-for-nolocal@", "");
-#endif
 
 #ifdef HAVE_IPV6
 
diff --git a/src/bin/pg_upgrade/option.c b/src/bin/pg_upgrade/option.c
index 0954b75ec0..fbab1c4fb7 100644
--- a/src/bin/pg_upgrade/option.c
+++ b/src/bin/pg_upgrade/option.c
@@ -444,7 +444,7 @@ adjust_data_dir(ClusterInfo *cluster)
 void
 get_sock_dir(ClusterInfo *cluster, bool live_check)
 {
-#if defined(HAVE_UNIX_SOCKETS) && !defined(WIN32)
+#if !defined(WIN32)
 	if (!live_check)
 		cluster->sockdir = user_opts.socketdir;
 	else
@@ -490,7 +490,7 @@ get_sock_dir(ClusterInfo *cluster, bool live_check)
 			pg_log(PG_WARNING, "user-supplied old port number %hu corrected to %hu",
 				   orig_port, cluster->port);
 	}
-#else							/* !HAVE_UNIX_SOCKETS || WIN32 */
+#else							/* WIN32 */
 	cluster->sockdir = NULL;
 #endif
 }
diff --git a/src/bin/pg_upgrade/server.c b/src/bin/pg_upgrade/server.c
index 79479edc0e..9a1a20fb27 100644
--- a/src/bin/pg_upgrade/server.c
+++ b/src/bin/pg_upgrade/server.c
@@ -212,7 +212,7 @@ start_postmaster(ClusterInfo *cluster, bool report_and_exit_on_error)
 
 	socket_string[0] = '\0';
 
-#if defined(HAVE_UNIX_SOCKETS) && !defined(WIN32)
+#if !defined(WIN32)
 	/* prevent TCP/IP connections, restrict socket access */
 	strcat(socket_string,
 		   " -c listen_addresses='' -c unix_socket_permissions=0700");
diff --git a/src/common/ip.c b/src/common/ip.c
index 267103efb9..dd9193feb1 100644
--- a/src/common/ip.c
+++ b/src/common/ip.c
@@ -38,7 +38,6 @@
 
 
 
-#ifdef	HAVE_UNIX_SOCKETS
 static int	getaddrinfo_unix(const char *path,
 							 const struct addrinfo *hintsp,
 							 struct addrinfo **result);
@@ -47,7 +46,6 @@ static int	getnameinfo_unix(const struct sockaddr_un *sa, int salen,
 							 char *node, int nodelen,
 							 char *service, int servicelen,
 							 int flags);
-#endif
 
 
 /*
@@ -62,10 +60,8 @@ pg_getaddrinfo_all(const char *hostname, const char *servname,
 	/* not all versions of getaddrinfo() zero *result on failure */
 	*result = NULL;
 
-#ifdef HAVE_UNIX_SOCKETS
 	if (hintp->ai_family == AF_UNIX)
 		return getaddrinfo_unix(servname, hintp, result);
-#endif
 
 	/* NULL has special meaning to getaddrinfo(). */
 	rc = getaddrinfo((!hostname || hostname[0] == '\0') ? NULL : hostname,
@@ -87,7 +83,6 @@ pg_getaddrinfo_all(const char *hostname, const char *servname,
 void
 pg_freeaddrinfo_all(int hint_ai_family, struct addrinfo *ai)
 {
-#ifdef HAVE_UNIX_SOCKETS
 	if (hint_ai_family == AF_UNIX)
 	{
 		/* struct was built by getaddrinfo_unix (see pg_getaddrinfo_all) */
@@ -101,7 +96,6 @@ pg_freeaddrinfo_all(int hint_ai_family, struct addrinfo *ai)
 		}
 	}
 	else
-#endif							/* HAVE_UNIX_SOCKETS */
 	{
 		/* struct was built by getaddrinfo() */
 		if (ai != NULL)
@@ -126,14 +120,12 @@ pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen,
 {
 	int			rc;
 
-#ifdef HAVE_UNIX_SOCKETS
 	if (addr && addr->ss_family == AF_UNIX)
 		rc = getnameinfo_unix((const struct sockaddr_un *) addr, salen,
 							  node, nodelen,
 							  service, servicelen,
 							  flags);
 	else
-#endif
 		rc = getnameinfo((const struct sockaddr *) addr, salen,
 						 node, nodelen,
 						 service, servicelen,
@@ -151,8 +143,6 @@ pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen,
 }
 
 
-#if defined(HAVE_UNIX_SOCKETS)
-
 /* -------
  *	getaddrinfo_unix - get unix socket info using IPv6-compatible API
  *
@@ -286,4 +276,3 @@ getnameinfo_unix(const struct sockaddr_un *sa, int salen,
 
 	return 0;
 }
-#endif							/* HAVE_UNIX_SOCKETS */
diff --git a/src/include/port.h b/src/include/port.h
index 80dcfb7dfe..cec41eae71 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -503,7 +503,4 @@ extern bool wait_result_is_any_signal(int exit_status, bool include_command_not_
 #define HAVE_SYMLINK 1
 #endif
 
-/* Interfaces that we assume that all systems have. */
-#define HAVE_UNIX_SOCKETS 1
-
 #endif							/* PG_PORT_H */
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index dc49387d6c..730e79a31d 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -1102,10 +1102,8 @@ connectOptions2(PGconn *conn)
 		else if (ch->host != NULL && ch->host[0] != '\0')
 		{
 			ch->type = CHT_HOST_NAME;
-#ifdef HAVE_UNIX_SOCKETS
 			if (is_unixsock_path(ch->host))
 				ch->type = CHT_UNIX_SOCKET;
-#endif
 		}
 		else
 		{
@@ -1115,14 +1113,12 @@ connectOptions2(PGconn *conn)
 			 * This bit selects the default host location.  If you change
 			 * this, see also pg_regress.
 			 */
-#ifdef HAVE_UNIX_SOCKETS
 			if (DEFAULT_PGSOCKET_DIR[0])
 			{
 				ch->host = strdup(DEFAULT_PGSOCKET_DIR);
 				ch->type = CHT_UNIX_SOCKET;
 			}
 			else
-#endif
 			{
 				ch->host = strdup(DefaultHost);
 				ch->type = CHT_HOST_NAME;
@@ -1684,7 +1680,6 @@ getHostaddr(PGconn *conn, char *host_addr, int host_addr_len)
 static void
 emitHostIdentityInfo(PGconn *conn, const char *host_addr)
 {
-#ifdef HAVE_UNIX_SOCKETS
 	if (conn->raddr.addr.ss_family == AF_UNIX)
 	{
 		char		service[NI_MAXHOST];
@@ -1698,7 +1693,6 @@ emitHostIdentityInfo(PGconn *conn, const char *host_addr)
 						  service);
 	}
 	else
-#endif							/* HAVE_UNIX_SOCKETS */
 	{
 		const char *displayed_host;
 		const char *displayed_port;
@@ -1748,12 +1742,10 @@ connectFailureMessage(PGconn *conn, int errorno)
 					  "%s\n",
 					  SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)));
 
-#ifdef HAVE_UNIX_SOCKETS
 	if (conn->raddr.addr.ss_family == AF_UNIX)
 		appendPQExpBufferStr(&conn->errorMessage,
 							 libpq_gettext("\tIs the server running locally and accepting connections on that socket?\n"));
 	else
-#endif
 		appendPQExpBufferStr(&conn->errorMessage,
 							 libpq_gettext("\tIs the server running on that host and accepting TCP/IP connections?\n"));
 }
@@ -2415,7 +2407,6 @@ keep_going:						/* We will come back to here until there is
 				break;
 
 			case CHT_UNIX_SOCKET:
-#ifdef HAVE_UNIX_SOCKETS
 				conn->addrlist_family = hint.ai_family = AF_UNIX;
 				UNIXSOCK_PATH(portstr, thisport, ch->host);
 				if (strlen(portstr) >= UNIXSOCK_PATH_BUFLEN)
@@ -2440,9 +2431,6 @@ keep_going:						/* We will come back to here until there is
 									  portstr, gai_strerror(ret));
 					goto keep_going;
 				}
-#else
-				Assert(false);
-#endif
 				break;
 		}
 
diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c
index e015a11c21..cd5a5fd5dd 100644
--- a/src/test/regress/pg_regress.c
+++ b/src/test/regress/pg_regress.c
@@ -99,11 +99,9 @@ static char *logfilename;
 static FILE *logfile;
 static char *difffilename;
 static const char *sockdir;
-#ifdef HAVE_UNIX_SOCKETS
 static const char *temp_sockdir;
 static char sockself[MAXPGPATH];
 static char socklock[MAXPGPATH];
-#endif
 
 static _resultmap *resultmap = NULL;
 
@@ -285,7 +283,6 @@ stop_postmaster(void)
 	}
 }
 
-#ifdef HAVE_UNIX_SOCKETS
 /*
  * Remove the socket temporary directory.  pg_regress never waits for a
  * postmaster exit, so it is indeterminate whether the postmaster has yet to
@@ -360,7 +357,6 @@ make_temp_sockdir(void)
 
 	return temp_sockdir;
 }
-#endif							/* HAVE_UNIX_SOCKETS */
 
 /*
  * Check whether string matches pattern
@@ -683,7 +679,6 @@ initialize_environment(void)
 		/* PGPORT, see below */
 		/* PGHOST, see below */
 
-#ifdef HAVE_UNIX_SOCKETS
 		if (hostname != NULL)
 			setenv("PGHOST", hostname, 1);
 		else
@@ -693,10 +688,6 @@ initialize_environment(void)
 				sockdir = make_temp_sockdir();
 			setenv("PGHOST", sockdir, 1);
 		}
-#else
-		Assert(hostname != NULL);
-		setenv("PGHOST", hostname, 1);
-#endif
 		unsetenv("PGHOSTADDR");
 		if (port != -1)
 		{
@@ -746,11 +737,9 @@ initialize_environment(void)
 		if (!pghost)
 		{
 			/* Keep this bit in sync with libpq's default host location: */
-#ifdef HAVE_UNIX_SOCKETS
 			if (DEFAULT_PGSOCKET_DIR[0])
 				 /* do nothing, we'll print "Unix socket" below */ ;
 			else
-#endif
 				pghost = "localhost";	/* DefaultHost in fe-connect.c */
 		}
 
@@ -2068,9 +2057,7 @@ regression_main(int argc, char *argv[],
 
 	atexit(stop_postmaster);
 
-#if !defined(HAVE_UNIX_SOCKETS)
-	use_unix_sockets = false;
-#elif defined(WIN32)
+#if defined(WIN32)
 
 	/*
 	 * We don't use Unix-domain sockets on Windows by default, even if the
@@ -2209,7 +2196,7 @@ regression_main(int argc, char *argv[],
 		/*
 		 * To reduce chances of interference with parallel installations, use
 		 * a port number starting in the private range (49152-65535)
-		 * calculated from the version number.  This aids !HAVE_UNIX_SOCKETS
+		 * calculated from the version number.  This aids non-Unix socket mode
 		 * systems; elsewhere, the use of a private socket directory already
 		 * prevents interference.
 		 */
@@ -2329,8 +2316,6 @@ regression_main(int argc, char *argv[],
 			snprintf(buf, sizeof(buf), "%s/data", temp_instance);
 			config_sspi_auth(buf, NULL);
 		}
-#elif !defined(HAVE_UNIX_SOCKETS)
-#error Platform has no means to secure the test installation.
 #endif
 
 		/*
-- 
2.30.2

0002-Remove-configure-probe-for-struct-sockaddr_storage.patchtext/x-patch; charset=US-ASCII; name=0002-Remove-configure-probe-for-struct-sockaddr_storage.patchDownload
From 05f16ae2e21704cea6c560c4f333bff555222fa0 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 13 Aug 2022 21:10:39 +1200
Subject: [PATCH 2/4] Remove configure probe for struct sockaddr_storage.

<sys/socket.h> provides sockaddr_storage in SUSv3.  Windows has it too.
---
 config/c-library.m4        | 14 +-------------
 configure                  | 13 -------------
 configure.ac               |  1 -
 src/include/libpq/pqcomm.h | 23 -----------------------
 src/include/pg_config.h.in |  3 ---
 src/tools/msvc/Solution.pm |  1 -
 6 files changed, 1 insertion(+), 54 deletions(-)

diff --git a/config/c-library.m4 b/config/c-library.m4
index f6b171d923..7a79033730 100644
--- a/config/c-library.m4
+++ b/config/c-library.m4
@@ -73,23 +73,11 @@ AC_DEFUN([PGAC_UNION_SEMUN],
 ])])# PGAC_UNION_SEMUN
 
 
-# PGAC_STRUCT_SOCKADDR_STORAGE
-# ----------------------------
-# If `struct sockaddr_storage' exists, define HAVE_STRUCT_SOCKADDR_STORAGE.
-# If it is missing then one could define it.
-AC_DEFUN([PGAC_STRUCT_SOCKADDR_STORAGE],
-[AC_CHECK_TYPES([struct sockaddr_storage], [], [],
-[#include <sys/types.h>
-#include <sys/socket.h>
-])])# PGAC_STRUCT_SOCKADDR_STORAGE
-
 # PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS
 # --------------------------------------
 # Check the members of `struct sockaddr_storage'.  We need to know about
 # ss_family and ss_len.  (Some platforms follow RFC 2553 and call them
-# __ss_family and __ss_len.)  We also check struct sockaddr's sa_len;
-# if we have to define our own `struct sockaddr_storage', this tells us
-# whether we need to provide an ss_len field.
+# __ss_family and __ss_len.)  We also check struct sockaddr's sa_len.
 AC_DEFUN([PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS],
 [AC_CHECK_MEMBERS([struct sockaddr_storage.ss_family,
 		   struct sockaddr_storage.__ss_family,
diff --git a/configure b/configure
index c6300a9a54..7c10905dfd 100755
--- a/configure
+++ b/configure
@@ -15058,19 +15058,6 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
-fi
-
-ac_fn_c_check_type "$LINENO" "struct sockaddr_storage" "ac_cv_type_struct_sockaddr_storage" "#include <sys/types.h>
-#include <sys/socket.h>
-
-"
-if test "x$ac_cv_type_struct_sockaddr_storage" = xyes; then :
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_STRUCT_SOCKADDR_STORAGE 1
-_ACEOF
-
-
 fi
 
 ac_fn_c_check_member "$LINENO" "struct sockaddr_storage" "ss_family" "ac_cv_member_struct_sockaddr_storage_ss_family" "#include <sys/types.h>
diff --git a/configure.ac b/configure.ac
index 010c8e6a25..d3e402dfc0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1618,7 +1618,6 @@ PGAC_C_COMPUTED_GOTO
 PGAC_STRUCT_TIMEZONE
 PGAC_UNION_SEMUN
 AC_CHECK_TYPES(socklen_t, [], [], [#include <sys/socket.h>])
-PGAC_STRUCT_SOCKADDR_STORAGE
 PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS
 PGAC_STRUCT_ADDRINFO
 
diff --git a/src/include/libpq/pqcomm.h b/src/include/libpq/pqcomm.h
index 3bcc06b2d6..7e2f1495f3 100644
--- a/src/include/libpq/pqcomm.h
+++ b/src/include/libpq/pqcomm.h
@@ -21,8 +21,6 @@
 #include <netdb.h>
 #include <netinet/in.h>
 
-#ifdef HAVE_STRUCT_SOCKADDR_STORAGE
-
 #ifndef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY
 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY
 #define ss_family __ss_family
@@ -35,27 +33,6 @@
 #define ss_len __ss_len
 #define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1
 #endif
-#else							/* !HAVE_STRUCT_SOCKADDR_STORAGE */
-
-/* Define a struct sockaddr_storage if we don't have one. */
-
-struct sockaddr_storage
-{
-	union
-	{
-		struct sockaddr sa;		/* get the system-dependent fields */
-		int64		ss_align;	/* ensures struct is properly aligned */
-		char		ss_pad[128];	/* ensures struct has desired size */
-	}			ss_stuff;
-};
-
-#define ss_family	ss_stuff.sa.sa_family
-/* It should have an ss_len field if sockaddr has sa_len. */
-#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
-#define ss_len		ss_stuff.sa.sa_len
-#define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1
-#endif
-#endif							/* HAVE_STRUCT_SOCKADDR_STORAGE */
 
 typedef struct
 {
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 45faf05121..31674bde4e 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -463,9 +463,6 @@
 /* Define to 1 if `sa_len' is a member of `struct sockaddr'. */
 #undef HAVE_STRUCT_SOCKADDR_SA_LEN
 
-/* Define to 1 if the system has the type `struct sockaddr_storage'. */
-#undef HAVE_STRUCT_SOCKADDR_STORAGE
-
 /* Define to 1 if `ss_family' is a member of `struct sockaddr_storage'. */
 #undef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY
 
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index df594b2fe7..1632931840 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -350,7 +350,6 @@ sub GenerateFiles
 		HAVE_STRUCT_CMSGCRED                     => undef,
 		HAVE_STRUCT_OPTION                       => undef,
 		HAVE_STRUCT_SOCKADDR_SA_LEN              => undef,
-		HAVE_STRUCT_SOCKADDR_STORAGE             => 1,
 		HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY   => 1,
 		HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN      => undef,
 		HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY => undef,
-- 
2.30.2

0003-Remove-configure-probe-for-getaddrinfo-and-replaceme.patchtext/x-patch; charset=US-ASCII; name=0003-Remove-configure-probe-for-getaddrinfo-and-replaceme.patchDownload
From d11c344a0cc59d6e657073d243358be16347907c Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 13 Aug 2022 21:35:18 +1200
Subject: [PATCH 3/4] Remove configure probe for getaddrinfo, and replacement
 code.

SUSv3 and modern Windows have getaddrinfo() and related interfaces.
Drop the replacement implementation, and adjust some headers slightly to
make sure that the OS APIs are visible on both OSes using POSIX header
names.
---
 config/c-library.m4                   |  11 -
 configure                             |  42 ---
 configure.ac                          |  11 -
 src/backend/libpq/auth.c              |   1 +
 src/backend/libpq/hba.c               |   1 +
 src/bin/initdb/initdb.c               |   3 +-
 src/include/common/ip.h               |   4 +-
 src/include/getaddrinfo.h             | 162 ----------
 src/include/libpq/libpq-be.h          |   8 -
 src/include/pg_config.h.in            |   6 -
 src/include/port/win32/netdb.h        |   8 +
 src/include/replication/walreceiver.h |   4 +-
 src/interfaces/libpq/fe-connect.c     |   1 +
 src/interfaces/libpq/libpq-int.h      |   3 +-
 src/port/Makefile                     |   4 -
 src/port/getaddrinfo.c                | 439 --------------------------
 src/tools/msvc/Mkvcbuild.pm           |   2 +-
 src/tools/msvc/Solution.pm            |   2 -
 18 files changed, 22 insertions(+), 690 deletions(-)
 delete mode 100644 src/include/getaddrinfo.h
 delete mode 100644 src/port/getaddrinfo.c

diff --git a/config/c-library.m4 b/config/c-library.m4
index 7a79033730..58453c4f76 100644
--- a/config/c-library.m4
+++ b/config/c-library.m4
@@ -89,17 +89,6 @@ AC_DEFUN([PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS],
 ])])# PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS
 
 
-# PGAC_STRUCT_ADDRINFO
-# -----------------------
-# If `struct addrinfo' exists, define HAVE_STRUCT_ADDRINFO.
-AC_DEFUN([PGAC_STRUCT_ADDRINFO],
-[AC_CHECK_TYPES([struct addrinfo], [], [],
-[#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-])])# PGAC_STRUCT_ADDRINFO
-
-
 # PGAC_TYPE_LOCALE_T
 # ------------------
 # Check for the locale_t type and find the right header file.  macOS
diff --git a/configure b/configure
index 7c10905dfd..c1daab15d6 100755
--- a/configure
+++ b/configure
@@ -15119,20 +15119,6 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
-fi
-
-ac_fn_c_check_type "$LINENO" "struct addrinfo" "ac_cv_type_struct_addrinfo" "#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-
-"
-if test "x$ac_cv_type_struct_addrinfo" = xyes; then :
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_STRUCT_ADDRINFO 1
-_ACEOF
-
-
 fi
 
 
@@ -16565,34 +16551,6 @@ esac
 $as_echo "$as_me: On $host_os we will use our strtof wrapper." >&6;}
 fi
 
-# System's version of getaddrinfo(), if any, may be used only if we found
-# a definition for struct addrinfo; see notes in src/include/getaddrinfo.h.
-# We use only our own getaddrinfo.c on Windows, but it's time to revisit that.
-if test x"$ac_cv_type_struct_addrinfo" = xyes && \
-   test "$PORTNAME" != "win32"; then
-  ac_fn_c_check_func "$LINENO" "getaddrinfo" "ac_cv_func_getaddrinfo"
-if test "x$ac_cv_func_getaddrinfo" = xyes; then :
-  $as_echo "#define HAVE_GETADDRINFO 1" >>confdefs.h
-
-else
-  case " $LIBOBJS " in
-  *" getaddrinfo.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS getaddrinfo.$ac_objext"
- ;;
-esac
-
-fi
-
-
-else
-  case " $LIBOBJS " in
-  *" getaddrinfo.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS getaddrinfo.$ac_objext"
- ;;
-esac
-
-fi
-
 # Similarly, use system's getopt_long() only if system provides struct option.
 if test x"$ac_cv_type_struct_option" = xyes ; then
   ac_fn_c_check_func "$LINENO" "getopt_long" "ac_cv_func_getopt_long"
diff --git a/configure.ac b/configure.ac
index d3e402dfc0..1ce9766a31 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1619,7 +1619,6 @@ PGAC_STRUCT_TIMEZONE
 PGAC_UNION_SEMUN
 AC_CHECK_TYPES(socklen_t, [], [], [#include <sys/socket.h>])
 PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS
-PGAC_STRUCT_ADDRINFO
 
 PGAC_TYPE_LOCALE_T
 
@@ -1860,16 +1859,6 @@ if test "$PORTNAME" = "win32" -o "$PORTNAME" = "cygwin"; then
 	AC_MSG_NOTICE([On $host_os we will use our strtof wrapper.])
 fi
 
-# System's version of getaddrinfo(), if any, may be used only if we found
-# a definition for struct addrinfo; see notes in src/include/getaddrinfo.h.
-# We use only our own getaddrinfo.c on Windows, but it's time to revisit that.
-if test x"$ac_cv_type_struct_addrinfo" = xyes && \
-   test "$PORTNAME" != "win32"; then
-  AC_REPLACE_FUNCS([getaddrinfo])
-else
-  AC_LIBOBJ(getaddrinfo)
-fi
-
 # Similarly, use system's getopt_long() only if system provides struct option.
 if test x"$ac_cv_type_struct_option" = xyes ; then
   AC_REPLACE_FUNCS([getopt_long])
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index 41d60e06d0..290eb17325 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -19,6 +19,7 @@
 #include <sys/select.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
+#include <netdb.h>
 #include <pwd.h>
 #include <unistd.h>
 
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index 66f2156cde..857b9e5eb2 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -21,6 +21,7 @@
 #include <fcntl.h>
 #include <sys/param.h>
 #include <sys/socket.h>
+#include <netdb.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <unistd.h>
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 4feb5db3fa..6f56d3f703 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -50,7 +50,9 @@
 
 #include <dirent.h>
 #include <fcntl.h>
+#include <netdb.h>
 #include <sys/stat.h>
+#include <sys/socket.h>
 #include <unistd.h>
 #include <signal.h>
 #include <time.h>
@@ -72,7 +74,6 @@
 #include "common/string.h"
 #include "common/username.h"
 #include "fe_utils/string_utils.h"
-#include "getaddrinfo.h"
 #include "getopt_long.h"
 #include "mb/pg_wchar.h"
 #include "miscadmin.h"
diff --git a/src/include/common/ip.h b/src/include/common/ip.h
index 8414520989..6c044f7fa2 100644
--- a/src/include/common/ip.h
+++ b/src/include/common/ip.h
@@ -14,7 +14,9 @@
 #ifndef IP_H
 #define IP_H
 
-#include "getaddrinfo.h"		/* pgrminclude ignore */
+#include <netdb.h>
+#include <sys/socket.h>
+
 #include "libpq/pqcomm.h"		/* pgrminclude ignore */
 
 
diff --git a/src/include/getaddrinfo.h b/src/include/getaddrinfo.h
deleted file mode 100644
index 2042c2d303..0000000000
--- a/src/include/getaddrinfo.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * getaddrinfo.h
- *	  Support getaddrinfo() on platforms that don't have it.
- *
- * Note: we use our own routines on platforms that don't HAVE_STRUCT_ADDRINFO,
- * whether or not the library routine getaddrinfo() can be found.  This
- * policy is needed because on some platforms a manually installed libbind.a
- * may provide getaddrinfo(), yet the system headers may not provide the
- * struct definitions needed to call it.  To avoid conflict with the libbind
- * definition in such cases, we rename our routines to pg_xxx() via macros.
- *
- * This code will also work on platforms where struct addrinfo is defined
- * in the system headers but no getaddrinfo() can be located.
- *
- * Copyright (c) 2003-2022, PostgreSQL Global Development Group
- *
- * src/include/getaddrinfo.h
- *
- *-------------------------------------------------------------------------
- */
-#ifndef GETADDRINFO_H
-#define GETADDRINFO_H
-
-#include <sys/socket.h>
-#include <netdb.h>
-
-
-/* Various macros that ought to be in <netdb.h>, but might not be */
-
-#ifndef EAI_FAIL
-#ifndef WIN32
-#define EAI_BADFLAGS	(-1)
-#define EAI_NONAME		(-2)
-#define EAI_AGAIN		(-3)
-#define EAI_FAIL		(-4)
-#define EAI_FAMILY		(-6)
-#define EAI_SOCKTYPE	(-7)
-#define EAI_SERVICE		(-8)
-#define EAI_MEMORY		(-10)
-#define EAI_SYSTEM		(-11)
-#else							/* WIN32 */
-#ifdef _MSC_VER
-#ifndef WSA_NOT_ENOUGH_MEMORY
-#define WSA_NOT_ENOUGH_MEMORY	(WSAENOBUFS)
-#endif
-#define WSATYPE_NOT_FOUND		(WSABASEERR+109)
-#endif
-#define EAI_AGAIN		WSATRY_AGAIN
-#define EAI_BADFLAGS	WSAEINVAL
-#define EAI_FAIL		WSANO_RECOVERY
-#define EAI_FAMILY		WSAEAFNOSUPPORT
-#define EAI_MEMORY		WSA_NOT_ENOUGH_MEMORY
-#define EAI_NODATA		WSANO_DATA
-#define EAI_NONAME		WSAHOST_NOT_FOUND
-#define EAI_SERVICE		WSATYPE_NOT_FOUND
-#define EAI_SOCKTYPE	WSAESOCKTNOSUPPORT
-#endif							/* !WIN32 */
-#endif							/* !EAI_FAIL */
-
-#ifndef AI_PASSIVE
-#define AI_PASSIVE		0x0001
-#endif
-
-#ifndef AI_NUMERICHOST
-/*
- * some platforms don't support AI_NUMERICHOST; define as zero if using
- * the system version of getaddrinfo...
- */
-#if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO)
-#define AI_NUMERICHOST	0
-#else
-#define AI_NUMERICHOST	0x0004
-#endif
-#endif
-
-#ifndef NI_NUMERICHOST
-#define NI_NUMERICHOST	1
-#endif
-#ifndef NI_NUMERICSERV
-#define NI_NUMERICSERV	2
-#endif
-#ifndef NI_NAMEREQD
-#define NI_NAMEREQD		4
-#endif
-
-#ifndef NI_MAXHOST
-#define NI_MAXHOST	1025
-#endif
-#ifndef NI_MAXSERV
-#define NI_MAXSERV	32
-#endif
-
-
-#ifndef HAVE_STRUCT_ADDRINFO
-
-#ifndef WIN32
-struct addrinfo
-{
-	int			ai_flags;
-	int			ai_family;
-	int			ai_socktype;
-	int			ai_protocol;
-	size_t		ai_addrlen;
-	struct sockaddr *ai_addr;
-	char	   *ai_canonname;
-	struct addrinfo *ai_next;
-};
-#else
-/*
- *	The order of the structure elements on Win32 doesn't match the
- *	order specified in the standard, but we have to match it for
- *	IPv6 to work.
- */
-struct addrinfo
-{
-	int			ai_flags;
-	int			ai_family;
-	int			ai_socktype;
-	int			ai_protocol;
-	size_t		ai_addrlen;
-	char	   *ai_canonname;
-	struct sockaddr *ai_addr;
-	struct addrinfo *ai_next;
-};
-#endif
-#endif							/* HAVE_STRUCT_ADDRINFO */
-
-
-#ifndef HAVE_GETADDRINFO
-
-/* Rename private copies per comments above */
-#ifdef getaddrinfo
-#undef getaddrinfo
-#endif
-#define getaddrinfo pg_getaddrinfo
-
-#ifdef freeaddrinfo
-#undef freeaddrinfo
-#endif
-#define freeaddrinfo pg_freeaddrinfo
-
-#ifdef gai_strerror
-#undef gai_strerror
-#endif
-#define gai_strerror pg_gai_strerror
-
-#ifdef getnameinfo
-#undef getnameinfo
-#endif
-#define getnameinfo pg_getnameinfo
-
-extern int	getaddrinfo(const char *node, const char *service,
-						const struct addrinfo *hints, struct addrinfo **res);
-extern void freeaddrinfo(struct addrinfo *res);
-extern const char *gai_strerror(int errcode);
-extern int	getnameinfo(const struct sockaddr *sa, int salen,
-						char *node, int nodelen,
-						char *service, int servicelen, int flags);
-#endif							/* HAVE_GETADDRINFO */
-
-#endif							/* GETADDRINFO_H */
diff --git a/src/include/libpq/libpq-be.h b/src/include/libpq/libpq-be.h
index 90c20da22b..fa2fd03009 100644
--- a/src/include/libpq/libpq-be.h
+++ b/src/include/libpq/libpq-be.h
@@ -33,14 +33,6 @@
 #else
 #include <gssapi/gssapi.h>
 #endif							/* HAVE_GSSAPI_H */
-/*
- * GSSAPI brings in headers that set a lot of things in the global namespace on win32,
- * that doesn't match the msvc build. It gives a bunch of compiler warnings that we ignore,
- * but also defines a symbol that simply does not exist. Undefine it again.
- */
-#ifdef _MSC_VER
-#undef HAVE_GETADDRINFO
-#endif
 #endif							/* ENABLE_GSS */
 
 #ifdef ENABLE_SSPI
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 31674bde4e..e5e68fac03 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -178,9 +178,6 @@
    */
 #undef HAVE_GCC__SYNC_INT64_CAS
 
-/* Define to 1 if you have the `getaddrinfo' function. */
-#undef HAVE_GETADDRINFO
-
 /* Define to 1 if you have the `gethostbyname_r' function. */
 #undef HAVE_GETHOSTBYNAME_R
 
@@ -451,9 +448,6 @@
 /* Define to 1 if you have the `strsignal' function. */
 #undef HAVE_STRSIGNAL
 
-/* Define to 1 if the system has the type `struct addrinfo'. */
-#undef HAVE_STRUCT_ADDRINFO
-
 /* Define to 1 if the system has the type `struct cmsgcred'. */
 #undef HAVE_STRUCT_CMSGCRED
 
diff --git a/src/include/port/win32/netdb.h b/src/include/port/win32/netdb.h
index ad0627e986..f0cc2c2367 100644
--- a/src/include/port/win32/netdb.h
+++ b/src/include/port/win32/netdb.h
@@ -1 +1,9 @@
 /* src/include/port/win32/netdb.h */
+#ifndef WIN32_NETDB_H
+#define WIN32_NETDB_H
+
+#include <ws2tcpip.h>
+
+#define gai_strerror gai_strerrorA
+
+#endif
diff --git a/src/include/replication/walreceiver.h b/src/include/replication/walreceiver.h
index bd8398de0b..9339f29303 100644
--- a/src/include/replication/walreceiver.h
+++ b/src/include/replication/walreceiver.h
@@ -12,9 +12,11 @@
 #ifndef _WALRECEIVER_H
 #define _WALRECEIVER_H
 
+#include <netdb.h>
+#include <sys/socket.h>
+
 #include "access/xlog.h"
 #include "access/xlogdefs.h"
-#include "getaddrinfo.h"		/* for NI_MAXHOST */
 #include "pgtime.h"
 #include "port/atomics.h"
 #include "replication/logicalproto.h"
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 730e79a31d..0b8fabc7e8 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -18,6 +18,7 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <ctype.h>
+#include <netdb.h>
 #include <time.h>
 #include <unistd.h>
 
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index 51ab51f9f9..1eb752a82d 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -23,6 +23,8 @@
 /* We assume libpq-fe.h has already been included. */
 #include "libpq-events.h"
 
+#include <netdb.h>
+#include <sys/socket.h>
 #include <time.h>
 #ifndef WIN32
 #include <sys/time.h>
@@ -38,7 +40,6 @@
 #endif
 
 /* include stuff common to fe and be */
-#include "getaddrinfo.h"
 #include "libpq/pqcomm.h"
 /* include stuff found in fe only */
 #include "fe-auth-sasl.h"
diff --git a/src/port/Makefile b/src/port/Makefile
index bfe1feb0d4..b3754d8940 100644
--- a/src/port/Makefile
+++ b/src/port/Makefile
@@ -84,10 +84,6 @@ libpgport.a: $(OBJS)
 	rm -f $@
 	$(AR) $(AROPT) $@ $^
 
-# getaddrinfo.o and getaddrinfo_shlib.o need PTHREAD_CFLAGS (but getaddrinfo_srv.o does not)
-getaddrinfo.o: CFLAGS+=$(PTHREAD_CFLAGS)
-getaddrinfo_shlib.o: CFLAGS+=$(PTHREAD_CFLAGS)
-
 # thread.o and thread_shlib.o need PTHREAD_CFLAGS (but thread_srv.o does not)
 thread.o: CFLAGS+=$(PTHREAD_CFLAGS)
 thread_shlib.o: CFLAGS+=$(PTHREAD_CFLAGS)
diff --git a/src/port/getaddrinfo.c b/src/port/getaddrinfo.c
deleted file mode 100644
index bea7b520f0..0000000000
--- a/src/port/getaddrinfo.c
+++ /dev/null
@@ -1,439 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * getaddrinfo.c
- *	  Support getaddrinfo() on platforms that don't have it.
- *
- * We also supply getnameinfo() here, assuming that the platform will have
- * it if and only if it has getaddrinfo().  If this proves false on some
- * platform, we'll need to split this file and provide a separate configure
- * test for getnameinfo().
- *
- * Windows may or may not have these routines, so we handle Windows specially
- * by dynamically checking for their existence.  If they already exist, we
- * use the Windows native routines, but if not, we use our own.
- *
- *
- * Copyright (c) 2003-2022, PostgreSQL Global Development Group
- *
- * IDENTIFICATION
- *	  src/port/getaddrinfo.c
- *
- *-------------------------------------------------------------------------
- */
-
-/* This is intended to be used in both frontend and backend, so use c.h */
-#include "c.h"
-
-#include <sys/socket.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include "getaddrinfo.h"
-#include "libpq/pqcomm.h"		/* needed for struct sockaddr_storage */
-#include "port/pg_bswap.h"
-
-
-#ifdef FRONTEND
-static int	pqGethostbyname(const char *name,
-							struct hostent *resultbuf,
-							char *buffer, size_t buflen,
-							struct hostent **result,
-							int *herrno);
-#endif
-
-#ifdef WIN32
-/*
- * The native routines may or may not exist on the Windows platform we are on,
- * so we dynamically look up the routines, and call them via function pointers.
- * Here we need to declare what the function pointers look like
- */
-typedef int (__stdcall * getaddrinfo_ptr_t) (const char *nodename,
-											 const char *servname,
-											 const struct addrinfo *hints,
-											 struct addrinfo **res);
-
-typedef void (__stdcall * freeaddrinfo_ptr_t) (struct addrinfo *ai);
-
-typedef int (__stdcall * getnameinfo_ptr_t) (const struct sockaddr *sa,
-											 int salen,
-											 char *node, int nodelen,
-											 char *service, int servicelen,
-											 int flags);
-
-/* static pointers to the native routines, so we only do the lookup once. */
-static getaddrinfo_ptr_t getaddrinfo_ptr = NULL;
-static freeaddrinfo_ptr_t freeaddrinfo_ptr = NULL;
-static getnameinfo_ptr_t getnameinfo_ptr = NULL;
-
-
-static bool
-haveNativeWindowsIPv6routines(void)
-{
-	void	   *hLibrary = NULL;
-	static bool alreadyLookedForIpv6routines = false;
-
-	if (alreadyLookedForIpv6routines)
-		return (getaddrinfo_ptr != NULL);
-
-	/*
-	 * For Windows XP and later versions, the IPv6 routines are present in the
-	 * WinSock 2 library (ws2_32.dll).
-	 */
-	hLibrary = LoadLibraryA("ws2_32");
-
-	/* If hLibrary is null, we couldn't find a dll with functions */
-	if (hLibrary != NULL)
-	{
-		/* We found a dll, so now get the addresses of the routines */
-
-		getaddrinfo_ptr = (getaddrinfo_ptr_t) (pg_funcptr_t) GetProcAddress(hLibrary,
-																			"getaddrinfo");
-		freeaddrinfo_ptr = (freeaddrinfo_ptr_t) (pg_funcptr_t) GetProcAddress(hLibrary,
-																			  "freeaddrinfo");
-		getnameinfo_ptr = (getnameinfo_ptr_t) (pg_funcptr_t) GetProcAddress(hLibrary,
-																			"getnameinfo");
-
-		/*
-		 * If any one of the routines is missing, let's play it safe and
-		 * ignore them all
-		 */
-		if (getaddrinfo_ptr == NULL ||
-			freeaddrinfo_ptr == NULL ||
-			getnameinfo_ptr == NULL)
-		{
-			FreeLibrary(hLibrary);
-			hLibrary = NULL;
-			getaddrinfo_ptr = NULL;
-			freeaddrinfo_ptr = NULL;
-			getnameinfo_ptr = NULL;
-		}
-	}
-
-	alreadyLookedForIpv6routines = true;
-	return (getaddrinfo_ptr != NULL);
-}
-#endif
-
-
-/*
- * get address info for ipv4 sockets.
- *
- *	Bugs:	- only one addrinfo is set even though hintp is NULL or
- *		  ai_socktype is 0
- *		- AI_CANONNAME is not supported.
- *		- servname can only be a number, not text.
- */
-int
-getaddrinfo(const char *node, const char *service,
-			const struct addrinfo *hintp,
-			struct addrinfo **res)
-{
-	struct addrinfo *ai;
-	struct sockaddr_in sin,
-			   *psin;
-	struct addrinfo hints;
-
-#ifdef WIN32
-
-	/*
-	 * If Windows has native IPv6 support, use the native Windows routine.
-	 * Otherwise, fall through and use our own code.
-	 */
-	if (haveNativeWindowsIPv6routines())
-		return (*getaddrinfo_ptr) (node, service, hintp, res);
-#endif
-
-	if (hintp == NULL)
-	{
-		memset(&hints, 0, sizeof(hints));
-		hints.ai_family = AF_INET;
-		hints.ai_socktype = SOCK_STREAM;
-	}
-	else
-		memcpy(&hints, hintp, sizeof(hints));
-
-	if (hints.ai_family != AF_INET && hints.ai_family != AF_UNSPEC)
-		return EAI_FAMILY;
-
-	if (hints.ai_socktype == 0)
-		hints.ai_socktype = SOCK_STREAM;
-
-	if (!node && !service)
-		return EAI_NONAME;
-
-	memset(&sin, 0, sizeof(sin));
-
-	sin.sin_family = AF_INET;
-
-	if (node)
-	{
-		if (node[0] == '\0')
-			sin.sin_addr.s_addr = pg_hton32(INADDR_ANY);
-		else if (hints.ai_flags & AI_NUMERICHOST)
-		{
-			if (!inet_aton(node, &sin.sin_addr))
-				return EAI_NONAME;
-		}
-		else
-		{
-			struct hostent *hp;
-
-#ifdef FRONTEND
-			struct hostent hpstr;
-			char		buf[BUFSIZ];
-			int			herrno = 0;
-
-			pqGethostbyname(node, &hpstr, buf, sizeof(buf),
-							&hp, &herrno);
-#else
-			hp = gethostbyname(node);
-#endif
-			if (hp == NULL)
-			{
-				switch (h_errno)
-				{
-					case HOST_NOT_FOUND:
-					case NO_DATA:
-						return EAI_NONAME;
-					case TRY_AGAIN:
-						return EAI_AGAIN;
-					case NO_RECOVERY:
-					default:
-						return EAI_FAIL;
-				}
-			}
-			if (hp->h_addrtype != AF_INET)
-				return EAI_FAIL;
-
-			memcpy(&(sin.sin_addr), hp->h_addr, hp->h_length);
-		}
-	}
-	else
-	{
-		if (hints.ai_flags & AI_PASSIVE)
-			sin.sin_addr.s_addr = pg_hton32(INADDR_ANY);
-		else
-			sin.sin_addr.s_addr = pg_hton32(INADDR_LOOPBACK);
-	}
-
-	if (service)
-		sin.sin_port = pg_hton16((unsigned short) atoi(service));
-
-#ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN
-	sin.sin_len = sizeof(sin);
-#endif
-
-	ai = malloc(sizeof(*ai));
-	if (!ai)
-		return EAI_MEMORY;
-
-	psin = malloc(sizeof(*psin));
-	if (!psin)
-	{
-		free(ai);
-		return EAI_MEMORY;
-	}
-
-	memcpy(psin, &sin, sizeof(*psin));
-
-	ai->ai_flags = 0;
-	ai->ai_family = AF_INET;
-	ai->ai_socktype = hints.ai_socktype;
-	ai->ai_protocol = hints.ai_protocol;
-	ai->ai_addrlen = sizeof(*psin);
-	ai->ai_addr = (struct sockaddr *) psin;
-	ai->ai_canonname = NULL;
-	ai->ai_next = NULL;
-
-	*res = ai;
-
-	return 0;
-}
-
-
-void
-freeaddrinfo(struct addrinfo *res)
-{
-	if (res)
-	{
-#ifdef WIN32
-
-		/*
-		 * If Windows has native IPv6 support, use the native Windows routine.
-		 * Otherwise, fall through and use our own code.
-		 */
-		if (haveNativeWindowsIPv6routines())
-		{
-			(*freeaddrinfo_ptr) (res);
-			return;
-		}
-#endif
-
-		free(res->ai_addr);
-		free(res);
-	}
-}
-
-
-const char *
-gai_strerror(int errcode)
-{
-#ifdef HAVE_HSTRERROR
-	int			hcode;
-
-	switch (errcode)
-	{
-		case EAI_NONAME:
-			hcode = HOST_NOT_FOUND;
-			break;
-		case EAI_AGAIN:
-			hcode = TRY_AGAIN;
-			break;
-		case EAI_FAIL:
-		default:
-			hcode = NO_RECOVERY;
-			break;
-	}
-
-	return hstrerror(hcode);
-#else							/* !HAVE_HSTRERROR */
-
-	switch (errcode)
-	{
-		case EAI_NONAME:
-			return "Unknown host";
-		case EAI_AGAIN:
-			return "Host name lookup failure";
-			/* Errors below are probably WIN32 only */
-#ifdef EAI_BADFLAGS
-		case EAI_BADFLAGS:
-			return "Invalid argument";
-#endif
-#ifdef EAI_FAMILY
-		case EAI_FAMILY:
-			return "Address family not supported";
-#endif
-#ifdef EAI_MEMORY
-		case EAI_MEMORY:
-			return "Not enough memory";
-#endif
-#if defined(EAI_NODATA) && EAI_NODATA != EAI_NONAME /* MSVC/WIN64 duplicate */
-		case EAI_NODATA:
-			return "No host data of that type was found";
-#endif
-#ifdef EAI_SERVICE
-		case EAI_SERVICE:
-			return "Class type not found";
-#endif
-#ifdef EAI_SOCKTYPE
-		case EAI_SOCKTYPE:
-			return "Socket type not supported";
-#endif
-		default:
-			return "Unknown server error";
-	}
-#endif							/* HAVE_HSTRERROR */
-}
-
-/*
- * Convert an ipv4 address to a hostname.
- *
- * Bugs:	- Only supports NI_NUMERICHOST and NI_NUMERICSERV behavior.
- *		  It will never resolve a hostname.
- *		- No IPv6 support.
- */
-int
-getnameinfo(const struct sockaddr *sa, int salen,
-			char *node, int nodelen,
-			char *service, int servicelen, int flags)
-{
-#ifdef WIN32
-
-	/*
-	 * If Windows has native IPv6 support, use the native Windows routine.
-	 * Otherwise, fall through and use our own code.
-	 */
-	if (haveNativeWindowsIPv6routines())
-		return (*getnameinfo_ptr) (sa, salen, node, nodelen,
-								   service, servicelen, flags);
-#endif
-
-	/* Invalid arguments. */
-	if (sa == NULL || (node == NULL && service == NULL))
-		return EAI_FAIL;
-
-#ifdef	HAVE_IPV6
-	if (sa->sa_family == AF_INET6)
-		return EAI_FAMILY;
-#endif
-
-	/* Unsupported flags. */
-	if (flags & NI_NAMEREQD)
-		return EAI_AGAIN;
-
-	if (node)
-	{
-		if (sa->sa_family == AF_INET)
-		{
-			if (pg_inet_net_ntop(AF_INET,
-								 &((struct sockaddr_in *) sa)->sin_addr,
-								 sa->sa_family == AF_INET ? 32 : 128,
-								 node, nodelen) == NULL)
-				return EAI_MEMORY;
-		}
-		else
-			return EAI_MEMORY;
-	}
-
-	if (service)
-	{
-		int			ret = -1;
-
-		if (sa->sa_family == AF_INET)
-		{
-			ret = snprintf(service, servicelen, "%d",
-						   pg_ntoh16(((struct sockaddr_in *) sa)->sin_port));
-		}
-		if (ret < 0 || ret >= servicelen)
-			return EAI_MEMORY;
-	}
-
-	return 0;
-}
-
-/*
- * Wrapper around gethostbyname() or gethostbyname_r() to mimic
- * POSIX gethostbyname_r() behaviour, if it is not available or required.
- */
-#ifdef FRONTEND
-static int
-pqGethostbyname(const char *name,
-				struct hostent *resultbuf,
-				char *buffer, size_t buflen,
-				struct hostent **result,
-				int *herrno)
-{
-#if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_GETHOSTBYNAME_R)
-
-	/*
-	 * broken (well early POSIX draft) gethostbyname_r() which returns 'struct
-	 * hostent *'
-	 */
-	*result = gethostbyname_r(name, resultbuf, buffer, buflen, herrno);
-	return (*result == NULL) ? -1 : 0;
-#else
-
-	/* no gethostbyname_r(), just use gethostbyname() */
-	*result = gethostbyname(name);
-
-	if (*result != NULL)
-		*herrno = h_errno;
-
-	if (*result != NULL)
-		return 0;
-	else
-		return -1;
-#endif
-}
-#endif							/* FRONTEND */
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index 0a4f0d2eaa..85d03372a5 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -101,7 +101,7 @@ sub mkvcbuild
 	our @pgportfiles = qw(
 	  chklocale.c explicit_bzero.c
 	  getpeereid.c inet_aton.c
-	  getaddrinfo.c inet_net_ntop.c kill.c open.c
+	  inet_net_ntop.c kill.c open.c
 	  snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c
 	  dirent.c getopt.c getopt_long.c
 	  preadv.c pwritev.c pg_bitutils.c
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 1632931840..09ad8489a6 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -256,7 +256,6 @@ sub GenerateFiles
 		HAVE_GCC__SYNC_INT32_CAS                    => undef,
 		HAVE_GCC__SYNC_INT32_TAS                    => undef,
 		HAVE_GCC__SYNC_INT64_CAS                    => undef,
-		HAVE_GETADDRINFO                            => undef,
 		HAVE_GETHOSTBYNAME_R                        => undef,
 		HAVE_GETIFADDRS                             => undef,
 		HAVE_GETOPT                                 => undef,
@@ -346,7 +345,6 @@ sub GenerateFiles
 		HAVE_STRLCPY                             => undef,
 		HAVE_STRNLEN                             => 1,
 		HAVE_STRSIGNAL                           => undef,
-		HAVE_STRUCT_ADDRINFO                     => 1,
 		HAVE_STRUCT_CMSGCRED                     => undef,
 		HAVE_STRUCT_OPTION                       => undef,
 		HAVE_STRUCT_SOCKADDR_SA_LEN              => undef,
-- 
2.30.2

0004-Remove-configure-probe-for-gethostbyname_r.patchtext/x-patch; charset=US-ASCII; name=0004-Remove-configure-probe-for-gethostbyname_r.patchDownload
From 68bc57d48597090ff1a3c682d7deebe27b4a22dd Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sun, 14 Aug 2022 00:48:09 +1200
Subject: [PATCH 4/4] Remove configure probe for gethostbyname_r.

It was only used by src/port/getaddrinfo.c, removed by an earlier
commit.
---
 configure                         | 65 ++-----------------------------
 configure.ac                      |  3 +-
 src/include/pg_config.h.in        |  3 --
 src/interfaces/libpq/fe-connect.c |  2 +-
 src/tools/msvc/Solution.pm        |  1 -
 5 files changed, 6 insertions(+), 68 deletions(-)

diff --git a/configure b/configure
index c1daab15d6..ced77816a9 100755
--- a/configure
+++ b/configure
@@ -11750,13 +11750,12 @@ fi
 
 
 
-for ac_func in strerror_r gethostbyname_r
+for ac_func in strerror_r
 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"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  ac_fn_c_check_func "$LINENO" "strerror_r" "ac_cv_func_strerror_r"
+if test "x$ac_cv_func_strerror_r" = xyes; then :
   cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+#define HAVE_STRERROR_R 1
 _ACEOF
 
 fi
@@ -12431,62 +12430,6 @@ fi
 
 
 if test "$enable_thread_safety" = yes; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gethostbyname_r" >&5
-$as_echo_n "checking for library containing gethostbyname_r... " >&6; }
-if ${ac_cv_search_gethostbyname_r+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_func_search_save_LIBS=$LIBS
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char gethostbyname_r ();
-int
-main ()
-{
-return gethostbyname_r ();
-  ;
-  return 0;
-}
-_ACEOF
-for ac_lib in '' nsl; do
-  if test -z "$ac_lib"; then
-    ac_res="none required"
-  else
-    ac_res=-l$ac_lib
-    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
-  fi
-  if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_search_gethostbyname_r=$ac_res
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext
-  if ${ac_cv_search_gethostbyname_r+:} false; then :
-  break
-fi
-done
-if ${ac_cv_search_gethostbyname_r+:} false; then :
-
-else
-  ac_cv_search_gethostbyname_r=no
-fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_gethostbyname_r" >&5
-$as_echo "$ac_cv_search_gethostbyname_r" >&6; }
-ac_res=$ac_cv_search_gethostbyname_r
-if test "$ac_res" != no; then :
-  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-
-fi
-
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_barrier_wait" >&5
 $as_echo_n "checking for library containing pthread_barrier_wait... " >&6; }
 if ${ac_cv_search_pthread_barrier_wait+:} false; then :
diff --git a/configure.ac b/configure.ac
index 1ce9766a31..f08955321c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1214,7 +1214,7 @@ LIBS="$LIBS $PTHREAD_LIBS"
 AC_CHECK_HEADER(pthread.h, [], [AC_MSG_ERROR([
 pthread.h not found;  use --disable-thread-safety to disable thread safety])])
 
-AC_CHECK_FUNCS([strerror_r gethostbyname_r])
+AC_CHECK_FUNCS([strerror_r])
 
 # Do test here with the proper thread flags
 PGAC_FUNC_STRERROR_R_INT
@@ -1260,7 +1260,6 @@ AC_SEARCH_LIBS(shmget, cygipc)
 AC_SEARCH_LIBS(backtrace_symbols, execinfo)
 
 if test "$enable_thread_safety" = yes; then
-  AC_SEARCH_LIBS(gethostbyname_r, nsl)
   AC_SEARCH_LIBS(pthread_barrier_wait, pthread)
 fi
 
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index e5e68fac03..b8b7acab75 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -178,9 +178,6 @@
    */
 #undef HAVE_GCC__SYNC_INT64_CAS
 
-/* Define to 1 if you have the `gethostbyname_r' function. */
-#undef HAVE_GETHOSTBYNAME_R
-
 /* Define to 1 if you have the `getifaddrs' function. */
 #undef HAVE_GETIFADDRS
 
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 0b8fabc7e8..1e057db336 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -2229,7 +2229,7 @@ connectDBComplete(PGconn *conn)
  *		will not block.
  *	 o	If you do not supply an IP address for the remote host (i.e. you
  *		supply a host name instead) then PQconnectStart will block on
- *		gethostbyname.  You will be fine if using Unix sockets (i.e. by
+ *		getaddrinfo.  You will be fine if using Unix sockets (i.e. by
  *		supplying neither a host name nor a host address).
  *	 o	If your backend wants to use Kerberos authentication then you must
  *		supply both a host name and a host address, otherwise this function
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 09ad8489a6..102424c417 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -256,7 +256,6 @@ sub GenerateFiles
 		HAVE_GCC__SYNC_INT32_CAS                    => undef,
 		HAVE_GCC__SYNC_INT32_TAS                    => undef,
 		HAVE_GCC__SYNC_INT64_CAS                    => undef,
-		HAVE_GETHOSTBYNAME_R                        => undef,
 		HAVE_GETIFADDRS                             => undef,
 		HAVE_GETOPT                                 => undef,
 		HAVE_GETOPT_H                               => undef,
-- 
2.30.2

#77Tom Lane
tgl@sss.pgh.pa.us
In reply to: Thomas Munro (#75)
Re: Cleaning up historical portability baggage

Thomas Munro <thomas.munro@gmail.com> writes:

I pushed these, except I chopped out the HAVE_UNIX_SOCKETS part as
requested. Here it is in a separate patch, with a commit message that
explains the rationale (essentially, what you said, it's basically a
runtime matter for a hypothetical AF_UNIX-less system to complain
about). Tom, does this argument persuade you?

I looked more closely and saw that basically what HAVE_UNIX_SOCKETS
is guarding is code that assumes the existence of AF_UNIX and
struct sockaddr_un. As Peter said, we already rely on AF_UNIX
in some other places; and I see that sys/un.h is required to exist
and to define struct sockaddr_un as far back as SUSv2. So it
does seem like the worst consequence is that we'd be compiling
some code that would be unreachable on platforms lacking support.
Objection withdrawn.

As for the other two, they look like nice cleanup if we can actually
get away with it. I agree that the business about nonstandard libbind
is not of interest anymore, but I have no idea about the state of
play on Windows. I guess we can push 'em and see what the buildfarm
thinks.

I tried to figure out how to get rid of
PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS, but there we're into genuine
non-standard cross-platform differences.

Right. I don't think it's worth sweating over.

regards, tom lane

#78Thomas Munro
thomas.munro@gmail.com
In reply to: Tom Lane (#77)
Re: Cleaning up historical portability baggage

On Sun, Aug 14, 2022 at 6:07 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Thomas Munro <thomas.munro@gmail.com> writes:

I pushed these, except I chopped out the HAVE_UNIX_SOCKETS part as
requested. Here it is in a separate patch, with a commit message that
explains the rationale (essentially, what you said, it's basically a
runtime matter for a hypothetical AF_UNIX-less system to complain
about). Tom, does this argument persuade you?

I looked more closely and saw that basically what HAVE_UNIX_SOCKETS
is guarding is code that assumes the existence of AF_UNIX and
struct sockaddr_un. As Peter said, we already rely on AF_UNIX
in some other places; and I see that sys/un.h is required to exist
and to define struct sockaddr_un as far back as SUSv2. So it
does seem like the worst consequence is that we'd be compiling
some code that would be unreachable on platforms lacking support.
Objection withdrawn.

Thanks, and pushed with a couple of minor doc tweaks.

I hadn't paid attention to our existing abstract Unix socket support
before and now I'm curious: do we have a confirmed sighting of that
working on Windows? The thread didn't say so[1]/messages/by-id/6dee8574-b0ad-fc49-9c8c-2edc796f0033@2ndquadrant.com, and I'm suspicious
because I couldn't get simple standalone programs that bind() to
"\000c:\\xxx" to work sanely (but my method for investigating Windows
is to send the punch cards over to the CI system and wait for the
results to arrive by carrier pigeon which is cumbersome enough that I
haven't tried very hard). Naively shoving a @ into PostreSQL's
PG_REGRESS_SOCK_DIR also breaks CI.

As for the other two, they look like nice cleanup if we can actually
get away with it. I agree that the business about nonstandard libbind
is not of interest anymore, but I have no idea about the state of
play on Windows. I guess we can push 'em and see what the buildfarm
thinks.

All green on CI... Next stop, build farm.

I'm a bit confused about why I had to #define gai_sterror
gai_strerrorA myself to get this working (my non-Windows-guy
understanding is that the A-for-ANSI [sic] variants of system
functions should be selected automatically unless you #define UNICODE
to get W-for-wide variants). If anyone has any clues about that, I'd
be glad to clean it up.

I *guess* the main risk here is that different error messages might
show up in some scenarios on Windows (everything else was already
going directly to OS functions on Windows 8.1+ if I'm reading the code
right), but surely that'd be progress -- messages from the real netdb
implementation are surely preferable to our fallback stuff.

[1]: /messages/by-id/6dee8574-b0ad-fc49-9c8c-2edc796f0033@2ndquadrant.com

#79Andres Freund
andres@anarazel.de
In reply to: Thomas Munro (#78)
Re: Cleaning up historical portability baggage

Hi,

On 2022-08-14 10:03:19 +1200, Thomas Munro wrote:

I hadn't paid attention to our existing abstract Unix socket support
before and now I'm curious: do we have a confirmed sighting of that
working on Windows?

I vaguely remember successfully trying it in the past. But I just tried it
unsuccessfully in a VM and there's a bunch of other places saying it's not
working...
https://github.com/microsoft/WSL/issues/4240

Greetings,

Andres Freund

#80Thomas Munro
thomas.munro@gmail.com
In reply to: Andres Freund (#79)
1 attachment(s)
Re: Cleaning up historical portability baggage

On Sun, Aug 14, 2022 at 10:36 AM Andres Freund <andres@anarazel.de> wrote:

On 2022-08-14 10:03:19 +1200, Thomas Munro wrote:

I hadn't paid attention to our existing abstract Unix socket support
before and now I'm curious: do we have a confirmed sighting of that
working on Windows?

I vaguely remember successfully trying it in the past. But I just tried it
unsuccessfully in a VM and there's a bunch of other places saying it's not
working...
https://github.com/microsoft/WSL/issues/4240

I think we'd better remove our claim that it works then. Patch attached.

We could also reject it, I guess, but it doesn't immediately seem
harmful so I'm on the fence. On the Windows version that Cirrus is
running, we happily start up with:

2022-08-13 20:44:35.174 GMT [4760][postmaster] LOG: listening on Unix
socket "@c:/cirrus/.s.PGSQL.61696"

... and then client processes apparently can't see it, which is
confusing but, I guess, defensible if we're only claiming it works on
Linux. We don't go out of our way to avoid this feature on a per-OS
basis in general, though at least on a typical Unix system it fails
fast. For example, my FreeBSD system here barfs:

2022-08-15 13:26:13.483 NZST [29956] LOG: could not bind Unix address
"@/tmp/.s.PGSQL.5432": No such file or directory

... because the kernel just sees an empty string and can't locate the
parent directory.

Attachments:

0001-Doc-Abstract-AF_UNIX-sockets-don-t-work-on-Windows-a.patchtext/x-patch; charset=US-ASCII; name=0001-Doc-Abstract-AF_UNIX-sockets-don-t-work-on-Windows-a.patchDownload
From a850eb8b46bfdcd768a04b335f7de360a4bc3c69 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Mon, 15 Aug 2022 10:43:13 +1200
Subject: [PATCH] Doc: Abstract AF_UNIX sockets don't work on Windows after
 all.

An early release of AF_UNIX in Windows might have supported Linux-style
"abstract" Unix sockets with a system-wide namespace, but they do not
seem to work in current Windows versions and there is no mention of any
of this in the Winsock documentation.  Remove the claim that it works
from our documentation.

Back-patch to 14, where commit c9f0624b landed.

Discussion: https://postgr.es/m/20220813223646.oh2dkjrkj7jn7dpe%40awork3.anarazel.de
---
 doc/src/sgml/config.sgml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index a5cd4e44c7..1fbd5fc0d4 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -759,7 +759,7 @@ include_dir 'conf.d'
        <para>
         A value that starts with <literal>@</literal> specifies that a
         Unix-domain socket in the abstract namespace should be created
-        (currently supported on Linux and Windows).  In that case, this value
+        (currently supported on Linux).  In that case, this value
         does not specify a <quote>directory</quote> but a prefix from which
         the actual socket name is computed in the same manner as for the
         file-system namespace.  While the abstract socket name prefix can be
-- 
2.35.1

#81Thomas Munro
thomas.munro@gmail.com
In reply to: Thomas Munro (#78)
6 attachment(s)
Re: Cleaning up historical portability baggage

On Sun, Aug 14, 2022 at 10:03 AM Thomas Munro <thomas.munro@gmail.com> wrote:

All green on CI... Next stop, build farm.

All good so far (except for an admonishment from crake, for which my
penance was to fix headerscheck, see separate thread...). I did
figure out one thing that I mentioned I was confused by before: the
reason Windows didn't like my direct calls to gai_strerror() is
because another header of ours clobbered one of Windows' own macros.
This new batch includes a fix for that.

Remove configure probe for IPv6.
Remove dead ifaddrs.c fallback code.
Remove configure probe for net/if.h.
Fix macro problem with gai_strerror on Windows.
Remove configure probe for netinet/tcp.h.
mstcpip.h is not missing on MinGW.

The interesting one is a continuation of my "all computers have X"
series. This episode: IPv6.

Attachments:

0001-Remove-configure-probe-for-IPv6.patchtext/x-patch; charset=US-ASCII; name=0001-Remove-configure-probe-for-IPv6.patchDownload
From cd6ba7f0b275a5c2840ee93849a54b94e40a6450 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Mon, 15 Aug 2022 14:47:58 +1200
Subject: [PATCH 1/6] Remove configure probe for IPv6.

SUSv3 requires <netinet/in.h> to define struct sockaddr_in6, and all
targeted Unix systems have it.  Windows has it in ws2ipdef.h.  Remove
the configure probe, the macro and a small amount of dead code.  Also
remove a mention of IPv6-less builds from the documentation, since there
aren't any.
---
 configure                           | 10 ----------
 configure.ac                        |  6 ------
 doc/src/sgml/client-auth.sgml       |  2 --
 src/backend/libpq/auth.c            | 21 ---------------------
 src/backend/libpq/hba.c             |  5 -----
 src/backend/libpq/ifaddr.c          | 29 +----------------------------
 src/backend/libpq/pqcomm.c          |  2 --
 src/backend/utils/adt/network.c     | 10 ----------
 src/backend/utils/adt/pgstatfuncs.c | 11 ++---------
 src/bin/initdb/initdb.c             | 10 ----------
 src/include/pg_config.h.in          |  3 ---
 src/interfaces/libpq/fe-connect.c   |  2 --
 src/tools/ifaddrs/test_ifaddrs.c    |  2 --
 src/tools/msvc/Solution.pm          |  1 -
 14 files changed, 3 insertions(+), 111 deletions(-)

diff --git a/configure b/configure
index 176e0f9b00..8178f290a9 100755
--- a/configure
+++ b/configure
@@ -16279,16 +16279,6 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
-ac_fn_c_check_type "$LINENO" "struct sockaddr_in6" "ac_cv_type_struct_sockaddr_in6" "$ac_includes_default
-#include <netinet/in.h>
-"
-if test "x$ac_cv_type_struct_sockaddr_in6" = xyes; then :
-
-$as_echo "#define HAVE_IPV6 1" >>confdefs.h
-
-fi
-
-
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PS_STRINGS" >&5
 $as_echo_n "checking for PS_STRINGS... " >&6; }
 if ${pgac_cv_var_PS_STRINGS+:} false; then :
diff --git a/configure.ac b/configure.ac
index eed7019c4a..ee45d856c7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1804,12 +1804,6 @@ AC_CHECK_DECLS([pwritev], [], [AC_LIBOBJ(pwritev)], [#include <sys/uio.h>])
 # This is probably only present on macOS, but may as well check always
 AC_CHECK_DECLS(F_FULLFSYNC, [], [], [#include <fcntl.h>])
 
-AC_CHECK_TYPE([struct sockaddr_in6],
-        [AC_DEFINE(HAVE_IPV6, 1, [Define to 1 if you have support for IPv6.])],
-        [],
-[$ac_includes_default
-#include <netinet/in.h>])
-
 AC_CACHE_CHECK([for PS_STRINGS], [pgac_cv_var_PS_STRINGS],
 [AC_LINK_IFELSE([AC_LANG_PROGRAM(
 [#include <machine/vmparam.h>
diff --git a/doc/src/sgml/client-auth.sgml b/doc/src/sgml/client-auth.sgml
index 433759928b..c6f1b70fd3 100644
--- a/doc/src/sgml/client-auth.sgml
+++ b/doc/src/sgml/client-auth.sgml
@@ -305,8 +305,6 @@ hostnogssenc  <replaceable>database</replaceable>  <replaceable>user</replaceabl
        An entry given in IPv4 format will match only IPv4 connections,
        and an entry given in IPv6 format will match only IPv6 connections,
        even if the represented address is in the IPv4-in-IPv6 range.
-       Note that entries in IPv6 format will be rejected if the system's
-       C library does not have support for IPv6 addresses.
       </para>
 
       <para>
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index 290eb17325..7760d714a0 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -3014,13 +3014,8 @@ PerformRadiusTransaction(const char *server, const char *secret, const char *por
 	int			packetlength;
 	pgsocket	sock;
 
-#ifdef HAVE_IPV6
 	struct sockaddr_in6 localaddr;
 	struct sockaddr_in6 remoteaddr;
-#else
-	struct sockaddr_in localaddr;
-	struct sockaddr_in remoteaddr;
-#endif
 	struct addrinfo hint;
 	struct addrinfo *serveraddrs;
 	int			port;
@@ -3130,18 +3125,12 @@ PerformRadiusTransaction(const char *server, const char *secret, const char *por
 	}
 
 	memset(&localaddr, 0, sizeof(localaddr));
-#ifdef HAVE_IPV6
 	localaddr.sin6_family = serveraddrs[0].ai_family;
 	localaddr.sin6_addr = in6addr_any;
 	if (localaddr.sin6_family == AF_INET6)
 		addrsize = sizeof(struct sockaddr_in6);
 	else
 		addrsize = sizeof(struct sockaddr_in);
-#else
-	localaddr.sin_family = serveraddrs[0].ai_family;
-	localaddr.sin_addr.s_addr = INADDR_ANY;
-	addrsize = sizeof(struct sockaddr_in);
-#endif
 
 	if (bind(sock, (struct sockaddr *) &localaddr, addrsize))
 	{
@@ -3244,21 +3233,11 @@ PerformRadiusTransaction(const char *server, const char *secret, const char *por
 			return STATUS_ERROR;
 		}
 
-#ifdef HAVE_IPV6
 		if (remoteaddr.sin6_port != pg_hton16(port))
-#else
-		if (remoteaddr.sin_port != pg_hton16(port))
-#endif
 		{
-#ifdef HAVE_IPV6
 			ereport(LOG,
 					(errmsg("RADIUS response from %s was sent from incorrect port: %d",
 							server, pg_ntoh16(remoteaddr.sin6_port))));
-#else
-			ereport(LOG,
-					(errmsg("RADIUS response from %s was sent from incorrect port: %d",
-							server, pg_ntoh16(remoteaddr.sin_port))));
-#endif
 			continue;
 		}
 
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index 857b9e5eb2..3be94244f5 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -645,8 +645,6 @@ ipv4eq(struct sockaddr_in *a, struct sockaddr_in *b)
 	return (a->sin_addr.s_addr == b->sin_addr.s_addr);
 }
 
-#ifdef HAVE_IPV6
-
 static bool
 ipv6eq(struct sockaddr_in6 *a, struct sockaddr_in6 *b)
 {
@@ -658,7 +656,6 @@ ipv6eq(struct sockaddr_in6 *a, struct sockaddr_in6 *b)
 
 	return true;
 }
-#endif							/* HAVE_IPV6 */
 
 /*
  * Check whether host name matches pattern.
@@ -747,7 +744,6 @@ check_hostname(hbaPort *port, const char *hostname)
 					break;
 				}
 			}
-#ifdef HAVE_IPV6
 			else if (gai->ai_addr->sa_family == AF_INET6)
 			{
 				if (ipv6eq((struct sockaddr_in6 *) gai->ai_addr,
@@ -757,7 +753,6 @@ check_hostname(hbaPort *port, const char *hostname)
 					break;
 				}
 			}
-#endif
 		}
 	}
 
diff --git a/src/backend/libpq/ifaddr.c b/src/backend/libpq/ifaddr.c
index 5494c9b303..cb1645bc57 100644
--- a/src/backend/libpq/ifaddr.c
+++ b/src/backend/libpq/ifaddr.c
@@ -36,11 +36,9 @@ static int	range_sockaddr_AF_INET(const struct sockaddr_in *addr,
 								   const struct sockaddr_in *netaddr,
 								   const struct sockaddr_in *netmask);
 
-#ifdef HAVE_IPV6
 static int	range_sockaddr_AF_INET6(const struct sockaddr_in6 *addr,
 									const struct sockaddr_in6 *netaddr,
 									const struct sockaddr_in6 *netmask);
-#endif
 
 
 /*
@@ -58,12 +56,10 @@ pg_range_sockaddr(const struct sockaddr_storage *addr,
 		return range_sockaddr_AF_INET((const struct sockaddr_in *) addr,
 									  (const struct sockaddr_in *) netaddr,
 									  (const struct sockaddr_in *) netmask);
-#ifdef HAVE_IPV6
 	else if (addr->ss_family == AF_INET6)
 		return range_sockaddr_AF_INET6((const struct sockaddr_in6 *) addr,
 									   (const struct sockaddr_in6 *) netaddr,
 									   (const struct sockaddr_in6 *) netmask);
-#endif
 	else
 		return 0;
 }
@@ -80,9 +76,6 @@ range_sockaddr_AF_INET(const struct sockaddr_in *addr,
 		return 0;
 }
 
-
-#ifdef HAVE_IPV6
-
 static int
 range_sockaddr_AF_INET6(const struct sockaddr_in6 *addr,
 						const struct sockaddr_in6 *netaddr,
@@ -99,7 +92,6 @@ range_sockaddr_AF_INET6(const struct sockaddr_in6 *addr,
 
 	return 1;
 }
-#endif							/* HAVE_IPV6 */
 
 /*
  *	pg_sockaddr_cidr_mask - make a network mask of the appropriate family
@@ -149,7 +141,6 @@ pg_sockaddr_cidr_mask(struct sockaddr_storage *mask, char *numbits, int family)
 				break;
 			}
 
-#ifdef HAVE_IPV6
 		case AF_INET6:
 			{
 				struct sockaddr_in6 mask6;
@@ -174,7 +165,7 @@ pg_sockaddr_cidr_mask(struct sockaddr_storage *mask, char *numbits, int family)
 				memcpy(mask, &mask6, sizeof(mask6));
 				break;
 			}
-#endif
+
 		default:
 			return -1;
 	}
@@ -209,13 +200,11 @@ run_ifaddr_callback(PgIfAddrCallback callback, void *cb_data,
 			if (((struct sockaddr_in *) mask)->sin_addr.s_addr == INADDR_ANY)
 				mask = NULL;
 		}
-#ifdef HAVE_IPV6
 		else if (mask->sa_family == AF_INET6)
 		{
 			if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *) mask)->sin6_addr))
 				mask = NULL;
 		}
-#endif
 	}
 
 	/* If mask is invalid, generate our own fully-set mask */
@@ -358,10 +347,7 @@ pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data)
 	size_t		n_buffer = 1024;
 	pgsocket	sock,
 				fd;
-
-#ifdef HAVE_IPV6
 	pgsocket	sock6;
-#endif
 	int			i,
 				total;
 
@@ -404,7 +390,6 @@ pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data)
 			break;
 	}
 
-#ifdef HAVE_IPV6
 	/* We'll need an IPv6 socket too for the SIOCGLIFNETMASK ioctls */
 	sock6 = socket(AF_INET6, SOCK_DGRAM, 0);
 	if (sock6 == PGINVALID_SOCKET)
@@ -413,7 +398,6 @@ pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data)
 		close(sock);
 		return -1;
 	}
-#endif
 
 	total = lifc.lifc_len / sizeof(struct lifreq);
 	lifr = lifc.lifc_req;
@@ -421,11 +405,7 @@ pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data)
 	{
 		addr = (struct sockaddr *) &lifr[i].lifr_addr;
 		memcpy(&lmask, &lifr[i], sizeof(struct lifreq));
-#ifdef HAVE_IPV6
 		fd = (addr->sa_family == AF_INET6) ? sock6 : sock;
-#else
-		fd = sock;
-#endif
 		if (ioctl(fd, SIOCGLIFNETMASK, &lmask) < 0)
 			mask = NULL;
 		else
@@ -435,9 +415,7 @@ pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data)
 
 	free(buffer);
 	close(sock);
-#ifdef HAVE_IPV6
 	close(sock6);
-#endif
 	return 0;
 }
 #elif defined(SIOCGIFCONF)
@@ -554,10 +532,7 @@ pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data)
 {
 	struct sockaddr_in addr;
 	struct sockaddr_storage mask;
-
-#ifdef HAVE_IPV6
 	struct sockaddr_in6 addr6;
-#endif
 
 	/* addr 127.0.0.1/8 */
 	memset(&addr, 0, sizeof(addr));
@@ -569,7 +544,6 @@ pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data)
 						(struct sockaddr *) &addr,
 						(struct sockaddr *) &mask);
 
-#ifdef HAVE_IPV6
 	/* addr ::1/128 */
 	memset(&addr6, 0, sizeof(addr6));
 	addr6.sin6_family = AF_INET6;
@@ -579,7 +553,6 @@ pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data)
 	run_ifaddr_callback(callback, cb_data,
 						(struct sockaddr *) &addr6,
 						(struct sockaddr *) &mask);
-#endif
 
 	return 0;
 }
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 3ec4328613..f7ba2fc5f5 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -415,11 +415,9 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
 			case AF_INET:
 				familyDesc = _("IPv4");
 				break;
-#ifdef HAVE_IPV6
 			case AF_INET6:
 				familyDesc = _("IPv6");
 				break;
-#endif
 			case AF_UNIX:
 				familyDesc = _("Unix");
 				break;
diff --git a/src/backend/utils/adt/network.c b/src/backend/utils/adt/network.c
index ea1c7390d0..6d580ea78f 100644
--- a/src/backend/utils/adt/network.c
+++ b/src/backend/utils/adt/network.c
@@ -1725,9 +1725,7 @@ inet_client_addr(PG_FUNCTION_ARGS)
 	switch (port->raddr.addr.ss_family)
 	{
 		case AF_INET:
-#ifdef HAVE_IPV6
 		case AF_INET6:
-#endif
 			break;
 		default:
 			PG_RETURN_NULL();
@@ -1764,9 +1762,7 @@ inet_client_port(PG_FUNCTION_ARGS)
 	switch (port->raddr.addr.ss_family)
 	{
 		case AF_INET:
-#ifdef HAVE_IPV6
 		case AF_INET6:
-#endif
 			break;
 		default:
 			PG_RETURN_NULL();
@@ -1801,9 +1797,7 @@ inet_server_addr(PG_FUNCTION_ARGS)
 	switch (port->laddr.addr.ss_family)
 	{
 		case AF_INET:
-#ifdef HAVE_IPV6
 		case AF_INET6:
-#endif
 			break;
 		default:
 			PG_RETURN_NULL();
@@ -1840,9 +1834,7 @@ inet_server_port(PG_FUNCTION_ARGS)
 	switch (port->laddr.addr.ss_family)
 	{
 		case AF_INET:
-#ifdef HAVE_IPV6
 		case AF_INET6:
-#endif
 			break;
 		default:
 			PG_RETURN_NULL();
@@ -2102,7 +2094,6 @@ inetmi(PG_FUNCTION_ARGS)
 void
 clean_ipv6_addr(int addr_family, char *addr)
 {
-#ifdef HAVE_IPV6
 	if (addr_family == AF_INET6)
 	{
 		char	   *pct = strchr(addr, '%');
@@ -2110,5 +2101,4 @@ clean_ipv6_addr(int addr_family, char *addr)
 		if (pct)
 			*pct = '\0';
 	}
-#endif
 }
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index d9e2a79382..4cca30aae7 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -735,11 +735,8 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
 			}
 			else
 			{
-				if (beentry->st_clientaddr.addr.ss_family == AF_INET
-#ifdef HAVE_IPV6
-					|| beentry->st_clientaddr.addr.ss_family == AF_INET6
-#endif
-					)
+				if (beentry->st_clientaddr.addr.ss_family == AF_INET ||
+					beentry->st_clientaddr.addr.ss_family == AF_INET6)
 				{
 					char		remote_host[NI_MAXHOST];
 					char		remote_port[NI_MAXSERV];
@@ -1105,9 +1102,7 @@ pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS)
 	switch (beentry->st_clientaddr.addr.ss_family)
 	{
 		case AF_INET:
-#ifdef HAVE_IPV6
 		case AF_INET6:
-#endif
 			break;
 		default:
 			PG_RETURN_NULL();
@@ -1152,9 +1147,7 @@ pg_stat_get_backend_client_port(PG_FUNCTION_ARGS)
 	switch (beentry->st_clientaddr.addr.ss_family)
 	{
 		case AF_INET:
-#ifdef HAVE_IPV6
 		case AF_INET6:
-#endif
 			break;
 		case AF_UNIX:
 			PG_RETURN_INT32(-1);
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index a779153c74..29c28b7315 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -1176,7 +1176,6 @@ setup_config(void)
 
 	conflines = replace_token(conflines, "@remove-line-for-nolocal@", "");
 
-#ifdef HAVE_IPV6
 
 	/*
 	 * Probe to see if there is really any platform support for IPv6, and
@@ -1218,15 +1217,6 @@ setup_config(void)
 									  "#host    replication     all             ::1");
 		}
 	}
-#else							/* !HAVE_IPV6 */
-	/* If we didn't compile IPV6 support at all, always comment it out */
-	conflines = replace_token(conflines,
-							  "host    all             all             ::1",
-							  "#host    all             all             ::1");
-	conflines = replace_token(conflines,
-							  "host    replication     all             ::1",
-							  "#host    replication     all             ::1");
-#endif							/* HAVE_IPV6 */
 
 	/* Replace default authentication methods */
 	conflines = replace_token(conflines,
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 3087883401..2bc962ca2f 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -241,9 +241,6 @@
 /* Define to 1 if you have the global variable 'int timezone'. */
 #undef HAVE_INT_TIMEZONE
 
-/* Define to 1 if you have support for IPv6. */
-#undef HAVE_IPV6
-
 /* Define to 1 if __builtin_constant_p(x) implies "i"(x) acceptance. */
 #undef HAVE_I_CONSTRAINT__BUILTIN_CONSTANT_P
 
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 1e057db336..0dcce48888 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -1656,7 +1656,6 @@ getHostaddr(PGconn *conn, char *host_addr, int host_addr_len)
 							 host_addr, host_addr_len) == NULL)
 			host_addr[0] = '\0';
 	}
-#ifdef HAVE_IPV6
 	else if (addr->ss_family == AF_INET6)
 	{
 		if (pg_inet_net_ntop(AF_INET6,
@@ -1665,7 +1664,6 @@ getHostaddr(PGconn *conn, char *host_addr, int host_addr_len)
 							 host_addr, host_addr_len) == NULL)
 			host_addr[0] = '\0';
 	}
-#endif
 	else
 		host_addr[0] = '\0';
 }
diff --git a/src/tools/ifaddrs/test_ifaddrs.c b/src/tools/ifaddrs/test_ifaddrs.c
index b8dbb84945..b9a1b7b5e8 100644
--- a/src/tools/ifaddrs/test_ifaddrs.c
+++ b/src/tools/ifaddrs/test_ifaddrs.c
@@ -26,11 +26,9 @@ print_addr(struct sockaddr *addr)
 		case AF_INET:
 			len = sizeof(struct sockaddr_in);
 			break;
-#ifdef HAVE_IPV6
 		case AF_INET6:
 			len = sizeof(struct sockaddr_in6);
 			break;
-#endif
 		default:
 			len = sizeof(struct sockaddr_storage);
 			break;
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 92722a1271..2c4b888266 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -277,7 +277,6 @@ sub GenerateFiles
 		HAVE_INTTYPES_H                             => undef,
 		HAVE_INT_OPTERR                             => undef,
 		HAVE_INT_OPTRESET                           => undef,
-		HAVE_IPV6                                   => 1,
 		HAVE_I_CONSTRAINT__BUILTIN_CONSTANT_P       => undef,
 		HAVE_KQUEUE                                 => undef,
 		HAVE_LANGINFO_H                             => undef,
-- 
2.35.1

0002-Remove-dead-ifaddr.c-fallback-code.patchtext/x-patch; charset=US-ASCII; name=0002-Remove-dead-ifaddr.c-fallback-code.patchDownload
From 4fc436b20807a25576d4652e6d4069e88a5b566a Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Mon, 15 Aug 2022 15:19:13 +1200
Subject: [PATCH 2/6] Remove dead ifaddr.c fallback code.

We carried a special implementation using Solaris-specific ioctl
SIOCGLIFCONF, but Solaris 11 and illumos adopted BSD-style getifaddrs()
a bit over a decade ago, and Solaris 10 is EOL'd.  Remove the dead code.

Our comment about which OSes have getifaddrs() incorrectly listed AIX,
so fix that.  It is in fact the only Unix in the build farm that
*doesn't* have it today, so the implementation based on SIOCGIFCONF
(note, no 'L') is still live.  There may be a better way to do this on
AIX, though (not investigated).

The last-stop fallback is dead code in practice, but it's hard to
justify removing it because our better options are all non-standard.
---
 src/backend/libpq/ifaddr.c | 101 +------------------------------------
 1 file changed, 2 insertions(+), 99 deletions(-)

diff --git a/src/backend/libpq/ifaddr.c b/src/backend/libpq/ifaddr.c
index cb1645bc57..876a1dac08 100644
--- a/src/backend/libpq/ifaddr.c
+++ b/src/backend/libpq/ifaddr.c
@@ -291,7 +291,7 @@ pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data)
  * for each one.  Returns 0 if successful, -1 if trouble.
  *
  * This version uses the getifaddrs() interface, which is available on
- * BSDs, AIX, and modern Linux.
+ * BSDs, macOS, Solaris, illumos and Linux.
  */
 int
 pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data)
@@ -321,104 +321,7 @@ pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data)
 #include <sys/sockio.h>
 #endif
 
-/*
- * SIOCGIFCONF does not return IPv6 addresses on Solaris.
- * So we prefer SIOCGLIFCONF if it's available.
- */
-
-#if defined(SIOCGLIFCONF)
-
-/*
- * Enumerate the system's network interface addresses and call the callback
- * for each one.  Returns 0 if successful, -1 if trouble.
- *
- * This version uses ioctl(SIOCGLIFCONF).
- */
-int
-pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data)
-{
-	struct lifconf lifc;
-	struct lifreq *lifr,
-				lmask;
-	struct sockaddr *addr,
-			   *mask;
-	char	   *ptr,
-			   *buffer = NULL;
-	size_t		n_buffer = 1024;
-	pgsocket	sock,
-				fd;
-	pgsocket	sock6;
-	int			i,
-				total;
-
-	sock = socket(AF_INET, SOCK_DGRAM, 0);
-	if (sock == PGINVALID_SOCKET)
-		return -1;
-
-	while (n_buffer < 1024 * 100)
-	{
-		n_buffer += 1024;
-		ptr = realloc(buffer, n_buffer);
-		if (!ptr)
-		{
-			free(buffer);
-			close(sock);
-			errno = ENOMEM;
-			return -1;
-		}
-
-		memset(&lifc, 0, sizeof(lifc));
-		lifc.lifc_family = AF_UNSPEC;
-		lifc.lifc_buf = buffer = ptr;
-		lifc.lifc_len = n_buffer;
-
-		if (ioctl(sock, SIOCGLIFCONF, &lifc) < 0)
-		{
-			if (errno == EINVAL)
-				continue;
-			free(buffer);
-			close(sock);
-			return -1;
-		}
-
-		/*
-		 * Some Unixes try to return as much data as possible, with no
-		 * indication of whether enough space allocated. Don't believe we have
-		 * it all unless there's lots of slop.
-		 */
-		if (lifc.lifc_len < n_buffer - 1024)
-			break;
-	}
-
-	/* We'll need an IPv6 socket too for the SIOCGLIFNETMASK ioctls */
-	sock6 = socket(AF_INET6, SOCK_DGRAM, 0);
-	if (sock6 == PGINVALID_SOCKET)
-	{
-		free(buffer);
-		close(sock);
-		return -1;
-	}
-
-	total = lifc.lifc_len / sizeof(struct lifreq);
-	lifr = lifc.lifc_req;
-	for (i = 0; i < total; ++i)
-	{
-		addr = (struct sockaddr *) &lifr[i].lifr_addr;
-		memcpy(&lmask, &lifr[i], sizeof(struct lifreq));
-		fd = (addr->sa_family == AF_INET6) ? sock6 : sock;
-		if (ioctl(fd, SIOCGLIFNETMASK, &lmask) < 0)
-			mask = NULL;
-		else
-			mask = (struct sockaddr *) &lmask.lifr_addr;
-		run_ifaddr_callback(callback, cb_data, addr, mask);
-	}
-
-	free(buffer);
-	close(sock);
-	close(sock6);
-	return 0;
-}
-#elif defined(SIOCGIFCONF)
+#if defined(SIOCGIFCONF)
 
 /*
  * Remaining Unixes use SIOCGIFCONF. Some only return IPv4 information
-- 
2.35.1

0003-Remove-configure-probe-for-net-if.h.patchtext/x-patch; charset=US-ASCII; name=0003-Remove-configure-probe-for-net-if.h.patchDownload
From 2b842b038fe86a1f43341254f6f86edce37352f9 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Mon, 15 Aug 2022 16:05:44 +1200
Subject: [PATCH 3/6] Remove configure probe for net/if.h.

<net/if.h> is in SUSv3 and all targeted Unixes have it.  It's used in a
region that is already ifdef'd out for Windows.  According to the
standard it's for the if_nameindex facilities, which we aren't using
directly, but AIX needs it for a related non-standard ioctl.
---
 configure                  | 2 +-
 configure.ac               | 1 -
 src/backend/libpq/ifaddr.c | 3 ---
 src/include/pg_config.h.in | 3 ---
 src/tools/msvc/Solution.pm | 1 -
 5 files changed, 1 insertion(+), 9 deletions(-)

diff --git a/configure b/configure
index 8178f290a9..dd27cc4f85 100755
--- a/configure
+++ b/configure
@@ -13761,7 +13761,7 @@ $as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h
 fi
 
 
-for ac_header in atomic.h copyfile.h execinfo.h getopt.h ifaddrs.h langinfo.h mbarrier.h net/if.h netinet/tcp.h sys/epoll.h sys/event.h sys/personality.h sys/prctl.h sys/procctl.h sys/signalfd.h sys/sockio.h sys/ucred.h termios.h ucred.h
+for ac_header in atomic.h copyfile.h execinfo.h getopt.h ifaddrs.h langinfo.h mbarrier.h netinet/tcp.h sys/epoll.h sys/event.h sys/personality.h sys/prctl.h sys/procctl.h sys/signalfd.h sys/sockio.h sys/ucred.h termios.h ucred.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
diff --git a/configure.ac b/configure.ac
index ee45d856c7..d04372e29d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1450,7 +1450,6 @@ AC_CHECK_HEADERS(m4_normalize([
 	ifaddrs.h
 	langinfo.h
 	mbarrier.h
-	net/if.h
 	netinet/tcp.h
 	sys/epoll.h
 	sys/event.h
diff --git a/src/backend/libpq/ifaddr.c b/src/backend/libpq/ifaddr.c
index 876a1dac08..eb4de5ec2f 100644
--- a/src/backend/libpq/ifaddr.c
+++ b/src/backend/libpq/ifaddr.c
@@ -312,10 +312,7 @@ pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data)
 #else							/* !HAVE_GETIFADDRS && !WIN32 */
 
 #include <sys/ioctl.h>
-
-#ifdef HAVE_NET_IF_H
 #include <net/if.h>
-#endif
 
 #ifdef HAVE_SYS_SOCKIO_H
 #include <sys/sockio.h>
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 2bc962ca2f..4a2914a780 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -322,9 +322,6 @@
 /* Define to 1 if you have the <netinet/tcp.h> header file. */
 #undef HAVE_NETINET_TCP_H
 
-/* Define to 1 if you have the <net/if.h> header file. */
-#undef HAVE_NET_IF_H
-
 /* Define to 1 if you have the `OPENSSL_init_ssl' function. */
 #undef HAVE_OPENSSL_INIT_SSL
 
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 2c4b888266..26217e6d19 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -304,7 +304,6 @@ sub GenerateFiles
 		HAVE_MEMSET_S               => undef,
 		HAVE_MKDTEMP                => undef,
 		HAVE_NETINET_TCP_H          => undef,
-		HAVE_NET_IF_H               => undef,
 		HAVE_OPENSSL_INIT_SSL       => undef,
 		HAVE_OSSP_UUID_H            => undef,
 		HAVE_PAM_PAM_APPL_H         => undef,
-- 
2.35.1

0004-Fix-macro-problem-with-gai_strerror-on-Windows.patchtext/x-patch; charset=US-ASCII; name=0004-Fix-macro-problem-with-gai_strerror-on-Windows.patchDownload
From 967bdf2d3acfcb8ee20942577d51cbeb6cca5c9b Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Mon, 15 Aug 2022 16:19:08 +1200
Subject: [PATCH 4/6] Fix macro problem with gai_strerror on Windows.

Commit 5579388d was confused about why gai_strerror() didn't work on
Windows, and had to be redirected with a macro to gai_strerrorA().  It
turns out that we explicitly undefined Windows' own macro for that
somewhere else.  Oops.  Get rid of all that, so now we can use
gai_sterror() directly using declarations from the system headers.
---
 src/include/port/win32/netdb.h      | 2 --
 src/include/port/win32/sys/socket.h | 7 -------
 2 files changed, 9 deletions(-)

diff --git a/src/include/port/win32/netdb.h b/src/include/port/win32/netdb.h
index f0cc2c2367..9ed13e457b 100644
--- a/src/include/port/win32/netdb.h
+++ b/src/include/port/win32/netdb.h
@@ -4,6 +4,4 @@
 
 #include <ws2tcpip.h>
 
-#define gai_strerror gai_strerrorA
-
 #endif
diff --git a/src/include/port/win32/sys/socket.h b/src/include/port/win32/sys/socket.h
index 9b2cdf3b9b..0c32c0f7b2 100644
--- a/src/include/port/win32/sys/socket.h
+++ b/src/include/port/win32/sys/socket.h
@@ -23,11 +23,4 @@
 #define ERROR PGERROR
 #endif
 
-/*
- * we can't use the windows gai_strerror{AW} functions because
- * they are defined inline in the MS header files. So we'll use our
- * own
- */
-#undef gai_strerror
-
 #endif							/* WIN32_SYS_SOCKET_H */
-- 
2.35.1

0005-Remove-configure-probe-for-netinet-tcp.h.patchtext/x-patch; charset=US-ASCII; name=0005-Remove-configure-probe-for-netinet-tcp.h.patchDownload
From d95e2533c0bdea3d1346879f31fb1718fc1f27cc Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Mon, 15 Aug 2022 16:28:28 +1200
Subject: [PATCH 5/6] Remove configure probe for netinet/tcp.h.

<netinet/tcp.h> is in SUSv3 and all targeted Unix systems have it.
For Windows, we can provide a stub include file, to avoid some #ifdef
noise.
---
 configure                                | 2 +-
 configure.ac                             | 1 -
 src/backend/libpq/be-secure-openssl.c    | 2 --
 src/backend/libpq/be-secure.c            | 2 --
 src/backend/libpq/ifaddr.c               | 2 --
 src/backend/libpq/pqcomm.c               | 2 --
 src/common/ip.c                          | 2 --
 src/include/libpq/libpq-be.h             | 2 --
 src/include/pg_config.h.in               | 3 ---
 src/include/port/win32/netinet/tcp.h     | 3 +++
 src/interfaces/libpq/fe-connect.c        | 2 --
 src/interfaces/libpq/fe-protocol3.c      | 2 --
 src/interfaces/libpq/fe-secure-openssl.c | 2 --
 src/interfaces/libpq/fe-secure.c         | 2 --
 src/tools/msvc/Solution.pm               | 1 -
 15 files changed, 4 insertions(+), 26 deletions(-)
 create mode 100644 src/include/port/win32/netinet/tcp.h

diff --git a/configure b/configure
index dd27cc4f85..554348c413 100755
--- a/configure
+++ b/configure
@@ -13761,7 +13761,7 @@ $as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h
 fi
 
 
-for ac_header in atomic.h copyfile.h execinfo.h getopt.h ifaddrs.h langinfo.h mbarrier.h netinet/tcp.h sys/epoll.h sys/event.h sys/personality.h sys/prctl.h sys/procctl.h sys/signalfd.h sys/sockio.h sys/ucred.h termios.h ucred.h
+for ac_header in atomic.h copyfile.h execinfo.h getopt.h ifaddrs.h langinfo.h mbarrier.h sys/epoll.h sys/event.h sys/personality.h sys/prctl.h sys/procctl.h sys/signalfd.h sys/sockio.h sys/ucred.h termios.h ucred.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
diff --git a/configure.ac b/configure.ac
index d04372e29d..e17f54d1e6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1450,7 +1450,6 @@ AC_CHECK_HEADERS(m4_normalize([
 	ifaddrs.h
 	langinfo.h
 	mbarrier.h
-	netinet/tcp.h
 	sys/epoll.h
 	sys/event.h
 	sys/personality.h
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index 9cec6866a3..55d4b29f7e 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -24,10 +24,8 @@
 #include <unistd.h>
 #include <netdb.h>
 #include <netinet/in.h>
-#ifdef HAVE_NETINET_TCP_H
 #include <netinet/tcp.h>
 #include <arpa/inet.h>
-#endif
 
 #include "libpq/libpq.h"
 #include "miscadmin.h"
diff --git a/src/backend/libpq/be-secure.c b/src/backend/libpq/be-secure.c
index a05f67afb5..e3e54713e8 100644
--- a/src/backend/libpq/be-secure.c
+++ b/src/backend/libpq/be-secure.c
@@ -24,10 +24,8 @@
 #include <sys/socket.h>
 #include <netdb.h>
 #include <netinet/in.h>
-#ifdef HAVE_NETINET_TCP_H
 #include <netinet/tcp.h>
 #include <arpa/inet.h>
-#endif
 
 #include "libpq/libpq.h"
 #include "miscadmin.h"
diff --git a/src/backend/libpq/ifaddr.c b/src/backend/libpq/ifaddr.c
index eb4de5ec2f..18e70741d7 100644
--- a/src/backend/libpq/ifaddr.c
+++ b/src/backend/libpq/ifaddr.c
@@ -24,9 +24,7 @@
 #include <sys/socket.h>
 #include <netdb.h>
 #include <netinet/in.h>
-#ifdef HAVE_NETINET_TCP_H
 #include <netinet/tcp.h>
-#endif
 #include <sys/file.h>
 
 #include "libpq/ifaddr.h"
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index f7ba2fc5f5..3352ddb23b 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -67,9 +67,7 @@
 #include <sys/time.h>
 #include <netdb.h>
 #include <netinet/in.h>
-#ifdef HAVE_NETINET_TCP_H
 #include <netinet/tcp.h>
-#endif
 #include <utime.h>
 #ifdef _MSC_VER					/* mstcpip.h is missing on mingw */
 #include <mstcpip.h>
diff --git a/src/common/ip.c b/src/common/ip.c
index dd9193feb1..0149d07ae7 100644
--- a/src/common/ip.c
+++ b/src/common/ip.c
@@ -28,9 +28,7 @@
 #include <sys/socket.h>
 #include <netdb.h>
 #include <netinet/in.h>
-#ifdef HAVE_NETINET_TCP_H
 #include <netinet/tcp.h>
-#endif
 #include <arpa/inet.h>
 #include <sys/file.h>
 
diff --git a/src/include/libpq/libpq-be.h b/src/include/libpq/libpq-be.h
index fa2fd03009..32d3a4b085 100644
--- a/src/include/libpq/libpq-be.h
+++ b/src/include/libpq/libpq-be.h
@@ -23,9 +23,7 @@
 #include <openssl/ssl.h>
 #include <openssl/err.h>
 #endif
-#ifdef HAVE_NETINET_TCP_H
 #include <netinet/tcp.h>
-#endif
 
 #ifdef ENABLE_GSS
 #if defined(HAVE_GSSAPI_H)
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 4a2914a780..1ae65cfe81 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -319,9 +319,6 @@
 /* Define to 1 if you have the `mkdtemp' function. */
 #undef HAVE_MKDTEMP
 
-/* Define to 1 if you have the <netinet/tcp.h> header file. */
-#undef HAVE_NETINET_TCP_H
-
 /* Define to 1 if you have the `OPENSSL_init_ssl' function. */
 #undef HAVE_OPENSSL_INIT_SSL
 
diff --git a/src/include/port/win32/netinet/tcp.h b/src/include/port/win32/netinet/tcp.h
new file mode 100644
index 0000000000..c1b5062674
--- /dev/null
+++ b/src/include/port/win32/netinet/tcp.h
@@ -0,0 +1,3 @@
+/* src/include/port/win32/netinet/tcp.h */
+
+#include <sys/socket.h>
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 0dcce48888..36aabeef65 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -51,10 +51,8 @@
 #include <sys/socket.h>
 #include <netdb.h>
 #include <netinet/in.h>
-#ifdef HAVE_NETINET_TCP_H
 #include <netinet/tcp.h>
 #endif
-#endif
 
 #ifdef ENABLE_THREAD_SAFETY
 #ifdef WIN32
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index f267dfd33c..bbfb55542d 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -21,10 +21,8 @@
 #include "win32.h"
 #else
 #include <unistd.h>
-#ifdef HAVE_NETINET_TCP_H
 #include <netinet/tcp.h>
 #endif
-#endif
 
 #include "libpq-fe.h"
 #include "libpq-int.h"
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index 8117cbd40f..29a575588e 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -38,9 +38,7 @@
 #include <unistd.h>
 #include <netdb.h>
 #include <netinet/in.h>
-#ifdef HAVE_NETINET_TCP_H
 #include <netinet/tcp.h>
-#endif
 #include <arpa/inet.h>
 #endif
 
diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c
index a1dc7b796d..3df4a97f2e 100644
--- a/src/interfaces/libpq/fe-secure.c
+++ b/src/interfaces/libpq/fe-secure.c
@@ -29,9 +29,7 @@
 #include <unistd.h>
 #include <netdb.h>
 #include <netinet/in.h>
-#ifdef HAVE_NETINET_TCP_H
 #include <netinet/tcp.h>
-#endif
 #include <arpa/inet.h>
 #endif
 
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 26217e6d19..d80efbd95c 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -303,7 +303,6 @@ sub GenerateFiles
 		HAVE_MEMORY_H               => 1,
 		HAVE_MEMSET_S               => undef,
 		HAVE_MKDTEMP                => undef,
-		HAVE_NETINET_TCP_H          => undef,
 		HAVE_OPENSSL_INIT_SSL       => undef,
 		HAVE_OSSP_UUID_H            => undef,
 		HAVE_PAM_PAM_APPL_H         => undef,
-- 
2.35.1

0006-mstcpip.h-is-not-missing-on-MinGW.patchtext/x-patch; charset=US-ASCII; name=0006-mstcpip.h-is-not-missing-on-MinGW.patchDownload
From 69615f6072a4cdad07dd31fe077b46d70391ce4f Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Mon, 15 Aug 2022 16:37:06 +1200
Subject: [PATCH 6/6] mstcpip.h is not missing on MinGW.

Remove a small difference between MinGW and MSVC builds which is no
longer necessary.
---
 src/backend/libpq/pqcomm.c        | 2 +-
 src/interfaces/libpq/fe-connect.c | 2 --
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 3352ddb23b..d2f18dfe50 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -69,7 +69,7 @@
 #include <netinet/in.h>
 #include <netinet/tcp.h>
 #include <utime.h>
-#ifdef _MSC_VER					/* mstcpip.h is missing on mingw */
+#ifdef WIN32
 #include <mstcpip.h>
 #endif
 
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 36aabeef65..917b19e0e9 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -44,9 +44,7 @@
 #endif
 #define near
 #include <shlobj.h>
-#ifdef _MSC_VER					/* mstcpip.h is missing on mingw */
 #include <mstcpip.h>
-#endif
 #else
 #include <sys/socket.h>
 #include <netdb.h>
-- 
2.35.1

#82Peter Eisentraut
peter.eisentraut@enterprisedb.com
In reply to: Thomas Munro (#80)
Re: Cleaning up historical portability baggage

On 15.08.22 03:48, Thomas Munro wrote:

I vaguely remember successfully trying it in the past. But I just tried it
unsuccessfully in a VM and there's a bunch of other places saying it's not
working...
https://github.com/microsoft/WSL/issues/4240

I think we'd better remove our claim that it works then. Patch attached.

When I developed support for abstract unix sockets, I did test them on
Windows. The lack of support on WSL appears to be an unrelated fact.
See for example how [0]https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/ talks about them separately.

[0]: https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/

#83Thomas Munro
thomas.munro@gmail.com
In reply to: Peter Eisentraut (#82)
Re: Cleaning up historical portability baggage

On Mon, Aug 15, 2022 at 8:36 PM Peter Eisentraut
<peter.eisentraut@enterprisedb.com> wrote:

On 15.08.22 03:48, Thomas Munro wrote:

I vaguely remember successfully trying it in the past. But I just tried it
unsuccessfully in a VM and there's a bunch of other places saying it's not
working...
https://github.com/microsoft/WSL/issues/4240

I think we'd better remove our claim that it works then. Patch attached.

When I developed support for abstract unix sockets, I did test them on
Windows. The lack of support on WSL appears to be an unrelated fact.
See for example how [0] talks about them separately.

User amoldeshpande's complaint was posted to the WSL project's issue
tracker but it's about native Windows/winsock code and s/he says so
explicitly (though other people pile in with various other complaints
including WSL interop). User sunilmut's comment says it's not
working, and [0] is now just confusing everybody :-(

#84Andres Freund
andres@anarazel.de
In reply to: Thomas Munro (#80)
Re: Cleaning up historical portability baggage

Hi,

On 2022-08-15 13:48:22 +1200, Thomas Munro wrote:

On Sun, Aug 14, 2022 at 10:36 AM Andres Freund <andres@anarazel.de> wrote:

On 2022-08-14 10:03:19 +1200, Thomas Munro wrote:

I hadn't paid attention to our existing abstract Unix socket support
before and now I'm curious: do we have a confirmed sighting of that
working on Windows?

I vaguely remember successfully trying it in the past. But I just tried it
unsuccessfully in a VM and there's a bunch of other places saying it's not
working...
https://github.com/microsoft/WSL/issues/4240

I think we'd better remove our claim that it works then. Patch attached.

We could also reject it, I guess, but it doesn't immediately seem
harmful so I'm on the fence. On the Windows version that Cirrus is
running, we happily start up with:

2022-08-13 20:44:35.174 GMT [4760][postmaster] LOG: listening on Unix
socket "@c:/cirrus/.s.PGSQL.61696"

What I find odd is that you said your naive program rejected this...

FWIW, in an up-to-date windows 10 VM the client side fails with:

psql: error: connection to server on socket "@frak/.s.PGSQL.5432" failed: Invalid argument (0x00002726/10022)
Is the server running locally and accepting connections on that socket?

That's with most security things disabled and developer mode turned on.

Greetings,

Andres Freund

#85Thomas Munro
thomas.munro@gmail.com
In reply to: Andres Freund (#84)
Re: Cleaning up historical portability baggage

On Tue, Aug 16, 2022 at 7:25 AM Andres Freund <andres@anarazel.de> wrote:

On 2022-08-15 13:48:22 +1200, Thomas Munro wrote:

2022-08-13 20:44:35.174 GMT [4760][postmaster] LOG: listening on Unix
socket "@c:/cirrus/.s.PGSQL.61696"

What I find odd is that you said your naive program rejected this...

No, I said it wasn't behaving sanely. It allowed me to create two
sockets and bind them both to "\000C:\\xxxxxxxxxx", but I expected the
second to fail with EADDRINUSE/10048[1]https://cirrus-ci.com/task/4643322672185344?logs=main#L16. I was messing around with
things like that because my original aim was to check if the names are
silently truncated through EADDRINUSE errors, an approach that worked
for regular Unix sockets.

[1]: https://cirrus-ci.com/task/4643322672185344?logs=main#L16

#86Thomas Munro
thomas.munro@gmail.com
In reply to: Thomas Munro (#85)
Re: Cleaning up historical portability baggage

On Tue, Aug 16, 2022 at 7:51 AM Thomas Munro <thomas.munro@gmail.com> wrote:

[1] https://cirrus-ci.com/task/4643322672185344?logs=main#L16

Derp, I noticed that that particular horrendous quick and dirty test
code was invalidated by a closesocket() call, but in another version I
commented that out and it didn't help. Of course it's possible that
I'm still doing something wrong in the test, I didn't spend long on
this once I saw the bigger picture...

#87Thomas Munro
thomas.munro@gmail.com
In reply to: Thomas Munro (#69)
Re: Cleaning up historical portability baggage

On Fri, Aug 12, 2022 at 7:42 PM Thomas Munro <thomas.munro@gmail.com> wrote:

On Fri, Aug 12, 2022 at 5:14 AM Andres Freund <andres@anarazel.de> wrote:

I don't really know what to do about the warnings around remove_temp() and
trapsig(). I think we actually may be overreading the restrictions. To me the
documented restrictions read more like a high-level-ish explanation of what's
safe in a signal handler and what not. And it seems to not have caused a
problem on windows on several thousand CI cycles, including plenty failures.

So the question there is whether we can run this stuff safely in
Windows signal handler context, considering the rather vaguely defined
conditions[1]https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/signal?view=msvc-170:

unlink(sockself);
unlink(socklock);
rmdir(temp_sockdir);

You'd think that basic stuff like DeleteFile() that just enters the
kernel would be async-signal-safe, like on Unix; the danger surely
comes from stepping on the user context's toes with state mutations,
locks etc. But let's suppose we want to play by a timid
interpretation of that page's "do not issue low-level or STDIO.H I/O
routines". It also says that SIGINT is special and runs the handler
in a new thread (in a big warning box because that has other hazards
that would break other kinds of code). Well, we *know* it's safe to
unlink files in another thread... so... how cheesy would it be if we
just did raise(SIGINT) in the real handlers?

[1]: https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/signal?view=msvc-170

#88Andres Freund
andres@anarazel.de
In reply to: Thomas Munro (#87)
Re: Cleaning up historical portability baggage

Hi,

On 2022-08-16 13:02:55 +1200, Thomas Munro wrote:

On Fri, Aug 12, 2022 at 7:42 PM Thomas Munro <thomas.munro@gmail.com> wrote:

On Fri, Aug 12, 2022 at 5:14 AM Andres Freund <andres@anarazel.de> wrote:

I don't really know what to do about the warnings around remove_temp() and
trapsig(). I think we actually may be overreading the restrictions. To me the
documented restrictions read more like a high-level-ish explanation of what's
safe in a signal handler and what not. And it seems to not have caused a
problem on windows on several thousand CI cycles, including plenty failures.

So the question there is whether we can run this stuff safely in
Windows signal handler context, considering the rather vaguely defined
conditions[1]:

unlink(sockself);
unlink(socklock);
rmdir(temp_sockdir);

You'd think that basic stuff like DeleteFile() that just enters the
kernel would be async-signal-safe, like on Unix; the danger surely
comes from stepping on the user context's toes with state mutations,
locks etc.

Yea.

I guess it could be different because things like file descriptors are just a
userland concept.

But let's suppose we want to play by a timid interpretation of that page's
"do not issue low-level or STDIO.H I/O routines". It also says that SIGINT
is special and runs the handler in a new thread (in a big warning box
because that has other hazards that would break other kinds of code). Well,
we *know* it's safe to unlink files in another thread... so... how cheesy
would it be if we just did raise(SIGINT) in the real handlers?

Not quite sure I understand. You're proposing to raise(SIGINT) for all other
handlers, so that signal_remove_temp() gets called in another thread, because
we assume that'd be safe because doing file IO in other threads is safe? That
assumes the signal handler invocation infrastructure isn't the problem...

Looks like we could register a "native" ctrl-c handler:
https://docs.microsoft.com/en-us/windows/console/setconsolectrlhandler
they're documented to run in a different thread, but without any of the
file-io warnings.
https://docs.microsoft.com/en-us/windows/console/handlerroutine

Greetings,

Andres Freund

#89Thomas Munro
thomas.munro@gmail.com
In reply to: Andres Freund (#88)
Re: Cleaning up historical portability baggage

On Tue, Aug 16, 2022 at 1:16 PM Andres Freund <andres@anarazel.de> wrote:

But let's suppose we want to play by a timid interpretation of that page's
"do not issue low-level or STDIO.H I/O routines". It also says that SIGINT
is special and runs the handler in a new thread (in a big warning box
because that has other hazards that would break other kinds of code). Well,
we *know* it's safe to unlink files in another thread... so... how cheesy
would it be if we just did raise(SIGINT) in the real handlers?

Not quite sure I understand. You're proposing to raise(SIGINT) for all other
handlers, so that signal_remove_temp() gets called in another thread, because
we assume that'd be safe because doing file IO in other threads is safe? That
assumes the signal handler invocation infrastructure isn't the problem...

That's what I was thinking about, yeah. But after some more reading,
now I'm wondering if we'd even need to do that, or what I'm missing.
The 6 listed signals in the manual are SIGABRT, SIGFPE, SIGILL,
SIGINT, SIGSEGV and SIGTERM (the 6 required by C). We want to run
signal_remove_temp() on SIGHUP (doesn't exist, we made it up), SIGINT,
SIGPIPE (doesn't exist, we made it up), and SIGTERM (exists for C spec
compliance but will never be raised by the system according to the
manual, and we don't raise it ourselves IIUC). So the only case we
actually have to consider is SIGINT, and SIGINT handlers run in a
thread, so if we assume it is therefore exempt from those
very-hard-to-comply-with rules, aren't we good already? What am I
missing?

Looks like we could register a "native" ctrl-c handler:
https://docs.microsoft.com/en-us/windows/console/setconsolectrlhandler
they're documented to run in a different thread, but without any of the
file-io warnings.
https://docs.microsoft.com/en-us/windows/console/handlerroutine

Sounds better in general, considering the extreme constraints of the
signal system, but it'd be nice to see if the current system is truly
unsafe before writing more alien code.

Someone who wants to handle more than one SIGINT would certainly need
to consider that, because there doesn't seem to be a race-free way to
reinstall the signal handler when you receive it[1]https://wiki.sei.cmu.edu/confluence/display/c/SIG01-C.+Understand+implementation-specific+details+regarding+signal+handler+persistence. Races aside, for
any signal except SIGINT (assuming the above-mentioned exemption),
you're probably also not even allowed to try because raise() might be
a system call and they're banned. Fortunately we don't care, we
wanted SIG_DFL next anyway.

[1]: https://wiki.sei.cmu.edu/confluence/display/c/SIG01-C.+Understand+implementation-specific+details+regarding+signal+handler+persistence

#90Thomas Munro
thomas.munro@gmail.com
In reply to: Thomas Munro (#81)
1 attachment(s)
Re: Cleaning up historical portability baggage

On Mon, Aug 15, 2022 at 5:53 PM Thomas Munro <thomas.munro@gmail.com> wrote:

Remove configure probe for IPv6.
Remove dead ifaddrs.c fallback code.
Remove configure probe for net/if.h.
Fix macro problem with gai_strerror on Windows.
Remove configure probe for netinet/tcp.h.
mstcpip.h is not missing on MinGW.

I pushed these except one, plus one more about <sys/sockio.h> which
turned out to be not needed after a bit of archeology.

Here's a slightly better AF_INET6 one. I'm planning to push it
tomorrow if there are no objections. It does something a little more
aggressive than the preceding stuff, because SUSv3 says that IPv6 is
an "option". I don't see that as an issue: it also says that various
other ubiquitous stuff we're using is optional. Of course, it would
be absurd for a new socket implementation to appear today that can't
talk to a decent chunk of the internet, and all we require here is the
headers. That optionality was relevant for the transition period a
couple of decades ago.

Attachments:

0001-Remove-configure-probe-for-sockaddr_in6-and-require-.patchtext/x-patch; charset=US-ASCII; name=0001-Remove-configure-probe-for-sockaddr_in6-and-require-.patchDownload
From f162a15a6d723f8c94d9daa6236149e1f39b0d9a Mon Sep 17 00:00:00 2001
From: Thomas Munro <tmunro@postgresql.org>
Date: Thu, 18 Aug 2022 11:55:10 +1200
Subject: [PATCH] Remove configure probe for sockaddr_in6 and require AF_INET6.

SUSv3 <netinet/in.h> defines struct sockaddr_in6, and all targeted Unix
systems have it.  Windows has it in <ws2ipdef.h>.  Remove the configure
probe, the macro and a small amount of dead code.

Also remove a mention of IPv6-less builds from the documentation, since
there aren't any.

This is similar to commits f5580882 and 077bf2f2 for Unix sockets.
Even though AF_INET6 is an "optional" component of SUSv3, there are no
known modern operating system without it, and it seems even less likely
to be omitted from future systems than AF_UNIX.

Discussion: https://postgr.es/m/CA+hUKGKErNfhmvb_H0UprEmp4LPzGN06yR2_0tYikjzB-2ECMw@mail.gmail.com
---
 configure                           | 10 ----------
 configure.ac                        |  6 ------
 doc/src/sgml/client-auth.sgml       |  2 --
 src/backend/libpq/auth.c            | 21 ---------------------
 src/backend/libpq/hba.c             |  5 -----
 src/backend/libpq/ifaddr.c          | 18 +-----------------
 src/backend/libpq/pqcomm.c          |  2 --
 src/backend/utils/adt/network.c     | 10 ----------
 src/backend/utils/adt/pgstatfuncs.c | 11 ++---------
 src/bin/initdb/initdb.c             | 10 ----------
 src/include/pg_config.h.in          |  3 ---
 src/include/utils/inet.h            |  9 ++++-----
 src/interfaces/libpq/fe-connect.c   |  2 --
 src/port/inet_net_ntop.c            |  5 ++---
 src/tools/ifaddrs/test_ifaddrs.c    |  2 --
 src/tools/msvc/Solution.pm          |  1 -
 16 files changed, 9 insertions(+), 108 deletions(-)

diff --git a/configure b/configure
index b7fd6c5f4e..c275330114 100755
--- a/configure
+++ b/configure
@@ -16279,16 +16279,6 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
-ac_fn_c_check_type "$LINENO" "struct sockaddr_in6" "ac_cv_type_struct_sockaddr_in6" "$ac_includes_default
-#include <netinet/in.h>
-"
-if test "x$ac_cv_type_struct_sockaddr_in6" = xyes; then :
-
-$as_echo "#define HAVE_IPV6 1" >>confdefs.h
-
-fi
-
-
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PS_STRINGS" >&5
 $as_echo_n "checking for PS_STRINGS... " >&6; }
 if ${pgac_cv_var_PS_STRINGS+:} false; then :
diff --git a/configure.ac b/configure.ac
index e5740f4fb5..a97a48a508 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1801,12 +1801,6 @@ AC_CHECK_DECLS([pwritev], [], [AC_LIBOBJ(pwritev)], [#include <sys/uio.h>])
 # This is probably only present on macOS, but may as well check always
 AC_CHECK_DECLS(F_FULLFSYNC, [], [], [#include <fcntl.h>])
 
-AC_CHECK_TYPE([struct sockaddr_in6],
-        [AC_DEFINE(HAVE_IPV6, 1, [Define to 1 if you have support for IPv6.])],
-        [],
-[$ac_includes_default
-#include <netinet/in.h>])
-
 AC_CACHE_CHECK([for PS_STRINGS], [pgac_cv_var_PS_STRINGS],
 [AC_LINK_IFELSE([AC_LANG_PROGRAM(
 [#include <machine/vmparam.h>
diff --git a/doc/src/sgml/client-auth.sgml b/doc/src/sgml/client-auth.sgml
index 433759928b..c6f1b70fd3 100644
--- a/doc/src/sgml/client-auth.sgml
+++ b/doc/src/sgml/client-auth.sgml
@@ -305,8 +305,6 @@ hostnogssenc  <replaceable>database</replaceable>  <replaceable>user</replaceabl
        An entry given in IPv4 format will match only IPv4 connections,
        and an entry given in IPv6 format will match only IPv6 connections,
        even if the represented address is in the IPv4-in-IPv6 range.
-       Note that entries in IPv6 format will be rejected if the system's
-       C library does not have support for IPv6 addresses.
       </para>
 
       <para>
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index 1545ff9f16..71677b69d8 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -3014,13 +3014,8 @@ PerformRadiusTransaction(const char *server, const char *secret, const char *por
 	int			packetlength;
 	pgsocket	sock;
 
-#ifdef HAVE_IPV6
 	struct sockaddr_in6 localaddr;
 	struct sockaddr_in6 remoteaddr;
-#else
-	struct sockaddr_in localaddr;
-	struct sockaddr_in remoteaddr;
-#endif
 	struct addrinfo hint;
 	struct addrinfo *serveraddrs;
 	int			port;
@@ -3130,18 +3125,12 @@ PerformRadiusTransaction(const char *server, const char *secret, const char *por
 	}
 
 	memset(&localaddr, 0, sizeof(localaddr));
-#ifdef HAVE_IPV6
 	localaddr.sin6_family = serveraddrs[0].ai_family;
 	localaddr.sin6_addr = in6addr_any;
 	if (localaddr.sin6_family == AF_INET6)
 		addrsize = sizeof(struct sockaddr_in6);
 	else
 		addrsize = sizeof(struct sockaddr_in);
-#else
-	localaddr.sin_family = serveraddrs[0].ai_family;
-	localaddr.sin_addr.s_addr = INADDR_ANY;
-	addrsize = sizeof(struct sockaddr_in);
-#endif
 
 	if (bind(sock, (struct sockaddr *) &localaddr, addrsize))
 	{
@@ -3244,21 +3233,11 @@ PerformRadiusTransaction(const char *server, const char *secret, const char *por
 			return STATUS_ERROR;
 		}
 
-#ifdef HAVE_IPV6
 		if (remoteaddr.sin6_port != pg_hton16(port))
-#else
-		if (remoteaddr.sin_port != pg_hton16(port))
-#endif
 		{
-#ifdef HAVE_IPV6
 			ereport(LOG,
 					(errmsg("RADIUS response from %s was sent from incorrect port: %d",
 							server, pg_ntoh16(remoteaddr.sin6_port))));
-#else
-			ereport(LOG,
-					(errmsg("RADIUS response from %s was sent from incorrect port: %d",
-							server, pg_ntoh16(remoteaddr.sin_port))));
-#endif
 			continue;
 		}
 
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index 1447588c4a..8f2b8c6b03 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -645,8 +645,6 @@ ipv4eq(struct sockaddr_in *a, struct sockaddr_in *b)
 	return (a->sin_addr.s_addr == b->sin_addr.s_addr);
 }
 
-#ifdef HAVE_IPV6
-
 static bool
 ipv6eq(struct sockaddr_in6 *a, struct sockaddr_in6 *b)
 {
@@ -658,7 +656,6 @@ ipv6eq(struct sockaddr_in6 *a, struct sockaddr_in6 *b)
 
 	return true;
 }
-#endif							/* HAVE_IPV6 */
 
 /*
  * Check whether host name matches pattern.
@@ -747,7 +744,6 @@ check_hostname(hbaPort *port, const char *hostname)
 					break;
 				}
 			}
-#ifdef HAVE_IPV6
 			else if (gai->ai_addr->sa_family == AF_INET6)
 			{
 				if (ipv6eq((struct sockaddr_in6 *) gai->ai_addr,
@@ -757,7 +753,6 @@ check_hostname(hbaPort *port, const char *hostname)
 					break;
 				}
 			}
-#endif
 		}
 	}
 
diff --git a/src/backend/libpq/ifaddr.c b/src/backend/libpq/ifaddr.c
index de35fbba45..ff9dadfb37 100644
--- a/src/backend/libpq/ifaddr.c
+++ b/src/backend/libpq/ifaddr.c
@@ -34,11 +34,9 @@ static int	range_sockaddr_AF_INET(const struct sockaddr_in *addr,
 								   const struct sockaddr_in *netaddr,
 								   const struct sockaddr_in *netmask);
 
-#ifdef HAVE_IPV6
 static int	range_sockaddr_AF_INET6(const struct sockaddr_in6 *addr,
 									const struct sockaddr_in6 *netaddr,
 									const struct sockaddr_in6 *netmask);
-#endif
 
 
 /*
@@ -56,12 +54,10 @@ pg_range_sockaddr(const struct sockaddr_storage *addr,
 		return range_sockaddr_AF_INET((const struct sockaddr_in *) addr,
 									  (const struct sockaddr_in *) netaddr,
 									  (const struct sockaddr_in *) netmask);
-#ifdef HAVE_IPV6
 	else if (addr->ss_family == AF_INET6)
 		return range_sockaddr_AF_INET6((const struct sockaddr_in6 *) addr,
 									   (const struct sockaddr_in6 *) netaddr,
 									   (const struct sockaddr_in6 *) netmask);
-#endif
 	else
 		return 0;
 }
@@ -78,9 +74,6 @@ range_sockaddr_AF_INET(const struct sockaddr_in *addr,
 		return 0;
 }
 
-
-#ifdef HAVE_IPV6
-
 static int
 range_sockaddr_AF_INET6(const struct sockaddr_in6 *addr,
 						const struct sockaddr_in6 *netaddr,
@@ -97,7 +90,6 @@ range_sockaddr_AF_INET6(const struct sockaddr_in6 *addr,
 
 	return 1;
 }
-#endif							/* HAVE_IPV6 */
 
 /*
  *	pg_sockaddr_cidr_mask - make a network mask of the appropriate family
@@ -147,7 +139,6 @@ pg_sockaddr_cidr_mask(struct sockaddr_storage *mask, char *numbits, int family)
 				break;
 			}
 
-#ifdef HAVE_IPV6
 		case AF_INET6:
 			{
 				struct sockaddr_in6 mask6;
@@ -172,7 +163,7 @@ pg_sockaddr_cidr_mask(struct sockaddr_storage *mask, char *numbits, int family)
 				memcpy(mask, &mask6, sizeof(mask6));
 				break;
 			}
-#endif
+
 		default:
 			return -1;
 	}
@@ -207,13 +198,11 @@ run_ifaddr_callback(PgIfAddrCallback callback, void *cb_data,
 			if (((struct sockaddr_in *) mask)->sin_addr.s_addr == INADDR_ANY)
 				mask = NULL;
 		}
-#ifdef HAVE_IPV6
 		else if (mask->sa_family == AF_INET6)
 		{
 			if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *) mask)->sin6_addr))
 				mask = NULL;
 		}
-#endif
 	}
 
 	/* If mask is invalid, generate our own fully-set mask */
@@ -437,10 +426,7 @@ pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data)
 {
 	struct sockaddr_in addr;
 	struct sockaddr_storage mask;
-
-#ifdef HAVE_IPV6
 	struct sockaddr_in6 addr6;
-#endif
 
 	/* addr 127.0.0.1/8 */
 	memset(&addr, 0, sizeof(addr));
@@ -452,7 +438,6 @@ pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data)
 						(struct sockaddr *) &addr,
 						(struct sockaddr *) &mask);
 
-#ifdef HAVE_IPV6
 	/* addr ::1/128 */
 	memset(&addr6, 0, sizeof(addr6));
 	addr6.sin6_family = AF_INET6;
@@ -462,7 +447,6 @@ pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data)
 	run_ifaddr_callback(callback, cb_data,
 						(struct sockaddr *) &addr6,
 						(struct sockaddr *) &mask);
-#endif
 
 	return 0;
 }
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 8ff3be611d..d2f18dfe50 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -413,11 +413,9 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
 			case AF_INET:
 				familyDesc = _("IPv4");
 				break;
-#ifdef HAVE_IPV6
 			case AF_INET6:
 				familyDesc = _("IPv6");
 				break;
-#endif
 			case AF_UNIX:
 				familyDesc = _("Unix");
 				break;
diff --git a/src/backend/utils/adt/network.c b/src/backend/utils/adt/network.c
index ea1c7390d0..6d580ea78f 100644
--- a/src/backend/utils/adt/network.c
+++ b/src/backend/utils/adt/network.c
@@ -1725,9 +1725,7 @@ inet_client_addr(PG_FUNCTION_ARGS)
 	switch (port->raddr.addr.ss_family)
 	{
 		case AF_INET:
-#ifdef HAVE_IPV6
 		case AF_INET6:
-#endif
 			break;
 		default:
 			PG_RETURN_NULL();
@@ -1764,9 +1762,7 @@ inet_client_port(PG_FUNCTION_ARGS)
 	switch (port->raddr.addr.ss_family)
 	{
 		case AF_INET:
-#ifdef HAVE_IPV6
 		case AF_INET6:
-#endif
 			break;
 		default:
 			PG_RETURN_NULL();
@@ -1801,9 +1797,7 @@ inet_server_addr(PG_FUNCTION_ARGS)
 	switch (port->laddr.addr.ss_family)
 	{
 		case AF_INET:
-#ifdef HAVE_IPV6
 		case AF_INET6:
-#endif
 			break;
 		default:
 			PG_RETURN_NULL();
@@ -1840,9 +1834,7 @@ inet_server_port(PG_FUNCTION_ARGS)
 	switch (port->laddr.addr.ss_family)
 	{
 		case AF_INET:
-#ifdef HAVE_IPV6
 		case AF_INET6:
-#endif
 			break;
 		default:
 			PG_RETURN_NULL();
@@ -2102,7 +2094,6 @@ inetmi(PG_FUNCTION_ARGS)
 void
 clean_ipv6_addr(int addr_family, char *addr)
 {
-#ifdef HAVE_IPV6
 	if (addr_family == AF_INET6)
 	{
 		char	   *pct = strchr(addr, '%');
@@ -2110,5 +2101,4 @@ clean_ipv6_addr(int addr_family, char *addr)
 		if (pct)
 			*pct = '\0';
 	}
-#endif
 }
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index d9e2a79382..4cca30aae7 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -735,11 +735,8 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
 			}
 			else
 			{
-				if (beentry->st_clientaddr.addr.ss_family == AF_INET
-#ifdef HAVE_IPV6
-					|| beentry->st_clientaddr.addr.ss_family == AF_INET6
-#endif
-					)
+				if (beentry->st_clientaddr.addr.ss_family == AF_INET ||
+					beentry->st_clientaddr.addr.ss_family == AF_INET6)
 				{
 					char		remote_host[NI_MAXHOST];
 					char		remote_port[NI_MAXSERV];
@@ -1105,9 +1102,7 @@ pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS)
 	switch (beentry->st_clientaddr.addr.ss_family)
 	{
 		case AF_INET:
-#ifdef HAVE_IPV6
 		case AF_INET6:
-#endif
 			break;
 		default:
 			PG_RETURN_NULL();
@@ -1152,9 +1147,7 @@ pg_stat_get_backend_client_port(PG_FUNCTION_ARGS)
 	switch (beentry->st_clientaddr.addr.ss_family)
 	{
 		case AF_INET:
-#ifdef HAVE_IPV6
 		case AF_INET6:
-#endif
 			break;
 		case AF_UNIX:
 			PG_RETURN_INT32(-1);
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index a779153c74..29c28b7315 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -1176,7 +1176,6 @@ setup_config(void)
 
 	conflines = replace_token(conflines, "@remove-line-for-nolocal@", "");
 
-#ifdef HAVE_IPV6
 
 	/*
 	 * Probe to see if there is really any platform support for IPv6, and
@@ -1218,15 +1217,6 @@ setup_config(void)
 									  "#host    replication     all             ::1");
 		}
 	}
-#else							/* !HAVE_IPV6 */
-	/* If we didn't compile IPV6 support at all, always comment it out */
-	conflines = replace_token(conflines,
-							  "host    all             all             ::1",
-							  "#host    all             all             ::1");
-	conflines = replace_token(conflines,
-							  "host    replication     all             ::1",
-							  "#host    replication     all             ::1");
-#endif							/* HAVE_IPV6 */
 
 	/* Replace default authentication methods */
 	conflines = replace_token(conflines,
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index b8fe2201f4..112760e302 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -241,9 +241,6 @@
 /* Define to 1 if you have the global variable 'int timezone'. */
 #undef HAVE_INT_TIMEZONE
 
-/* Define to 1 if you have support for IPv6. */
-#undef HAVE_IPV6
-
 /* Define to 1 if __builtin_constant_p(x) implies "i"(x) acceptance. */
 #undef HAVE_I_CONSTRAINT__BUILTIN_CONSTANT_P
 
diff --git a/src/include/utils/inet.h b/src/include/utils/inet.h
index 3073c0307e..578c44ab40 100644
--- a/src/include/utils/inet.h
+++ b/src/include/utils/inet.h
@@ -30,11 +30,10 @@ typedef struct
 /*
  * We use these values for the "family" field.
  *
- * Referencing all of the non-AF_INET types to AF_INET lets us work on
- * machines which may not have the appropriate address family (like
- * inet6 addresses when AF_INET6 isn't present) but doesn't cause a
- * dump/reload requirement.  Pre-7.4 databases used AF_INET for the family
- * type on disk.
+ * We started when operating system support for IPv6 was not ubiquitous.
+ * Since we couldn't rely on AF_INET6 being defined yet, we used AF_INET + 1.
+ * We continue to do that so that on-disk data originating on such systems
+ * survives pg_upgrade.
  */
 #define PGSQL_AF_INET	(AF_INET + 0)
 #define PGSQL_AF_INET6	(AF_INET + 1)
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 8cefef20d1..917b19e0e9 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -1652,7 +1652,6 @@ getHostaddr(PGconn *conn, char *host_addr, int host_addr_len)
 							 host_addr, host_addr_len) == NULL)
 			host_addr[0] = '\0';
 	}
-#ifdef HAVE_IPV6
 	else if (addr->ss_family == AF_INET6)
 	{
 		if (pg_inet_net_ntop(AF_INET6,
@@ -1661,7 +1660,6 @@ getHostaddr(PGconn *conn, char *host_addr, int host_addr_len)
 							 host_addr, host_addr_len) == NULL)
 			host_addr[0] = '\0';
 	}
-#endif
 	else
 		host_addr[0] = '\0';
 }
diff --git a/src/port/inet_net_ntop.c b/src/port/inet_net_ntop.c
index b8ad69c390..500c66dbf1 100644
--- a/src/port/inet_net_ntop.c
+++ b/src/port/inet_net_ntop.c
@@ -80,15 +80,14 @@ pg_inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size)
 	 * We need to cover both the address family constants used by the PG inet
 	 * type (PGSQL_AF_INET and PGSQL_AF_INET6) and those used by the system
 	 * libraries (AF_INET and AF_INET6).  We can safely assume PGSQL_AF_INET
-	 * == AF_INET, but the INET6 constants are very likely to be different. If
-	 * AF_INET6 isn't defined, silently ignore it.
+	 * == AF_INET, but the INET6 constants are very likely to be different.
 	 */
 	switch (af)
 	{
 		case PGSQL_AF_INET:
 			return (inet_net_ntop_ipv4(src, bits, dst, size));
 		case PGSQL_AF_INET6:
-#if defined(AF_INET6) && AF_INET6 != PGSQL_AF_INET6
+#if AF_INET6 != PGSQL_AF_INET6
 		case AF_INET6:
 #endif
 			return (inet_net_ntop_ipv6(src, bits, dst, size));
diff --git a/src/tools/ifaddrs/test_ifaddrs.c b/src/tools/ifaddrs/test_ifaddrs.c
index b8dbb84945..b9a1b7b5e8 100644
--- a/src/tools/ifaddrs/test_ifaddrs.c
+++ b/src/tools/ifaddrs/test_ifaddrs.c
@@ -26,11 +26,9 @@ print_addr(struct sockaddr *addr)
 		case AF_INET:
 			len = sizeof(struct sockaddr_in);
 			break;
-#ifdef HAVE_IPV6
 		case AF_INET6:
 			len = sizeof(struct sockaddr_in6);
 			break;
-#endif
 		default:
 			len = sizeof(struct sockaddr_storage);
 			break;
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 55b30090f6..e20702824e 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -277,7 +277,6 @@ sub GenerateFiles
 		HAVE_INTTYPES_H                             => undef,
 		HAVE_INT_OPTERR                             => undef,
 		HAVE_INT_OPTRESET                           => undef,
-		HAVE_IPV6                                   => 1,
 		HAVE_I_CONSTRAINT__BUILTIN_CONSTANT_P       => undef,
 		HAVE_KQUEUE                                 => undef,
 		HAVE_LANGINFO_H                             => undef,
-- 
2.35.1

#91Thomas Munro
thomas.munro@gmail.com
In reply to: Thomas Munro (#89)
2 attachment(s)
Re: Cleaning up historical portability baggage

On Tue, Aug 16, 2022 at 4:14 PM Thomas Munro <thomas.munro@gmail.com> wrote:

On Tue, Aug 16, 2022 at 1:16 PM Andres Freund <andres@anarazel.de> wrote:

But let's suppose we want to play by a timid interpretation of that page's
"do not issue low-level or STDIO.H I/O routines". It also says that SIGINT
is special and runs the handler in a new thread (in a big warning box
because that has other hazards that would break other kinds of code). Well,
we *know* it's safe to unlink files in another thread... so... how cheesy
would it be if we just did raise(SIGINT) in the real handlers?

Not quite sure I understand. You're proposing to raise(SIGINT) for all other
handlers, so that signal_remove_temp() gets called in another thread, because
we assume that'd be safe because doing file IO in other threads is safe? That
assumes the signal handler invocation infrastructure isn't the problem...

That's what I was thinking about, yeah. But after some more reading,
now I'm wondering if we'd even need to do that, or what I'm missing.
The 6 listed signals in the manual are SIGABRT, SIGFPE, SIGILL,
SIGINT, SIGSEGV and SIGTERM (the 6 required by C). We want to run
signal_remove_temp() on SIGHUP (doesn't exist, we made it up), SIGINT,
SIGPIPE (doesn't exist, we made it up), and SIGTERM (exists for C spec
compliance but will never be raised by the system according to the
manual, and we don't raise it ourselves IIUC). So the only case we
actually have to consider is SIGINT, and SIGINT handlers run in a
thread, so if we assume it is therefore exempt from those
very-hard-to-comply-with rules, aren't we good already? What am I
missing?

I converted that analysis into a WIP patch, and tried to make the
Windows test setup as similar to Unix as possible. I put in the
explanation and an assertion that it's running in another thread.
This is blind coded as I don't have Windows, but it passes CI. I'd
probably need some help from a Windows-enabled hacker to go further
with this, though. Does the assertion hold if you control-C the
regression test, and is there any other way to get it to fail?

The next thing is that the security infrastructure added by commit
f6dc6dd5 for CVE-2014-0067 is ripped out (because unreachable) by the
attached, but the security infrastructure added by commit be76a6d3
probably doesn't work on Windows yet. Where src/port/mkdtemp.c does
mkdir(name, 0700), I believe Windows throws away the mode and makes a
default ACL directory, probably due to the mismatch between the
permissions models. I haven't studied the Windows security model, but
reading tells me that AF_UNIX will obey filesystem ACLs, so I think we
should be able to make it exactly as secure as Unix if we use native
APIs. Perhaps we just need to replace the mkdir() call in mkdtemp.c
with CreateDirectory(), passing in a locked-down owner-only
SECURITY_DESCRIPTOR, or something like that?

Attachments:

0001-WIP-Always-use-Unix-domain-sockets-in-pg_regress-on-.patchtext/x-patch; charset=US-ASCII; name=0001-WIP-Always-use-Unix-domain-sockets-in-pg_regress-on-.patchDownload
From 2bbaa4b37b4044f03d99b1effa137b06abfe0b21 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Fri, 19 Aug 2022 11:28:38 +1200
Subject: [PATCH 1/2] WIP: Always use Unix-domain sockets in pg_regress on
 Windows.

Since we can now rely on Unix-domain sockets working on supported
Windows releases, we can remove a difference between Unix and Windows in
pg_regress.

Previously, we thought the socket cleanup code was unsafe, so we made
Unix-domain sockets an option with a "use-at-your-own-risk" note.  On
closer inspection, the concerns about signal handlers don't seem to
apply here.  (initdb.c has similar concerns but needs separate
investigation.)

XXX This removes the code added to secure the temporary cluster by
commit f6dc6dd5, since that's based on TCP sockets.

XXX In order to secure the temporary cluster as done for Unix by commit
be76a6d3, we want to make the socket directory non-accessible to other
users.  That's done by POSIX.1-2008 mkdtemp() or our replacement code,
on Unix, which ultimately does mkdir(some_name, 0700).  The
Windows/MinGW mkdir(name, mode) macro just throws away the mode, so it
makes a default-accessible directory.  To do the equivalent thing in
Windows you'd probably need to use CreateDirectory() with an ACL that
means approximately 0700.  Research needed.
---
 src/port/mkdtemp.c            |   4 +
 src/test/regress/pg_regress.c | 274 ++++------------------------------
 2 files changed, 36 insertions(+), 242 deletions(-)

diff --git a/src/port/mkdtemp.c b/src/port/mkdtemp.c
index 8809957dcd..bf90f91848 100644
--- a/src/port/mkdtemp.c
+++ b/src/port/mkdtemp.c
@@ -187,6 +187,10 @@ GETTEMP(char *path, int *doopen, int domkdir)
 		}
 		else if (domkdir)
 		{
+			/*
+			 *  XXX Here we probably need to make a Windows ACL that allows
+			 *  only the current user, and use CreateDirectory().
+			 */
 			if (mkdir(path, 0700) >= 0)
 				return 1;
 			if (errno != EEXIST)
diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c
index 9ca1a8d906..87bd030214 100644
--- a/src/test/regress/pg_regress.c
+++ b/src/test/regress/pg_regress.c
@@ -55,6 +55,20 @@ char	   *host_platform = HOST_TUPLE;
 static char *shellprog = SHELLPROG;
 #endif
 
+/*
+ * The name of the environment variable that controls where we put temporary
+ * files, to override the defaut of "/tmp".
+ */
+#ifdef WIN32
+#define TMPDIR "TMP"
+#else
+#define TMPDIR "TMPDIR"
+#endif
+
+#if defined(WIN32) && defined(USE_ASSERT_CHECKING)
+static DWORD main_thread_id;
+#endif
+
 /*
  * On Windows we use -w in diff switches to avoid problems with inconsistent
  * newline representation.  The actual result files will generally have
@@ -288,9 +302,7 @@ stop_postmaster(void)
  * postmaster exit, so it is indeterminate whether the postmaster has yet to
  * unlink the socket and lock file.  Unlink them here so we can proceed to
  * remove the directory.  Ignore errors; leaking a temporary directory is
- * unimportant.  This can run from a signal handler.  The code is not
- * acceptable in a Windows signal handler (see initdb.c:trapsig()), but
- * on Windows, pg_regress does not use Unix sockets by default.
+ * unimportant.  This can run from a signal handler.
  */
 static void
 remove_temp(void)
@@ -307,6 +319,18 @@ remove_temp(void)
 static void
 signal_remove_temp(int signum)
 {
+#ifdef WIN32
+	/*
+	 * In general, it would not be acceptable to call remove_temp() in a
+	 * Windows signal handler.  It is safe in this program though, because
+	 * SIGHUP and SIGPIPE don't really exist and SIGTERM is never raised by the
+	 * system, leaving just SIGINT.  SIGINT doesn't interrupt the main
+	 * execution context on Windows, it runs the handler concurrently in
+	 * another thread.
+	 */
+	Assert(GetCurrentThreadId() != main_thread_id);
+#endif
+
 	remove_temp();
 
 	pqsignal(signum, SIG_DFL);
@@ -329,7 +353,7 @@ static const char *
 make_temp_sockdir(void)
 {
 	char	   *template = psprintf("%s/pg_regress-XXXXXX",
-									getenv("TMPDIR") ? getenv("TMPDIR") : "/tmp");
+									getenv(TMPDIR) ? getenv(TMPDIR) : "/tmp");
 
 	temp_sockdir = mkdtemp(template);
 	if (temp_sockdir == NULL)
@@ -346,6 +370,10 @@ make_temp_sockdir(void)
 	/* Remove the directory during clean exit. */
 	atexit(remove_temp);
 
+#if defined(WIN32) && defined(USE_ASSERT_CHECKING)
+	main_thread_id = GetCurrentThreadId();
+#endif
+
 	/*
 	 * Remove the directory before dying to the usual signals.  Omit SIGQUIT,
 	 * preserving it as a quick, untidy exit.
@@ -756,211 +784,6 @@ initialize_environment(void)
 	load_resultmap();
 }
 
-#ifdef ENABLE_SSPI
-
-/* support for config_sspi_auth() */
-static const char *
-fmtHba(const char *raw)
-{
-	static char *ret;
-	const char *rp;
-	char	   *wp;
-
-	wp = ret = pg_realloc(ret, 3 + strlen(raw) * 2);
-
-	*wp++ = '"';
-	for (rp = raw; *rp; rp++)
-	{
-		if (*rp == '"')
-			*wp++ = '"';
-		*wp++ = *rp;
-	}
-	*wp++ = '"';
-	*wp++ = '\0';
-
-	return ret;
-}
-
-/*
- * Get account and domain/realm names for the current user.  This is based on
- * pg_SSPI_recvauth().  The returned strings use static storage.
- */
-static void
-current_windows_user(const char **acct, const char **dom)
-{
-	static char accountname[MAXPGPATH];
-	static char domainname[MAXPGPATH];
-	HANDLE		token;
-	TOKEN_USER *tokenuser;
-	DWORD		retlen;
-	DWORD		accountnamesize = sizeof(accountname);
-	DWORD		domainnamesize = sizeof(domainname);
-	SID_NAME_USE accountnameuse;
-
-	if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token))
-	{
-		fprintf(stderr,
-				_("%s: could not open process token: error code %lu\n"),
-				progname, GetLastError());
-		exit(2);
-	}
-
-	if (!GetTokenInformation(token, TokenUser, NULL, 0, &retlen) && GetLastError() != 122)
-	{
-		fprintf(stderr,
-				_("%s: could not get token information buffer size: error code %lu\n"),
-				progname, GetLastError());
-		exit(2);
-	}
-	tokenuser = pg_malloc(retlen);
-	if (!GetTokenInformation(token, TokenUser, tokenuser, retlen, &retlen))
-	{
-		fprintf(stderr,
-				_("%s: could not get token information: error code %lu\n"),
-				progname, GetLastError());
-		exit(2);
-	}
-
-	if (!LookupAccountSid(NULL, tokenuser->User.Sid, accountname, &accountnamesize,
-						  domainname, &domainnamesize, &accountnameuse))
-	{
-		fprintf(stderr,
-				_("%s: could not look up account SID: error code %lu\n"),
-				progname, GetLastError());
-		exit(2);
-	}
-
-	free(tokenuser);
-
-	*acct = accountname;
-	*dom = domainname;
-}
-
-/*
- * Rewrite pg_hba.conf and pg_ident.conf to use SSPI authentication.  Permit
- * the current OS user to authenticate as the bootstrap superuser and as any
- * user named in a --create-role option.
- *
- * In --config-auth mode, the --user switch can be used to specify the
- * bootstrap superuser's name, otherwise we assume it is the default.
- */
-static void
-config_sspi_auth(const char *pgdata, const char *superuser_name)
-{
-	const char *accountname,
-			   *domainname;
-	char	   *errstr;
-	bool		have_ipv6;
-	char		fname[MAXPGPATH];
-	int			res;
-	FILE	   *hba,
-			   *ident;
-	_stringlist *sl;
-
-	/* Find out the name of the current OS user */
-	current_windows_user(&accountname, &domainname);
-
-	/* Determine the bootstrap superuser's name */
-	if (superuser_name == NULL)
-	{
-		/*
-		 * Compute the default superuser name the same way initdb does.
-		 *
-		 * It's possible that this result always matches "accountname", the
-		 * value SSPI authentication discovers.  But the underlying system
-		 * functions do not clearly guarantee that.
-		 */
-		superuser_name = get_user_name(&errstr);
-		if (superuser_name == NULL)
-		{
-			fprintf(stderr, "%s: %s\n", progname, errstr);
-			exit(2);
-		}
-	}
-
-	/*
-	 * Like initdb.c:setup_config(), determine whether the platform recognizes
-	 * ::1 (IPv6 loopback) as a numeric host address string.
-	 */
-	{
-		struct addrinfo *gai_result;
-		struct addrinfo hints;
-		WSADATA		wsaData;
-
-		hints.ai_flags = AI_NUMERICHOST;
-		hints.ai_family = AF_UNSPEC;
-		hints.ai_socktype = 0;
-		hints.ai_protocol = 0;
-		hints.ai_addrlen = 0;
-		hints.ai_canonname = NULL;
-		hints.ai_addr = NULL;
-		hints.ai_next = NULL;
-
-		have_ipv6 = (WSAStartup(MAKEWORD(2, 2), &wsaData) == 0 &&
-					 getaddrinfo("::1", NULL, &hints, &gai_result) == 0);
-	}
-
-	/* Check a Write outcome and report any error. */
-#define CW(cond)	\
-	do { \
-		if (!(cond)) \
-		{ \
-			fprintf(stderr, _("%s: could not write to file \"%s\": %s\n"), \
-					progname, fname, strerror(errno)); \
-			exit(2); \
-		} \
-	} while (0)
-
-	res = snprintf(fname, sizeof(fname), "%s/pg_hba.conf", pgdata);
-	if (res < 0 || res >= sizeof(fname))
-	{
-		/*
-		 * Truncating this name is a fatal error, because we must not fail to
-		 * overwrite an original trust-authentication pg_hba.conf.
-		 */
-		fprintf(stderr, _("%s: directory name too long\n"), progname);
-		exit(2);
-	}
-	hba = fopen(fname, "w");
-	if (hba == NULL)
-	{
-		fprintf(stderr, _("%s: could not open file \"%s\" for writing: %s\n"),
-				progname, fname, strerror(errno));
-		exit(2);
-	}
-	CW(fputs("# Configuration written by config_sspi_auth()\n", hba) >= 0);
-	CW(fputs("host all all 127.0.0.1/32  sspi include_realm=1 map=regress\n",
-			 hba) >= 0);
-	if (have_ipv6)
-		CW(fputs("host all all ::1/128  sspi include_realm=1 map=regress\n",
-				 hba) >= 0);
-	CW(fclose(hba) == 0);
-
-	snprintf(fname, sizeof(fname), "%s/pg_ident.conf", pgdata);
-	ident = fopen(fname, "w");
-	if (ident == NULL)
-	{
-		fprintf(stderr, _("%s: could not open file \"%s\" for writing: %s\n"),
-				progname, fname, strerror(errno));
-		exit(2);
-	}
-	CW(fputs("# Configuration written by config_sspi_auth()\n", ident) >= 0);
-
-	/*
-	 * Double-quote for the benefit of account names containing whitespace or
-	 * '#'.  Windows forbids the double-quote character itself, so don't
-	 * bother escaping embedded double-quote characters.
-	 */
-	CW(fprintf(ident, "regress  \"%s@%s\"  %s\n",
-			   accountname, domainname, fmtHba(superuser_name)) >= 0);
-	for (sl = extraroles; sl; sl = sl->next)
-		CW(fprintf(ident, "regress  \"%s@%s\"  %s\n",
-				   accountname, domainname, fmtHba(sl->str)) >= 0);
-	CW(fclose(ident) == 0);
-}
-
-#endif							/* ENABLE_SSPI */
-
 /*
  * psql_start_command, psql_add_command, psql_end_command
  *
@@ -2041,7 +1864,6 @@ regression_main(int argc, char *argv[],
 		{NULL, 0, NULL, 0}
 	};
 
-	bool		use_unix_sockets;
 	_stringlist *sl;
 	int			c;
 	int			i;
@@ -2057,20 +1879,6 @@ regression_main(int argc, char *argv[],
 
 	atexit(stop_postmaster);
 
-#if defined(WIN32)
-
-	/*
-	 * We don't use Unix-domain sockets on Windows by default (see comment at
-	 * remove_temp() for a reason).  Override at your own risk.
-	 */
-	use_unix_sockets = getenv("PG_TEST_USE_UNIX_SOCKETS") ? true : false;
-#else
-	use_unix_sockets = true;
-#endif
-
-	if (!use_unix_sockets)
-		hostname = "localhost";
-
 	/*
 	 * We call the initialization function here because that way we can set
 	 * default parameters and let them be overwritten by the commandline.
@@ -2182,13 +1990,7 @@ regression_main(int argc, char *argv[],
 	}
 
 	if (config_auth_datadir)
-	{
-#ifdef ENABLE_SSPI
-		if (!use_unix_sockets)
-			config_sspi_auth(config_auth_datadir, user);
-#endif
 		exit(0);
-	}
 
 	if (temp_instance && !port_specified_by_user)
 
@@ -2305,18 +2107,6 @@ regression_main(int argc, char *argv[],
 
 		fclose(pg_conf);
 
-#ifdef ENABLE_SSPI
-		if (!use_unix_sockets)
-		{
-			/*
-			 * Since we successfully used the same buffer for the much-longer
-			 * "initdb" command, this can't truncate.
-			 */
-			snprintf(buf, sizeof(buf), "%s/data", temp_instance);
-			config_sspi_auth(buf, NULL);
-		}
-#endif
-
 		/*
 		 * Check if there is a postmaster running already.
 		 */
-- 
2.35.1

0002-WIP-Stop-using-TCP-in-TAP-tests-on-Windows.patchtext/x-patch; charset=US-ASCII; name=0002-WIP-Stop-using-TCP-in-TAP-tests-on-Windows.patchDownload
From 9df705e98ef6197f3c9abd24a66ca2b299ba6d74 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Fri, 19 Aug 2022 12:00:07 +1200
Subject: [PATCH 2/2] WIP: Stop using TCP in TAP tests on Windows.

Since Unix-domain sockets are available on our minimum target Windows
version, we can remove a source of instability and a point of variation
between Unix and Windows.
---
 .cirrus.yml                               |  3 -
 src/bin/pg_ctl/t/001_start_stop.pl        | 13 +---
 src/test/authentication/t/001_password.pl |  6 --
 src/test/authentication/t/002_saslprep.pl |  7 --
 src/test/perl/PostgreSQL/Test/Cluster.pm  | 91 ++++-------------------
 src/test/perl/PostgreSQL/Test/Utils.pm    |  9 +--
 6 files changed, 20 insertions(+), 109 deletions(-)

diff --git a/.cirrus.yml b/.cirrus.yml
index 81eb8a9996..8890f660c9 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -361,9 +361,6 @@ task:
     # git's tar doesn't deal with drive letters, see
     # https://postgr.es/m/b6782dc3-a7b0-ed56-175f-f8f54cb08d67%40dunslane.net
     TAR: "c:/windows/system32/tar.exe"
-    # Avoids port conflicts between concurrent tap test runs
-    PG_TEST_USE_UNIX_SOCKETS: 1
-    PG_REGRESS_SOCK_DIR: "c:/cirrus/"
     # -m enables parallelism
     # verbosity:minimal + Summary reduce verbosity, while keeping a summary of
     #   errors/warnings
diff --git a/src/bin/pg_ctl/t/001_start_stop.pl b/src/bin/pg_ctl/t/001_start_stop.pl
index fdffd76d99..23f942a440 100644
--- a/src/bin/pg_ctl/t/001_start_stop.pl
+++ b/src/bin/pg_ctl/t/001_start_stop.pl
@@ -29,16 +29,9 @@ print $conf "port = $node_port\n";
 print $conf PostgreSQL::Test::Utils::slurp_file($ENV{TEMP_CONFIG})
   if defined $ENV{TEMP_CONFIG};
 
-if ($use_unix_sockets)
-{
-	print $conf "listen_addresses = ''\n";
-	$tempdir_short =~ s!\\!/!g if $PostgreSQL::Test::Utils::windows_os;
-	print $conf "unix_socket_directories = '$tempdir_short'\n";
-}
-else
-{
-	print $conf "listen_addresses = '127.0.0.1'\n";
-}
+print $conf "listen_addresses = ''\n";
+$tempdir_short =~ s!\\!/!g if $PostgreSQL::Test::Utils::windows_os;
+print $conf "unix_socket_directories = '$tempdir_short'\n";
 close $conf;
 my $ctlcmd = [
 	'pg_ctl', 'start', '-D', "$tempdir/data", '-l',
diff --git a/src/test/authentication/t/001_password.pl b/src/test/authentication/t/001_password.pl
index 3e3079c824..3e1c1a070b 100644
--- a/src/test/authentication/t/001_password.pl
+++ b/src/test/authentication/t/001_password.pl
@@ -6,18 +6,12 @@
 # - Plain
 # - MD5-encrypted
 # - SCRAM-encrypted
-# This test can only run with Unix-domain sockets.
 
 use strict;
 use warnings;
 use PostgreSQL::Test::Cluster;
 use PostgreSQL::Test::Utils;
 use Test::More;
-if (!$use_unix_sockets)
-{
-	plan skip_all =>
-	  "authentication tests cannot run without Unix-domain sockets";
-}
 
 # Delete pg_hba.conf from the given node, add a new entry to it
 # and then execute a reload to refresh it.
diff --git a/src/test/authentication/t/002_saslprep.pl b/src/test/authentication/t/002_saslprep.pl
index 5e87e21ee9..23849632c2 100644
--- a/src/test/authentication/t/002_saslprep.pl
+++ b/src/test/authentication/t/002_saslprep.pl
@@ -2,19 +2,12 @@
 # Copyright (c) 2021-2022, PostgreSQL Global Development Group
 
 # Test password normalization in SCRAM.
-#
-# This test can only run with Unix-domain sockets.
 
 use strict;
 use warnings;
 use PostgreSQL::Test::Cluster;
 use PostgreSQL::Test::Utils;
 use Test::More;
-if (!$use_unix_sockets)
-{
-	plan skip_all =>
-	  "authentication tests cannot run without Unix-domain sockets";
-}
 
 # Delete pg_hba.conf from the given node, add a new entry to it
 # and then execute a reload to refresh it.
diff --git a/src/test/perl/PostgreSQL/Test/Cluster.pm b/src/test/perl/PostgreSQL/Test/Cluster.pm
index 27fa607da4..6fdf73db2d 100644
--- a/src/test/perl/PostgreSQL/Test/Cluster.pm
+++ b/src/test/perl/PostgreSQL/Test/Cluster.pm
@@ -108,7 +108,7 @@ use PostgreSQL::Test::Utils ();
 use Time::HiRes qw(usleep);
 use Scalar::Util qw(blessed);
 
-our ($use_tcp, $test_localhost, $test_pghost, $last_host_assigned,
+our ($test_pghost,
 	$last_port_assigned, @all_nodes, $died);
 
 # the minimum version we believe to be compatible with this package without
@@ -120,21 +120,11 @@ INIT
 
 	# Set PGHOST for backward compatibility.  This doesn't work for own_host
 	# nodes, so prefer to not rely on this when writing new tests.
-	$use_tcp            = !$PostgreSQL::Test::Utils::use_unix_sockets;
-	$test_localhost     = "127.0.0.1";
-	$last_host_assigned = 1;
-	if ($use_tcp)
-	{
-		$test_pghost = $test_localhost;
-	}
-	else
-	{
-		# On windows, replace windows-style \ path separators with / when
-		# putting socket directories either in postgresql.conf or libpq
-		# connection strings, otherwise they are interpreted as escapes.
-		$test_pghost = PostgreSQL::Test::Utils::tempdir_short;
-		$test_pghost =~ s!\\!/!g if $PostgreSQL::Test::Utils::windows_os;
-	}
+	# On windows, replace windows-style \ path separators with / when
+	# putting socket directories either in postgresql.conf or libpq
+	# connection strings, otherwise they are interpreted as escapes.
+	$test_pghost = PostgreSQL::Test::Utils::tempdir_short;
+	$test_pghost =~ s!\\!/!g if $PostgreSQL::Test::Utils::windows_os;
 	$ENV{PGHOST}     = $test_pghost;
 	$ENV{PGDATABASE} = 'postgres';
 
@@ -425,12 +415,6 @@ sub set_replication_conf
 	open my $hba, '>>', "$pgdata/pg_hba.conf";
 	print $hba
 	  "\n# Allow replication (set up by PostgreSQL::Test::Cluster.pm)\n";
-	if ($PostgreSQL::Test::Utils::windows_os
-		&& !$PostgreSQL::Test::Utils::use_unix_sockets)
-	{
-		print $hba
-		  "host replication all $test_localhost/32 sspi include_realm=1 map=regress\n";
-	}
 	close $hba;
 	return;
 }
@@ -523,16 +507,8 @@ sub init
 	}
 
 	print $conf "port = $port\n";
-	if ($use_tcp)
-	{
-		print $conf "unix_socket_directories = ''\n";
-		print $conf "listen_addresses = '$host'\n";
-	}
-	else
-	{
-		print $conf "unix_socket_directories = '$host'\n";
-		print $conf "listen_addresses = ''\n";
-	}
+	print $conf "unix_socket_directories = '$host'\n";
+	print $conf "listen_addresses = ''\n";
 	close $conf;
 
 	chmod($self->group_access ? 0640 : 0600, "$pgdata/postgresql.conf")
@@ -751,15 +727,8 @@ sub init_from_backup
 		qq(
 port = $port
 ));
-	if ($use_tcp)
-	{
-		$self->append_conf('postgresql.conf', "listen_addresses = '$host'");
-	}
-	else
-	{
-		$self->append_conf('postgresql.conf',
-			"unix_socket_directories = '$host'");
-	}
+	$self->append_conf('postgresql.conf',
+		"unix_socket_directories = '$host'");
 	$self->enable_streaming($root_node) if $params{has_streaming};
 	$self->enable_restoring($root_node, $params{standby})
 	  if $params{has_restoring};
@@ -1225,9 +1194,7 @@ sub new
 	else
 	{
 		# When selecting a port, we look for an unassigned TCP port number,
-		# even if we intend to use only Unix-domain sockets.  This is clearly
-		# necessary on $use_tcp (Windows) configurations, and it seems like a
-		# good idea on Unixen as well.
+		# even if we intend to use only Unix-domain sockets.
 		$port = get_free_port();
 	}
 
@@ -1235,17 +1202,8 @@ sub new
 	my $host = $test_pghost;
 	if ($params{own_host})
 	{
-		if ($use_tcp)
-		{
-			$last_host_assigned++;
-			$last_host_assigned > 254 and BAIL_OUT("too many own_host nodes");
-			$host = '127.0.0.' . $last_host_assigned;
-		}
-		else
-		{
-			$host = "$test_pghost/$name"; # Assume $name =~ /^[-_a-zA-Z0-9]+$/
-			mkdir $host;
-		}
+		$host = "$test_pghost/$name"; # Assume $name =~ /^[-_a-zA-Z0-9]+$/
+		mkdir $host;
 	}
 
 	my $testname = basename($0);
@@ -1452,6 +1410,7 @@ start other, non-Postgres servers.
 Ports assigned to existing PostgreSQL::Test::Cluster objects are automatically
 excluded, even if those servers are not currently running.
 
+
 XXX A port available now may become unavailable by the time we start
 the desired service.
 
@@ -1481,29 +1440,11 @@ sub get_free_port
 		}
 
 		# Check to see if anything else is listening on this TCP port.
-		# Seek a port available for all possible listen_addresses values,
-		# so callers can harness this port for the widest range of purposes.
-		# The 0.0.0.0 test achieves that for MSYS, which automatically sets
-		# SO_EXCLUSIVEADDRUSE.  Testing 0.0.0.0 is insufficient for Windows
-		# native Perl (https://stackoverflow.com/a/14388707), so we also
-		# have to test individual addresses.  Doing that for 127.0.0/24
-		# addresses other than 127.0.0.1 might fail with EADDRNOTAVAIL on
-		# non-Linux, non-Windows kernels.
-		#
-		# Thus, 0.0.0.0 and individual 127.0.0/24 addresses are tested
-		# only on Windows and only when TCP usage is requested.
 		if ($found == 1)
 		{
-			foreach my $addr (qw(127.0.0.1),
-				($use_tcp && $PostgreSQL::Test::Utils::windows_os)
-				  ? qw(127.0.0.2 127.0.0.3 0.0.0.0)
-				  : ())
+			if (!can_bind(qw(127.0.0.1), $port))
 			{
-				if (!can_bind($addr, $port))
-				{
-					$found = 0;
-					last;
-				}
+				$found = 0;
 			}
 		}
 	}
diff --git a/src/test/perl/PostgreSQL/Test/Utils.pm b/src/test/perl/PostgreSQL/Test/Utils.pm
index 1ca2cc5917..40968176fc 100644
--- a/src/test/perl/PostgreSQL/Test/Utils.pm
+++ b/src/test/perl/PostgreSQL/Test/Utils.pm
@@ -88,10 +88,9 @@ our @EXPORT = qw(
 
   $windows_os
   $is_msys2
-  $use_unix_sockets
 );
 
-our ($windows_os, $is_msys2, $use_unix_sockets, $timeout_default,
+our ($windows_os, $is_msys2, $timeout_default,
 	$tmp_check, $log_path, $test_logfile);
 
 BEGIN
@@ -153,12 +152,6 @@ BEGIN
 		Win32API::File->import(qw(createFile OsFHandleOpen CloseHandle));
 	}
 
-	# Specifies whether to use Unix sockets for test setups.  On
-	# Windows we don't use them by default since it's not universally
-	# supported, but it can be overridden if desired.
-	$use_unix_sockets =
-	  (!$windows_os || defined $ENV{PG_TEST_USE_UNIX_SOCKETS});
-
 	$timeout_default = $ENV{PG_TEST_TIMEOUT_DEFAULT};
 	$timeout_default = 180
 	  if not defined $timeout_default or $timeout_default eq '';
-- 
2.35.1

#92Thomas Munro
thomas.munro@gmail.com
In reply to: Tom Lane (#77)
1 attachment(s)
Re: Cleaning up historical portability baggage

On Sun, Aug 14, 2022 at 6:07 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Thomas Munro <thomas.munro@gmail.com> writes:

I tried to figure out how to get rid of
PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS, but there we're into genuine
non-standard cross-platform differences.

Right. I don't think it's worth sweating over.

I managed to get rid of four of these probes. Some were unused, and
one could be consolidated into another leaving just one probe of this
ilk.

1. src/common/ip.c already made a leap by assuming that if you have
ss_len then you must have sun_len. We might as well change that to be
driven by the presence of sa_len instead. That leap is fine: if you
have one, you have them all, and sa_len has the advantage of a stable
name across systems that have it (unlike ss_len, which AIX calls
__ss_len, requiring more configure gloop).

2. src/backend/libpq/ifaddr.c only needs to know if you have sa_len.
This code is only used on AIX, so we could hard-wire it in theory, but
it's good to keep it general so you can still compile and test it on
systems without sa_len (mostly Linux).

Attachments:

0001-Remove-configure-probes-for-sockaddr_storage-members.patchtext/x-patch; charset=US-ASCII; name=0001-Remove-configure-probes-for-sockaddr_storage-members.patchDownload
From a4cc14b0de234102bfe6312e793d515797fa572e Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Fri, 19 Aug 2022 16:16:34 +1200
Subject: [PATCH] Remove configure probes for sockaddr_storage members.

Previously we had to deal with implementation details of struct
sockaddr_storage in various replacement code, but now that we're able to
rely on newer standard facilities we don't need to do that.

We still need to keep a probe for sockaddr's sa_len, to use in a couple
of places.  In one place we previously assumed that the presence of
ss_len implied the presence sun_len, but it's no less justifiable to
test for sa_len there, since they all go together.
---
 config/c-library.m4        | 18 +++++---------
 configure                  | 48 --------------------------------------
 configure.ac               |  2 +-
 src/common/ip.c            |  2 +-
 src/include/libpq/pqcomm.h | 13 -----------
 src/include/pg_config.h.in | 12 ----------
 src/tools/msvc/Solution.pm |  4 ----
 7 files changed, 8 insertions(+), 91 deletions(-)

diff --git a/config/c-library.m4 b/config/c-library.m4
index 58453c4f76..c1dd804679 100644
--- a/config/c-library.m4
+++ b/config/c-library.m4
@@ -73,20 +73,14 @@ AC_DEFUN([PGAC_UNION_SEMUN],
 ])])# PGAC_UNION_SEMUN
 
 
-# PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS
-# --------------------------------------
-# Check the members of `struct sockaddr_storage'.  We need to know about
-# ss_family and ss_len.  (Some platforms follow RFC 2553 and call them
-# __ss_family and __ss_len.)  We also check struct sockaddr's sa_len.
-AC_DEFUN([PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS],
-[AC_CHECK_MEMBERS([struct sockaddr_storage.ss_family,
-		   struct sockaddr_storage.__ss_family,
-		   struct sockaddr_storage.ss_len,
-		   struct sockaddr_storage.__ss_len,
-		   struct sockaddr.sa_len], [], [],
+# PGAC_STRUCT_SOCKADDR_MEMBERS
+# ----------------------------
+# Check if struct sockaddr and subtypes have 4.4BSD-style length.
+AC_DEFUN([PGAC_STRUCT_SOCKADDR_SA_LEN],
+[AC_CHECK_MEMBERS([struct sockaddr.sa_len], [], [],
 [#include <sys/types.h>
 #include <sys/socket.h>
-])])# PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS
+])])# PGAC_STRUCT_SOCKADDR_MEMBERS
 
 
 # PGAC_TYPE_LOCALE_T
diff --git a/configure b/configure
index b28fccbc47..4bd050008b 100755
--- a/configure
+++ b/configure
@@ -14990,54 +14990,6 @@ _ACEOF
 
 fi
 
-ac_fn_c_check_member "$LINENO" "struct sockaddr_storage" "ss_family" "ac_cv_member_struct_sockaddr_storage_ss_family" "#include <sys/types.h>
-#include <sys/socket.h>
-
-"
-if test "x$ac_cv_member_struct_sockaddr_storage_ss_family" = xyes; then :
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY 1
-_ACEOF
-
-
-fi
-ac_fn_c_check_member "$LINENO" "struct sockaddr_storage" "__ss_family" "ac_cv_member_struct_sockaddr_storage___ss_family" "#include <sys/types.h>
-#include <sys/socket.h>
-
-"
-if test "x$ac_cv_member_struct_sockaddr_storage___ss_family" = xyes; then :
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY 1
-_ACEOF
-
-
-fi
-ac_fn_c_check_member "$LINENO" "struct sockaddr_storage" "ss_len" "ac_cv_member_struct_sockaddr_storage_ss_len" "#include <sys/types.h>
-#include <sys/socket.h>
-
-"
-if test "x$ac_cv_member_struct_sockaddr_storage_ss_len" = xyes; then :
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1
-_ACEOF
-
-
-fi
-ac_fn_c_check_member "$LINENO" "struct sockaddr_storage" "__ss_len" "ac_cv_member_struct_sockaddr_storage___ss_len" "#include <sys/types.h>
-#include <sys/socket.h>
-
-"
-if test "x$ac_cv_member_struct_sockaddr_storage___ss_len" = xyes; then :
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN 1
-_ACEOF
-
-
-fi
 ac_fn_c_check_member "$LINENO" "struct sockaddr" "sa_len" "ac_cv_member_struct_sockaddr_sa_len" "#include <sys/types.h>
 #include <sys/socket.h>
 
diff --git a/configure.ac b/configure.ac
index dd368290a6..6ff294d405 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1614,7 +1614,7 @@ PGAC_C_COMPUTED_GOTO
 PGAC_STRUCT_TIMEZONE
 PGAC_UNION_SEMUN
 AC_CHECK_TYPES(socklen_t, [], [], [#include <sys/socket.h>])
-PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS
+PGAC_STRUCT_SOCKADDR_SA_LEN
 
 PGAC_TYPE_LOCALE_T
 
diff --git a/src/common/ip.c b/src/common/ip.c
index 0149d07ae7..9b611cdc8c 100644
--- a/src/common/ip.c
+++ b/src/common/ip.c
@@ -227,7 +227,7 @@ getaddrinfo_unix(const char *path, const struct addrinfo *hintsp,
 	 * something with it.  To suppress the warning, clamp the struct size to
 	 * what will fit in sun_len.
 	 */
-#ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
 	unp->sun_len = Min(sizeof(struct sockaddr_un),
 					   ((size_t) 1 << (sizeof(unp->sun_len) * BITS_PER_BYTE)) - 1);
 #endif
diff --git a/src/include/libpq/pqcomm.h b/src/include/libpq/pqcomm.h
index 7e2f1495f3..fcf68df39b 100644
--- a/src/include/libpq/pqcomm.h
+++ b/src/include/libpq/pqcomm.h
@@ -21,19 +21,6 @@
 #include <netdb.h>
 #include <netinet/in.h>
 
-#ifndef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY
-#ifdef HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY
-#define ss_family __ss_family
-#else
-#error struct sockaddr_storage does not provide an ss_family member
-#endif
-#endif
-
-#ifdef HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN
-#define ss_len __ss_len
-#define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1
-#endif
-
 typedef struct
 {
 	struct sockaddr_storage addr;
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 26eb6a2dfe..109776e465 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -442,18 +442,6 @@
 /* Define to 1 if `sa_len' is a member of `struct sockaddr'. */
 #undef HAVE_STRUCT_SOCKADDR_SA_LEN
 
-/* Define to 1 if `ss_family' is a member of `struct sockaddr_storage'. */
-#undef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY
-
-/* Define to 1 if `ss_len' is a member of `struct sockaddr_storage'. */
-#undef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN
-
-/* Define to 1 if `__ss_family' is a member of `struct sockaddr_storage'. */
-#undef HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY
-
-/* Define to 1 if `__ss_len' is a member of `struct sockaddr_storage'. */
-#undef HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN
-
 /* Define to 1 if `tm_zone' is a member of `struct tm'. */
 #undef HAVE_STRUCT_TM_TM_ZONE
 
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index fead5c2a72..a3da3f748a 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -343,10 +343,6 @@ sub GenerateFiles
 		HAVE_STRUCT_CMSGCRED                     => undef,
 		HAVE_STRUCT_OPTION                       => undef,
 		HAVE_STRUCT_SOCKADDR_SA_LEN              => undef,
-		HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY   => 1,
-		HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN      => undef,
-		HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY => undef,
-		HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN    => undef,
 		HAVE_STRUCT_TM_TM_ZONE                   => undef,
 		HAVE_SYNC_FILE_RANGE                     => undef,
 		HAVE_SYNCFS                              => undef,
-- 
2.36.1

#93Andres Freund
andres@anarazel.de
In reply to: Thomas Munro (#90)
Re: Cleaning up historical portability baggage

Hi,

On 2022-08-18 18:13:38 +1200, Thomas Munro wrote:

Here's a slightly better AF_INET6 one. I'm planning to push it
tomorrow if there are no objections.

You didn't yet, I think. Any chance you could? The HAVE_IPV6 stuff is
wrong/ugly in the meson build, right now, and I'd rather not spend time fixing
it up ;)

It does something a little more aggressive than the preceding stuff, because
SUSv3 says that IPv6 is an "option". I don't see that as an issue: it also
says that various other ubiquitous stuff we're using is optional. Of
course, it would be absurd for a new socket implementation to appear today
that can't talk to a decent chunk of the internet, and all we require here
is the headers. That optionality was relevant for the transition period a
couple of decades ago.

From f162a15a6d723f8c94d9daa6236149e1f39b0d9a Mon Sep 17 00:00:00 2001
From: Thomas Munro <tmunro@postgresql.org>
Date: Thu, 18 Aug 2022 11:55:10 +1200
Subject: [PATCH] Remove configure probe for sockaddr_in6 and require AF_INET6.

SUSv3 <netinet/in.h> defines struct sockaddr_in6, and all targeted Unix
systems have it. Windows has it in <ws2ipdef.h>. Remove the configure
probe, the macro and a small amount of dead code.

Also remove a mention of IPv6-less builds from the documentation, since
there aren't any.

This is similar to commits f5580882 and 077bf2f2 for Unix sockets.
Even though AF_INET6 is an "optional" component of SUSv3, there are no
known modern operating system without it, and it seems even less likely
to be omitted from future systems than AF_UNIX.

Discussion: /messages/by-id/CA+hUKGKErNfhmvb_H0UprEmp4LPzGN06yR2_0tYikjzB-2ECMw@mail.gmail.com

Looks good to me.

I'm idly wondering whether it's worth at some point to introduce a configure
test of just compiling a file referencing all the headers and symbols we exist
to be there...

Greetings,

Andres Freund

#94Thomas Munro
thomas.munro@gmail.com
In reply to: Andres Freund (#93)
Re: Cleaning up historical portability baggage

On Fri, Aug 26, 2022 at 7:47 AM Andres Freund <andres@anarazel.de> wrote:

On 2022-08-18 18:13:38 +1200, Thomas Munro wrote:

Here's a slightly better AF_INET6 one. I'm planning to push it
tomorrow if there are no objections.

You didn't yet, I think. Any chance you could? The HAVE_IPV6 stuff is
wrong/ugly in the meson build, right now, and I'd rather not spend time fixing
it up ;)

Done, and thanks for looking.

Remaining things from this thread:
* removing --disable-thread-safety
* removing those vestigial HAVE_XXX macros (one by one analysis and patches)
* making Unix sockets secure for Windows in tests

#95Tom Lane
tgl@sss.pgh.pa.us
In reply to: Thomas Munro (#94)
1 attachment(s)
Re: Cleaning up historical portability baggage

Here's another bit of baggage handling: fixing up the places that
were afraid to use fflush(NULL). We could doubtless have done
this years ago (indeed, I found several places already using it)
but as long as we're making a push to get rid of obsolete code,
doing it now seems appropriate.

One thing that's not clear to me is what the appropriate rules
should be for popen(). POSIX makes clear that you shouldn't
expect popen() to include an fflush() itself, but we seem quite
haphazard about whether to do one or not before popen(). In
the case of popen(..., "r") we can expect that the child can't
write on our stdout, but stderr could be a problem anyway.

Likewise, there are some places that fflush before system(),
but they are a minority. Again it seems like the main risk
is duplicated or mis-ordered stderr output.

I'm inclined to add fflush(NULL) before any popen() or system()
that hasn't got one already, but did not do that in the attached.

Thoughts?

regards, tom lane

Attachments:

use-fflush-NULL-where-appropriate.patchtext/x-diff; charset=us-ascii; name=use-fflush-NULL-where-appropriate.patchDownload
diff --git a/src/backend/postmaster/fork_process.c b/src/backend/postmaster/fork_process.c
index c75be03d2c..ec67761487 100644
--- a/src/backend/postmaster/fork_process.c
+++ b/src/backend/postmaster/fork_process.c
@@ -37,13 +37,8 @@ fork_process(void)
 
 	/*
 	 * Flush stdio channels just before fork, to avoid double-output problems.
-	 * Ideally we'd use fflush(NULL) here, but there are still a few non-ANSI
-	 * stdio libraries out there (like SunOS 4.1.x) that coredump if we do.
-	 * Presently stdout and stderr are the only stdio output channels used by
-	 * the postmaster, so fflush'ing them should be sufficient.
 	 */
-	fflush(stdout);
-	fflush(stderr);
+	fflush(NULL);
 
 #ifdef LINUX_PROFILE
 
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index e3b19ca1ed..1aaab6c554 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -2503,8 +2503,7 @@ OpenPipeStream(const char *command, const char *mode)
 	ReleaseLruFiles();
 
 TryAgain:
-	fflush(stdout);
-	fflush(stderr);
+	fflush(NULL);
 	pqsignal(SIGPIPE, SIG_DFL);
 	errno = 0;
 	file = popen(command, mode);
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index 95f32de4e2..cb3c289889 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -643,8 +643,7 @@ errfinish(const char *filename, int lineno, const char *funcname)
 		 * Any other code you might be tempted to add here should probably be
 		 * in an on_proc_exit or on_shmem_exit callback instead.
 		 */
-		fflush(stdout);
-		fflush(stderr);
+		fflush(NULL);
 
 		/*
 		 * Let the cumulative stats system know. Only mark the session as
@@ -670,8 +669,7 @@ errfinish(const char *filename, int lineno, const char *funcname)
 		 * XXX: what if we are *in* the postmaster?  abort() won't kill our
 		 * children...
 		 */
-		fflush(stdout);
-		fflush(stderr);
+		fflush(NULL);
 		abort();
 	}
 
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 29c28b7315..8567c875fe 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -489,8 +489,7 @@ popen_check(const char *command, const char *mode)
 {
 	FILE	   *cmdfd;
 
-	fflush(stdout);
-	fflush(stderr);
+	fflush(NULL);
 	errno = 0;
 	cmdfd = popen(command, mode);
 	if (cmdfd == NULL)
diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
index 73e20081d1..be2af9f261 100644
--- a/src/bin/pg_ctl/pg_ctl.c
+++ b/src/bin/pg_ctl/pg_ctl.c
@@ -448,8 +448,7 @@ start_postmaster(void)
 	pgpid_t		pm_pid;
 
 	/* Flush stdio channels just before fork, to avoid double-output problems */
-	fflush(stdout);
-	fflush(stderr);
+	fflush(NULL);
 
 #ifdef EXEC_BACKEND
 	pg_disable_aslr();
diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c
index 68c455f84b..d665b257c9 100644
--- a/src/bin/pg_dump/pg_dumpall.c
+++ b/src/bin/pg_dump/pg_dumpall.c
@@ -1578,8 +1578,7 @@ runPgDump(const char *dbname, const char *create_opts)
 
 	pg_log_info("running \"%s\"", cmd->data);
 
-	fflush(stdout);
-	fflush(stderr);
+	fflush(NULL);
 
 	ret = system(cmd->data);
 
diff --git a/src/bin/pg_upgrade/controldata.c b/src/bin/pg_upgrade/controldata.c
index e2086a07de..018cd310f7 100644
--- a/src/bin/pg_upgrade/controldata.c
+++ b/src/bin/pg_upgrade/controldata.c
@@ -123,8 +123,7 @@ get_control_data(ClusterInfo *cluster, bool live_check)
 		/* only pg_controldata outputs the cluster state */
 		snprintf(cmd, sizeof(cmd), "\"%s/pg_controldata\" \"%s\"",
 				 cluster->bindir, cluster->pgdata);
-		fflush(stdout);
-		fflush(stderr);
+		fflush(NULL);
 
 		if ((output = popen(cmd, "r")) == NULL)
 			pg_fatal("could not get control data using %s: %s",
@@ -191,8 +190,7 @@ get_control_data(ClusterInfo *cluster, bool live_check)
 			 cluster->bindir,
 			 live_check ? "pg_controldata\"" : resetwal_bin,
 			 cluster->pgdata);
-	fflush(stdout);
-	fflush(stderr);
+	fflush(NULL);
 
 	if ((output = popen(cmd, "r")) == NULL)
 		pg_fatal("could not get control data using %s: %s",
diff --git a/src/bin/psql/copy.c b/src/bin/psql/copy.c
index c181682a13..0f66ebc2ed 100644
--- a/src/bin/psql/copy.c
+++ b/src/bin/psql/copy.c
@@ -288,8 +288,7 @@ do_copy(const char *args)
 		{
 			if (options->program)
 			{
-				fflush(stdout);
-				fflush(stderr);
+				fflush(NULL);
 				errno = 0;
 				copystream = popen(options->file, PG_BINARY_R);
 			}
@@ -307,10 +306,9 @@ do_copy(const char *args)
 		{
 			if (options->program)
 			{
-				fflush(stdout);
-				fflush(stderr);
-				errno = 0;
+				fflush(NULL);
 				disable_sigpipe_trap();
+				errno = 0;
 				copystream = popen(options->file, PG_BINARY_W);
 			}
 			else
diff --git a/src/common/exec.c b/src/common/exec.c
index fdcad0ee8c..81ff86dce6 100644
--- a/src/common/exec.c
+++ b/src/common/exec.c
@@ -389,8 +389,7 @@ pipe_read_line(char *cmd, char *line, int maxsize)
 	FILE	   *pgver;
 
 	/* flush output buffers in case popen does not... */
-	fflush(stdout);
-	fflush(stderr);
+	fflush(NULL);
 
 	errno = 0;
 	if ((pgver = popen(cmd, "r")) == NULL)
diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c
index a803355f8e..3c92aa8836 100644
--- a/src/test/regress/pg_regress.c
+++ b/src/test/regress/pg_regress.c
@@ -264,8 +264,7 @@ stop_postmaster(void)
 		int			r;
 
 		/* On Windows, system() seems not to force fflush, so... */
-		fflush(stdout);
-		fflush(stderr);
+		fflush(NULL);
 
 		snprintf(buf, sizeof(buf),
 				 "\"%s%spg_ctl\" stop -D \"%s/data\" -s",
@@ -1063,13 +1062,9 @@ spawn_process(const char *cmdline)
 	pid_t		pid;
 
 	/*
-	 * Must flush I/O buffers before fork.  Ideally we'd use fflush(NULL) here
-	 * ... does anyone still care about systems where that doesn't work?
+	 * Must flush I/O buffers before fork.
 	 */
-	fflush(stdout);
-	fflush(stderr);
-	if (logfile)
-		fflush(logfile);
+	fflush(NULL);
 
 #ifdef EXEC_BACKEND
 	pg_disable_aslr();
#96Thomas Munro
thomas.munro@gmail.com
In reply to: Tom Lane (#95)
Re: Cleaning up historical portability baggage

On Mon, Aug 29, 2022 at 9:40 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Here's another bit of baggage handling: fixing up the places that
were afraid to use fflush(NULL). We could doubtless have done
this years ago (indeed, I found several places already using it)
but as long as we're making a push to get rid of obsolete code,
doing it now seems appropriate.

+1, must be OK (pg_dump and pg_upgrade).

Archeology:

commit 79fcde48b229534fd4a5e07834e5e0e84dd38bee
Author: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sun Nov 29 01:51:56 1998 +0000

Portability fix for old SunOS releases: fflush(NULL)

/messages/by-id/199811241847.NAA04690@tuna.uimage.com

SunOS 4.x was still in some kind of support phase for a few more
years, but I guess they weren't working too hard on conformance and
features, given that SunOS 5 (the big BSD -> System V rewrite) had
come out in '92...

One thing that's not clear to me is what the appropriate rules
should be for popen(). POSIX makes clear that you shouldn't
expect popen() to include an fflush() itself, but we seem quite
haphazard about whether to do one or not before popen(). In
the case of popen(..., "r") we can expect that the child can't
write on our stdout, but stderr could be a problem anyway.

Likewise, there are some places that fflush before system(),
but they are a minority. Again it seems like the main risk
is duplicated or mis-ordered stderr output.

I'm inclined to add fflush(NULL) before any popen() or system()
that hasn't got one already, but did not do that in the attached.

Couldn't hurt. (Looking around at our setvbuf() setup to check the
expected stream state in various places... and huh, I hadn't
previously noticed the thing about Windows interpreting line buffering
to mean full buffering. Pfnghghl...)

#97Ibrar Ahmed
ibrar.ahmad@gmail.com
In reply to: Thomas Munro (#96)
Re: Cleaning up historical portability baggage

On Mon, Aug 29, 2022 at 3:13 AM Thomas Munro <thomas.munro@gmail.com> wrote:

On Mon, Aug 29, 2022 at 9:40 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Here's another bit of baggage handling: fixing up the places that
were afraid to use fflush(NULL). We could doubtless have done
this years ago (indeed, I found several places already using it)
but as long as we're making a push to get rid of obsolete code,
doing it now seems appropriate.

+1, must be OK (pg_dump and pg_upgrade).

Archeology:

commit 79fcde48b229534fd4a5e07834e5e0e84dd38bee
Author: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sun Nov 29 01:51:56 1998 +0000

Portability fix for old SunOS releases: fflush(NULL)

/messages/by-id/199811241847.NAA04690@tuna.uimage.com

SunOS 4.x was still in some kind of support phase for a few more
years, but I guess they weren't working too hard on conformance and
features, given that SunOS 5 (the big BSD -> System V rewrite) had
come out in '92...

One thing that's not clear to me is what the appropriate rules
should be for popen(). POSIX makes clear that you shouldn't
expect popen() to include an fflush() itself, but we seem quite
haphazard about whether to do one or not before popen(). In
the case of popen(..., "r") we can expect that the child can't
write on our stdout, but stderr could be a problem anyway.

Likewise, there are some places that fflush before system(),
but they are a minority. Again it seems like the main risk
is duplicated or mis-ordered stderr output.

I'm inclined to add fflush(NULL) before any popen() or system()
that hasn't got one already, but did not do that in the attached.

Couldn't hurt. (Looking around at our setvbuf() setup to check the
expected stream state in various places... and huh, I hadn't
previously noticed the thing about Windows interpreting line buffering
to mean full buffering. Pfnghghl...)

The patch does not apply successfully; please rebase the patch.

patching file src/backend/postmaster/fork_process.c
Hunk #1 FAILED at 37.
1 out of 1 hunk FAILED -- saving rejects to file
src/backend/postmaster/fork_process.c.rej
patching file src/backend/storage/file/fd.c
Hunk #1 FAILED at 2503.
1 out of 1 hunk FAILED -- saving rejects to file
src/backend/storage/file/fd.c.rej
patching file src/backend/utils/error/elog.c
Hunk #1 FAILED at 643.
Hunk #2 FAILED at 670.

--
Ibrar Ahmed

#98John Naylor
john.naylor@enterprisedb.com
In reply to: Ibrar Ahmed (#97)
Re: Cleaning up historical portability baggage

On Thu, Sep 15, 2022 at 3:11 PM Ibrar Ahmed <ibrar.ahmad@gmail.com> wrote:

The patch does not apply successfully; please rebase the patch.

There's a good reason for that -- the latest one was committed two
weeks ago. The status should still be waiting on author, though,
namely for:

On Fri, Aug 26, 2022 at 5:28 AM Thomas Munro <thomas.munro@gmail.com> wrote:

Remaining things from this thread:
* removing --disable-thread-safety
* removing those vestigial HAVE_XXX macros (one by one analysis and patches)
* making Unix sockets secure for Windows in tests

--
John Naylor
EDB: http://www.enterprisedb.com

#99Tom Lane
tgl@sss.pgh.pa.us
In reply to: John Naylor (#98)
Re: Cleaning up historical portability baggage

John Naylor <john.naylor@enterprisedb.com> writes:

On Thu, Sep 15, 2022 at 3:11 PM Ibrar Ahmed <ibrar.ahmad@gmail.com> wrote:

The patch does not apply successfully; please rebase the patch.

There's a good reason for that -- the latest one was committed two
weeks ago. The status should still be waiting on author, though,
namely for:

On Fri, Aug 26, 2022 at 5:28 AM Thomas Munro <thomas.munro@gmail.com> wrote:

Remaining things from this thread:
* removing --disable-thread-safety
* removing those vestigial HAVE_XXX macros (one by one analysis and patches)
* making Unix sockets secure for Windows in tests

I imagine we should just close the current CF entry as committed.
There's no patch in existence for any of those TODO items, and
I didn't think one was imminent.

regards, tom lane

#100Thomas Munro
thomas.munro@gmail.com
In reply to: Tom Lane (#99)
Re: Cleaning up historical portability baggage

On Fri, Sep 16, 2022 at 1:55 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

John Naylor <john.naylor@enterprisedb.com> writes:

On Thu, Sep 15, 2022 at 3:11 PM Ibrar Ahmed <ibrar.ahmad@gmail.com> wrote:

The patch does not apply successfully; please rebase the patch.

There's a good reason for that -- the latest one was committed two
weeks ago. The status should still be waiting on author, though,
namely for:

On Fri, Aug 26, 2022 at 5:28 AM Thomas Munro <thomas.munro@gmail.com> wrote:

Remaining things from this thread:
* removing --disable-thread-safety
* removing those vestigial HAVE_XXX macros (one by one analysis and patches)
* making Unix sockets secure for Windows in tests

I imagine we should just close the current CF entry as committed.
There's no patch in existence for any of those TODO items, and
I didn't think one was imminent.

I have patches for these, but not quite ready to post. I'll mark this
entry closed, and make a new one or two when ready, instead of this
one-gigantic-CF-entry-that-goes-on-forever format.

#101Michael Banck
mbanck@gmx.net
In reply to: Thomas Munro (#62)
Re: Cleaning up historical portability baggage

Hi Thomas,

On Thu, Aug 11, 2022 at 10:02:29PM +1200, Thomas Munro wrote:

Remove configure probe for sys/uio.h.

Removing the configure probe is fine, but the patch also changes
behavior in the sense that IOV_MAX is now considered defined everywhere
but on Windows. However, in the good-old GNU "we have no arbitrary
limits" fashion, this breaks on GNU Hurd:

|gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wcast-function-type -Wshado
|w=compatible-local -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -g -O2 -DFRONTEND -I. -I../../src/common -
|I../../src/include -D_GNU_SOURCE -I/usr/include/libxml2 -DVAL_CC="\"gcc\"" -DVAL_CPPFLAGS="\"-D_GNU_SOURCE -I/usr/include/libxml2\"" -DVAL_CFLAGS="\"-Wall -Wmissing-prototypes -Wpoin
|ter-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wcast-function-type -Wshadow=compatible-local -Wformat-security
|-fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -g -O2\"" -DVAL_CFLAGS_SL="\"-fPIC\"" -DVAL_LDFLAGS="\"-Wl,--as-needed -Wl,-rpa
|th,'/home/demo/build-farm-19.1/buildroot/REL_16_STABLE/inst/lib',--enable-new-dtags\"" -DVAL_LDFLAGS_EX="\"\"" -DVAL_LDFLAGS_SL="\"\"" -DVAL_LIBS="\"-lpgcommon -lpgport -lxslt -lxml2 -
|lssl -lcrypto -lgssapi_krb5 -lz -lreadline -lpthread -lm \"" -c -o file_utils.o file_utils.c
|In file included from ../../src/include/postgres_fe.h:25,
| from file_utils.c:19:
|file_utils.c: In function 'pg_pwritev_with_retry':
|../../src/include/port/pg_iovec.h:36:24: error: 'IOV_MAX' undeclared (first use in this function); did you mean 'INT_MAX'?
| 36 | #define PG_IOV_MAX Min(IOV_MAX, 32)
| | ^~~~~~~
|../../src/include/c.h:988:35: note: in definition of macro 'Min'
| 988 | #define Min(x, y) ((x) < (y) ? (x) : (y))
| | ^
|file_utils.c:474:31: note: in expansion of macro 'PG_IOV_MAX'
| 474 | struct iovec iov_copy[PG_IOV_MAX];
| | ^~~~~~~~~~
|../../src/include/port/pg_iovec.h:36:24: note: each undeclared identifier is reported only once for each function it appears in

|$ grep IOV_MAX /usr/include/i386-gnu/bits/uio_lim.h
|#undef __IOV_MAX

Postgres built fine up and until v15 on the Hurd, so this is a build
regression, and the fact that we define #PG_IOV_MAX to at most 32
anyway suggest we could just #definde IOV_MAX to 16 if undefined as on
Windows.

Christoph fixed this up for Debian's hurd-i386 builds in
https://salsa.debian.org/postgresql/postgresql/-/commit/641713a4585e4b040266a1fa567b7ec90469a1bb
but I have not seen a discussion about this (but might have missed it),
so bringing it up here for upstream consideration in v16 and newer.

Michael

#102Andres Freund
andres@anarazel.de
In reply to: Michael Banck (#101)
Re: Cleaning up historical portability baggage

Hi,

On 2025-06-09 15:25:22 +0200, Michael Banck wrote:

Hi Thomas,

On Thu, Aug 11, 2022 at 10:02:29PM +1200, Thomas Munro wrote:

Remove configure probe for sys/uio.h.

Removing the configure probe is fine, but the patch also changes
behavior in the sense that IOV_MAX is now considered defined everywhere
but on Windows. However, in the good-old GNU "we have no arbitrary
limits" fashion, this breaks on GNU Hurd:

|gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wcast-function-type -Wshado
|w=compatible-local -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -g -O2 -DFRONTEND -I. -I../../src/common -
|I../../src/include -D_GNU_SOURCE -I/usr/include/libxml2 -DVAL_CC="\"gcc\"" -DVAL_CPPFLAGS="\"-D_GNU_SOURCE -I/usr/include/libxml2\"" -DVAL_CFLAGS="\"-Wall -Wmissing-prototypes -Wpoin
|ter-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wcast-function-type -Wshadow=compatible-local -Wformat-security
|-fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -g -O2\"" -DVAL_CFLAGS_SL="\"-fPIC\"" -DVAL_LDFLAGS="\"-Wl,--as-needed -Wl,-rpa
|th,'/home/demo/build-farm-19.1/buildroot/REL_16_STABLE/inst/lib',--enable-new-dtags\"" -DVAL_LDFLAGS_EX="\"\"" -DVAL_LDFLAGS_SL="\"\"" -DVAL_LIBS="\"-lpgcommon -lpgport -lxslt -lxml2 -
|lssl -lcrypto -lgssapi_krb5 -lz -lreadline -lpthread -lm \"" -c -o file_utils.o file_utils.c
|In file included from ../../src/include/postgres_fe.h:25,
| from file_utils.c:19:
|file_utils.c: In function 'pg_pwritev_with_retry':
|../../src/include/port/pg_iovec.h:36:24: error: 'IOV_MAX' undeclared (first use in this function); did you mean 'INT_MAX'?
| 36 | #define PG_IOV_MAX Min(IOV_MAX, 32)
| | ^~~~~~~
|../../src/include/c.h:988:35: note: in definition of macro 'Min'
| 988 | #define Min(x, y) ((x) < (y) ? (x) : (y))
| | ^
|file_utils.c:474:31: note: in expansion of macro 'PG_IOV_MAX'
| 474 | struct iovec iov_copy[PG_IOV_MAX];
| | ^~~~~~~~~~
|../../src/include/port/pg_iovec.h:36:24: note: each undeclared identifier is reported only once for each function it appears in

|$ grep IOV_MAX /usr/include/i386-gnu/bits/uio_lim.h
|#undef __IOV_MAX

Postgres built fine up and until v15 on the Hurd, so this is a build
regression, and the fact that we define #PG_IOV_MAX to at most 32
anyway suggest we could just #definde IOV_MAX to 16 if undefined as on
Windows.

I think our policy basically is that if it doesn't exist on the BF, it's
unsupported. Also note that Hurd is not listed as a supported OS:
https://www.postgresql.org/docs/devel/supported-platforms.html

We can't design for OS that we don't know it's used with postgres and/or how
that OS works / what it supports.

So I reject the premise that this is a regression.

If you want to argue that we should add support for Hurd, you can do that, but
that's obviously a different discussion.

Greetings,

Andres Freund

#103Michael Banck
mbanck@gmx.net
In reply to: Andres Freund (#102)
Re: Cleaning up historical portability baggage

Hi,

On Mon, Jun 09, 2025 at 10:25:23AM -0400, Andres Freund wrote:

I think our policy basically is that if it doesn't exist on the BF, it's
unsupported. Also note that Hurd is not listed as a supported OS:
https://www.postgresql.org/docs/devel/supported-platforms.html

We can't design for OS that we don't know it's used with postgres and/or how
that OS works / what it supports.

So I reject the premise that this is a regression.

Fair enough. I'll see whether I can get a BF animal going for it at some
point.

Michael

#104Thomas Munro
thomas.munro@gmail.com
In reply to: Andres Freund (#102)
Re: Cleaning up historical portability baggage

On Tue, Jun 10, 2025 at 2:25 AM Andres Freund <andres@anarazel.de> wrote:

On 2025-06-09 15:25:22 +0200, Michael Banck wrote:

On Thu, Aug 11, 2022 at 10:02:29PM +1200, Thomas Munro wrote:

Remove configure probe for sys/uio.h.

Removing the configure probe is fine, but the patch also changes
behavior in the sense that IOV_MAX is now considered defined everywhere
but on Windows. However, in the good-old GNU "we have no arbitrary
limits" fashion, this breaks on GNU Hurd:

|gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wcast-function-type -Wshado
|w=compatible-local -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -g -O2 -DFRONTEND -I. -I../../src/common -
|I../../src/include -D_GNU_SOURCE -I/usr/include/libxml2 -DVAL_CC="\"gcc\"" -DVAL_CPPFLAGS="\"-D_GNU_SOURCE -I/usr/include/libxml2\"" -DVAL_CFLAGS="\"-Wall -Wmissing-prototypes -Wpoin
|ter-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wcast-function-type -Wshadow=compatible-local -Wformat-security
|-fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -g -O2\"" -DVAL_CFLAGS_SL="\"-fPIC\"" -DVAL_LDFLAGS="\"-Wl,--as-needed -Wl,-rpa
|th,'/home/demo/build-farm-19.1/buildroot/REL_16_STABLE/inst/lib',--enable-new-dtags\"" -DVAL_LDFLAGS_EX="\"\"" -DVAL_LDFLAGS_SL="\"\"" -DVAL_LIBS="\"-lpgcommon -lpgport -lxslt -lxml2 -
|lssl -lcrypto -lgssapi_krb5 -lz -lreadline -lpthread -lm \"" -c -o file_utils.o file_utils.c
|In file included from ../../src/include/postgres_fe.h:25,
| from file_utils.c:19:
|file_utils.c: In function 'pg_pwritev_with_retry':
|../../src/include/port/pg_iovec.h:36:24: error: 'IOV_MAX' undeclared (first use in this function); did you mean 'INT_MAX'?
| 36 | #define PG_IOV_MAX Min(IOV_MAX, 32)
| | ^~~~~~~
|../../src/include/c.h:988:35: note: in definition of macro 'Min'
| 988 | #define Min(x, y) ((x) < (y) ? (x) : (y))
| | ^
|file_utils.c:474:31: note: in expansion of macro 'PG_IOV_MAX'
| 474 | struct iovec iov_copy[PG_IOV_MAX];
| | ^~~~~~~~~~
|../../src/include/port/pg_iovec.h:36:24: note: each undeclared identifier is reported only once for each function it appears in

|$ grep IOV_MAX /usr/include/i386-gnu/bits/uio_lim.h
|#undef __IOV_MAX

Postgres built fine up and until v15 on the Hurd, so this is a build
regression, and the fact that we define #PG_IOV_MAX to at most 32
anyway suggest we could just #definde IOV_MAX to 16 if undefined as on
Windows.

I think our policy basically is that if it doesn't exist on the BF, it's
unsupported. Also note that Hurd is not listed as a supported OS:
https://www.postgresql.org/docs/devel/supported-platforms.html

We can't design for OS that we don't know it's used with postgres and/or how
that OS works / what it supports.

So I reject the premise that this is a regression.

If you want to argue that we should add support for Hurd, you can do that, but
that's obviously a different discussion.

Since time immemorial, PostgreSQL could compile successfully on
GNU/Hurd systems (perhaps with a few superficial tweak patches of this
ilk), but it couldn't actually run because its semaphores didn't work
cross-process. I knew that because Christoph told us somewhere on
this list not so long ago, but it seems there has been some movement
since then and I am guilty of being wrong on the internet, as
mentioned here:

https://savannah.gnu.org/task/?7050

So it looks like they added working semaphores in 2022, but in 2023 I
removed some unrelated stuff during and happened to mention that Hurd
can't run PostgreSQL anyway, and they didn't like that (I mean it
wasn't an unreasonable chain of thought, it was just unfortunate
timing given they'd worked on addressing that). The log linked there
shows the regression tests mostly passing, so that seems promising: at
least a cluster can finally actually start up and run! There may be a
few more little things to chase down, who knows.

I wonder if the pthreads implementation is still unfinished as hinted
at there too. We're gonna need that as a hard dependency quite soon,
or at least several of us are working hard to make that true... that
said, we'd be far from the only thing needing pthreads so that must be
a high priority for them if they haven't already addressed it.

Anyway, that's a long way of saying +1, GNU/Hurd would be a new
platform for us, and obviously it hasn't even been plausible until
quite recently. There are also circularities when you're bringing up
an OS and application support for it in parallel, so there will no
doubt be a few little threads like this along the way, and I'm not
against helping on our side. More than that, for the specific point,
yeah the GNU project's unlimited limits thing is kinda admirable, and
they are quite right to complain about this one: {IOV_MAX} appears
with curly braces in POSIX and <limits.h> says:

"A definition of one of the symbolic constants in the following list
shall be omitted from <limits.h> on specific implementations where the
corresponding value is equal to or greater than the stated minimum,
but is unspecified."

So irrespective of Hurd support, it was a mistake to require the
symbol to be defined, based on POSIX language lawyering alone. It's
annoying though, we've hit the only known system so far that doesn't
actually define it, and POSIX then says we can only rely on 16 if we
want a compile-time limit. Yet Hurd presumably really wants to make
it unlimited (well limited only by things like data types), while
POSIX says that if we want to use anything but the required minimum
when the macro isn't defined, we should call sysconf(_SC_IOV_MAX) at
runtime. So... I guess the correct thing to do may be to use 16 for
the benefit of our (few) statically sized arrays that Richard Stallman
would hate, but also consult sysconf() when limiting
io_max_combine_limit, our own runtime bound on I/O combining for the
main serious user of vectored I/O. A little complicated, but...
they're quite right about all that. Hnghh.

#105Michael Banck
mbanck@gmx.net
In reply to: Thomas Munro (#104)
Re: Cleaning up historical portability baggage

Hi,

On Tue, Jun 10, 2025 at 09:05:03AM +1200, Thomas Munro wrote:

On Tue, Jun 10, 2025 at 2:25 AM Andres Freund <andres@anarazel.de> wrote:

On 2025-06-09 15:25:22 +0200, Michael Banck wrote:

Postgres built fine up and until v15 on the Hurd, so this is a build
regression, and the fact that we define #PG_IOV_MAX to at most 32
anyway suggest we could just #definde IOV_MAX to 16 if undefined as on
Windows.

I think our policy basically is that if it doesn't exist on the BF, it's
unsupported. Also note that Hurd is not listed as a supported OS:
https://www.postgresql.org/docs/devel/supported-platforms.html

We can't design for OS that we don't know it's used with postgres and/or how
that OS works / what it supports.

So I reject the premise that this is a regression.

If you want to argue that we should add support for Hurd, you can do that, but
that's obviously a different discussion.

Since time immemorial, PostgreSQL could compile successfully on
GNU/Hurd systems (perhaps with a few superficial tweak patches of this
ilk), but it couldn't actually run because its semaphores didn't work
cross-process. I knew that because Christoph told us somewhere on
this list not so long ago, but it seems there has been some movement
since then and I am guilty of being wrong on the internet, as
mentioned here:

https://savannah.gnu.org/task/?7050

Yeah.

So it looks like they added working semaphores in 2022, but in 2023 I
removed some unrelated stuff during and happened to mention that Hurd
can't run PostgreSQL anyway, and they didn't like that (I mean it
wasn't an unreasonable chain of thought, it was just unfortunate
timing given they'd worked on addressing that). The log linked there
shows the regression tests mostly passing, so that seems promising: at
least a cluster can finally actually start up and run! There may be a
few more little things to chase down, who knows.

I tried again (as seen in this thread) and the current status is:

1. build failure due to IOV_MAX being undefined (under discussion here)
2. initdb (at least) fails with assert-enabled builds due to O_RDONLY
being 1 on the Hurd and 0 everywhere else, I sent a patch for that here:
/messages/by-id/68480868.5d0a0220.1e214d.68a6@mx.google.com
3. make check nowadays succeeds the subscription test that it failed in
the log mentioned in the above task, but it still fails the stats test:

|@@ -672,7 +672,7 @@
| SELECT stats_reset > :'slru_commit_ts_reset_ts'::timestamptz FROM pg_stat_slru WHERE name = 'CommitTs';
| ?column?
| ----------
|- t
|+ f
| (1 row)
|
| SELECT stats_reset > :'slru_notify_reset_ts'::timestamptz FROM pg_stat_slru WHERE name = 'Notify';
|@@ -769,7 +769,7 @@
| SELECT stats_reset > :'db_reset_ts'::timestamptz FROM pg_stat_database WHERE datname = (SELECT current_database());
| ?column?
| ----------
|- t
|+ f
| (1 row)
|
| ----

I'll try to figure out why that is next.

I wonder if the pthreads implementation is still unfinished as hinted
at there too.

I think it is reasonably complete nowadays that I don't think it makes
sense to worry about this right now.

Anyway, that's a long way of saying +1, GNU/Hurd would be a new
platform for us, and obviously it hasn't even been plausible until
quite recently. There are also circularities when you're bringing up
an OS and application support for it in parallel, so there will no
doubt be a few little threads like this along the way, and I'm not
against helping on our side. More than that, for the specific point,
yeah the GNU project's unlimited limits thing is kinda admirable, and
they are quite right to complain about this one: {IOV_MAX} appears
with curly braces in POSIX and <limits.h> says:

"A definition of one of the symbolic constants in the following list
shall be omitted from <limits.h> on specific implementations where the
corresponding value is equal to or greater than the stated minimum,
but is unspecified."

So irrespective of Hurd support, it was a mistake to require the
symbol to be defined, based on POSIX language lawyering alone. It's
annoying though, we've hit the only known system so far that doesn't
actually define it, and POSIX then says we can only rely on 16 if we
want a compile-time limit. Yet Hurd presumably really wants to make
it unlimited (well limited only by things like data types), while
POSIX says that if we want to use anything but the required minimum
when the macro isn't defined, we should call sysconf(_SC_IOV_MAX) at
runtime. So... I guess the correct thing to do may be to use 16 for
the benefit of our (few) statically sized arrays that Richard Stallman
would hate, but also consult sysconf() when limiting
io_max_combine_limit, our own runtime bound on I/O combining for the
main serious user of vectored I/O. A little complicated, but...
they're quite right about all that. Hnghh.

I don't have an opinion here, I think it would be ok to just define it
to 16 if it is undefined and if the Hurd people want something better at
some point, they should submit patches.

Michael

#106Michael Banck
mbanck@gmx.net
In reply to: Michael Banck (#105)
1 attachment(s)
Re: Cleaning up historical portability baggage

Hi,

On Tue, Jun 10, 2025 at 12:59:16PM +0200, Michael Banck wrote:

On Tue, Jun 10, 2025 at 09:05:03AM +1200, Thomas Munro wrote:

https://savannah.gnu.org/task/?7050

3. make check nowadays succeeds the subscription test that it failed in
the log mentioned in the above task, but it still fails the stats test:

I take that back, the subscription test is flakey, but less so than the
stats test as it only has one of those stats_reset comparisons, compared
to several for stats. So I am seeing failures there only every few test
runs.

The reason those tests fail is that the Debian 12 era [1]As hurd-i386 is not a release architecture, there is no Debian 12 release for it. But the Debian GNU/Hurd porters made their own release based on a snapshot of the hurd-i386 archive at time of the bookworm release. GNU Mach I am
currently using has 10ms timer resolution, so some of those stats_reset
calls in quick succession do not lead to different timestamps and the
checks fail.

There are several "SELECT pg_sleep(0.1);" calls in stats.sql already, so
I wonder whether a few more would be acceptable, or at least using
pg_sleep(0.01)? Using the attached, I no longer see regression failures,
even after running it for 10+ times.

The good news is maybe two-fold:

1. GNU Mach recently got better timer resolution and the version in
Debian unstable got that backported [2]https://salsa.debian.org/hurd-team/gnumach/-/blob/master/debian/patches/git-hpet?ref_type=heads, so going forward this should
not be a problem anymore. I'll try upgrading my VM and see whether that
helps without the patch.

2. The fact that nobody else complained about those new(er) timestamp-
comparison additions appears to imply that there are no 100ms resolution
machines we support anymore. So did we consider switching those
pg_sleep(0.1) calls in stats.sql to pg_sleep(0.01) to save a bit of
time?

Michael

[1]: As hurd-i386 is not a release architecture, there is no Debian 12 release for it. But the Debian GNU/Hurd porters made their own release based on a snapshot of the hurd-i386 archive at time of the bookworm release.
release for it. But the Debian GNU/Hurd porters made their own release
based on a snapshot of the hurd-i386 archive at time of the bookworm
release.
[2]: https://salsa.debian.org/hurd-team/gnumach/-/blob/master/debian/patches/git-hpet?ref_type=heads

Attachments:

0001-Stabilize-stats_reset-based-tests-for-low-resolution.patchtext/x-diff; charset=us-asciiDownload
From a0b71da960ada0f5f8927920486e8a7096ac975b Mon Sep 17 00:00:00 2001
From: Michael Banck <mbanck@debian.org>
Date: Tue, 10 Jun 2025 22:55:44 +0200
Subject: [PATCH] Stabilize stats_reset-based tests for low-resolution timers.

On systems where the timestamp resolution is 10ms, two stats reset calls
in quick sucession and the comparison of their timestamps might not lead
to differences. Add 10ms pg_sleep() calls in order to ensure different
timestamps on those systems.

For the last_seq_scan timestamps tests we use 100ms pg_sleep() delays,
which we could reconsider adjusting to 10ms as well giving nobody else
complained about the stat reset tests without delay.
---
 src/test/regress/expected/stats.out        | 18 ++++++++++++++++++
 src/test/regress/expected/subscription.out |  6 ++++++
 src/test/regress/sql/stats.sql             |  3 +++
 src/test/regress/sql/subscription.sql      |  1 +
 4 files changed, 28 insertions(+)

diff --git a/src/test/regress/expected/stats.out b/src/test/regress/expected/stats.out
index 776f1ad0e53..803f4eac8ff 100644
--- a/src/test/regress/expected/stats.out
+++ b/src/test/regress/expected/stats.out
@@ -983,6 +983,12 @@ SELECT stats_reset > :'slru_commit_ts_reset_ts'::timestamptz FROM pg_stat_slru W
 
 SELECT stats_reset AS slru_commit_ts_reset_ts FROM pg_stat_slru WHERE name = 'commit_timestamp' \gset
 -- Test that multiple SLRUs are reset when no specific SLRU provided to reset function
+SELECT pg_sleep(0.01); -- assume a minimum timestamp granularity of 10ms
+ pg_sleep 
+----------
+ 
+(1 row)
+
 SELECT pg_stat_reset_slru();
  pg_stat_reset_slru 
 --------------------
@@ -1059,6 +1065,12 @@ SELECT stats_reset > :'recovery_prefetch_reset_ts'::timestamptz FROM pg_stat_rec
 
 -- Test that reset_shared with slru specified as the stats type works
 SELECT max(stats_reset) AS slru_reset_ts FROM pg_stat_slru \gset
+SELECT pg_sleep(0.01);
+ pg_sleep 
+----------
+ 
+(1 row)
+
 SELECT pg_stat_reset_shared('slru');
  pg_stat_reset_shared 
 ----------------------
@@ -1098,6 +1110,12 @@ SELECT pg_stat_reset();
 (1 row)
 
 SELECT stats_reset AS db_reset_ts FROM pg_stat_database WHERE datname = (SELECT current_database()) \gset
+SELECT pg_sleep(0.01);
+ pg_sleep 
+----------
+ 
+(1 row)
+
 SELECT pg_stat_reset();
  pg_stat_reset 
 ---------------
diff --git a/src/test/regress/expected/subscription.out b/src/test/regress/expected/subscription.out
index 1443e1d9292..a2baa599769 100644
--- a/src/test/regress/expected/subscription.out
+++ b/src/test/regress/expected/subscription.out
@@ -61,6 +61,12 @@ SELECT subname, stats_reset IS NULL stats_reset_is_null FROM pg_stat_subscriptio
 
 -- Reset the stats again and check if the new reset_stats is updated.
 SELECT stats_reset as prev_stats_reset FROM pg_stat_subscription_stats WHERE subname = 'regress_testsub' \gset
+SELECT pg_sleep(0.01);  -- assume a minimum timestamp granularity of 10ms
+ pg_sleep 
+----------
+ 
+(1 row)
+
 SELECT pg_stat_reset_subscription_stats(oid) FROM pg_subscription WHERE subname = 'regress_testsub';
  pg_stat_reset_subscription_stats 
 ----------------------------------
diff --git a/src/test/regress/sql/stats.sql b/src/test/regress/sql/stats.sql
index 232ab8db8fa..b78dc0c670d 100644
--- a/src/test/regress/sql/stats.sql
+++ b/src/test/regress/sql/stats.sql
@@ -467,6 +467,7 @@ SELECT stats_reset > :'slru_commit_ts_reset_ts'::timestamptz FROM pg_stat_slru W
 SELECT stats_reset AS slru_commit_ts_reset_ts FROM pg_stat_slru WHERE name = 'commit_timestamp' \gset
 
 -- Test that multiple SLRUs are reset when no specific SLRU provided to reset function
+SELECT pg_sleep(0.01); -- assume a minimum timestamp granularity of 10ms
 SELECT pg_stat_reset_slru();
 SELECT stats_reset > :'slru_commit_ts_reset_ts'::timestamptz FROM pg_stat_slru WHERE name = 'commit_timestamp';
 SELECT stats_reset > :'slru_notify_reset_ts'::timestamptz FROM pg_stat_slru WHERE name = 'notify';
@@ -493,6 +494,7 @@ SELECT stats_reset > :'recovery_prefetch_reset_ts'::timestamptz FROM pg_stat_rec
 
 -- Test that reset_shared with slru specified as the stats type works
 SELECT max(stats_reset) AS slru_reset_ts FROM pg_stat_slru \gset
+SELECT pg_sleep(0.01);
 SELECT pg_stat_reset_shared('slru');
 SELECT max(stats_reset) > :'slru_reset_ts'::timestamptz FROM pg_stat_slru;
 
@@ -509,6 +511,7 @@ SELECT pg_stat_reset_shared('unknown');
 -- Since pg_stat_database stats_reset starts out as NULL, reset it once first so we have something to compare it to
 SELECT pg_stat_reset();
 SELECT stats_reset AS db_reset_ts FROM pg_stat_database WHERE datname = (SELECT current_database()) \gset
+SELECT pg_sleep(0.01);
 SELECT pg_stat_reset();
 SELECT stats_reset > :'db_reset_ts'::timestamptz FROM pg_stat_database WHERE datname = (SELECT current_database());
 
diff --git a/src/test/regress/sql/subscription.sql b/src/test/regress/sql/subscription.sql
index 007c9e70374..d0ec8d18fa1 100644
--- a/src/test/regress/sql/subscription.sql
+++ b/src/test/regress/sql/subscription.sql
@@ -39,6 +39,7 @@ SELECT subname, stats_reset IS NULL stats_reset_is_null FROM pg_stat_subscriptio
 
 -- Reset the stats again and check if the new reset_stats is updated.
 SELECT stats_reset as prev_stats_reset FROM pg_stat_subscription_stats WHERE subname = 'regress_testsub' \gset
+SELECT pg_sleep(0.01);  -- assume a minimum timestamp granularity of 10ms
 SELECT pg_stat_reset_subscription_stats(oid) FROM pg_subscription WHERE subname = 'regress_testsub';
 SELECT :'prev_stats_reset' < stats_reset FROM pg_stat_subscription_stats WHERE subname = 'regress_testsub';
 
-- 
2.39.5

#107Tom Lane
tgl@sss.pgh.pa.us
In reply to: Michael Banck (#106)
Re: Cleaning up historical portability baggage

Michael Banck <mbanck@gmx.net> writes:

2. The fact that nobody else complained about those new(er) timestamp-
comparison additions appears to imply that there are no 100ms resolution
machines we support anymore. So did we consider switching those
pg_sleep(0.1) calls in stats.sql to pg_sleep(0.01) to save a bit of
time?

Yeah, we realized last year that no supported platform has worse than
1usec gettimeofday resolution anymore [1]/messages/by-id/be0339cc-1ae1-4892-9445-8e6d8995a44d@eisentraut.org. So I think you're right
that we could shave some milliseconds off stats.sql, as well as some
other test scripts. I doubt this'd make for a meaningful time
savings, but perhaps it's worth doing just for consistency: grepping
for pg_sleep in our tests, I see anywhere from 0.1 to 0.001 sec.

regards, tom lane

[1]: /messages/by-id/be0339cc-1ae1-4892-9445-8e6d8995a44d@eisentraut.org

#108Thomas Munro
thomas.munro@gmail.com
In reply to: Michael Banck (#105)
Re: Cleaning up historical portability baggage

On Tue, Jun 10, 2025 at 10:59 PM Michael Banck <mbanck@gmx.net> wrote:

I don't have an opinion here, I think it would be ok to just define it
to 16 if it is undefined and if the Hurd people want something better at
some point, they should submit patches.

Cool. I will go ahead and do that, as you proposed, and back-patch
appropriately. This will have zero effect on any other system, and is
justifiable as a bug fix based on the POSIX spec.

Hurd builds will be slightly stunted in the sense that they won't be
able to set io_combine_limit > 128kB. Fixing that will be a matter
for another day (I'm not sure if it's worth bothering with
sysconf(_SC_IOV_MAX), I guess they probably just return -1 anyway
(meaning unlimited), which means that we'd apply our own cap of 128,
so maybe it's easier to just skip the middle step and somehow just use
128 already... but yeah, patches welcome for v19).