diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c index eac4e771ab..a3fd002ac4 100644 --- a/src/bin/pg_ctl/pg_ctl.c +++ b/src/bin/pg_ctl/pg_ctl.c @@ -106,7 +106,6 @@ static char promote_file[MAXPGPATH]; static char logrotate_file[MAXPGPATH]; static volatile pgpid_t postmasterPID = -1; -static pgpid_t old_postmaster_pid = 0; #ifdef WIN32 static DWORD pgctl_start_type = SERVICE_AUTO_START; @@ -486,17 +485,16 @@ start_postmaster(void) /* * Since there might be quotes to handle here, it is easier simply to pass - * everything to a shell to process them. - * - * Since we aren't telling the shell to directly exec the postmaster, - * the returned PID is a parent process, the same as on Windows. + * everything to a shell to process them. Use exec so that the postmaster + * has the same PID as the current child process. */ if (log_file != NULL) - snprintf(cmd, MAXPGPATH, "exec < \"%s\" >> \"%s\" 2>&1; \"%s\" %s%s; echo postmaster exit status is $?", - DEVNULL, log_file, exec_path, pgdata_opt, post_opts); + snprintf(cmd, MAXPGPATH, "exec \"%s\" %s%s < \"%s\" >> \"%s\" 2>&1", + exec_path, pgdata_opt, post_opts, + DEVNULL, log_file); else - snprintf(cmd, MAXPGPATH, "exec < \"%s\" 2>&1; \"%s\" %s%s; echo postmaster exit status is $?", - DEVNULL, exec_path, pgdata_opt, post_opts); + snprintf(cmd, MAXPGPATH, "exec \"%s\" %s%s < \"%s\" 2>&1", + exec_path, pgdata_opt, post_opts, DEVNULL); (void) execl("/bin/sh", "/bin/sh", "-c", cmd, (char *) NULL); @@ -583,8 +581,12 @@ wait_for_postmaster(pgpid_t pm_pid, bool do_checkpoint) pmpid = atol(optlines[LOCK_FILE_LINE_PID - 1]); pmstart = atol(optlines[LOCK_FILE_LINE_START_TIME - 1]); if (pmstart >= start_time - 2 && - /* If pid is the value we saw before starting, assume it's stale */ - pmpid > 0 && pmpid != old_postmaster_pid +#ifndef WIN32 + pmpid == pm_pid +#else + /* Windows can only reject standalone-backend PIDs */ + pmpid > 0 +#endif ) { /* @@ -614,7 +616,7 @@ wait_for_postmaster(pgpid_t pm_pid, bool do_checkpoint) * Check whether the child postmaster process is still alive. This * lets us exit early if the postmaster fails during startup. * - * We may be checking the postmaster's parent shell, but + * On Windows, we may be checking the postmaster's parent shell, but * that's fine for this purpose. */ #ifndef WIN32 @@ -816,12 +818,13 @@ do_init(void) static void do_start(void) { + pgpid_t old_pid = 0; pgpid_t pm_pid; if (ctl_command != RESTART_COMMAND) { - old_postmaster_pid = get_pgpid(false); - if (old_postmaster_pid != 0) + old_pid = get_pgpid(false); + if (old_pid != 0) write_stderr(_("%s: another server might be running; " "trying to start server anyway\n"), progname);