stdcxx-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Martin Sebor <se...@roguewave.com>
Subject Re: [PATCH] Exec utility signal relay
Date Fri, 08 Dec 2006 02:54:23 GMT
Andrew Black wrote:
> Greetings all.
> 
> Attached is a patch that aims to resolve an old issue with the exec 
> utility on UNIX.  The problem observed is that when a kill signal is 
> sent to the exec utility, the child processes aren't killed.  This patch 
> has been tested on Linux IA-32 and HPUX-11.23 on IA-64 (chosen due to 
> previous issues with signals).

Looks good to me. Unless Farid objects go ahead and commit it.

Thanks
Martin

> 
> --Andrew Black
> 
> Changelog:
>     * exec.cpp (alarm_timeout) [!_WIN32]: Update documentation.
>     (kill_signal) [!WIN32]: Add file local variable to track signal used to
>     kill process.
>     (handle_term_signal) [!_WIN32]: Add new callback function...
>     (wait_for_child) [!_WIN32]: ... Used here for SIGHUP, SIGINT, SIGQUIT,
>     and SIGTERM signals (via sigaction).  Handlers are cleared if
>     kill_signal is set and the signal contained within is raise()ed.
> 
> 
> ------------------------------------------------------------------------
> 
> Index: util/exec.cpp
> ===================================================================
> --- util/exec.cpp	(revision 483585)
> +++ util/exec.cpp	(working copy)
> @@ -64,10 +64,19 @@
>     Value is 1 when alarm has been triggered and hasn't been handled
>  
>     @see handle_alrm
> +   @see handle_term_signal
>  */
>  static int alarm_timeout;
>  
>  /**
> +   Record of fatal signal recieved.  Used to raise() the signal again after
> +   child process has been killed.
> +
> +   @see handle_term_signal
> +*/
> +static int kill_signal;
> +
> +/**
>      Utility macro to generate a signal number/name pair.
>      
>      @parm val 'short' signal name (no leading SIG) to generate pair for.
> @@ -360,6 +369,22 @@
>          alarm_timeout = 1;
>  }
>  
> +/**
> +   Callback used to gracefully terminate the utility if signaled to do so
> +   while running a target
> +
> +   @param signo the signal recieved (should be in {SIGHUP, SIGINT, SIGQUIT, 
> +   SIGTERM})
> +   @see alarm_timeout
> +
> +*/
> +static void
> +handle_term_signal (int signo)
> +{
> +    kill_signal = signo;
> +    alarm_timeout = 1;
> +}
> +
>  typedef void (*alarm_handler)(int);
>  
>  #ifdef __cplusplus
> @@ -428,6 +453,19 @@
>  
>      sigaction (SIGALRM, &act, 0);
>      
> +    /* Set handlers for SIGHUP, SIGINT, SIGQUIT, SIGTERM so we can kill the
> +       child process prior to dieing.
> +    */
> +    kill_signal = 0;
> +
> +    phandler = handle_term_signal;
> +    memcpy (&act.sa_handler, &phandler, sizeof act.sa_handler);
> +
> +    sigaction (SIGHUP, &act, 0);
> +    sigaction (SIGINT, &act, 0);
> +    sigaction (SIGQUIT, &act, 0);
> +    sigaction (SIGTERM, &act, 0);
> +
>      if (timeout > 0)
>          alarm (timeout);
>  
> @@ -558,6 +596,20 @@
>          ++siginx;
>          sleep (1);
>      }
> +
> +    /* Check if we were signaled to quit. */
> +    if (kill_signal) {
> +        /* Reset the handlers to normal */
> +        act.sa_handler = SIG_DFL;
> +        sigaction (SIGHUP, &act, 0);
> +        sigaction (SIGINT, &act, 0);
> +        sigaction (SIGQUIT, &act, 0);
> +        sigaction (SIGTERM, &act, 0);
> +
> +        if (0 > raise (kill_signal))
> +            terminate (1, "raise(%s) failed: %s\n",
> +                       get_signame (kill_signal), strerror (errno));
> +    }
>  }
>  
>  /**


Mime
View raw message