On 02/11, Linus Torvalds wrote: > > @@ -2424,6 +2425,18 @@ wait_for (pid) > sigaction (SIGCHLD, &oact, (struct sigaction *)NULL); > sigprocmask (SIG_SETMASK, &chldset, (sigset_t *)NULL); > # endif > + /* If the waitchld returned EINTR, and the shell got a SIGINT, > + then the child has not died yet, and we assume that the > + child has blocked SIGINT. In that case, we require that the > + child return with WSIGTERM() == SIGINT to actually consider > + the ^C relevant. This is racy (the child may be in the > + process of exiting and bash reacted to the EINTR first), > + but this makes the race window much much smaller */
OK, I leave this up to you and Chet. At least the race is documented. Another problem, child_blocked_sigint can be false positive if the signal was sent to bash directly (not to pgrp). This means that the next ^C won't work again. And, > + if (r == -1 && errno == EINTR && wait_sigint_received) > + { > + child_blocked_sigint = 1; > + } This can't work afaics. waitchld() can never return -1 && EINTR. Perhaps waitchld() can set this flag, I don't know... 3087 /* If waitpid returns 0, there are running children. If it returns -1, 3088 the only other error POSIX says it can return is EINTR. */ 3089 CHECK_TERMSIG; 3090 if (pid <= 0) 3091 continue; /* jumps right to the test */ The code looks strange btw. "jumps right to the test" is correct, but this code does do { ... } while ((sigchld || block == 0) && pid > (pid_t)0); and this "continue" in fact means "break". So, perhaps, we can do if (pid < 0) { if (wait_sigint_received) child_blocked_sigint = 1; break; } Oleg.