summaryrefslogtreecommitdiff
path: root/src/interfaces
diff options
context:
space:
mode:
authorBruce Momjian2010-11-25 18:09:38 +0000
committerBruce Momjian2010-11-25 18:09:38 +0000
commitafd7d9adca971d9aae97e87ce617d8608d25ab10 (patch)
tree645f9588fd502bfa649d33b1c9924ad9d01868a6 /src/interfaces
parent212a1c7b0b4164e15381af327ee6656ae7e02298 (diff)
Add PQping and PQpingParams to libpq to allow detection of the server's
status, including a status where the server is running but refuses a postgres connection. Have pg_ctl use this new function. This fixes the case where pg_ctl reports that the server is not running (cannot connect) but in fact it is running.
Diffstat (limited to 'src/interfaces')
-rw-r--r--src/interfaces/libpq/exports.txt2
-rw-r--r--src/interfaces/libpq/fe-connect.c53
-rw-r--r--src/interfaces/libpq/libpq-fe.h10
3 files changed, 65 insertions, 0 deletions
diff --git a/src/interfaces/libpq/exports.txt b/src/interfaces/libpq/exports.txt
index ecbd54c8815..a6c73af52e8 100644
--- a/src/interfaces/libpq/exports.txt
+++ b/src/interfaces/libpq/exports.txt
@@ -157,3 +157,5 @@ PQescapeLiteral 154
PQescapeIdentifier 155
PQconnectdbParams 156
PQconnectStartParams 157
+PQping 158
+PQpingParams 159
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 8011604e5cd..6593f21d55e 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -285,6 +285,7 @@ static bool connectOptions1(PGconn *conn, const char *conninfo);
static bool connectOptions2(PGconn *conn);
static int connectDBStart(PGconn *conn);
static int connectDBComplete(PGconn *conn);
+static PGPing internal_ping(PGconn *conn);
static PGconn *makeEmptyPGconn(void);
static void fillPGconn(PGconn *conn, PQconninfoOption *connOptions);
static void freePGconn(PGconn *conn);
@@ -375,6 +376,20 @@ PQconnectdbParams(const char **keywords,
}
+PGPing
+PQpingParams(const char **keywords,
+ const char **values,
+ int expand_dbname)
+{
+ PGconn *conn = PQconnectStartParams(keywords, values, expand_dbname);
+ PGPing ret;
+
+ ret = internal_ping(conn);
+ PQfinish(conn);
+
+ return ret;
+}
+
/*
* PQconnectdb
*
@@ -408,6 +423,18 @@ PQconnectdb(const char *conninfo)
return conn;
}
+PGPing
+PQping(const char *conninfo)
+{
+ PGconn *conn = PQconnectStart(conninfo);
+ PGPing ret;
+
+ ret = internal_ping(conn);
+ PQfinish(conn);
+
+ return ret;
+}
+
/*
* PQconnectStartParams
*
@@ -2514,6 +2541,32 @@ error_return:
/*
+ * internal_ping
+ * Determine if a server is running and if we can connect to it.
+ */
+PGPing
+internal_ping(PGconn *conn)
+{
+ if (conn && conn->status != CONNECTION_BAD)
+ {
+ (void) connectDBComplete(conn);
+
+ /*
+ * If the connection needs a password, we can consider the
+ * server as accepting connections.
+ */
+ if (conn && (conn->status != CONNECTION_BAD ||
+ PQconnectionNeedsPassword(conn)))
+ return PQACCESS;
+ else
+ return PQREJECT;
+ }
+ else
+ return PQNORESPONSE;
+}
+
+
+/*
* makeEmptyPGconn
* - create a PGconn data structure with (as yet) no interesting data
*/
diff --git a/src/interfaces/libpq/libpq-fe.h b/src/interfaces/libpq/libpq-fe.h
index 659d82d74d8..d1a6dd413a5 100644
--- a/src/interfaces/libpq/libpq-fe.h
+++ b/src/interfaces/libpq/libpq-fe.h
@@ -107,6 +107,13 @@ typedef enum
PQERRORS_VERBOSE /* all the facts, ma'am */
} PGVerbosity;
+typedef enum
+{
+ PQACCESS, /* connected to server */
+ PQREJECT, /* server rejected access */
+ PQNORESPONSE /* server did not respond */
+} PGPing;
+
/* PGconn encapsulates a connection to the backend.
* The contents of this struct are not supposed to be known to applications.
*/
@@ -403,6 +410,9 @@ extern int PQendcopy(PGconn *conn);
extern int PQsetnonblocking(PGconn *conn, int arg);
extern int PQisnonblocking(const PGconn *conn);
extern int PQisthreadsafe(void);
+extern PGPing PQping(const char *conninfo);
+extern PGPing PQpingParams(const char **keywords,
+ const char **values, int expand_dbname);
/* Force the write buffer to be written (or at least try) */
extern int PQflush(PGconn *conn);