From 0682db975f1e715e727d2acfe335fec81e44811a Mon Sep 17 00:00:00 2001 From: "kuroda.hayato%40jp.fujitsu.com" Date: Tue, 1 Nov 2022 09:13:20 +0000 Subject: [PATCH v18 1/3] Add PQConncheck to libpq This new libpq function allows to check the status of socket by polling the socket. This function is currently available only on systems that support the non-standard POLLRDHUP extension to the poll system call, including Linux. --- doc/src/sgml/libpq.sgml | 24 +++++++++++++++++++ src/interfaces/libpq/exports.txt | 1 + src/interfaces/libpq/fe-misc.c | 41 ++++++++++++++++++++++++++++++++ src/interfaces/libpq/libpq-fe.h | 3 +++ 4 files changed, 69 insertions(+) diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml index 3c9bd3d673..99ef0f61a4 100644 --- a/doc/src/sgml/libpq.sgml +++ b/doc/src/sgml/libpq.sgml @@ -2679,6 +2679,30 @@ void *PQgetssl(const PGconn *conn); + + PQConncheckPQConncheck + + + Returns the status of the socket. + + +int PQConncheck(PGconn *conn); + + + + + Unlike , this function checks socket + health. This check is performed by polling the socket. This function is + currently available only on systems that support the non-standard + POLLRDHUP extension to the poll system + call, including Linux. returns 1 + if the remote peer seems to be closed, returns 0 if + the socket is valid, and returns -1 if the connection + has been already invalid. + + + + diff --git a/src/interfaces/libpq/exports.txt b/src/interfaces/libpq/exports.txt index e8bcc88370..3c4f946b51 100644 --- a/src/interfaces/libpq/exports.txt +++ b/src/interfaces/libpq/exports.txt @@ -186,3 +186,4 @@ PQpipelineStatus 183 PQsetTraceFlags 184 PQmblenBounded 185 PQsendFlushRequest 186 +PQConncheck 187 diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c index 795500c593..6502adcc09 100644 --- a/src/interfaces/libpq/fe-misc.c +++ b/src/interfaces/libpq/fe-misc.c @@ -1224,6 +1224,47 @@ PQenv2encoding(void) return encoding; } +/* + * Helper function for PQconncheck(). + * + * Return >0 if opposite side seems to be disconnected. + */ +static int +pqConncheck_internal(int sock) +{ +#if (defined(HAVE_POLL) && defined(POLLRDHUP)) + struct pollfd input_fd; + + input_fd.fd = sock; + input_fd.events = POLLRDHUP; + input_fd.revents = 0; + + poll(&input_fd, 1, 0); + + return input_fd.revents & POLLRDHUP; +#else + /* Do not support socket checking on this platform, return 0 */ + return 0; +#endif +} + +/* + * Check whether the socket peer closed connection or not. + * + * Returns >0 if remote peer seems to be closed, 0 if it is valid, + * -1 if the input connection is bad. + */ +int +PQConncheck(PGconn *conn) +{ + /* quick exit if invalid connection has come */ + if (conn == NULL || + conn->sock == PGINVALID_SOCKET || + conn->status != CONNECTION_OK) + return -1; + + return pqConncheck_internal(conn->sock); +} #ifdef ENABLE_NLS diff --git a/src/interfaces/libpq/libpq-fe.h b/src/interfaces/libpq/libpq-fe.h index b7df3224c0..8b2d78f3ef 100644 --- a/src/interfaces/libpq/libpq-fe.h +++ b/src/interfaces/libpq/libpq-fe.h @@ -648,6 +648,9 @@ extern int PQdsplen(const char *s, int encoding); /* Get encoding id from environment variable PGCLIENTENCODING */ extern int PQenv2encoding(void); +/* Check whether the postgres server is still alive or not */ +extern int PQConncheck(PGconn *conn); + /* === in fe-auth.c === */ extern char *PQencryptPassword(const char *passwd, const char *user); -- 2.27.0