+#if defined (JOB_CONTROL) && defined (SIGCHLD)
+ else if (sig == SIGCHLD &&
+ trap_list[SIGCHLD] != (char *)IMPOSSIBLE_TRAP_HANDLER &&
+ (sigmodes[SIGCHLD] & SIG_INPROGRESS) == 0)
+ {
+ sigmodes[SIGCHLD] |= SIG_INPROGRESS;
+ run_sigchld_trap (pending_traps[sig]); /* use as counter */
+ sigmodes[SIGCHLD] &= ~SIG_INPROGRESS;
+ }
+ else if (sig == SIGCHLD &&
+ trap_list[SIGCHLD] == (char *)IMPOSSIBLE_TRAP_HANDLER &&
+ (sigmodes[SIGCHLD] & SIG_INPROGRESS) != 0)
+ {
+ /* This can happen when run_pending_traps is called while
+ running a SIGCHLD trap handler. */
+ running_trap = 0;
+ /* want to leave pending_traps[SIGCHLD] alone here */
+ continue; /* XXX */
+ }
+ else if (sig == SIGCHLD && (sigmodes[SIGCHLD] & SIG_INPROGRESS))
+ {
+ /* whoops -- print warning? */
+ running_trap = 0; /* XXX */
+ /* want to leave pending_traps[SIGCHLD] alone here */
+ continue;
+ }
+#endif
+ else if (trap_list[sig] == (char *)DEFAULT_SIG ||
+ trap_list[sig] == (char *)IGNORE_SIG ||
+ trap_list[sig] == (char *)IMPOSSIBLE_TRAP_HANDLER)
+ {
+ /* This is possible due to a race condition. Say a bash
+ process has SIGTERM trapped. A subshell is spawned
+ using { list; } & and the parent does something and kills
+ the subshell with SIGTERM. It's possible for the subshell
+ to set pending_traps[SIGTERM] to 1 before the code in
+ execute_cmd.c eventually calls restore_original_signals
+ to reset the SIGTERM signal handler in the subshell. The
+ next time run_pending_traps is called, pending_traps[SIGTERM]
+ will be 1, but the trap handler in trap_list[SIGTERM] will
+ be invalid (probably DEFAULT_SIG, but it could be IGNORE_SIG).
+ Unless we catch this, the subshell will dump core when
+ trap_list[SIGTERM] == DEFAULT_SIG, because DEFAULT_SIG is
+ usually 0x0. */
+ internal_warning (_("run_pending_traps: bad value in trap_list[%d]: %p"),
+ sig, trap_list[sig]);
+ if (trap_list[sig] == (char *)DEFAULT_SIG)
+ {
+ internal_warning (_("run_pending_traps: signal handler is SIG_DFL, resending %d (%s) to myself"), sig, signal_name (sig));
+ kill (getpid (), sig);
+ }
+ }