Author: ablack
Date: Fri Dec 8 09:58:21 2006
New Revision: 484674
URL: http://svn.apache.org/viewvc?view=rev&rev=484674
Log:
2006-12-07 Andrew Black <[EMAIL PROTECTED]>
* 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.
Modified:
incubator/stdcxx/trunk/util/exec.cpp
Modified: incubator/stdcxx/trunk/util/exec.cpp
URL:
http://svn.apache.org/viewvc/incubator/stdcxx/trunk/util/exec.cpp?view=diff&rev=484674&r1=484673&r2=484674
==============================================================================
--- incubator/stdcxx/trunk/util/exec.cpp (original)
+++ incubator/stdcxx/trunk/util/exec.cpp Fri Dec 8 09:58:21 2006
@@ -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);
@@ -557,6 +595,20 @@
while (siginx < sigcount && 0 == kill (-child_pid, signals [siginx])) {
++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));
}
}