4242 *StreamServerPort- Open postmaster's server port
4343 *StreamConnection- Create new connection with client
4444 *StreamClose- Close a client/backend connection
45- *TouchSocketFile - Protect socketfile against /tmp cleaners
45+ *TouchSocketFiles - Protect socketfiles against /tmp cleaners
4646 *pq_init- initialize libpq at backend startup
4747 *pq_comm_reset- reset libpq during error recovery
4848 *pq_close- shutdown libpq at backend exit
@@ -103,8 +103,8 @@ intUnix_socket_permissions;
103103char * Unix_socket_group ;
104104
105105
106- /* Where the Unix socketfile is */
107- static char sock_path [ MAXPGPATH ] ;
106+ /* Where the Unix socketfiles are (list of palloc'd strings) */
107+ static List * sock_paths = NIL ;
108108
109109
110110/*
@@ -140,8 +140,8 @@ static intinternal_flush(void);
140140static void pq_set_nonblocking (bool nonblocking );
141141
142142#ifdef HAVE_UNIX_SOCKETS
143- static int Lock_AF_UNIX (unsigned short portNumber ,char * unixSocketName );
144- static int Setup_AF_UNIX (void );
143+ static int Lock_AF_UNIX (char * unixSocketDir ,char * unixSocketPath );
144+ static int Setup_AF_UNIX (char * sock_path );
145145#endif /* HAVE_UNIX_SOCKETS */
146146
147147
@@ -234,29 +234,43 @@ pq_close(int code, Datum arg)
234234
235235/* StreamDoUnlink()
236236 * Shutdown routine for backend connection
237- * Ifa Unixsocket is used for communication, explicitly closeit .
237+ * Ifany Unixsockets are used for communication, explicitly closethem .
238238 */
239239#ifdef HAVE_UNIX_SOCKETS
240240static void
241241StreamDoUnlink (int code ,Datum arg )
242242{
243- Assert (sock_path [0 ]);
244- unlink (sock_path );
243+ ListCell * l ;
244+
245+ /* Loop through all created sockets... */
246+ foreach (l ,sock_paths )
247+ {
248+ char * sock_path = (char * )lfirst (l );
249+
250+ unlink (sock_path );
251+ }
252+ /* Since we're about to exit, no need to reclaim storage */
253+ sock_paths = NIL ;
245254}
246255#endif /* HAVE_UNIX_SOCKETS */
247256
248257/*
249258 * StreamServerPort -- open a "listening" port to accept connections.
250259 *
251- * Successfully opened sockets are added to the ListenSocket[] array,
252- * at the first position that isn't PGINVALID_SOCKET.
260+ * family should be AF_UNIX or AF_UNSPEC; portNumber is the port number.
261+ * For AF_UNIX ports, hostName should be NULL and unixSocketDir must be
262+ * specified. For TCP ports, hostName is either NULL for all interfaces or
263+ * the interface to listen on, and unixSocketDir is ignored (can be NULL).
264+ *
265+ * Successfully opened sockets are added to the ListenSocket[] array (of
266+ * length MaxListen), at the first position that isn't PGINVALID_SOCKET.
253267 *
254268 * RETURNS: STATUS_OK or STATUS_ERROR
255269 */
256270
257271int
258272StreamServerPort (int family ,char * hostName ,unsigned short portNumber ,
259- char * unixSocketName ,
273+ char * unixSocketDir ,
260274pgsocket ListenSocket [],int MaxListen )
261275{
262276pgsocket fd ;
@@ -273,6 +287,9 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
273287int listen_index = 0 ;
274288int added = 0 ;
275289
290+ #ifdef HAVE_UNIX_SOCKETS
291+ char unixSocketPath [MAXPGPATH ];
292+ #endif
276293#if !defined(WIN32 )|| defined(IPV6_V6ONLY )
277294int one = 1 ;
278295#endif
@@ -286,10 +303,14 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
286303#ifdef HAVE_UNIX_SOCKETS
287304if (family == AF_UNIX )
288305{
289- /* Lock_AF_UNIX will also fill in sock_path. */
290- if (Lock_AF_UNIX (portNumber ,unixSocketName )!= STATUS_OK )
306+ /*
307+ * Create unixSocketPath from portNumber and unixSocketDir and lock
308+ * that file path
309+ */
310+ UNIXSOCK_PATH (unixSocketPath ,portNumber ,unixSocketDir );
311+ if (Lock_AF_UNIX (unixSocketDir ,unixSocketPath )!= STATUS_OK )
291312return STATUS_ERROR ;
292- service = sock_path ;
313+ service = unixSocketPath ;
293314}
294315else
295316#endif /* HAVE_UNIX_SOCKETS */
@@ -432,7 +453,7 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
432453 (IS_AF_UNIX (addr -> ai_family )) ?
433454errhint ("Is another postmaster already running on port %d?"
434455" If not, remove socket file \"%s\" and retry." ,
435- (int )portNumber ,sock_path ) :
456+ (int )portNumber ,service ) :
436457errhint ("Is another postmaster already running on port %d?"
437458" If not, wait a few seconds and retry." ,
438459 (int )portNumber )));
@@ -443,7 +464,7 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
443464#ifdef HAVE_UNIX_SOCKETS
444465if (addr -> ai_family == AF_UNIX )
445466{
446- if (Setup_AF_UNIX ()!= STATUS_OK )
467+ if (Setup_AF_UNIX (service )!= STATUS_OK )
447468{
448469closesocket (fd );
449470break ;
@@ -490,10 +511,8 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
490511 * Lock_AF_UNIX -- configure unix socket file path
491512 */
492513static int
493- Lock_AF_UNIX (unsigned short portNumber ,char * unixSocketName )
514+ Lock_AF_UNIX (char * unixSocketDir ,char * unixSocketPath )
494515{
495- UNIXSOCK_PATH (sock_path ,portNumber ,unixSocketName );
496-
497516/*
498517 * Grab an interlock file associated with the socket file.
499518 *
@@ -502,13 +521,23 @@ Lock_AF_UNIX(unsigned short portNumber, char *unixSocketName)
502521 * more portable, and second, it lets us remove any pre-existing socket
503522 * file without race conditions.
504523 */
505- CreateSocketLockFile (sock_path , true);
524+ CreateSocketLockFile (unixSocketPath , true, unixSocketDir );
506525
507526/*
508527 * Once we have the interlock, we can safely delete any pre-existing
509528 * socket file to avoid failure at bind() time.
510529 */
511- unlink (sock_path );
530+ unlink (unixSocketPath );
531+
532+ /*
533+ * Arrange to unlink the socket file(s) at proc_exit. If this is the
534+ * first one, set up the on_proc_exit function to do it; then add this
535+ * socket file to the list of files to unlink.
536+ */
537+ if (sock_paths == NIL )
538+ on_proc_exit (StreamDoUnlink ,0 );
539+
540+ sock_paths = lappend (sock_paths ,pstrdup (unixSocketPath ));
512541
513542return STATUS_OK ;
514543}
@@ -518,11 +547,8 @@ Lock_AF_UNIX(unsigned short portNumber, char *unixSocketName)
518547 * Setup_AF_UNIX -- configure unix socket permissions
519548 */
520549static int
521- Setup_AF_UNIX (void )
550+ Setup_AF_UNIX (char * sock_path )
522551{
523- /* Arrange to unlink the socket file at exit */
524- on_proc_exit (StreamDoUnlink ,0 );
525-
526552/*
527553 * Fix socket ownership/permission if requested. Note we must do this
528554 * before we listen() to avoid a window where unwanted connections could
@@ -704,20 +730,24 @@ StreamClose(pgsocket sock)
704730}
705731
706732/*
707- *TouchSocketFile -- mark socketfile as recently accessed
733+ *TouchSocketFiles -- mark socketfiles as recently accessed
708734 *
709735 * This routine should be called every so often to ensure that the socket
710- *file has a recent mod date (ordinary operations on sockets usually won't
711- * change the mod date). That savesit from being removed by
736+ *files have a recent mod date (ordinary operations on sockets usually won't
737+ * change the mod date). That savesthem from being removed by
712738 * overenthusiastic /tmp-directory-cleaner daemons. (Another reason we should
713739 * never have put the socket file in /tmp...)
714740 */
715741void
716- TouchSocketFile (void )
742+ TouchSocketFiles (void )
717743{
718- /* Do nothing if we did not create a socket... */
719- if (sock_path [0 ]!= '\0' )
744+ ListCell * l ;
745+
746+ /* Loop through all created sockets... */
747+ foreach (l ,sock_paths )
720748{
749+ char * sock_path = (char * )lfirst (l );
750+
721751/*
722752 * utime() is POSIX standard, utimes() is a common alternative. If we
723753 * have neither, there's no way to affect the mod or access time of