42
42
* StreamServerPort - Open postmaster's server port
43
43
* StreamConnection - Create new connection with client
44
44
* StreamClose - Close a client/backend connection
45
- * TouchSocketFile - Protect socket file against /tmp cleaners
45
+ * TouchSocketFiles - Protect socket files against /tmp cleaners
46
46
* pq_init - initialize libpq at backend startup
47
47
* pq_comm_reset - reset libpq during error recovery
48
48
* pq_close - shutdown libpq at backend exit
@@ -103,8 +103,8 @@ int Unix_socket_permissions;
103
103
char * Unix_socket_group ;
104
104
105
105
106
- /* Where the Unix socket file is */
107
- static char sock_path [ MAXPGPATH ] ;
106
+ /* Where the Unix socket files are (list of palloc'd strings) */
107
+ static List * sock_paths = NIL ;
108
108
109
109
110
110
/*
@@ -140,8 +140,8 @@ static int internal_flush(void);
140
140
static void pq_set_nonblocking (bool nonblocking );
141
141
142
142
#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 );
145
145
#endif /* HAVE_UNIX_SOCKETS */
146
146
147
147
@@ -234,29 +234,43 @@ pq_close(int code, Datum arg)
234
234
235
235
/* StreamDoUnlink()
236
236
* Shutdown routine for backend connection
237
- * If a Unix socket is used for communication, explicitly close it .
237
+ * If any Unix sockets are used for communication, explicitly close them .
238
238
*/
239
239
#ifdef HAVE_UNIX_SOCKETS
240
240
static void
241
241
StreamDoUnlink (int code , Datum arg )
242
242
{
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 ;
245
254
}
246
255
#endif /* HAVE_UNIX_SOCKETS */
247
256
248
257
/*
249
258
* StreamServerPort -- open a "listening" port to accept connections.
250
259
*
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.
253
267
*
254
268
* RETURNS: STATUS_OK or STATUS_ERROR
255
269
*/
256
270
257
271
int
258
272
StreamServerPort (int family , char * hostName , unsigned short portNumber ,
259
- char * unixSocketName ,
273
+ char * unixSocketDir ,
260
274
pgsocket ListenSocket [], int MaxListen )
261
275
{
262
276
pgsocket fd ;
@@ -273,6 +287,9 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
273
287
int listen_index = 0 ;
274
288
int added = 0 ;
275
289
290
+ #ifdef HAVE_UNIX_SOCKETS
291
+ char unixSocketPath [MAXPGPATH ];
292
+ #endif
276
293
#if !defined(WIN32 ) || defined(IPV6_V6ONLY )
277
294
int one = 1 ;
278
295
#endif
@@ -286,10 +303,14 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
286
303
#ifdef HAVE_UNIX_SOCKETS
287
304
if (family == AF_UNIX )
288
305
{
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 )
291
312
return STATUS_ERROR ;
292
- service = sock_path ;
313
+ service = unixSocketPath ;
293
314
}
294
315
else
295
316
#endif /* HAVE_UNIX_SOCKETS */
@@ -432,7 +453,7 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
432
453
(IS_AF_UNIX (addr -> ai_family )) ?
433
454
errhint ("Is another postmaster already running on port %d?"
434
455
" If not, remove socket file \"%s\" and retry." ,
435
- (int ) portNumber , sock_path ) :
456
+ (int ) portNumber , service ) :
436
457
errhint ("Is another postmaster already running on port %d?"
437
458
" If not, wait a few seconds and retry." ,
438
459
(int ) portNumber )));
@@ -443,7 +464,7 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
443
464
#ifdef HAVE_UNIX_SOCKETS
444
465
if (addr -> ai_family == AF_UNIX )
445
466
{
446
- if (Setup_AF_UNIX () != STATUS_OK )
467
+ if (Setup_AF_UNIX (service ) != STATUS_OK )
447
468
{
448
469
closesocket (fd );
449
470
break ;
@@ -490,10 +511,8 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
490
511
* Lock_AF_UNIX -- configure unix socket file path
491
512
*/
492
513
static int
493
- Lock_AF_UNIX (unsigned short portNumber , char * unixSocketName )
514
+ Lock_AF_UNIX (char * unixSocketDir , char * unixSocketPath )
494
515
{
495
- UNIXSOCK_PATH (sock_path , portNumber , unixSocketName );
496
-
497
516
/*
498
517
* Grab an interlock file associated with the socket file.
499
518
*
@@ -502,13 +521,23 @@ Lock_AF_UNIX(unsigned short portNumber, char *unixSocketName)
502
521
* more portable, and second, it lets us remove any pre-existing socket
503
522
* file without race conditions.
504
523
*/
505
- CreateSocketLockFile (sock_path , true);
524
+ CreateSocketLockFile (unixSocketPath , true, unixSocketDir );
506
525
507
526
/*
508
527
* Once we have the interlock, we can safely delete any pre-existing
509
528
* socket file to avoid failure at bind() time.
510
529
*/
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 ));
512
541
513
542
return STATUS_OK ;
514
543
}
@@ -518,11 +547,8 @@ Lock_AF_UNIX(unsigned short portNumber, char *unixSocketName)
518
547
* Setup_AF_UNIX -- configure unix socket permissions
519
548
*/
520
549
static int
521
- Setup_AF_UNIX (void )
550
+ Setup_AF_UNIX (char * sock_path )
522
551
{
523
- /* Arrange to unlink the socket file at exit */
524
- on_proc_exit (StreamDoUnlink , 0 );
525
-
526
552
/*
527
553
* Fix socket ownership/permission if requested. Note we must do this
528
554
* before we listen() to avoid a window where unwanted connections could
@@ -704,20 +730,24 @@ StreamClose(pgsocket sock)
704
730
}
705
731
706
732
/*
707
- * TouchSocketFile -- mark socket file as recently accessed
733
+ * TouchSocketFiles -- mark socket files as recently accessed
708
734
*
709
735
* 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 saves it from being removed by
736
+ * files have a recent mod date (ordinary operations on sockets usually won't
737
+ * change the mod date). That saves them from being removed by
712
738
* overenthusiastic /tmp-directory-cleaner daemons. (Another reason we should
713
739
* never have put the socket file in /tmp...)
714
740
*/
715
741
void
716
- TouchSocketFile (void )
742
+ TouchSocketFiles (void )
717
743
{
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 )
720
748
{
749
+ char * sock_path = (char * ) lfirst (l );
750
+
721
751
/*
722
752
* utime() is POSIX standard, utimes() is a common alternative. If we
723
753
* have neither, there's no way to affect the mod or access time of
0 commit comments