bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [BUG] Bash not reacting to Ctrl-C


From: Oleg Nesterov
Subject: Re: [BUG] Bash not reacting to Ctrl-C
Date: Sun, 13 Feb 2011 21:21:49 +0100
User-agent: Mutt/1.5.18 (2008-05-17)

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.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]