From 0f056815c17585756ed81aed7e712b823ba02080 Mon Sep 17 00:00:00 2001 From: Xu Wang <59418106+xwang1498@users.noreply.github.com> Date: Thu, 26 Jun 2025 11:13:05 -0400 Subject: [PATCH] better handling of SIGINT / Ctrl-C This change ignores SIGINT only for the pipeline elements downstream of ping. This way ping will correctly receive the SIGINT, print its summary and cleanly exit, and then downstream elements will cleanly close afterwards. --- prettyping | 54 +++++++++++++----------------------------------------- 1 file changed, 13 insertions(+), 41 deletions(-) diff --git a/prettyping b/prettyping index b6e7881..386eca8 100755 --- a/prettyping +++ b/prettyping @@ -198,52 +198,23 @@ parse_arguments "$@" export LC_ALL=C -# Warning! Ugly code ahead! -# The code is so ugly that the comments explaining it are -# bigger than the code itself! -# -# Suppose this: -# -# cmd_a | cmd_b & -# -# I need the PID of cmd_a. How can I get it? -# In bash, $! will give me the PID of cmd_b. -# -# So, I came up with this ugly solution: open a subshell, like this: -# -# ( -# cmd_a & -# echo "This is the PID I want $!" -# wait -# ) | cmd_b - +# Ignore SIGINT (Ctrl-C) downstream of ping, so the pipeline can cleanly finish when ping is interrupted. -# Ignore Ctrl+C here. -# If I don't do this, this shell script is killed before -# ping and gawk can finish their work. -trap '' 2 +"${PING_BIN}" "${PING_PARAMS[@]}" 2>&1 | ( + trap '' INT -# Now the ugly code. -( - "${PING_BIN}" "${PING_PARAMS[@]}" & - PING_PID="$!" - - # Commented out, because it looks like this line is not needed - #trap "kill -2 $PING_PID ; exit 1" 2 # Catch Ctrl+C here - - wait -) 2>&1 | ( if [ "${IS_TERMINAL}" = 1 ]; then # Print a message to notify the awk script about terminal size change. - trap "echo SIGWINCH" 28 + trap 'echo SIGWINCH' WINCH fi - # The trap must be in another subshell because otherwise it will interrupt - # the "wait" commmand. - while read line; do - echo -E "$line" + while read -r line; do + printf '%s\n' "$line" done -) 2>&1 | "${AWK_BIN}" "${AWK_PARAMS[@]}" ' +) 2>&1 | ( + trap '' INT + + "${AWK_BIN}" "${AWK_PARAMS[@]}" ' # Weird that awk does not come with abs(), so I need to implement it. function abs(x) { return ( (x < 0) ? -x : x ) @@ -478,12 +449,12 @@ function print_received_response(rtt, block_index) { } else { block_index = 1 + int((rtt - BLOCK_RTT_MIN) * (BLOCK_LEN - 2) / BLOCK_RTT_RANGE) } - printf( BLOCK[block_index] ) + printf( BLOCK[block_index] ESC_DEFAULT) CURR_COL++ } function print_missing_response(rtt) { - printf( ESC_RED "!" ) + printf( ESC_RED "!" ESC_DEFAULT) CURR_COL++ } @@ -889,3 +860,4 @@ BEGIN { # Not needed when the output is a terminal, but does not hurt either. fflush() }' +)