Blame SOURCES/postgresql-multi-sockets.patch

7686b4
Back-port of upstream 9.3 patch to support multiple sockets
7686b4
(upstream git commits c9b0cbe98bd783e24a8c4d8d8ac472a494b81292 and
7686b4
d2286a98ef3fb88bafb57381b4c20b8b878827f1, plus updates of derived
7686b4
documentation files).
7686b4
7686b4
Note the patch also touches html-stamp and man-stamp in doc/src/sgml/;
7686b4
this is to keep the makefiles from trying to rebuild the derived doc
7686b4
files.  We don't want that to happen because the BuildRequires for the
7686b4
package don't include the necessary documentation tools.  Those diff
7686b4
hunks *must be at the end* so that those files are newer than the
7686b4
master doc files.
7686b4
7686b4
748346
diff -up postgresql-9.2.10/contrib/pg_upgrade/server.c.orig postgresql-9.2.10/contrib/pg_upgrade/server.c
748346
--- postgresql-9.2.10/contrib/pg_upgrade/server.c.orig	2015-02-02 21:44:39.000000000 +0100
748346
+++ postgresql-9.2.10/contrib/pg_upgrade/server.c	2015-02-26 14:04:26.613801158 +0100
748346
@@ -197,7 +197,8 @@ start_postmaster(ClusterInfo *cluster)
7686b4
 		snprintf(socket_string + strlen(socket_string),
7686b4
 				 sizeof(socket_string) - strlen(socket_string),
7686b4
 				 " -c %s='%s'",
7686b4
-				 (GET_MAJOR_VERSION(cluster->major_version) < 903) ?
7686b4
+	/* assume 9.1 build will not have unix_socket_directories patch */
7686b4
+				 (GET_MAJOR_VERSION(cluster->major_version) < 902) ?
7686b4
 				 "unix_socket_directory" : "unix_socket_directories",
7686b4
 				 cluster->sockdir);
7686b4
 #endif
748346
diff -up postgresql-9.2.10/doc/src/sgml/client-auth.sgml.orig postgresql-9.2.10/doc/src/sgml/client-auth.sgml
748346
--- postgresql-9.2.10/doc/src/sgml/client-auth.sgml.orig	2015-02-02 21:44:39.000000000 +0100
748346
+++ postgresql-9.2.10/doc/src/sgml/client-auth.sgml	2015-02-26 14:04:26.614801168 +0100
748346
@@ -838,7 +838,7 @@ omicron         bryanh
7686b4
     <varname>unix_socket_permissions</varname> (and possibly
7686b4
     <varname>unix_socket_group</varname>) configuration parameters as
7686b4
     described in <xref linkend="runtime-config-connection">.  Or you
7686b4
-    could set the <varname>unix_socket_directory</varname>
7686b4
+    could set the <varname>unix_socket_directories</varname>
7686b4
     configuration parameter to place the socket file in a suitably
7686b4
     restricted directory.
7686b4
    </para>
748346
diff -up postgresql-9.2.10/doc/src/sgml/config.sgml.orig postgresql-9.2.10/doc/src/sgml/config.sgml
748346
--- postgresql-9.2.10/doc/src/sgml/config.sgml.orig	2015-02-02 21:44:39.000000000 +0100
748346
+++ postgresql-9.2.10/doc/src/sgml/config.sgml	2015-02-26 14:04:26.617801197 +0100
748346
@@ -453,17 +453,24 @@ SET ENABLE_SEQSCAN TO OFF;
7686b4
       </listitem>
7686b4
      </varlistentry>
7686b4
 
7686b4
-     <varlistentry id="guc-unix-socket-directory" xreflabel="unix_socket_directory">
7686b4
-      <term><varname>unix_socket_directory</varname> (<type>string</type>)</term>
7686b4
+     <varlistentry id="guc-unix-socket-directories" xreflabel="unix_socket_directories">
7686b4
+      <term><varname>unix_socket_directories</varname> (<type>string</type>)</term>
7686b4
       <indexterm>
7686b4
-       <primary><varname>unix_socket_directory configuration parameter</primary>
7686b4
+       <primary><varname>unix_socket_directories configuration parameter</primary>
7686b4
       </indexterm>
7686b4
       <listitem>
7686b4
        <para>
7686b4
-        Specifies the directory of the Unix-domain socket on which the
7686b4
-        server is to listen for
7686b4
-        connections from client applications.  The default is normally
7686b4
-        <filename>/tmp</filename>, but can be changed at build time.
7686b4
+        Specifies the directory of the Unix-domain socket(s) on which the
7686b4
+        server is to listen for connections from client applications.
7686b4
+        Multiple sockets can be created by listing multiple directories
7686b4
+        separated by commas.  Whitespace between entries is
7686b4
+        ignored; surround a directory name with double quotes if you need
7686b4
+        to include whitespace or commas in the name.
7686b4
+        An empty value
7686b4
+        specifies not listening on any Unix-domain sockets, in which case
7686b4
+        only TCP/IP sockets can be used to connect to the server.
7686b4
+        The default value is normally
7686b4
+        <filename>/tmp</filename>, but that can be changed at build time.
7686b4
         This parameter can only be set at server start.
7686b4
        </para>
7686b4
 
748346
@@ -472,8 +479,8 @@ SET ENABLE_SEQSCAN TO OFF;
7686b4
         <literal>.s.PGSQL.<replaceable>nnnn</literal> where
7686b4
         <replaceable>nnnn is the server's port number, an ordinary file
7686b4
         named <literal>.s.PGSQL.<replaceable>nnnn.lock</literal> will be
7686b4
-        created in the <varname>unix_socket_directory directory.  Neither
7686b4
-        file should ever be removed manually.
7686b4
+        created in each of the <varname>unix_socket_directories directories.
7686b4
+        Neither file should ever be removed manually.
7686b4
        </para>
7686b4
 
7686b4
        <para>
748346
@@ -490,8 +497,8 @@ SET ENABLE_SEQSCAN TO OFF;
7686b4
       </indexterm>
7686b4
       <listitem>
7686b4
        <para>
7686b4
-        Sets the owning group of the Unix-domain socket.  (The owning
7686b4
-        user of the socket is always the user that starts the
7686b4
+        Sets the owning group of the Unix-domain socket(s).  (The owning
7686b4
+        user of the sockets is always the user that starts the
7686b4
         server.)  In combination with the parameter
7686b4
         <varname>unix_socket_permissions</varname> this can be used as
7686b4
         an additional access control mechanism for Unix-domain connections.
748346
@@ -514,7 +521,7 @@ SET ENABLE_SEQSCAN TO OFF;
7686b4
       </indexterm>
7686b4
       <listitem>
7686b4
        <para>
7686b4
-        Sets the access permissions of the Unix-domain socket.  Unix-domain
7686b4
+        Sets the access permissions of the Unix-domain socket(s).  Unix-domain
7686b4
         sockets use the usual Unix file system permission set.
7686b4
         The parameter value is expected to be a numeric mode
7686b4
         specified in the format accepted by the
748346
@@ -6624,7 +6631,7 @@ LOG:  CleanUpLock: deleting: lock(0xb7ac
7686b4
        </row>
7686b4
        <row>
7686b4
         <entry><option>-k <replaceable>x</replaceable></option></entry>
7686b4
-        <entry><literal>unix_socket_directory = <replaceable>x</replaceable></entry>
7686b4
+        <entry><literal>unix_socket_directories = <replaceable>x</replaceable></entry>
7686b4
        </row>
7686b4
        <row>
7686b4
         <entry><option>-l</option></entry>
748346
diff -up postgresql-9.2.10/doc/src/sgml/html/app-postgres.html.orig postgresql-9.2.10/doc/src/sgml/html/app-postgres.html
748346
--- postgresql-9.2.10/doc/src/sgml/html/app-postgres.html.orig	2015-02-02 21:59:33.000000000 +0100
748346
+++ postgresql-9.2.10/doc/src/sgml/html/app-postgres.html	2015-02-26 14:04:26.618801207 +0100
748346
@@ -574,11 +574,19 @@ CLASS="REPLACEABLE"
7686b4
 CLASS="COMMAND"
7686b4
 >postgres
7686b4
 > is to listen for
7686b4
-        connections from client applications.  The default is normally
7686b4
+        connections from client applications.  The value can also be a
7686b4
+        comma-separated list of directories.  An empty value
7686b4
+        specifies not listening on any Unix-domain sockets, in which case
7686b4
+        only TCP/IP sockets can be used to connect to the server.
7686b4
+        The default value is normally
7686b4
         
7686b4
 CLASS="FILENAME"
7686b4
 >/tmp
7686b4
->, but can be changed at build time.
7686b4
+>, but that can be changed at build time.
7686b4
+        Specifying this option is equivalent to setting the 
7686b4
+HREF="runtime-config-connection.html#GUC-UNIX-SOCKET-DIRECTORIES"
7686b4
+>unix_socket_directories
7686b4
+> configuration parameter.
7686b4
        
7686b4
 >
7686b4
 >
748346
diff -up postgresql-9.2.10/doc/src/sgml/html/auth-methods.html.orig postgresql-9.2.10/doc/src/sgml/html/auth-methods.html
748346
--- postgresql-9.2.10/doc/src/sgml/html/auth-methods.html.orig	2015-02-02 21:59:17.000000000 +0100
748346
+++ postgresql-9.2.10/doc/src/sgml/html/auth-methods.html	2015-02-26 14:04:26.620801227 +0100
748346
@@ -161,7 +161,7 @@ HREF="runtime-config-connection.html"
7686b4
 >.  Or you
7686b4
     could set the 
7686b4
 CLASS="VARNAME"
7686b4
->unix_socket_directory
7686b4
+>unix_socket_directories
7686b4
 >
7686b4
     configuration parameter to place the socket file in a suitably
7686b4
     restricted directory.
748346
diff -up postgresql-9.2.10/doc/src/sgml/html/bookindex.html.orig postgresql-9.2.10/doc/src/sgml/html/bookindex.html
748346
--- postgresql-9.2.10/doc/src/sgml/html/bookindex.html.orig	2015-02-02 22:00:12.000000000 +0100
748346
+++ postgresql-9.2.10/doc/src/sgml/html/bookindex.html	2015-02-26 14:04:26.625801276 +0100
748346
@@ -17250,7 +17250,7 @@ HREF="xfunc-c.html#DFUNC"
7686b4
 >
7686b4
 >
7686b4
 >
7686b4
->unix_socket_directory configuration parameter,
7686b4
+>unix_socket_directories configuration parameter,
7686b4
     
7686b4
 HREF="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SETTINGS"
7686b4
 >Connection Settings
748346
diff -up postgresql-9.2.10/doc/src/sgml/html/preventing-server-spoofing.html.orig postgresql-9.2.10/doc/src/sgml/html/preventing-server-spoofing.html
748346
--- postgresql-9.2.10/doc/src/sgml/html/preventing-server-spoofing.html.orig	2015-02-02 21:59:16.000000000 +0100
748346
+++ postgresql-9.2.10/doc/src/sgml/html/preventing-server-spoofing.html	2015-02-26 14:04:26.626801286 +0100
748346
@@ -115,8 +115,8 @@ CLASS="LITERAL"
7686b4
 >local
7686b4
 >
7686b4
    connections is to use a Unix domain socket directory (
7686b4
-HREF="runtime-config-connection.html#GUC-UNIX-SOCKET-DIRECTORY"
7686b4
->unix_socket_directory
7686b4
+HREF="runtime-config-connection.html#GUC-UNIX-SOCKET-DIRECTORIES"
7686b4
+>unix_socket_directories
7686b4
 >) that has write permission only
7686b4
    for a trusted local user.  This prevents a malicious user from creating
7686b4
    their own socket file in that directory.  If you are concerned that
748346
diff -up postgresql-9.2.10/doc/src/sgml/html/runtime-config-connection.html.orig postgresql-9.2.10/doc/src/sgml/html/runtime-config-connection.html
748346
--- postgresql-9.2.10/doc/src/sgml/html/runtime-config-connection.html.orig	2015-02-02 21:59:16.000000000 +0100
748346
+++ postgresql-9.2.10/doc/src/sgml/html/runtime-config-connection.html	2015-02-26 14:04:26.628801305 +0100
748346
@@ -274,24 +274,31 @@ CLASS="VARNAME"
7686b4
 >
7686b4
 >
7686b4
 >
7686b4
-NAME="GUC-UNIX-SOCKET-DIRECTORY"
7686b4
+NAME="GUC-UNIX-SOCKET-DIRECTORIES"
7686b4
 >
7686b4
 >
7686b4
 CLASS="VARNAME"
7686b4
->unix_socket_directory
7686b4
+>unix_socket_directories
7686b4
 > (
7686b4
 CLASS="TYPE"
7686b4
 >string
7686b4
 >)
7686b4
 >
7686b4
 >
7686b4
->        Specifies the directory of the Unix-domain socket on which the
7686b4
-        server is to listen for
7686b4
-        connections from client applications.  The default is normally
7686b4
+>        Specifies the directory of the Unix-domain socket(s) on which the
7686b4
+        server is to listen for connections from client applications.
7686b4
+        Multiple sockets can be created by listing multiple directories
7686b4
+        separated by commas.  Whitespace between entries is
7686b4
+        ignored; surround a directory name with double quotes if you need
7686b4
+        to include whitespace or commas in the name.
7686b4
+        An empty value
7686b4
+        specifies not listening on any Unix-domain sockets, in which case
7686b4
+        only TCP/IP sockets can be used to connect to the server.
7686b4
+        The default value is normally
7686b4
         
7686b4
 CLASS="FILENAME"
7686b4
 >/tmp
7686b4
->, but can be changed at build time.
7686b4
+>, but that can be changed at build time.
7686b4
         This parameter can only be set at server start.
7686b4
        
7686b4
 >
748346
@@ -320,11 +327,11 @@ CLASS="REPLACEABLE"
7686b4
 >
7686b4
 >.lock
7686b4
 > will be
7686b4
-        created in the 
7686b4
+        created in each of the 
7686b4
 CLASS="VARNAME"
7686b4
->unix_socket_directory
7686b4
-> directory.  Neither
7686b4
-        file should ever be removed manually.
7686b4
+>unix_socket_directories
7686b4
+> directories.
7686b4
+        Neither file should ever be removed manually.
7686b4
        
7686b4
 >
7686b4
 >        This parameter is irrelevant on Windows, which does not have
748346
@@ -344,8 +351,8 @@ CLASS="TYPE"
7686b4
 >)
7686b4
 >
7686b4
 >
7686b4
->        Sets the owning group of the Unix-domain socket.  (The owning
7686b4
-        user of the socket is always the user that starts the
7686b4
+>        Sets the owning group of the Unix-domain socket(s).  (The owning
7686b4
+        user of the sockets is always the user that starts the
7686b4
         server.)  In combination with the parameter
7686b4
         
7686b4
 CLASS="VARNAME"
748346
@@ -374,7 +381,7 @@ CLASS="TYPE"
7686b4
 >)
7686b4
 >
7686b4
 >
7686b4
->        Sets the access permissions of the Unix-domain socket.  Unix-domain
7686b4
+>        Sets the access permissions of the Unix-domain socket(s).  Unix-domain
7686b4
         sockets use the usual Unix file system permission set.
7686b4
         The parameter value is expected to be a numeric mode
7686b4
         specified in the format accepted by the
748346
diff -up postgresql-9.2.10/doc/src/sgml/html/runtime-config-short.html.orig postgresql-9.2.10/doc/src/sgml/html/runtime-config-short.html
748346
--- postgresql-9.2.10/doc/src/sgml/html/runtime-config-short.html.orig	2015-02-02 21:59:17.000000000 +0100
748346
+++ postgresql-9.2.10/doc/src/sgml/html/runtime-config-short.html	2015-02-26 14:04:26.629801315 +0100
748346
@@ -330,7 +330,7 @@ CLASS="REPLACEABLE"
7686b4
 >
7686b4
 >
7686b4
 CLASS="LITERAL"
7686b4
->unix_socket_directory = 
7686b4
+>unix_socket_directories = 
7686b4
 CLASS="REPLACEABLE"
7686b4
 >
7686b4
 >x
748346
diff -up postgresql-9.2.10/doc/src/sgml/man1/postgres.1.orig postgresql-9.2.10/doc/src/sgml/man1/postgres.1
748346
--- postgresql-9.2.10/doc/src/sgml/man1/postgres.1.orig	2015-02-02 22:01:09.000000000 +0100
748346
+++ postgresql-9.2.10/doc/src/sgml/man1/postgres.1	2015-02-26 14:04:26.631801334 +0100
748346
@@ -195,8 +195,10 @@ directly\&.
7686b4
 .RS 4
7686b4
 Specifies the directory of the Unix\-domain socket on which
7686b4
 \fBpostgres\fR
7686b4
-is to listen for connections from client applications\&. The default is normally
7686b4
-/tmp, but can be changed at build time\&.
7686b4
+is to listen for connections from client applications\&. The value can also be a comma\-separated list of directories\&. An empty value specifies not listening on any Unix\-domain sockets, in which case only TCP/IP sockets can be used to connect to the server\&. The default value is normally
7686b4
+/tmp, but that can be changed at build time\&. Specifying this option is equivalent to setting the
7686b4
+unix_socket_directories
7686b4
+configuration parameter\&.
7686b4
 .RE
7686b4
 .PP
7686b4
 \fB\-l\fR
748346
diff -up postgresql-9.2.10/doc/src/sgml/ref/postgres-ref.sgml.orig postgresql-9.2.10/doc/src/sgml/ref/postgres-ref.sgml
748346
--- postgresql-9.2.10/doc/src/sgml/ref/postgres-ref.sgml.orig	2015-02-02 21:44:39.000000000 +0100
748346
+++ postgresql-9.2.10/doc/src/sgml/ref/postgres-ref.sgml	2015-02-26 14:04:26.632801344 +0100
748346
@@ -254,8 +254,14 @@ PostgreSQL documentation
7686b4
        <para>
7686b4
         Specifies the directory of the Unix-domain socket on which
7686b4
         <command>postgres</command> is to listen for
7686b4
-        connections from client applications.  The default is normally
7686b4
-        <filename>/tmp</filename>, but can be changed at build time.
7686b4
+        connections from client applications.  The value can also be a
7686b4
+        comma-separated list of directories.  An empty value
7686b4
+        specifies not listening on any Unix-domain sockets, in which case
7686b4
+        only TCP/IP sockets can be used to connect to the server.
7686b4
+        The default value is normally
7686b4
+        <filename>/tmp</filename>, but that can be changed at build time.
7686b4
+        Specifying this option is equivalent to setting the 
7686b4
+        linkend="guc-unix-socket-directories"> configuration parameter.
7686b4
        </para>
7686b4
       </listitem>
7686b4
      </varlistentry>
748346
diff -up postgresql-9.2.10/doc/src/sgml/runtime.sgml.orig postgresql-9.2.10/doc/src/sgml/runtime.sgml
748346
--- postgresql-9.2.10/doc/src/sgml/runtime.sgml.orig	2015-02-02 21:44:39.000000000 +0100
748346
+++ postgresql-9.2.10/doc/src/sgml/runtime.sgml	2015-02-26 14:04:26.633801354 +0100
748346
@@ -1800,7 +1800,7 @@ pg_dumpall -p 5432 | psql -d postgres -p
7686b4
   <para>
7686b4
    The simplest way to prevent spoofing for <literal>local
7686b4
    connections is to use a Unix domain socket directory (
7686b4
-   linkend="guc-unix-socket-directory">) that has write permission only
7686b4
+   linkend="guc-unix-socket-directories">) that has write permission only
7686b4
    for a trusted local user.  This prevents a malicious user from creating
7686b4
    their own socket file in that directory.  If you are concerned that
7686b4
    some applications might still reference <filename>/tmp for the
748346
diff -up postgresql-9.2.10/src/backend/libpq/pqcomm.c.orig postgresql-9.2.10/src/backend/libpq/pqcomm.c
748346
--- postgresql-9.2.10/src/backend/libpq/pqcomm.c.orig	2015-02-02 21:44:39.000000000 +0100
748346
+++ postgresql-9.2.10/src/backend/libpq/pqcomm.c	2015-02-26 14:04:26.634801364 +0100
7686b4
@@ -42,7 +42,7 @@
7686b4
  *		StreamServerPort	- Open postmaster's server port
7686b4
  *		StreamConnection	- Create new connection with client
7686b4
  *		StreamClose			- Close a client/backend connection
7686b4
- *		TouchSocketFile		- Protect socket file against /tmp cleaners
7686b4
+ *		TouchSocketFiles	- Protect socket files against /tmp cleaners
7686b4
  *		pq_init			- initialize libpq at backend startup
7686b4
  *		pq_comm_reset	- reset libpq during error recovery
7686b4
  *		pq_close		- shutdown libpq at backend exit
748346
@@ -103,8 +103,8 @@ int			Unix_socket_permissions;
7686b4
 char	   *Unix_socket_group;
7686b4
 
7686b4
 
7686b4
-/* Where the Unix socket file is */
7686b4
-static char sock_path[MAXPGPATH];
7686b4
+/* Where the Unix socket files are (list of palloc'd strings) */
7686b4
+static List *sock_paths = NIL;
7686b4
 
7686b4
 
7686b4
 /*
748346
@@ -141,8 +141,8 @@ static int	internal_flush(void);
7686b4
 static void pq_set_nonblocking(bool nonblocking);
7686b4
 
7686b4
 #ifdef HAVE_UNIX_SOCKETS
7686b4
-static int	Lock_AF_UNIX(unsigned short portNumber, char *unixSocketName);
7686b4
-static int	Setup_AF_UNIX(void);
7686b4
+static int	Lock_AF_UNIX(char *unixSocketDir, char *unixSocketPath);
7686b4
+static int	Setup_AF_UNIX(char *sock_path);
7686b4
 #endif   /* HAVE_UNIX_SOCKETS */
7686b4
 
7686b4
 
748346
@@ -236,29 +236,43 @@ pq_close(int code, Datum arg)
7686b4
 
7686b4
 /* StreamDoUnlink()
7686b4
  * Shutdown routine for backend connection
7686b4
- * If a Unix socket is used for communication, explicitly close it.
7686b4
+ * If any Unix sockets are used for communication, explicitly close them.
7686b4
  */
7686b4
 #ifdef HAVE_UNIX_SOCKETS
7686b4
 static void
7686b4
 StreamDoUnlink(int code, Datum arg)
7686b4
 {
7686b4
-	Assert(sock_path[0]);
7686b4
-	unlink(sock_path);
7686b4
+	ListCell   *l;
7686b4
+
7686b4
+	/* Loop through all created sockets... */
7686b4
+	foreach(l, sock_paths)
7686b4
+	{
7686b4
+		char	   *sock_path = (char *) lfirst(l);
7686b4
+
7686b4
+		unlink(sock_path);
7686b4
+	}
7686b4
+	/* Since we're about to exit, no need to reclaim storage */
7686b4
+	sock_paths = NIL;
7686b4
 }
7686b4
 #endif   /* HAVE_UNIX_SOCKETS */
7686b4
 
7686b4
 /*
7686b4
  * StreamServerPort -- open a "listening" port to accept connections.
7686b4
  *
7686b4
- * Successfully opened sockets are added to the ListenSocket[] array,
7686b4
- * at the first position that isn't PGINVALID_SOCKET.
7686b4
+ * family should be AF_UNIX or AF_UNSPEC; portNumber is the port number.
7686b4
+ * For AF_UNIX ports, hostName should be NULL and unixSocketDir must be
7686b4
+ * specified.  For TCP ports, hostName is either NULL for all interfaces or
7686b4
+ * the interface to listen on, and unixSocketDir is ignored (can be NULL).
7686b4
+ *
7686b4
+ * Successfully opened sockets are added to the ListenSocket[] array (of
7686b4
+ * length MaxListen), at the first position that isn't PGINVALID_SOCKET.
7686b4
  *
7686b4
  * RETURNS: STATUS_OK or STATUS_ERROR
7686b4
  */
7686b4
 
7686b4
 int
7686b4
 StreamServerPort(int family, char *hostName, unsigned short portNumber,
7686b4
-				 char *unixSocketName,
7686b4
+				 char *unixSocketDir,
7686b4
 				 pgsocket ListenSocket[], int MaxListen)
7686b4
 {
7686b4
 	pgsocket	fd;
748346
@@ -275,6 +289,9 @@ StreamServerPort(int family, char *hostN
7686b4
 	int			listen_index = 0;
7686b4
 	int			added = 0;
7686b4
 
7686b4
+#ifdef HAVE_UNIX_SOCKETS
7686b4
+	char		unixSocketPath[MAXPGPATH];
7686b4
+#endif
7686b4
 #if !defined(WIN32) || defined(IPV6_V6ONLY)
7686b4
 	int			one = 1;
7686b4
 #endif
748346
@@ -288,10 +305,22 @@ StreamServerPort(int family, char *hostN
7686b4
 #ifdef HAVE_UNIX_SOCKETS
7686b4
 	if (family == AF_UNIX)
7686b4
 	{
7686b4
-		/* Lock_AF_UNIX will also fill in sock_path. */
7686b4
-		if (Lock_AF_UNIX(portNumber, unixSocketName) != STATUS_OK)
7686b4
+		/*
7686b4
+		 * Create unixSocketPath from portNumber and unixSocketDir and lock
7686b4
+		 * that file path
7686b4
+		 */
7686b4
+		UNIXSOCK_PATH(unixSocketPath, portNumber, unixSocketDir);
7686b4
+		if (strlen(unixSocketPath) >= UNIXSOCK_PATH_BUFLEN)
7686b4
+		{
7686b4
+			ereport(LOG,
7686b4
+					(errmsg("Unix-domain socket path \"%s\" is too long (maximum %d bytes)",
7686b4
+							unixSocketPath,
7686b4
+							(int) (UNIXSOCK_PATH_BUFLEN - 1))));
7686b4
+			return STATUS_ERROR;
7686b4
+		}
7686b4
+		if (Lock_AF_UNIX(unixSocketDir, unixSocketPath) != STATUS_OK)
7686b4
 			return STATUS_ERROR;
7686b4
-		service = sock_path;
7686b4
+		service = unixSocketPath;
7686b4
 	}
7686b4
 	else
7686b4
 #endif   /* HAVE_UNIX_SOCKETS */
748346
@@ -434,7 +463,7 @@ StreamServerPort(int family, char *hostN
7686b4
 					 (IS_AF_UNIX(addr->ai_family)) ?
7686b4
 				  errhint("Is another postmaster already running on port %d?"
7686b4
 						  " If not, remove socket file \"%s\" and retry.",
7686b4
-						  (int) portNumber, sock_path) :
7686b4
+						  (int) portNumber, service) :
7686b4
 				  errhint("Is another postmaster already running on port %d?"
7686b4
 						  " If not, wait a few seconds and retry.",
7686b4
 						  (int) portNumber)));
748346
@@ -445,7 +474,7 @@ StreamServerPort(int family, char *hostN
7686b4
 #ifdef HAVE_UNIX_SOCKETS
7686b4
 		if (addr->ai_family == AF_UNIX)
7686b4
 		{
7686b4
-			if (Setup_AF_UNIX() != STATUS_OK)
7686b4
+			if (Setup_AF_UNIX(service) != STATUS_OK)
7686b4
 			{
7686b4
 				closesocket(fd);
7686b4
 				break;
748346
@@ -492,18 +521,8 @@ StreamServerPort(int family, char *hostN
7686b4
  * Lock_AF_UNIX -- configure unix socket file path
7686b4
  */
7686b4
 static int
7686b4
-Lock_AF_UNIX(unsigned short portNumber, char *unixSocketName)
7686b4
+Lock_AF_UNIX(char *unixSocketDir, char *unixSocketPath)
7686b4
 {
7686b4
-	UNIXSOCK_PATH(sock_path, portNumber, unixSocketName);
7686b4
-	if (strlen(sock_path) >= UNIXSOCK_PATH_BUFLEN)
7686b4
-	{
7686b4
-		ereport(LOG,
7686b4
-				(errmsg("Unix-domain socket path \"%s\" is too long (maximum %d bytes)",
7686b4
-						sock_path,
7686b4
-						(int) (UNIXSOCK_PATH_BUFLEN - 1))));
7686b4
-		return STATUS_ERROR;
7686b4
-	}
7686b4
-
7686b4
 	/*
7686b4
 	 * Grab an interlock file associated with the socket file.
7686b4
 	 *
748346
@@ -512,13 +531,23 @@ Lock_AF_UNIX(unsigned short portNumber,
7686b4
 	 * more portable, and second, it lets us remove any pre-existing socket
7686b4
 	 * file without race conditions.
7686b4
 	 */
7686b4
-	CreateSocketLockFile(sock_path, true);
7686b4
+	CreateSocketLockFile(unixSocketPath, true, unixSocketDir);
7686b4
 
7686b4
 	/*
7686b4
 	 * Once we have the interlock, we can safely delete any pre-existing
7686b4
 	 * socket file to avoid failure at bind() time.
7686b4
 	 */
7686b4
-	unlink(sock_path);
7686b4
+	unlink(unixSocketPath);
7686b4
+
7686b4
+	/*
7686b4
+	 * Arrange to unlink the socket file(s) at proc_exit.  If this is the
7686b4
+	 * first one, set up the on_proc_exit function to do it; then add this
7686b4
+	 * socket file to the list of files to unlink.
7686b4
+	 */
7686b4
+	if (sock_paths == NIL)
7686b4
+		on_proc_exit(StreamDoUnlink, 0);
7686b4
+
7686b4
+	sock_paths = lappend(sock_paths, pstrdup(unixSocketPath));
7686b4
 
7686b4
 	return STATUS_OK;
7686b4
 }
748346
@@ -528,11 +557,8 @@ Lock_AF_UNIX(unsigned short portNumber,
7686b4
  * Setup_AF_UNIX -- configure unix socket permissions
7686b4
  */
7686b4
 static int
7686b4
-Setup_AF_UNIX(void)
7686b4
+Setup_AF_UNIX(char *sock_path)
7686b4
 {
7686b4
-	/* Arrange to unlink the socket file at exit */
7686b4
-	on_proc_exit(StreamDoUnlink, 0);
7686b4
-
7686b4
 	/*
7686b4
 	 * Fix socket ownership/permission if requested.  Note we must do this
7686b4
 	 * before we listen() to avoid a window where unwanted connections could
748346
@@ -714,20 +740,24 @@ StreamClose(pgsocket sock)
7686b4
 }
7686b4
 
7686b4
 /*
7686b4
- * TouchSocketFile -- mark socket file as recently accessed
7686b4
+ * TouchSocketFiles -- mark socket files as recently accessed
7686b4
  *
7686b4
  * This routine should be called every so often to ensure that the socket
7686b4
- * file has a recent mod date (ordinary operations on sockets usually won't
7686b4
- * change the mod date).  That saves it from being removed by
7686b4
+ * files have a recent mod date (ordinary operations on sockets usually won't
7686b4
+ * change the mod date).  That saves them from being removed by
7686b4
  * overenthusiastic /tmp-directory-cleaner daemons.  (Another reason we should
7686b4
  * never have put the socket file in /tmp...)
7686b4
  */
7686b4
 void
7686b4
-TouchSocketFile(void)
7686b4
+TouchSocketFiles(void)
7686b4
 {
7686b4
-	/* Do nothing if we did not create a socket... */
7686b4
-	if (sock_path[0] != '\0')
7686b4
+	ListCell   *l;
7686b4
+
7686b4
+	/* Loop through all created sockets... */
7686b4
+	foreach(l, sock_paths)
7686b4
 	{
7686b4
+		char	   *sock_path = (char *) lfirst(l);
7686b4
+
7686b4
 		/*
7686b4
 		 * utime() is POSIX standard, utimes() is a common alternative. If we
7686b4
 		 * have neither, there's no way to affect the mod or access time of
748346
diff -up postgresql-9.2.10/src/backend/postmaster/postmaster.c.orig postgresql-9.2.10/src/backend/postmaster/postmaster.c
748346
--- postgresql-9.2.10/src/backend/postmaster/postmaster.c.orig	2015-02-02 21:44:39.000000000 +0100
748346
+++ postgresql-9.2.10/src/backend/postmaster/postmaster.c	2015-02-26 14:04:26.636801383 +0100
748346
@@ -160,7 +160,9 @@ static Backend *ShmemBackendArray;
7686b4
 
7686b4
 /* The socket number we are listening for connections on */
7686b4
 int			PostPortNumber;
7686b4
-char	   *UnixSocketDir;
7686b4
+/* The directory names for Unix socket(s) */
7686b4
+char	   *Unix_socket_directories;
7686b4
+/* The TCP listen address(es) */
7686b4
 char	   *ListenAddresses;
7686b4
 
7686b4
 /*
748346
@@ -636,7 +638,7 @@ PostmasterMain(int argc, char *argv[])
7686b4
 				break;
7686b4
 
7686b4
 			case 'k':
7686b4
-				SetConfigOption("unix_socket_directory", optarg, PGC_POSTMASTER, PGC_S_ARGV);
7686b4
+				SetConfigOption("unix_socket_directories", optarg, PGC_POSTMASTER, PGC_S_ARGV);
7686b4
 				break;
7686b4
 
7686b4
 			case 'l':
748346
@@ -880,7 +882,7 @@ PostmasterMain(int argc, char *argv[])
7686b4
 		/* Need a modifiable copy of ListenAddresses */
7686b4
 		rawstring = pstrdup(ListenAddresses);
7686b4
 
7686b4
-		/* Parse string into list of identifiers */
7686b4
+		/* Parse string into list of hostnames */
7686b4
 		if (!SplitIdentifierString(rawstring, ',', &elemlist))
7686b4
 		{
7686b4
 			/* syntax error in list */
748346
@@ -896,12 +898,12 @@ PostmasterMain(int argc, char *argv[])
7686b4
 			if (strcmp(curhost, "*") == 0)
7686b4
 				status = StreamServerPort(AF_UNSPEC, NULL,
7686b4
 										  (unsigned short) PostPortNumber,
7686b4
-										  UnixSocketDir,
7686b4
+										  NULL,
7686b4
 										  ListenSocket, MAXLISTEN);
7686b4
 			else
7686b4
 				status = StreamServerPort(AF_UNSPEC, curhost,
7686b4
 										  (unsigned short) PostPortNumber,
7686b4
-										  UnixSocketDir,
7686b4
+										  NULL,
7686b4
 										  ListenSocket, MAXLISTEN);
7686b4
 
7686b4
 			if (status == STATUS_OK)
748346
@@ -920,7 +922,7 @@ PostmasterMain(int argc, char *argv[])
7686b4
 								curhost)));
7686b4
 		}
7686b4
 
7686b4
-		if (!success && list_length(elemlist))
7686b4
+		if (!success && elemlist != NIL)
7686b4
 			ereport(FATAL,
7686b4
 					(errmsg("could not create any TCP/IP sockets")));
7686b4
 
748346
@@ -967,13 +969,54 @@ PostmasterMain(int argc, char *argv[])
7686b4
 #endif
7686b4
 
7686b4
 #ifdef HAVE_UNIX_SOCKETS
7686b4
-	status = StreamServerPort(AF_UNIX, NULL,
7686b4
-							  (unsigned short) PostPortNumber,
7686b4
-							  UnixSocketDir,
7686b4
-							  ListenSocket, MAXLISTEN);
7686b4
-	if (status != STATUS_OK)
7686b4
-		ereport(WARNING,
7686b4
-				(errmsg("could not create Unix-domain socket")));
7686b4
+	if (Unix_socket_directories)
7686b4
+	{
7686b4
+		char	   *rawstring;
7686b4
+		List	   *elemlist;
7686b4
+		ListCell   *l;
7686b4
+		int			success = 0;
7686b4
+
7686b4
+		/* Need a modifiable copy of Unix_socket_directories */
7686b4
+		rawstring = pstrdup(Unix_socket_directories);
7686b4
+
7686b4
+		/* Parse string into list of directories */
7686b4
+		if (!SplitDirectoriesString(rawstring, ',', &elemlist))
7686b4
+		{
7686b4
+			/* syntax error in list */
7686b4
+			ereport(FATAL,
7686b4
+					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
7686b4
+					 errmsg("invalid list syntax for \"unix_socket_directories\"")));
7686b4
+		}
7686b4
+
7686b4
+		foreach(l, elemlist)
7686b4
+		{
7686b4
+			char	   *socketdir = (char *) lfirst(l);
7686b4
+
7686b4
+			status = StreamServerPort(AF_UNIX, NULL,
7686b4
+									  (unsigned short) PostPortNumber,
7686b4
+									  socketdir,
7686b4
+									  ListenSocket, MAXLISTEN);
7686b4
+
7686b4
+			if (status == STATUS_OK)
7686b4
+			{
7686b4
+				success++;
7686b4
+				/* record the first successful Unix socket in lockfile */
7686b4
+				if (success == 1)
7686b4
+					AddToDataDirLockFile(LOCK_FILE_LINE_SOCKET_DIR, socketdir);
7686b4
+			}
7686b4
+			else
7686b4
+				ereport(WARNING,
7686b4
+						(errmsg("could not create Unix-domain socket in directory \"%s\"",
7686b4
+								socketdir)));
7686b4
+		}
7686b4
+
7686b4
+		if (!success && elemlist != NIL)
7686b4
+			ereport(FATAL,
7686b4
+					(errmsg("could not create any Unix-domain sockets")));
7686b4
+
7686b4
+		list_free_deep(elemlist);
7686b4
+		pfree(rawstring);
7686b4
+	}
7686b4
 #endif
7686b4
 
7686b4
 	/*
748346
@@ -1452,15 +1495,15 @@ ServerLoop(void)
7686b4
 		}
7686b4
 
7686b4
 		/*
7686b4
-		 * Touch the socket and lock file every 58 minutes, to ensure that
7686b4
+		 * Touch Unix socket and lock files every 58 minutes, to ensure that
7686b4
 		 * they are not removed by overzealous /tmp-cleaning tasks.  We assume
7686b4
 		 * no one runs cleaners with cutoff times of less than an hour ...
7686b4
 		 */
7686b4
 		now = time(NULL);
7686b4
 		if (now - last_touch_time >= 58 * SECS_PER_MINUTE)
7686b4
 		{
7686b4
-			TouchSocketFile();
7686b4
-			TouchSocketLockFile();
7686b4
+			TouchSocketFiles();
7686b4
+			TouchSocketLockFiles();
7686b4
 			last_touch_time = now;
7686b4
 		}
748346
 
748346
diff -up postgresql-9.2.10/src/backend/tcop/postgres.c.orig postgresql-9.2.10/src/backend/tcop/postgres.c
748346
--- postgresql-9.2.10/src/backend/tcop/postgres.c.orig	2015-02-02 21:44:39.000000000 +0100
748346
+++ postgresql-9.2.10/src/backend/tcop/postgres.c	2015-02-26 14:04:26.638801403 +0100
748346
@@ -3393,7 +3393,7 @@ process_postgres_switches(int argc, char
7686b4
 				break;
7686b4
 
7686b4
 			case 'k':
7686b4
-				SetConfigOption("unix_socket_directory", optarg, ctx, gucsource);
7686b4
+				SetConfigOption("unix_socket_directories", optarg, ctx, gucsource);
7686b4
 				break;
7686b4
 
7686b4
 			case 'l':
748346
diff -up postgresql-9.2.10/src/backend/utils/adt/varlena.c.orig postgresql-9.2.10/src/backend/utils/adt/varlena.c
748346
--- postgresql-9.2.10/src/backend/utils/adt/varlena.c.orig	2015-02-02 21:44:39.000000000 +0100
748346
+++ postgresql-9.2.10/src/backend/utils/adt/varlena.c	2015-02-26 14:04:26.639801413 +0100
748346
@@ -2446,6 +2446,119 @@ SplitIdentifierString(char *rawstring, c
7686b4
 }
7686b4
 
7686b4
 
7686b4
+/*
7686b4
+ * SplitDirectoriesString --- parse a string containing directory names
7686b4
+ *
7686b4
+ * This is similar to SplitIdentifierString, except that the parsing
7686b4
+ * rules are meant to handle pathnames instead of identifiers: there is
7686b4
+ * no downcasing, embedded spaces are allowed, the max length is MAXPGPATH-1,
7686b4
+ * and we apply canonicalize_path() to each extracted string.  Because of the
7686b4
+ * last, the returned strings are separately palloc'd rather than being
7686b4
+ * pointers into rawstring --- but we still scribble on rawstring.
7686b4
+ *
7686b4
+ * Inputs:
7686b4
+ *	rawstring: the input string; must be modifiable!
7686b4
+ *	separator: the separator punctuation expected between directories
7686b4
+ *			   (typically ',' or ';').	Whitespace may also appear around
7686b4
+ *			   directories.
7686b4
+ * Outputs:
7686b4
+ *	namelist: filled with a palloc'd list of directory names.
7686b4
+ *			  Caller should list_free_deep() this even on error return.
7686b4
+ *
7686b4
+ * Returns TRUE if okay, FALSE if there is a syntax error in the string.
7686b4
+ *
7686b4
+ * Note that an empty string is considered okay here.
7686b4
+ */
7686b4
+bool
7686b4
+SplitDirectoriesString(char *rawstring, char separator,
7686b4
+					   List **namelist)
7686b4
+{
7686b4
+	char	   *nextp = rawstring;
7686b4
+	bool		done = false;
7686b4
+
7686b4
+	*namelist = NIL;
7686b4
+
7686b4
+	while (isspace((unsigned char) *nextp))
7686b4
+		nextp++;				/* skip leading whitespace */
7686b4
+
7686b4
+	if (*nextp == '\0')
7686b4
+		return true;			/* allow empty string */
7686b4
+
7686b4
+	/* At the top of the loop, we are at start of a new directory. */
7686b4
+	do
7686b4
+	{
7686b4
+		char	   *curname;
7686b4
+		char	   *endp;
7686b4
+
7686b4
+		if (*nextp == '\"')
7686b4
+		{
7686b4
+			/* Quoted name --- collapse quote-quote pairs */
7686b4
+			curname = nextp + 1;
7686b4
+			for (;;)
7686b4
+			{
7686b4
+				endp = strchr(nextp + 1, '\"');
7686b4
+				if (endp == NULL)
7686b4
+					return false;		/* mismatched quotes */
7686b4
+				if (endp[1] != '\"')
7686b4
+					break;		/* found end of quoted name */
7686b4
+				/* Collapse adjacent quotes into one quote, and look again */
7686b4
+				memmove(endp, endp + 1, strlen(endp));
7686b4
+				nextp = endp;
7686b4
+			}
7686b4
+			/* endp now points at the terminating quote */
7686b4
+			nextp = endp + 1;
7686b4
+		}
7686b4
+		else
7686b4
+		{
7686b4
+			/* Unquoted name --- extends to separator or end of string */
7686b4
+			curname = endp = nextp;
7686b4
+			while (*nextp && *nextp != separator)
7686b4
+			{
7686b4
+				/* trailing whitespace should not be included in name */
7686b4
+				if (!isspace((unsigned char) *nextp))
7686b4
+					endp = nextp + 1;
7686b4
+				nextp++;
7686b4
+			}
7686b4
+			if (curname == endp)
7686b4
+				return false;	/* empty unquoted name not allowed */
7686b4
+		}
7686b4
+
7686b4
+		while (isspace((unsigned char) *nextp))
7686b4
+			nextp++;			/* skip trailing whitespace */
7686b4
+
7686b4
+		if (*nextp == separator)
7686b4
+		{
7686b4
+			nextp++;
7686b4
+			while (isspace((unsigned char) *nextp))
7686b4
+				nextp++;		/* skip leading whitespace for next */
7686b4
+			/* we expect another name, so done remains false */
7686b4
+		}
7686b4
+		else if (*nextp == '\0')
7686b4
+			done = true;
7686b4
+		else
7686b4
+			return false;		/* invalid syntax */
7686b4
+
7686b4
+		/* Now safe to overwrite separator with a null */
7686b4
+		*endp = '\0';
7686b4
+
7686b4
+		/* Truncate path if it's overlength */
7686b4
+		if (strlen(curname) >= MAXPGPATH)
7686b4
+			curname[MAXPGPATH - 1] = '\0';
7686b4
+
7686b4
+		/*
7686b4
+		 * Finished isolating current name --- add it to list
7686b4
+		 */
7686b4
+		curname = pstrdup(curname);
7686b4
+		canonicalize_path(curname);
7686b4
+		*namelist = lappend(*namelist, curname);
7686b4
+
7686b4
+		/* Loop back if we didn't reach end of string */
7686b4
+	} while (!done);
7686b4
+
7686b4
+	return true;
7686b4
+}
7686b4
+
7686b4
+
7686b4
 /*****************************************************************************
7686b4
  *	Comparison Functions used for bytea
7686b4
  *
748346
diff -up postgresql-9.2.10/src/backend/utils/init/miscinit.c.orig postgresql-9.2.10/src/backend/utils/init/miscinit.c
748346
--- postgresql-9.2.10/src/backend/utils/init/miscinit.c.orig	2015-02-02 21:44:39.000000000 +0100
748346
+++ postgresql-9.2.10/src/backend/utils/init/miscinit.c	2015-02-26 14:04:26.640801422 +0100
7686b4
@@ -49,8 +49,8 @@
7686b4
 
7686b4
 ProcessingMode Mode = InitProcessing;
7686b4
 
7686b4
-/* Note: we rely on this to initialize as zeroes */
7686b4
-static char socketLockFile[MAXPGPATH];
7686b4
+/* List of lock files to be removed at proc exit */
7686b4
+static List *lock_files = NIL;
7686b4
 
7686b4
 
7686b4
 /* ----------------------------------------------------------------
748346
@@ -640,32 +640,35 @@ GetUserNameFromId(Oid roleid)
7686b4
  */
7686b4
 
7686b4
 /*
7686b4
- * proc_exit callback to remove a lockfile.
7686b4
+ * proc_exit callback to remove lockfiles.
7686b4
  */
7686b4
 static void
7686b4
-UnlinkLockFile(int status, Datum filename)
7686b4
+UnlinkLockFiles(int status, Datum arg)
7686b4
 {
7686b4
-	char	   *fname = (char *) DatumGetPointer(filename);
7686b4
+	ListCell   *l;
7686b4
 
7686b4
-	if (fname != NULL)
7686b4
+	foreach(l, lock_files)
7686b4
 	{
7686b4
-		if (unlink(fname) != 0)
7686b4
-		{
7686b4
-			/* Should we complain if the unlink fails? */
7686b4
-		}
7686b4
-		free(fname);
7686b4
+		char	   *curfile = (char *) lfirst(l);
7686b4
+
7686b4
+		unlink(curfile);
7686b4
+		/* Should we complain if the unlink fails? */
7686b4
 	}
7686b4
+	/* Since we're about to exit, no need to reclaim storage */
7686b4
+	lock_files = NIL;
7686b4
 }
7686b4
 
7686b4
 /*
7686b4
  * Create a lockfile.
7686b4
  *
7686b4
- * filename is the name of the lockfile to create.
7686b4
+ * filename is the path name of the lockfile to create.
7686b4
  * amPostmaster is used to determine how to encode the output PID.
7686b4
+ * socketDir is the Unix socket directory path to include (possibly empty).
7686b4
  * isDDLock and refName are used to determine what error message to produce.
7686b4
  */
7686b4
 static void
7686b4
 CreateLockFile(const char *filename, bool amPostmaster,
7686b4
+			   const char *socketDir,
7686b4
 			   bool isDDLock, const char *refName)
7686b4
 {
7686b4
 	int			fd;
748346
@@ -891,12 +894,7 @@ CreateLockFile(const char *filename, boo
7686b4
 			 DataDir,
7686b4
 			 (long) MyStartTime,
7686b4
 			 PostPortNumber,
7686b4
-#ifdef HAVE_UNIX_SOCKETS
7686b4
-			 (*UnixSocketDir != '\0') ? UnixSocketDir : DEFAULT_PGSOCKET_DIR
7686b4
-#else
7686b4
-			 ""
7686b4
-#endif
7686b4
-		);
7686b4
+			 socketDir);
7686b4
 
7686b4
 	/*
7686b4
 	 * In a standalone backend, the next line (LOCK_FILE_LINE_LISTEN_ADDR)
748346
@@ -941,9 +939,14 @@ CreateLockFile(const char *filename, boo
7686b4
 	}
7686b4
 
7686b4
 	/*
7686b4
-	 * Arrange for automatic removal of lockfile at proc_exit.
7686b4
+	 * Arrange to unlink the lock file(s) at proc_exit.  If this is the
7686b4
+	 * first one, set up the on_proc_exit function to do it; then add this
7686b4
+	 * lock file to the list of files to unlink.
7686b4
 	 */
7686b4
-	on_proc_exit(UnlinkLockFile, PointerGetDatum(strdup(filename)));
7686b4
+	if (lock_files == NIL)
7686b4
+		on_proc_exit(UnlinkLockFiles, 0);
7686b4
+
7686b4
+	lock_files = lappend(lock_files, pstrdup(filename));
7686b4
 }
7686b4
 
7686b4
 /*
748346
@@ -952,41 +955,50 @@ CreateLockFile(const char *filename, boo
7686b4
  * When this is called, we must have already switched the working
7686b4
  * directory to DataDir, so we can just use a relative path.  This
7686b4
  * helps ensure that we are locking the directory we should be.
7686b4
+ *
7686b4
+ * Note that the socket directory path line is initially written as empty.
7686b4
+ * postmaster.c will rewrite it upon creating the first Unix socket.
7686b4
  */
7686b4
 void
7686b4
 CreateDataDirLockFile(bool amPostmaster)
7686b4
 {
7686b4
-	CreateLockFile(DIRECTORY_LOCK_FILE, amPostmaster, true, DataDir);
7686b4
+	CreateLockFile(DIRECTORY_LOCK_FILE, amPostmaster, "", true, DataDir);
7686b4
 }
7686b4
 
7686b4
 /*
7686b4
  * Create a lockfile for the specified Unix socket file.
7686b4
  */
7686b4
 void
7686b4
-CreateSocketLockFile(const char *socketfile, bool amPostmaster)
7686b4
+CreateSocketLockFile(const char *socketfile, bool amPostmaster,
7686b4
+					 const char *socketDir)
7686b4
 {
7686b4
 	char		lockfile[MAXPGPATH];
7686b4
 
7686b4
 	snprintf(lockfile, sizeof(lockfile), "%s.lock", socketfile);
7686b4
-	CreateLockFile(lockfile, amPostmaster, false, socketfile);
7686b4
-	/* Save name of lockfile for TouchSocketLockFile */
7686b4
-	strcpy(socketLockFile, lockfile);
7686b4
+	CreateLockFile(lockfile, amPostmaster, socketDir, false, socketfile);
7686b4
 }
7686b4
 
7686b4
 /*
7686b4
- * TouchSocketLockFile -- mark socket lock file as recently accessed
7686b4
+ * TouchSocketLockFiles -- mark socket lock files as recently accessed
7686b4
  *
7686b4
- * This routine should be called every so often to ensure that the lock file
7686b4
- * has a recent mod or access date.  That saves it
7686b4
+ * This routine should be called every so often to ensure that the socket
7686b4
+ * lock files have a recent mod or access date.  That saves them
7686b4
  * from being removed by overenthusiastic /tmp-directory-cleaner daemons.
7686b4
  * (Another reason we should never have put the socket file in /tmp...)
7686b4
  */
7686b4
 void
7686b4
-TouchSocketLockFile(void)
7686b4
+TouchSocketLockFiles(void)
7686b4
 {
7686b4
-	/* Do nothing if we did not create a socket... */
7686b4
-	if (socketLockFile[0] != '\0')
7686b4
+	ListCell   *l;
7686b4
+
7686b4
+	foreach(l, lock_files)
7686b4
 	{
7686b4
+		char	   *socketLockFile = (char *) lfirst(l);
7686b4
+
7686b4
+		/* No need to touch the data directory lock file, we trust */
7686b4
+		if (strcmp(socketLockFile, DIRECTORY_LOCK_FILE) == 0)
7686b4
+			continue;
7686b4
+
7686b4
 		/*
7686b4
 		 * utime() is POSIX standard, utimes() is a common alternative; if we
7686b4
 		 * have neither, fall back to actually reading the file (which only
748346
@@ -1018,8 +1030,10 @@ TouchSocketLockFile(void)
7686b4
  * Add (or replace) a line in the data directory lock file.
7686b4
  * The given string should not include a trailing newline.
7686b4
  *
7686b4
- * Caution: this erases all following lines.  In current usage that is OK
7686b4
- * because lines are added in order.  We could improve it if needed.
7686b4
+ * Note: because we don't truncate the file, if we were to rewrite a line
7686b4
+ * with less data than it had before, there would be garbage after the last
7686b4
+ * line.  We don't ever actually do that, so not worth adding another kernel
7686b4
+ * call to cover the possibility.
7686b4
  */
7686b4
 void
7686b4
 AddToDataDirLockFile(int target_line, const char *str)
748346
@@ -1027,8 +1041,10 @@ AddToDataDirLockFile(int target_line, co
7686b4
 	int			fd;
7686b4
 	int			len;
7686b4
 	int			lineno;
7686b4
-	char	   *ptr;
7686b4
-	char		buffer[BLCKSZ];
7686b4
+	char	   *srcptr;
7686b4
+	char	   *destptr;
7686b4
+	char		srcbuffer[BLCKSZ];
7686b4
+	char		destbuffer[BLCKSZ];
7686b4
 
7686b4
 	fd = open(DIRECTORY_LOCK_FILE, O_RDWR | PG_BINARY, 0);
7686b4
 	if (fd < 0)
748346
@@ -1039,7 +1055,7 @@ AddToDataDirLockFile(int target_line, co
7686b4
 						DIRECTORY_LOCK_FILE)));
7686b4
 		return;
7686b4
 	}
7686b4
-	len = read(fd, buffer, sizeof(buffer) - 1);
7686b4
+	len = read(fd, srcbuffer, sizeof(srcbuffer) - 1);
7686b4
 	if (len < 0)
7686b4
 	{
7686b4
 		ereport(LOG,
748346
@@ -1049,37 +1065,51 @@ AddToDataDirLockFile(int target_line, co
7686b4
 		close(fd);
7686b4
 		return;
7686b4
 	}
7686b4
-	buffer[len] = '\0';
7686b4
+	srcbuffer[len] = '\0';
7686b4
 
7686b4
 	/*
7686b4
-	 * Skip over lines we are not supposed to rewrite.
7686b4
+	 * Advance over lines we are not supposed to rewrite, then copy them
7686b4
+	 * to destbuffer.
7686b4
 	 */
7686b4
-	ptr = buffer;
7686b4
+	srcptr = srcbuffer;
7686b4
 	for (lineno = 1; lineno < target_line; lineno++)
7686b4
 	{
7686b4
-		if ((ptr = strchr(ptr, '\n')) == NULL)
7686b4
+		if ((srcptr = strchr(srcptr, '\n')) == NULL)
7686b4
 		{
7686b4
 			elog(LOG, "incomplete data in \"%s\": found only %d newlines while trying to add line %d",
7686b4
 				 DIRECTORY_LOCK_FILE, lineno - 1, target_line);
7686b4
 			close(fd);
7686b4
 			return;
7686b4
 		}
7686b4
-		ptr++;
7686b4
+		srcptr++;
7686b4
 	}
7686b4
+	memcpy(destbuffer, srcbuffer, srcptr - srcbuffer);
7686b4
+	destptr = destbuffer + (srcptr - srcbuffer);
7686b4
 
7686b4
 	/*
7686b4
 	 * Write or rewrite the target line.
7686b4
 	 */
7686b4
-	snprintf(ptr, buffer + sizeof(buffer) - ptr, "%s\n", str);
7686b4
+	snprintf(destptr, destbuffer + sizeof(destbuffer) - destptr, "%s\n", str);
7686b4
+	destptr += strlen(destptr);
7686b4
+
7686b4
+	/*
7686b4
+	 * If there are more lines in the old file, append them to destbuffer.
7686b4
+	 */
7686b4
+	if ((srcptr = strchr(srcptr, '\n')) != NULL)
7686b4
+	{
7686b4
+		srcptr++;
7686b4
+		snprintf(destptr, destbuffer + sizeof(destbuffer) - destptr, "%s",
7686b4
+				 srcptr);
7686b4
+	}
7686b4
 
7686b4
 	/*
7686b4
 	 * And rewrite the data.  Since we write in a single kernel call, this
7686b4
 	 * update should appear atomic to onlookers.
7686b4
 	 */
7686b4
-	len = strlen(buffer);
7686b4
+	len = strlen(destbuffer);
7686b4
 	errno = 0;
7686b4
 	if (lseek(fd, (off_t) 0, SEEK_SET) != 0 ||
7686b4
-		(int) write(fd, buffer, len) != len)
7686b4
+		(int) write(fd, destbuffer, len) != len)
7686b4
 	{
7686b4
 		/* if write didn't set errno, assume problem is no disk space */
7686b4
 		if (errno == 0)
748346
diff -up postgresql-9.2.10/src/backend/utils/misc/guc.c.orig postgresql-9.2.10/src/backend/utils/misc/guc.c
748346
--- postgresql-9.2.10/src/backend/utils/misc/guc.c.orig	2015-02-02 21:44:39.000000000 +0100
748346
+++ postgresql-9.2.10/src/backend/utils/misc/guc.c	2015-02-26 14:04:26.643801452 +0100
748346
@@ -2894,14 +2894,18 @@ static struct config_string ConfigureNam
7686b4
 	},
7686b4
 
7686b4
 	{
7686b4
-		{"unix_socket_directory", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
7686b4
-			gettext_noop("Sets the directory where the Unix-domain socket will be created."),
7686b4
+		{"unix_socket_directories", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
7686b4
+			gettext_noop("Sets the directories where Unix-domain sockets will be created."),
7686b4
 			NULL,
7686b4
 			GUC_SUPERUSER_ONLY
7686b4
 		},
7686b4
-		&UnixSocketDir,
7686b4
+		&Unix_socket_directories,
7686b4
+#ifdef HAVE_UNIX_SOCKETS
7686b4
+		DEFAULT_PGSOCKET_DIR,
7686b4
+#else
7686b4
 		"",
7686b4
-		check_canonical_path, NULL, NULL
7686b4
+#endif
7686b4
+		NULL, NULL, NULL
7686b4
 	},
7686b4
 
7686b4
 	{
748346
diff -up postgresql-9.2.10/src/backend/utils/misc/postgresql.conf.sample.orig postgresql-9.2.10/src/backend/utils/misc/postgresql.conf.sample
748346
--- postgresql-9.2.10/src/backend/utils/misc/postgresql.conf.sample.orig	2015-02-26 14:04:11.574654149 +0100
748346
+++ postgresql-9.2.10/src/backend/utils/misc/postgresql.conf.sample	2015-02-26 14:04:26.644801461 +0100
748346
@@ -67,7 +67,8 @@
7686b4
 # Note:  Increasing max_connections costs ~400 bytes of shared memory per
7686b4
 # connection slot, plus lock space (see max_locks_per_transaction).
7686b4
 #superuser_reserved_connections = 3	# (change requires restart)
7686b4
-#unix_socket_directory = ''		# (change requires restart)
7686b4
+#unix_socket_directories = '/tmp'	# comma-separated list of directories
7686b4
+					# (change requires restart)
7686b4
 #unix_socket_group = ''			# (change requires restart)
7686b4
 #unix_socket_permissions = 0777		# begin with 0 to use octal notation
7686b4
 					# (change requires restart)
748346
diff -up postgresql-9.2.10/src/bin/initdb/initdb.c.orig postgresql-9.2.10/src/bin/initdb/initdb.c
748346
--- postgresql-9.2.10/src/bin/initdb/initdb.c.orig	2015-02-02 21:44:39.000000000 +0100
748346
+++ postgresql-9.2.10/src/bin/initdb/initdb.c	2015-02-26 14:04:26.645801471 +0100
748346
@@ -991,7 +991,7 @@ static void
7686b4
 setup_config(void)
7686b4
 {
7686b4
 	char	  **conflines;
7686b4
-	char		repltok[TZ_STRLEN_MAX + 100];
7686b4
+	char		repltok[MAXPGPATH];
7686b4
 	char		path[MAXPGPATH];
7686b4
 	const char *default_timezone;
7686b4
 
748346
@@ -1013,6 +1013,15 @@ setup_config(void)
7686b4
 				 n_buffers * (BLCKSZ / 1024));
7686b4
 	conflines = replace_token(conflines, "#shared_buffers = 32MB", repltok);
7686b4
 
7686b4
+#ifdef HAVE_UNIX_SOCKETS
7686b4
+	snprintf(repltok, sizeof(repltok), "#unix_socket_directories = '%s'",
7686b4
+			 DEFAULT_PGSOCKET_DIR);
7686b4
+#else
7686b4
+	snprintf(repltok, sizeof(repltok), "#unix_socket_directories = ''");
7686b4
+#endif
7686b4
+	conflines = replace_token(conflines, "#unix_socket_directories = '/tmp'",
7686b4
+							  repltok);
7686b4
+
7686b4
 #if DEF_PGPORT != 5432
7686b4
 	snprintf(repltok, sizeof(repltok), "#port = %d", DEF_PGPORT);
7686b4
 	conflines = replace_token(conflines, "#port = 5432", repltok);
748346
diff -up postgresql-9.2.10/src/bin/pg_ctl/pg_ctl.c.orig postgresql-9.2.10/src/bin/pg_ctl/pg_ctl.c
748346
--- postgresql-9.2.10/src/bin/pg_ctl/pg_ctl.c.orig	2015-02-02 21:44:39.000000000 +0100
748346
+++ postgresql-9.2.10/src/bin/pg_ctl/pg_ctl.c	2015-02-26 14:04:26.646801481 +0100
748346
@@ -561,7 +561,7 @@ test_postmaster_connection(bool do_check
7686b4
 						hostaddr = optlines[LOCK_FILE_LINE_LISTEN_ADDR - 1];
7686b4
 
7686b4
 						/*
7686b4
-						 * While unix_socket_directory can accept relative
7686b4
+						 * While unix_socket_directories can accept relative
7686b4
 						 * directories, libpq's host parameter must have a
7686b4
 						 * leading slash to indicate a socket directory.  So,
7686b4
 						 * ignore sockdir if it's relative, and try to use TCP
748346
diff -up postgresql-9.2.10/src/include/libpq/libpq.h.orig postgresql-9.2.10/src/include/libpq/libpq.h
748346
--- postgresql-9.2.10/src/include/libpq/libpq.h.orig	2015-02-02 21:44:39.000000000 +0100
748346
+++ postgresql-9.2.10/src/include/libpq/libpq.h	2015-02-26 14:04:26.647801491 +0100
748346
@@ -44,12 +44,12 @@ typedef struct
7686b4
 /*
7686b4
  * prototypes for functions in pqcomm.c
7686b4
  */
7686b4
-extern int StreamServerPort(int family, char *hostName,
7686b4
-	unsigned short portNumber, char *unixSocketName, pgsocket ListenSocket[],
7686b4
-				 int MaxListen);
7686b4
+extern int	StreamServerPort(int family, char *hostName,
7686b4
+				 unsigned short portNumber, char *unixSocketDir,
7686b4
+				 pgsocket ListenSocket[], int MaxListen);
7686b4
 extern int	StreamConnection(pgsocket server_fd, Port *port);
7686b4
 extern void StreamClose(pgsocket sock);
7686b4
-extern void TouchSocketFile(void);
7686b4
+extern void TouchSocketFiles(void);
7686b4
 extern void pq_init(void);
7686b4
 extern void pq_comm_reset(void);
7686b4
 extern int	pq_getbytes(char *s, size_t len);
748346
diff -up postgresql-9.2.10/src/include/miscadmin.h.orig postgresql-9.2.10/src/include/miscadmin.h
748346
--- postgresql-9.2.10/src/include/miscadmin.h.orig	2015-02-02 21:44:39.000000000 +0100
748346
+++ postgresql-9.2.10/src/include/miscadmin.h	2015-02-26 14:04:26.647801491 +0100
748346
@@ -424,7 +424,7 @@ extern char *local_preload_libraries_str
7686b4
  *		2	data directory path
7686b4
  *		3	postmaster start timestamp (time_t representation)
7686b4
  *		4	port number
7686b4
- *		5	socket directory path (empty on Windows)
7686b4
+ *		5	first Unix socket directory path (empty if none)
7686b4
  *		6	first listen_address (IP address or "*"; empty if no TCP port)
7686b4
  *		7	shared memory key (not present on Windows)
7686b4
  *
748346
@@ -442,8 +442,9 @@ extern char *local_preload_libraries_str
7686b4
 #define LOCK_FILE_LINE_SHMEM_KEY	7
7686b4
 
7686b4
 extern void CreateDataDirLockFile(bool amPostmaster);
7686b4
-extern void CreateSocketLockFile(const char *socketfile, bool amPostmaster);
7686b4
-extern void TouchSocketLockFile(void);
7686b4
+extern void CreateSocketLockFile(const char *socketfile, bool amPostmaster,
7686b4
+					 const char *socketDir);
7686b4
+extern void TouchSocketLockFiles(void);
7686b4
 extern void AddToDataDirLockFile(int target_line, const char *str);
7686b4
 extern void ValidatePgVersion(const char *path);
7686b4
 extern void process_shared_preload_libraries(void);
748346
diff -up postgresql-9.2.10/src/include/postmaster/postmaster.h.orig postgresql-9.2.10/src/include/postmaster/postmaster.h
748346
--- postgresql-9.2.10/src/include/postmaster/postmaster.h.orig	2015-02-02 21:44:39.000000000 +0100
748346
+++ postgresql-9.2.10/src/include/postmaster/postmaster.h	2015-02-26 14:04:26.648801500 +0100
748346
@@ -19,7 +19,7 @@ extern int	ReservedBackends;
7686b4
 extern int	PostPortNumber;
7686b4
 extern int	Unix_socket_permissions;
7686b4
 extern char *Unix_socket_group;
7686b4
-extern char *UnixSocketDir;
7686b4
+extern char *Unix_socket_directories;
7686b4
 extern char *ListenAddresses;
7686b4
 extern bool ClientAuthInProgress;
7686b4
 extern int	PreAuthDelay;
748346
diff -up postgresql-9.2.10/src/include/utils/builtins.h.orig postgresql-9.2.10/src/include/utils/builtins.h
748346
--- postgresql-9.2.10/src/include/utils/builtins.h.orig	2015-02-02 21:44:39.000000000 +0100
748346
+++ postgresql-9.2.10/src/include/utils/builtins.h	2015-02-26 14:04:26.649801510 +0100
748346
@@ -754,6 +754,8 @@ extern int	varstr_cmp(char *arg1, int le
7686b4
 extern List *textToQualifiedNameList(text *textval);
7686b4
 extern bool SplitIdentifierString(char *rawstring, char separator,
7686b4
 					  List **namelist);
7686b4
+extern bool SplitDirectoriesString(char *rawstring, char separator,
7686b4
+					   List **namelist);
7686b4
 extern Datum replace_text(PG_FUNCTION_ARGS);
7686b4
 extern text *replace_text_regexp(text *src_text, void *regexp,
7686b4
 					text *replace_text, bool glob);
748346
diff -up postgresql-9.2.10/doc/src/sgml/html-stamp.orig postgresql-9.2.10/doc/src/sgml/html-stamp
748346
--- postgresql-9.2.10/doc/src/sgml/html-stamp.orig	2015-02-02 22:00:12.000000000 +0100
748346
+++ postgresql-9.2.10/doc/src/sgml/html-stamp	2015-02-26 14:04:26.649801510 +0100
7686b4
@@ -0,0 +1 @@
7686b4
+hack
748346
diff -up postgresql-9.2.10/doc/src/sgml/man-stamp.orig postgresql-9.2.10/doc/src/sgml/man-stamp
748346
--- postgresql-9.2.10/doc/src/sgml/man-stamp.orig	2015-02-02 22:01:15.000000000 +0100
748346
+++ postgresql-9.2.10/doc/src/sgml/man-stamp	2015-02-26 14:04:26.650801520 +0100
7686b4
@@ -0,0 +1 @@
7686b4
+hack