22
22
23
23
#include <locale.h>
24
24
#include <signal.h>
25
+ #include <stdlib.h>
25
26
#include <sys/types.h>
26
27
#include <sys/stat.h>
27
28
#include <unistd.h>
@@ -138,6 +139,7 @@ static void read_post_opts(void);
138
139
139
140
static PGPing test_postmaster_connection (bool );
140
141
static bool postmaster_is_alive (pid_t pid );
142
+ static time_t start_time ;
141
143
142
144
static char postopts_file [MAXPGPATH ];
143
145
static char pid_file [MAXPGPATH ];
@@ -404,13 +406,13 @@ static PGPing
404
406
test_postmaster_connection (bool do_checkpoint )
405
407
{
406
408
int portnum = 0 ;
407
- char socket_dir [MAXPGPATH ];
409
+ char host_str [MAXPGPATH ];
408
410
char connstr [MAXPGPATH + 256 ];
409
411
PGPing ret = PQPING_OK ; /* assume success for wait == zero */
410
412
char * * optlines ;
411
413
int i ;
412
414
413
- socket_dir [0 ] = '\0' ;
415
+ host_str [0 ] = '\0' ;
414
416
connstr [0 ] = '\0' ;
415
417
416
418
for (i = 0 ; i < wait_seconds ; i ++ )
@@ -425,21 +427,25 @@ test_postmaster_connection(bool do_checkpoint)
425
427
* 0 lock file created but status not written
426
428
* 2 pre-9.1 server, shared memory not created
427
429
* 3 pre-9.1 server, shared memory created
428
- * 4 9.1+ server, shared memory not created
429
- * 5 9.1+ server, shared memory created
430
+ * 5 9.1+ server, listen host not created
431
+ * 6 9.1+ server, shared memory not created
432
+ * 7 9.1+ server, shared memory created
430
433
*
431
434
* For pre-9.1 Unix servers, we grab the port number from the
432
435
* shmem key (first value on line 3). Pre-9.1 Win32 has no
433
- * written shmem key, so we fail. 9.1+ writes both the port
434
- * number and socket address in the file for us to use.
436
+ * written shmem key, so we fail. 9.1+ writes connection
437
+ * information in the file for us to use.
435
438
* (PG_VERSION could also have told us the major version.)
436
439
*/
437
440
438
441
/* Try to read a completed postmaster.pid file */
439
442
if ((optlines = readfile (pid_file )) != NULL &&
440
443
optlines [0 ] != NULL &&
441
444
optlines [1 ] != NULL &&
442
- optlines [2 ] != NULL )
445
+ optlines [2 ] != NULL &&
446
+ /* pre-9.1 server or listen_address line is present? */
447
+ (optlines [3 ] == NULL ||
448
+ optlines [5 ] != NULL ))
443
449
{
444
450
/* A 3-line file? */
445
451
if (optlines [3 ] == NULL )
@@ -459,41 +465,63 @@ test_postmaster_connection(bool do_checkpoint)
459
465
return PQPING_NO_ATTEMPT ;
460
466
}
461
467
}
462
- else /* 9.1+ server */
468
+ else
463
469
{
464
- portnum = atoi (optlines [2 ]);
465
-
466
- /* Get socket directory, if specified. */
467
- if (optlines [3 ][0 ] != '\n' )
470
+ /*
471
+ * Easy check to see if we are looking at the right
472
+ * data directory: Is the postmaster older than this
473
+ * execution of pg_ctl? Subtract 2 seconds to account
474
+ * for possible clock skew between pg_ctl and the
475
+ * postmaster.
476
+ */
477
+ if (atol (optlines [1 ]) < start_time - 2 )
468
478
{
469
- /*
470
- * While unix_socket_directory can accept relative
471
- * directories, libpq's host must have a leading slash
472
- * to indicate a socket directory.
473
- */
474
- if (optlines [3 ][0 ] != '/' )
475
- {
476
- write_stderr (_ ("%s: -w option cannot use a relative socket directory specification\n" ),
477
- progname );
478
- return PQPING_NO_ATTEMPT ;
479
- }
480
- strlcpy (socket_dir , optlines [3 ], MAXPGPATH );
481
- /* remove newline */
482
- if (strchr (socket_dir , '\n' ) != NULL )
483
- * strchr (socket_dir , '\n' ) = '\0' ;
479
+ write_stderr (_ ("%s: this data directory is running an older postmaster\n" ),
480
+ progname );
481
+ return PQPING_NO_ATTEMPT ;
484
482
}
485
- }
483
+
484
+ portnum = atoi (optlines [3 ]);
486
485
486
+ /*
487
+ * Determine the proper host string to use.
488
+ */
489
+ #ifdef HAVE_UNIX_SOCKETS
490
+ /*
491
+ * Use socket directory, if specified. We assume if we
492
+ * have unix sockets, the server does too because we
493
+ * just started the postmaster.
494
+ */
495
+ /*
496
+ * While unix_socket_directory can accept relative
497
+ * directories, libpq's host must have a leading slash
498
+ * to indicate a socket directory.
499
+ */
500
+ if (optlines [4 ][0 ] != '\n' && optlines [4 ][0 ] != '/' )
501
+ {
502
+ write_stderr (_ ("%s: -w option cannot use a relative socket directory specification\n" ),
503
+ progname );
504
+ return PQPING_NO_ATTEMPT ;
505
+ }
506
+ strlcpy (host_str , optlines [4 ], sizeof (host_str ));
507
+ #else
508
+ strlcpy (host_str , optlines [5 ], sizeof (host_str ));
509
+ #endif
510
+ /* remove newline */
511
+ if (strchr (host_str , '\n' ) != NULL )
512
+ * strchr (host_str , '\n' ) = '\0' ;
513
+ }
514
+
487
515
/*
488
516
* We need to set connect_timeout otherwise on Windows the
489
517
* Service Control Manager (SCM) will probably timeout first.
490
518
*/
491
519
snprintf (connstr , sizeof (connstr ),
492
520
"dbname=postgres port=%d connect_timeout=5" , portnum );
493
521
494
- if (socket_dir [0 ] != '\0' )
522
+ if (host_str [0 ] != '\0' )
495
523
snprintf (connstr + strlen (connstr ), sizeof (connstr ) - strlen (connstr ),
496
- " host='%s'" , socket_dir );
524
+ " host='%s'" , host_str );
497
525
}
498
526
}
499
527
@@ -1756,6 +1784,7 @@ main(int argc, char **argv)
1756
1784
1757
1785
progname = get_progname (argv [0 ]);
1758
1786
set_pglocale_pgservice (argv [0 ], PG_TEXTDOMAIN ("pg_ctl" ));
1787
+ start_time = time (NULL );
1759
1788
1760
1789
/*
1761
1790
* save argv[0] so do_start() can look for the postmaster if necessary. we
0 commit comments