The queue is once cleaned up, however, sigpacket::process() may set
si_signo in the queue to 0 by calling sig_clear(). This patch adds
another loop for cleanup after calling sigpacket::process().

Addresses: https://cygwin.com/pipermail/cygwin/2024-November/256744.html
Fixes: 9d2155089e87 ("(wait_sig): Define variable q to be the start of the 
signal queue.  Just iterate through sigq queue, deleting processed or zeroed 
signals")
Reported-by: Christian Franke <christian.fra...@t-online.de>
Reviewed-by:
Signed-off-by: Takashi Yano <takashi.y...@nifty.ne.jp>
---
 winsup/cygwin/sigproc.cc | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index 8f46a80ab..b8d961a07 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -1463,6 +1463,17 @@ wait_sig (VOID *)
                      qnext->si.si_signo = 0;
                    }
                }
+             /* Cleanup sigq chain. Remove entries having si_signo == 0.
+                There were once cleaned obeve, however sigpacket::process()
+                may set si_signo to 0 using sig_clear(). */
+             q = &sigq.start;
+             while ((qnext = q->next))
+               {
+                 if (qnext->si.si_signo)
+                   q = qnext;
+                 else
+                   q->next = qnext->next;
+               }
              /* At least one signal still queued?  The event is used in select
                 only, and only to decide if WFMO should wake up in case a
                 signalfd is waiting via select/poll for being ready to read a
-- 
2.45.1

Reply via email to