I have isolated a bug in bash 3.2 which doesn't appear in later versions of bash I have tried; now I am trying to figure out when where the bug got fixed so I can make an upgrade plan. I am using SLES 11 SP2.
To reproduce the issue do the following. * Block SIGPIPE in the current process. * From the current process, start bash interactively. (The new bash process also has SIGPIPE blocked.) * In the latter bash process, run a test program. (The new test-program process also has SIGPIPE blocked.) The latter process sees a pending SIGPIPE supposedly sent by itself. If it unblocks SIGPIPE then it receives this signal immediately. If the test program is started in various unusual ways such as the following then it does NOT receive SIGPIPE: bash -c '{ test ; }' bash -c ': ; test' bash -c 'test ; :' ( { test ; } ) ( test ; : ) echo test | bash -s whereas it DOES receive SIGPIPE if it as started as follows. bash -c test test ( test ) ( test ; ) { test ; } I have searched in the mailing list archives and looked in the bash docs but haven't found a clue as to where this bug was fixed. Does this ring a bell with anyone or is this most likely a distro-specific bug? Info: $ bash --version GNU bash, version 3.2.51(1)-release (x86_64-suse-linux-gnu) > rpm -q -a|grep bash bash-3.2-147.9.13 $ cat /etc/issue Welcome to SUSE Linux Enterprise Server 11 SP2 (x86_64) - Kernel \r (\l). I attach the test program I use. -- Thomas Hood RAAF Technology bv
#include <stdio.h> #include <signal.h> #include <sys/types.h> #include <unistd.h> static void sigactor(int signum, siginfo_t *si, void *ctx) { printf("Caught signal %d sent by process %d\n", signum, si->si_pid); } int main() { sigset_t sigmask; struct sigaction act; act.sa_sigaction = sigactor; act.sa_flags = SA_RESTART | SA_SIGINFO; printf("Running with PID %d\n", getpid()); printf("Will retrieve existing signal mask\n"); if (sigprocmask(SIG_SETMASK, NULL, &sigmask)) { printf("Failed to retrieve existing signal mask\n"); return 1; } if (sigismember (&sigmask, SIGPIPE)) { printf("SIGPIPE is blocked\n"); } else { printf("SIGPIPE is not blocked\n"); } printf("Will check for signals pending\n"); if (sigpending(&sigmask)) { printf("Failed to check for signals pending\n"); return 1; } if (sigismember (&sigmask, SIGPIPE)) { printf("SIGPIPE is pending\n"); } else { printf("SIGPIPE is not pending\n"); } printf("Will install signal handler\n"); if (sigaction(SIGPIPE, &act, NULL) || sigaction(SIGHUP, &act, NULL) || sigaction(SIGTERM, &act, NULL)) { printf("Failed to install signal handler\n"); return 1; } //printf("Will sleep\n"); //sleep(30); sigemptyset(&sigmask); sigaddset(&sigmask, SIGPIPE); printf("Will unblock signal\n"); if (sigprocmask(SIG_UNBLOCK, &sigmask, NULL)) { printf("Error unblocking signal\n"); return 1; } printf("Will exit\n"); return 0; }