From d655ac33d01c1b9de339b21da37de3df431a698a Mon Sep 17 00:00:00 2001 From: Jack O'Connor Date: Tue, 10 Jun 2025 19:34:19 -0700 Subject: [PATCH] patch libedit to stop re-broadcasting signals --- cpython-unix/build-libedit.sh | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/cpython-unix/build-libedit.sh b/cpython-unix/build-libedit.sh index 08387ece..61220593 100755 --- a/cpython-unix/build-libedit.sh +++ b/cpython-unix/build-libedit.sh @@ -82,6 +82,32 @@ index 614795f..4671f1b 100755 fi EOF +# When libedit receives a signal, it re-broadcasts it to its entire pgroup. +# This seems intended to preserve normal ^C behavior in "raw" mode when the +# terminal's ISIG flag is cleared? However, libedit does not in fact clear +# ISIG. (And Jack can't find any evidence of any version that ever did.) This +# sometimes results in the parent process receiving ^C twice back-to-back, +# depending on the vagaries of signal coalescing. More pathologically, if the +# parent tries to signal the child directly with e.g. `kill(pid, SIGTERM)`, +# libedit *signals the parent right back* (not to mention any other pgroup +# siblings or grandparents). This is just wild behavior, even though it's +# probably rare that it matters in practice. Patch it out. See also: +# https://github.com/astral-sh/uv/issues/13919#issuecomment-2960501229. +patch -p1 << "EOF" +diff --git i/src/sig.c w/src/sig.c +index d2b77e7..884b2dd 100644 +--- i/src/sig.c ++++ w/src/sig.c +@@ -107,7 +107,7 @@ sig_handler(int signo) + sel->el_signal->sig_action[i].sa_flags = 0; + sigemptyset(&sel->el_signal->sig_action[i].sa_mask); + (void) sigprocmask(SIG_SETMASK, &oset, NULL); +- (void) kill(0, signo); ++ (void) raise(signo); + errno = save_errno; + } +EOF + cflags="${EXTRA_TARGET_CFLAGS} -fPIC -I${TOOLS_PATH}/deps/include -I${TOOLS_PATH}/deps/include/ncursesw" ldflags="${EXTRA_TARGET_LDFLAGS} -L${TOOLS_PATH}/deps/lib"