diff --git a/doc/src/sgml/ref/pg_ctl-ref.sgml b/doc/src/sgml/ref/pg_ctl-ref.sgml index 45b53ce..99cb176 100644 --- a/doc/src/sgml/ref/pg_ctl-ref.sgml +++ b/doc/src/sgml/ref/pg_ctl-ref.sgml @@ -206,9 +206,10 @@ PostgreSQL documentation mode checks whether a server is running in the specified data directory. If it is, the PID - and the command line options that were used to invoke it are - displayed. If the server is not running, the process returns an - exit status of 3. + and the command line options that were used to invoke it are + displayed. If the server is not running, the process returns an + exit status of 3. If the specified data directory is not accessible, + the process returns an exit status of 4. diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c index 0dbaa6e..56d238f 100644 --- a/src/bin/pg_ctl/pg_ctl.c +++ b/src/bin/pg_ctl/pg_ctl.c @@ -97,6 +97,7 @@ static bool allow_core_files = false; static time_t start_time; static char postopts_file[MAXPGPATH]; +static char version_file[MAXPGPATH]; static char pid_file[MAXPGPATH]; static char backup_file[MAXPGPATH]; static char recovery_file[MAXPGPATH]; @@ -152,7 +153,7 @@ static void pgwin32_doRunAsService(void); static int CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, bool as_service); #endif -static pgpid_t get_pgpid(void); +static pgpid_t get_pgpid(bool is_status_request); static char **readfile(const char *path); static void free_readfile(char **optlines); static int start_postmaster(void); @@ -246,10 +247,34 @@ print_msg(const char *msg) } static pgpid_t -get_pgpid(void) +get_pgpid(bool is_status_request) { FILE *pidf; long pid; + struct stat statbuf; + + if (stat(pg_data, &statbuf) != 0) + { + if (errno == ENOENT) + printf(_("%s: directory \"%s\" does not exist\n"), progname, + pg_data); + else + printf(_("%s: cannot access directory \"%s\"\n"), progname, + pg_data); + /* + * The Linux Standard Base Core Specification 3.1 says this should return + * '4, program or service status is unknown' + * https://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html + */ + exit(is_status_request ? 4 : 1); + } + + if (stat(version_file, &statbuf) != 0 && errno == ENOENT) + { + printf(_("%s: directory \"%s\" is not a database cluster directory\n"), + progname, pg_data); + exit(is_status_request ? 4 : 1); + } pidf = fopen(pid_file, "r"); if (pidf == NULL) @@ -810,7 +835,7 @@ do_start(void) if (ctl_command != RESTART_COMMAND) { - old_pid = get_pgpid(); + old_pid = get_pgpid(false); if (old_pid != 0) write_stderr(_("%s: another server might be running; " "trying to start server anyway\n"), @@ -894,7 +919,7 @@ do_stop(void) pgpid_t pid; struct stat statbuf; - pid = get_pgpid(); + pid = get_pgpid(false); if (pid == 0) /* no pid file */ { @@ -943,7 +968,7 @@ do_stop(void) for (cnt = 0; cnt < wait_seconds; cnt++) { - if ((pid = get_pgpid()) != 0) + if ((pid = get_pgpid(false)) != 0) { print_msg("."); pg_usleep(1000000); /* 1 sec */ @@ -980,7 +1005,7 @@ do_restart(void) pgpid_t pid; struct stat statbuf; - pid = get_pgpid(); + pid = get_pgpid(false); if (pid == 0) /* no pid file */ { @@ -1033,7 +1058,7 @@ do_restart(void) for (cnt = 0; cnt < wait_seconds; cnt++) { - if ((pid = get_pgpid()) != 0) + if ((pid = get_pgpid(false)) != 0) { print_msg("."); pg_usleep(1000000); /* 1 sec */ @@ -1071,7 +1096,7 @@ do_reload(void) { pgpid_t pid; - pid = get_pgpid(); + pid = get_pgpid(false); if (pid == 0) /* no pid file */ { write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file); @@ -1110,7 +1135,7 @@ do_promote(void) pgpid_t pid; struct stat statbuf; - pid = get_pgpid(); + pid = get_pgpid(false); if (pid == 0) /* no pid file */ { @@ -1204,7 +1229,7 @@ do_status(void) { pgpid_t pid; - pid = get_pgpid(); + pid = get_pgpid(true); /* Is there a pid file? */ if (pid != 0) { @@ -1247,7 +1272,7 @@ do_status(void) /* * The Linux Standard Base Core Specification 3.1 says this should return - * '3' + * '3, program is not running' * https://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html */ exit(3); @@ -2285,6 +2310,7 @@ main(int argc, char **argv) if (pg_data) { snprintf(postopts_file, MAXPGPATH, "%s/postmaster.opts", pg_data); + snprintf(version_file, MAXPGPATH, "%s/PG_VERSION", pg_data); snprintf(pid_file, MAXPGPATH, "%s/postmaster.pid", pg_data); snprintf(backup_file, MAXPGPATH, "%s/backup_label", pg_data); snprintf(recovery_file, MAXPGPATH, "%s/recovery.conf", pg_data);