From 73a95bc537f205cdac567f3f1860b08cf8323e17 Mon Sep 17 00:00:00 2001 From: Tristan Partin Date: Mon, 24 Jul 2023 11:12:59 -0500 Subject: [PATCH v4] Allow SIGINT to cancel psql database reconnections After installing the SIGINT handler in psql, SIGINT can no longer cancel database reconnections. For instance, if the user starts a reconnection and then needs to do some form of interaction (ie psql is polling), there is no way to cancel the reconnection process currently. Use PQconnectStartParams() in order to insert a CancelRequested check into the polling loop. --- src/bin/psql/command.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 6733f008fd..bfecc25801 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -40,6 +40,7 @@ #include "large_obj.h" #include "libpq-fe.h" #include "libpq/pqcomm.h" +#include "libpq/pqsignal.h" #include "mainloop.h" #include "portability/instr_time.h" #include "pqexpbuffer.h" @@ -3577,11 +3578,33 @@ do_connect(enum trivalue reuse_previous_specification, values[paramnum] = NULL; /* Note we do not want libpq to re-expand the dbname parameter */ - n_conn = PQconnectdbParams(keywords, values, false); + n_conn = PQconnectStartParams(keywords, values, false); pg_free(keywords); pg_free(values); + while (true) { + int socket; + + if (CancelRequested) + break; + + socket = PQsocket(n_conn); + if (socket == -1) + break; + + switch (PQconnectPoll(n_conn)) { + case PGRES_POLLING_OK: + case PGRES_POLLING_FAILED: + break; + case PGRES_POLLING_READING: + case PGRES_POLLING_WRITING: + continue; + case PGRES_POLLING_ACTIVE: + pg_unreachable(); + } + } + if (PQstatus(n_conn) == CONNECTION_OK) break; -- Tristan Partin Neon (https://neon.tech)