v6-0003-initdb-Detect-Unix-domain-socket-support-dynamica.patch

text/plain

Filename: v6-0003-initdb-Detect-Unix-domain-socket-support-dynamica.patch
Type: text/plain
Part: 2
Message: Re: Unix-domain socket support on Windows

Patch

Format: format-patch
Series: patch v6-0003
Subject: initdb: Detect Unix-domain socket support dynamically
File+
src/backend/libpq/pg_hba.conf.sample 3 3
src/bin/initdb/initdb.c 81 89
From 5bbd177ff303308c2ed577ddc1c539c3027ae676 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Wed, 7 Aug 2019 15:44:19 +0200
Subject: [PATCH v6 3/5] initdb: Detect Unix-domain socket support dynamically

On Windows we now have to support the situation where a binary built
with Unix-domain socket support could be used on a system that doesn't
support it at run time.  So in initdb, for setting up the default
pg_hba.conf and postgresql.conf, do a run-time check for support
instead of relying on compile-time decisions.  This is very similar to
what we already do for IPv6, so similar code can be used.

A change is that now if Unix-domain socket support is not found, the
"local" lines in pg_hba.conf are commented out instead of removed,
again similar to IPv6 support.
---
 src/backend/libpq/pg_hba.conf.sample |   6 +-
 src/bin/initdb/initdb.c              | 170 +++++++++++++--------------
 2 files changed, 84 insertions(+), 92 deletions(-)

diff --git a/src/backend/libpq/pg_hba.conf.sample b/src/backend/libpq/pg_hba.conf.sample
index c853e36232..0c163d2c6d 100644
--- a/src/backend/libpq/pg_hba.conf.sample
+++ b/src/backend/libpq/pg_hba.conf.sample
@@ -76,14 +76,14 @@
 
 # TYPE  DATABASE        USER            ADDRESS                 METHOD
 
-@remove-line-for-nolocal@# "local" is for Unix domain socket connections only
-@remove-line-for-nolocal@local   all             all                                     @authmethodlocal@
+# "local" is for Unix domain socket connections only
+local   all             all                                     @authmethodlocal@
 # IPv4 local connections:
 host    all             all             127.0.0.1/32            @authmethodhost@
 # IPv6 local connections:
 host    all             all             ::1/128                 @authmethodhost@
 # Allow replication connections from localhost, by a user with the
 # replication privilege.
-@remove-line-for-nolocal@local   replication     all                                     @authmethodlocal@
+local   replication     all                                     @authmethodlocal@
 host    replication     all             127.0.0.1/32            @authmethodhost@
 host    replication     all             ::1/128                 @authmethodhost@
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 7f1534aebb..ad37748afe 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -231,9 +231,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);
@@ -431,36 +428,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
  */
@@ -1070,10 +1037,70 @@ setup_config(void)
 	char		repltok[MAXPGPATH];
 	char		path[MAXPGPATH];
 	char	   *autoconflines[3];
+	bool		unix_sockets_work = false;
+	bool		ipv6_works = false;
 
 	fputs(_("creating configuration files ... "), stdout);
 	fflush(stdout);
 
+#ifdef WIN32
+	{
+		/* need to call WSAStartup before calling socket or getaddrinfo */
+		int			err = 0;
+		WSADATA		wsaData;
+
+		err = WSAStartup(MAKEWORD(2, 2), &wsaData);
+		if (err != 0)
+		{
+			pg_log_error("WSAStartup failed: %d", err);
+			exit(1);
+		}
+	}
+#endif
+
+#ifdef HAVE_UNIX_SOCKETS
+	/*
+	 * Probe to see whether Unix-domain sockets are working.
+	 */
+	{
+		pgsocket    tmpsock;
+
+		tmpsock = socket(AF_UNIX, SOCK_STREAM, 0);
+		if (tmpsock != PGINVALID_SOCKET)
+		{
+			unix_sockets_work = true;
+			closesocket(tmpsock);
+		}
+	}
+#endif
+
+#ifdef HAVE_IPV6
+	/*
+	 * Probe to see if there is really any platform support for IPv6, and
+	 * comment out the relevant pg_hba line if not.  This avoids runtime
+	 * warnings if getaddrinfo doesn't actually cope with IPv6.  Particularly
+	 * useful on Windows, where executables built on a machine with IPv6 may
+	 * have to run on a machine without.
+	 */
+	{
+		struct addrinfo *gai_result;
+		struct addrinfo hints;
+
+		/* for best results, this code should match parse_hba_line() */
+		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;
+
+		if (getaddrinfo("::1", NULL, &hints, &gai_result) == 0)
+			ipv6_works = true;
+	}
+#endif							/* !HAVE_IPV6 */
+
 	/* postgresql.conf */
 
 	conflines = readfile(conf_file);
@@ -1090,8 +1117,11 @@ setup_config(void)
 	conflines = replace_token(conflines, "#shared_buffers = 32MB", repltok);
 
 #ifdef HAVE_UNIX_SOCKETS
-	snprintf(repltok, sizeof(repltok), "#unix_socket_directories = '%s'",
-			 DEFAULT_PGSOCKET_DIR);
+	if (unix_sockets_work)
+		snprintf(repltok, sizeof(repltok), "#unix_socket_directories = '%s'",
+				 DEFAULT_PGSOCKET_DIR);
+	else
+		snprintf(repltok, sizeof(repltok), "unix_socket_directories = ''");
 #else
 	snprintf(repltok, sizeof(repltok), "#unix_socket_directories = ''");
 #endif
@@ -1254,63 +1284,25 @@ 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
-
-	/*
-	 * Probe to see if there is really any platform support for IPv6, and
-	 * comment out the relevant pg_hba line if not.  This avoids runtime
-	 * warnings if getaddrinfo doesn't actually cope with IPv6.  Particularly
-	 * useful on Windows, where executables built on a machine with IPv6 may
-	 * have to run on a machine without.
-	 */
+	if (!unix_sockets_work)
 	{
-		struct addrinfo *gai_result;
-		struct addrinfo hints;
-		int			err = 0;
-
-#ifdef WIN32
-		/* need to call WSAStartup before calling getaddrinfo */
-		WSADATA		wsaData;
-
-		err = WSAStartup(MAKEWORD(2, 2), &wsaData);
-#endif
-
-		/* for best results, this code should match parse_hba_line() */
-		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;
+		conflines = replace_token(conflines,
+								  "local   all",
+								  "#local   all");
+		conflines = replace_token(conflines,
+								  "local   replication",
+								  "#local   replication");
+	}
 
-		if (err != 0 ||
-			getaddrinfo("::1", NULL, &hints, &gai_result) != 0)
-		{
-			conflines = replace_token(conflines,
-									  "host    all             all             ::1",
-									  "#host    all             all             ::1");
-			conflines = replace_token(conflines,
-									  "host    replication     all             ::1",
-									  "#host    replication     all             ::1");
-		}
+	if (!ipv6_works)
+	{
+		conflines = replace_token(conflines,
+								  "host    all             all             ::1",
+								  "#host    all             all             ::1");
+		conflines = replace_token(conflines,
+								  "host    replication     all             ::1",
+								  "#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,
-- 
2.25.0