@@ -106,6 +106,7 @@ static char promote_file[MAXPGPATH];
106106static char logrotate_file [MAXPGPATH ];
107107
108108static volatile pgpid_t postmasterPID = -1 ;
109+ static pgpid_t old_postmaster_pid = 0 ;
109110
110111#ifdef WIN32
111112static DWORD pgctl_start_type = SERVICE_AUTO_START ;
@@ -490,16 +491,17 @@ start_postmaster(void)
490491
491492 /*
492493 * Since there might be quotes to handle here, it is easier simply to pass
493- * everything to a shell to process them. Use exec so that the postmaster
494- * has the same PID as the current child process.
494+ * everything to a shell to process them.
495+ *
496+ * Since we aren't telling the shell to directly exec the postmaster,
497+ * the returned PID is a parent process, the same as on Windows.
495498 */
496499 if (log_file != NULL )
497- snprintf (cmd , MAXPGPATH , "exec \"%s\" %s%s < \"%s\" >> \"%s\" 2>&1" ,
498- exec_path , pgdata_opt , post_opts ,
499- DEVNULL , log_file );
500+ snprintf (cmd , MAXPGPATH , "exec < \"%s\" >> \"%s\" 2>&1; \"%s\" %s%s; echo postmaster exit status is $?" ,
501+ DEVNULL , log_file , exec_path , pgdata_opt , post_opts );
500502 else
501- snprintf (cmd , MAXPGPATH , "exec \"%s\" %s%s < \"%s\" 2>&1 " ,
502- exec_path , pgdata_opt , post_opts , DEVNULL );
503+ snprintf (cmd , MAXPGPATH , "exec < \"%s\" 2>&1; \"%s\" %s%s; echo postmaster exit status is $? " ,
504+ DEVNULL , exec_path , pgdata_opt , post_opts );
503505
504506 (void ) execl ("/bin/sh" , "/bin/sh" , "-c" , cmd , (char * ) NULL );
505507
@@ -586,12 +588,8 @@ wait_for_postmaster(pgpid_t pm_pid, bool do_checkpoint)
586588 pmpid = atol (optlines [LOCK_FILE_LINE_PID - 1 ]);
587589 pmstart = atol (optlines [LOCK_FILE_LINE_START_TIME - 1 ]);
588590 if (pmstart >= start_time - 2 &&
589- #ifndef WIN32
590- pmpid == pm_pid
591- #else
592- /* Windows can only reject standalone-backend PIDs */
593- pmpid > 0
594- #endif
591+ /* If pid is the value we saw before starting, assume it's stale */
592+ pmpid > 0 && pmpid != old_postmaster_pid
595593 )
596594 {
597595 /*
@@ -621,7 +619,7 @@ wait_for_postmaster(pgpid_t pm_pid, bool do_checkpoint)
621619 * Check whether the child postmaster process is still alive. This
622620 * lets us exit early if the postmaster fails during startup.
623621 *
624- * On Windows, we may be checking the postmaster's parent shell, but
622+ * We may be checking the postmaster's parent shell, but
625623 * that's fine for this purpose.
626624 */
627625#ifndef WIN32
@@ -823,13 +821,12 @@ do_init(void)
823821static void
824822do_start (void )
825823{
826- pgpid_t old_pid = 0 ;
827824 pgpid_t pm_pid ;
828825
829826 if (ctl_command != RESTART_COMMAND )
830827 {
831- old_pid = get_pgpid (false);
832- if (old_pid != 0 )
828+ old_postmaster_pid = get_pgpid (false);
829+ if (old_postmaster_pid != 0 )
833830 write_stderr (_ ("%s: another server might be running; "
834831 "trying to start server anyway\n" ),
835832 progname );
0 commit comments