Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
pg_receivewal, pg_recvlogical: allow canceling initial password prompt.
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 21 Nov 2021 19:13:35 +0000 (14:13 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 21 Nov 2021 19:13:35 +0000 (14:13 -0500)
Previously it was impossible to terminate these programs via control-C
while they were prompting for a password.  We can fix that trivially
for their initial password prompts, by moving setup of the SIGINT
handler from just before to just after their initial GetConnection()
calls.

This fix doesn't permit escaping out of later re-prompts, but those
should be exceedingly rare, since the user's password or the server's
authentication setup would have to have changed meanwhile.  We
considered applying a fix similar to commit 46d665bc2, but that
seemed more complicated than it'd be worth.  Moreover, this way is
back-patchable, which that wasn't.

The misbehavior exists in all supported versions, so back-patch to all.

Tom Lane and Nathan Bossart

Discussion: https://postgr.es/m/747443.1635536754@sss.pgh.pa.us

src/bin/pg_basebackup/pg_receivewal.c
src/bin/pg_basebackup/pg_recvlogical.c

index ed9d7f6378a57c963383b0366505d1d0707dc0c1..ac04dcd94455e57bbd868510327a0738a88c68b3 100644 (file)
@@ -684,10 +684,6 @@ main(int argc, char **argv)
        close_destination_dir(dir, basedir);
    }
 
-#ifndef WIN32
-   pqsignal(SIGINT, sigint_handler);
-#endif
-
    /*
     * Obtain a connection before doing anything.
     */
@@ -696,6 +692,14 @@ main(int argc, char **argv)
        /* error message already written in GetConnection() */
        exit(1);
 
+   /*
+    * Trap signals.  (Don't do this until after the initial password prompt,
+    * if one is needed, in GetConnection.)
+    */
+#ifndef WIN32
+   pqsignal(SIGINT, sigint_handler);
+#endif
+
    /*
     * Run IDENTIFY_SYSTEM to make sure we've successfully have established a
     * replication connection and haven't connected using a database specific
index f2fe4c55b2fd84ea74ac39be052c7732f61e1828..1f93907157d195c3d08939d6ce9279f6920f0982 100644 (file)
@@ -220,8 +220,6 @@ StreamLogicalLog(void)
    output_written_lsn = InvalidXLogRecPtr;
    output_fsync_lsn = InvalidXLogRecPtr;
 
-   query = createPQExpBuffer();
-
    /*
     * Connect in replication mode to the server
     */
@@ -241,6 +239,7 @@ StreamLogicalLog(void)
                replication_slot);
 
    /* Initiate the replication stream at specified location */
+   query = createPQExpBuffer();
    appendPQExpBuffer(query, "START_REPLICATION SLOT \"%s\" LOGICAL %X/%X",
                      replication_slot, (uint32) (startpos >> 32), (uint32) startpos);
 
@@ -956,21 +955,24 @@ main(int argc, char **argv)
        exit(1);
    }
 
-#ifndef WIN32
-   pqsignal(SIGINT, sigint_handler);
-   pqsignal(SIGHUP, sighup_handler);
-#endif
-
    /*
-    * Obtain a connection to server. This is not really necessary but it
-    * helps to get more precise error messages about authentication, required
-    * GUC parameters and such.
+    * Obtain a connection to server.  Notably, if we need a password, we want
+    * to collect it from the user immediately.
     */
    conn = GetConnection();
    if (!conn)
        /* Error message already written in GetConnection() */
        exit(1);
 
+   /*
+    * Trap signals.  (Don't do this until after the initial password prompt,
+    * if one is needed, in GetConnection.)
+    */
+#ifndef WIN32
+   pqsignal(SIGINT, sigint_handler);
+   pqsignal(SIGHUP, sighup_handler);
+#endif
+
    /*
     * Run IDENTIFY_SYSTEM to make sure we connected using a database specific
     * replication connection.