]> granicus.if.org Git - postgresql/commitdiff
Make pg_ctl status do a kill() test to verify that the PID found in
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 20 Apr 2005 23:10:16 +0000 (23:10 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 20 Apr 2005 23:10:16 +0000 (23:10 +0000)
postmaster.pid still represents a live postmaster.

src/bin/pg_ctl/pg_ctl.c

index a73ddffd323d3f6f56ea32c3cd4a97910cc7abd6..3fc0883678333d6ecbdecf6b2757d3b583fa8f17 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/bin/pg_ctl/pg_ctl.c,v 1.55 2005/03/11 17:20:33 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_ctl/pg_ctl.c,v 1.56 2005/04/20 23:10:16 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -236,7 +236,7 @@ static pgpid_t
 get_pgpid(void)
 {
        FILE       *pidf;
-       pgpid_t         pid;
+       long            pid;
 
        pidf = fopen(pid_file, "r");
        if (pidf == NULL)
@@ -246,14 +246,19 @@ get_pgpid(void)
                        return 0;
                else
                {
-                       write_stderr(_("%s: could not open PID file \"%s\": %s"),
+                       write_stderr(_("%s: could not open PID file \"%s\": %s\n"),
                                                 progname, pid_file, strerror(errno));
                        exit(1);
                }
        }
-       fscanf(pidf, "%ld", &pid);
+       if (fscanf(pidf, "%ld", &pid) != 1)
+       {
+               write_stderr(_("%s: invalid data in PID file \"%s\"\n"),
+                                        progname, pid_file);
+               exit(1);
+       }
        fclose(pidf);
-       return pid;
+       return (pgpid_t) pid;
 }
 
 
@@ -766,34 +771,67 @@ do_reload(void)
  *     utility routines
  */
 
+static bool
+postmaster_is_alive(pid_t pid)
+{
+       /*
+        * Test to see if the process is still there.  Note that we do not
+        * consider an EPERM failure to mean that the process is still there;
+        * EPERM must mean that the given PID belongs to some other userid,
+        * and considering the permissions on $PGDATA, that means it's not
+        * the postmaster we are after.
+        *
+        * Don't believe that our own PID or parent shell's PID is the postmaster,
+        * either.  (Windows hasn't got getppid(), though.)
+        */
+       if (pid == getpid())
+               return false;
+#ifndef WIN32
+       if (pid == getppid())
+               return false;
+#endif
+       if (kill(pid, 0) == 0)
+               return true;
+       return false;
+}
+
 static void
 do_status(void)
 {
        pgpid_t         pid;
 
        pid = get_pgpid();
-       if (pid == 0)                           /* no pid file */
-       {
-               printf(_("%s: neither postmaster nor postgres running\n"), progname);
-               exit(1);
-       }
-       else if (pid < 0)                       /* standalone backend */
-       {
-               pid = -pid;
-               printf(_("%s: a standalone backend \"postgres\" is running (PID: %ld)\n"), progname, pid);
-       }
-       else
-       /* postmaster */
+       if (pid != 0)                           /* 0 means no pid file */
        {
-               char      **optlines;
+               if (pid < 0)                    /* standalone backend */
+               {
+                       pid = -pid;
+                       if (postmaster_is_alive((pid_t) pid))
+                       {
+                               printf(_("%s: a standalone backend \"postgres\" is running (PID: %ld)\n"),
+                                          progname, pid);
+                               return;
+                       }
+               }
+               else                                    /* postmaster */
+               {
+                       if (postmaster_is_alive((pid_t) pid))
+                       {
+                               char      **optlines;
 
-               printf(_("%s: postmaster is running (PID: %ld)\n"), progname, pid);
+                               printf(_("%s: postmaster is running (PID: %ld)\n"),
+                                          progname, pid);
 
-               optlines = readfile(postopts_file);
-               if (optlines != NULL)
-                       for (; *optlines != NULL; optlines++)
-                               fputs(*optlines, stdout);
+                               optlines = readfile(postopts_file);
+                               if (optlines != NULL)
+                                       for (; *optlines != NULL; optlines++)
+                                               fputs(*optlines, stdout);
+                               return;
+                       }
+               }
        }
+       printf(_("%s: neither postmaster nor postgres running\n"), progname);
+       exit(1);
 }