From 6fc445954b8d2e64613124cef6583fc96aa617f9 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 4 Jul 2026 17:21:50 +1200
Subject: [PATCH v1 10/14] pg_dump: Block signals during signal handler.

Previously we tried to avoid running the cancellation handler more than
once by setting SIGINT, SIGQUIT, SIGTERM to SIG_IGN at the top of the
handler.  Let's just block them with sa_mask, to achieve the same thing
without races.

While it's unlikely that repeated cancellation would really be a
problem, and PQcancel() surely has to be reentrant, it's still nice to
remove comments about ancient pre-standard Unix problems that have long
been solved.

Discussion:
Reviewed-by:
---
 src/bin/pg_dump/parallel.c | 30 +++++++++++++++++-------------
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/src/bin/pg_dump/parallel.c b/src/bin/pg_dump/parallel.c
index 2381fa405ba..81d0865284d 100644
--- a/src/bin/pg_dump/parallel.c
+++ b/src/bin/pg_dump/parallel.c
@@ -545,20 +545,11 @@ WaitForTerminatingWorkers(ParallelState *pstate)
  * Signal handler (Unix only)
  */
 static void
-sigTermHandler(SIGNAL_ARGS)
+sigTermHandler(int signo)
 {
 	int			i;
 	char		errbuf[1];
 
-	/*
-	 * Some platforms allow delivery of new signals to interrupt an active
-	 * signal handler.  That could muck up our attempt to send PQcancel, so
-	 * disable the signals that set_cancel_handler enabled.
-	 */
-	pqsignal(SIGINT, PG_SIG_IGN);
-	pqsignal(SIGTERM, PG_SIG_IGN);
-	pqsignal(SIGQUIT, PG_SIG_IGN);
-
 	/*
 	 * If we're in the leader, forward signal to all workers.  (It seems best
 	 * to do this before PQcancel; killing the leader transaction will result
@@ -616,11 +607,24 @@ set_cancel_handler(void)
 	 */
 	if (!signal_info.handler_set)
 	{
+		struct sigaction sa = {0};
+
 		signal_info.handler_set = true;
 
-		pqsignal(SIGINT, sigTermHandler);
-		pqsignal(SIGTERM, sigTermHandler);
-		pqsignal(SIGQUIT, sigTermHandler);
+		/*
+		 * While any of these signals is handled, block all three to avoid
+		 * possible repeat cancellation.
+		 */
+		sigemptyset(&sa.sa_mask);
+		sigaddset(&sa.sa_mask, SIGINT);
+		sigaddset(&sa.sa_mask, SIGTERM);
+		sigaddset(&sa.sa_mask, SIGQUIT);
+
+		sa.sa_handler = sigTermHandler;
+
+		sigaction(SIGINT, &sa, NULL);
+		sigaction(SIGTERM, &sa, NULL);
+		sigaction(SIGQUIT, &sa, NULL);
 	}
 }
 
-- 
2.47.3

