On 02/17/2013 10:00 PM, Chet Ramey wrote:
On 2/9/13 12:02 AM, Pádraig Brady wrote:
$ rpm -q kernel glibc bash
kernel-2.6.40.4-5.fc15.x86_64
glibc-2.14.1-6.x86_64
bash-4.2.10-4.fc15.x86_64

I notice the following will wait for 5 seconds for
the timeout process to end with SIGALRM, rather than
immediately due to kill sending the SIGTERM.

I think the way to approach this is to change the SIGTERM handling from
straight SIG_IGN to a handler installed with SA_RESTART that catches the
signal but does nothing with it.

That will allow the shell to note whether it receives a SIGTERM between
fork and exec and react accordingly.

Thanks for continuing to look at this.
Just in case you need to consider other options,
elaborating a bit on my previous suggestion:

sigprocmask(sigterm_block);   // ensure parent shell doesn't get TERM
signal (SIGTERM, SIG_DFL);    // reset to default for child to inherit
fork();
if (child)
  {
    sigprocmask(sigterm_unblock); // reset
    /* From now any (pending) SIGTERM will cause
       the child process to exit with signal flag set in exit status.  */
    exec();
  }
else
  {
    signal (SIGTERM, SIG_IGN);    // continue to ignore TERM
    sigprocmask(sigterm_unblock); // reset
  }


Your suggested method I think is to have a handler something like
the following which should work too, but perhaps with the caveat
that the exit status of the child before the exec might not have
the signal bit set.

sigterm_handler (int sig)
{
    if (getpid() != interactive_pid)
      exit(...);
}

thanks,
Pádraig.

Reply via email to