2222
2323#include <locale.h>
2424#include <signal.h>
25+ #include <stdlib.h>
2526#include <sys/types.h>
2627#include <sys/stat.h>
2728#include <unistd.h>
@@ -138,6 +139,7 @@ static void read_post_opts(void);
138139
139140static PGPing test_postmaster_connection (bool );
140141static bool postmaster_is_alive (pid_t pid );
142+ static time_t start_time ;
141143
142144static char postopts_file [MAXPGPATH ];
143145static char pid_file [MAXPGPATH ];
@@ -404,13 +406,13 @@ static PGPing
404406test_postmaster_connection (bool do_checkpoint )
405407{
406408 int portnum = 0 ;
407- char socket_dir [MAXPGPATH ];
409+ char host_str [MAXPGPATH ];
408410 char connstr [MAXPGPATH + 256 ];
409411 PGPing ret = PQPING_OK ; /* assume success for wait == zero */
410412 char * * optlines ;
411413 int i ;
412414
413- socket_dir [0 ] = '\0' ;
415+ host_str [0 ] = '\0' ;
414416 connstr [0 ] = '\0' ;
415417
416418 for (i = 0 ; i < wait_seconds ; i ++ )
@@ -425,21 +427,25 @@ test_postmaster_connection(bool do_checkpoint)
425427 * 0 lock file created but status not written
426428 * 2 pre-9.1 server, shared memory not created
427429 * 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
430433 *
431434 * For pre-9.1 Unix servers, we grab the port number from the
432435 * 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.
435438 * (PG_VERSION could also have told us the major version.)
436439 */
437440
438441 /* Try to read a completed postmaster.pid file */
439442 if ((optlines = readfile (pid_file )) != NULL &&
440443 optlines [0 ] != NULL &&
441444 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 ))
443449 {
444450 /* A 3-line file? */
445451 if (optlines [3 ] == NULL )
@@ -459,41 +465,63 @@ test_postmaster_connection(bool do_checkpoint)
459465 return PQPING_NO_ATTEMPT ;
460466 }
461467 }
462- else /* 9.1+ server */
468+ else
463469 {
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 )
468478 {
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 ;
484482 }
485- }
483+
484+ portnum = atoi (optlines [3 ]);
486485
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+
487515 /*
488516 * We need to set connect_timeout otherwise on Windows the
489517 * Service Control Manager (SCM) will probably timeout first.
490518 */
491519 snprintf (connstr , sizeof (connstr ),
492520 "dbname=postgres port=%d connect_timeout=5" , portnum );
493521
494- if (socket_dir [0 ] != '\0' )
522+ if (host_str [0 ] != '\0' )
495523 snprintf (connstr + strlen (connstr ), sizeof (connstr ) - strlen (connstr ),
496- " host='%s'" , socket_dir );
524+ " host='%s'" , host_str );
497525 }
498526 }
499527
@@ -1756,6 +1784,7 @@ main(int argc, char **argv)
17561784
17571785 progname = get_progname (argv [0 ]);
17581786 set_pglocale_pgservice (argv [0 ], PG_TEXTDOMAIN ("pg_ctl" ));
1787+ start_time = time (NULL );
17591788
17601789 /*
17611790 * save argv[0] so do_start() can look for the postmaster if necessary. we
0 commit comments