Looks to me like you're on exactly the right track here.<div><br></div><div>Just needs some more test coverage. I have no further comments ;-)<br><br><div class="gmail_quote">On Mon, May 2, 2011 at 2:50 PM, Marc - A. Dahlhaus <span dir="ltr"><<a href="mailto:mad@wol.de">mad@wol.de</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class="im">Am 02.05.2011 20:33, schrieb Scott James Remnant:<br>
</div><div class="im">> On Mon, May 2, 2011 at 11:31 AM, Marc - A. Dahlhaus <<a href="mailto:mad@wol.de">mad@wol.de</a><br>
</div><div><div></div><div class="h5">> <mailto:<a href="mailto:mad@wol.de">mad@wol.de</a>>> wrote:<br>
><br>
> Am 02.05.2011 19:58, schrieb Scott James Remnant:<br>
> --8<--<br>
> > Talked about the topic with SpamapS on irc and he suggested<br>
> that we<br>
> > choos another stanza for it as there is a bug open for sending<br>
> another<br>
> > signal than HUP on reload...<br>
> ><br>
> > Maybe we better use "signal {stop,reload} SIGNAL" for it?!<br>
> ><br>
> > I would prefer:<br>
> ><br>
> > kill signal HUP<br>
> ><br>
> > since that goes better with timeout, etc. There should already be the<br>
> > code to translate signal names (normal exit uses it)<br>
><br>
> Nice. For the messages that now mention "sending TERM signal", we need a<br>
> intval to signalname translation, is there one in nih?<br>
><br>
> Yup, in nih/signal.h - nih_signal_to_name<br>
><br>
><br>
> ><br>
> > Then we could also rename the system_kill function to<br>
> system_signal_send<br>
> > and reuse it for the reloading also...<br>
><br>
> That renaming ok for you?<br>
><br>
> system_send_signal () is less yoda ;-)<br>
><br>
> Scott<br>
<br>
</div></div>This is the patch with a first added test that it does what it should.<br>
<br>
The comments are also changed to reflect the changes made.<br>
<br>
Will add some more tests to the testsuite tomorrow and get some sleep now.<br>
<br>
<br>
Marc<br>
<br>
--- a/init/errors.h<br>
+++ b/init/errors.h<br>
@@ -40,6 +40,7 @@ enum {<br>
/* Errors while parsing configuration files */<br>
PARSE_ILLEGAL_INTERVAL,<br>
PARSE_ILLEGAL_EXIT,<br>
+ PARSE_ILLEGAL_SIGNAL,<br>
PARSE_ILLEGAL_UMASK,<br>
PARSE_ILLEGAL_NICE,<br>
PARSE_ILLEGAL_OOM,<br>
@@ -60,6 +61,7 @@ enum {<br>
#define ENVIRON_MISMATCHED_BRACES_STR N_("Mismatched braces")<br>
#define PARSE_ILLEGAL_INTERVAL_STR N_("Illegal interval, expected<br>
number of seconds")<br>
#define PARSE_ILLEGAL_EXIT_STR N_("Illegal exit status, expected integer")<br>
+#define PARSE_ILLEGAL_SIGNAL_STR N_("Illegal signal status, expected<br>
integer")<br>
#define PARSE_ILLEGAL_UMASK_STR N_("Illegal file creation mask,<br>
expected octal integer")<br>
#define PARSE_ILLEGAL_NICE_STR N_("Illegal nice value, expected -20 to<br>
19")<br>
#define PARSE_ILLEGAL_OOM_STR N_("Illegal oom adjustment, expected -16<br>
to 15 or never")<br>
--- a/init/job_class.c<br>
<div class="im">+++ b/init/job_class.c<br>
</div><div class="im">@@ -26,6 +26,7 @@<br>
<br>
#include <errno.h><br>
#include <string.h><br>
+#include <signal.h><br>
<br>
#include <nih/macros.h><br>
#include <nih/alloc.h><br>
@@ -199,6 +200,7 @@ job_class_new (const void *parent,<br>
class->task = FALSE;<br>
<br>
class->kill_timeout = JOB_DEFAULT_KILL_TIMEOUT;<br>
+ class->kill_signal = SIGTERM;<br>
<br>
class->respawn = FALSE;<br>
class->respawn_limit = JOB_DEFAULT_RESPAWN_LIMIT;<br>
</div>--- a/init/job_class.h<br>
<div class="im">+++ b/init/job_class.h<br>
</div><div class="im">@@ -129,6 +129,7 @@ typedef struct job_class {<br>
int task;<br>
<br>
time_t kill_timeout;<br>
+ int kill_signal;<br>
<br>
int respawn;<br>
int respawn_limit;<br>
</div>--- a/init/job_process.c<br>
<div class="im">+++ b/init/job_process.c<br>
</div>@@ -769,9 +769,9 @@ job_process_error_read (int fd)<br>
* @process: process to be killed.<br>
*<br>
* This function forces a @job to leave its current state by sending<br>
- * @process the TERM signal, and maybe later the KILL signal. The actual<br>
- * state changes are performed by job_child_reaper when the process<br>
- * has actually terminated.<br>
+ * @process the "kill signal" defined signal (TERM by default), and maybe<br>
+ * later the KILL signal. The actual state changes are performed by<br>
+ * job_child_reaper when the process has actually terminated.<br>
**/<br>
void<br>
<div class="im"> job_process_kill (Job *job,<br>
</div>@@ -782,15 +782,17 @@ job_process_kill (Job *job,<br>
nih_assert (job->kill_timer == NULL);<br>
nih_assert (job->kill_process = -1);<br>
<br>
- nih_info (_("Sending TERM signal to %s %s process (%d)"),<br>
+ nih_info (_("Sending %s signal to %s %s process (%d)"),<br>
<div class="im">+ nih_signal_to_name (job->class->kill_signal),<br>
job_name (job), process_name (process), job->pid[process]);<br>
<br>
- if (system_kill (job->pid[process], FALSE) < 0) {<br>
+ if (system_send_signal (job->pid[process], job->class->kill_signal) < 0) {<br>
NihError *err;<br>
<br>
err = nih_error_get ();<br>
if (err->number != ESRCH)<br>
- nih_warn (_("Failed to send TERM signal to %s %s process (%d): %s"),<br>
+ nih_warn (_("Failed to send %s signal to %s %s process (%d): %s"),<br>
+ nih_signal_to_name (job->class->kill_signal),<br>
job_name (job), process_name (process),<br>
job->pid[process], err->message);<br>
nih_free (err);<br>
</div>@@ -833,7 +835,7 @@ job_process_kill_timer (Job *job,<br>
<div class="im"> nih_info (_("Sending KILL signal to %s %s process (%d)"),<br>
job_name (job), process_name (process), job->pid[process]);<br>
<br>
- if (system_kill (job->pid[process], TRUE) < 0) {<br>
+ if (system_send_signal (job->pid[process], SIGKILL) < 0) {<br>
NihError *err;<br>
<br>
err = nih_error_get ();<br>
</div>--- a/init/parse_job.c<br>
<div class="im">+++ b/init/parse_job.c<br>
</div><div><div></div><div class="h5">@@ -1782,6 +1782,7 @@ stanza_kill (JobClass *class,<br>
{<br>
size_t a_pos, a_lineno;<br>
int ret = -1;<br>
+ char *endptr;<br>
nih_local char *arg = NULL;<br>
<br>
nih_assert (class != NULL);<br>
@@ -1799,7 +1800,6 @@ stanza_kill (JobClass *class,<br>
<br>
if (! strcmp (arg, "timeout")) {<br>
nih_local char *timearg = NULL;<br>
- char *endptr;<br>
<br>
/* Update error position to the timeout value */<br>
*pos = a_pos;<br>
@@ -1816,14 +1816,40 @@ stanza_kill (JobClass *class,<br>
if (errno || *endptr || (class->kill_timeout < 0))<br>
nih_return_error (-1, PARSE_ILLEGAL_INTERVAL,<br>
_(PARSE_ILLEGAL_INTERVAL_STR));<br>
+ } else if (! strcmp (arg, "signal")) {<br>
+ unsigned long status;<br>
+ nih_local char *sigarg = NULL;<br>
+ int signal;<br>
<br>
- ret = nih_config_skip_comment (file, len, &a_pos, &a_lineno);<br>
+ /* Update error position to the exit status */<br>
+ *pos = a_pos;<br>
+ if (lineno)<br>
+ *lineno = a_lineno;<br>
+<br>
+ sigarg = nih_config_next_arg (NULL, file, len, &a_pos,<br>
+ &a_lineno);<br>
<br>
+ if (! sigarg)<br>
+ goto finish;<br>
+<br>
+ signal = nih_signal_from_name (sigarg);<br>
+ if (signal < 0) {<br>
+ errno = 0;<br>
+ status = strtoul (sigarg, &endptr, 10);<br>
+ if (errno || *endptr || (status > INT_MAX))<br>
</div></div>+ nih_return_error (-1, PARSE_ILLEGAL_SIGNAL,<br>
+ _(PARSE_ILLEGAL_SIGNAL_STR));<br>
<div class="im">+ }<br>
+<br>
+ /* Set the signal */<br>
+ class->kill_signal = signal;<br>
} else {<br>
nih_return_error (-1, NIH_CONFIG_UNKNOWN_STANZA,<br>
_(NIH_CONFIG_UNKNOWN_STANZA_STR));<br>
}<br>
<br>
+ ret = nih_config_skip_comment (file, len, &a_pos, &a_lineno);<br>
+<br>
finish:<br>
*pos = a_pos;<br>
if (lineno)<br>
</div>--- a/init/system.c<br>
+++ b/init/system.c<br>
<div class="im">@@ -46,29 +46,23 @@<br>
<br>
<br>
/**<br>
- * system_kill:<br>
+ * system_send_signal:<br>
* @pid: process id of process,<br>
- * @force: force the death.<br>
+ * @signal: signal to send.<br>
*<br>
- * Kill all processes in the same process group as @pid, which may not<br>
- * necessarily be the group leader.<br>
- *<br>
- * When @force is FALSE, the TERM signal is sent; when it is TRUE, KILL<br>
- * is sent instead.<br>
+ * Send all processes in the same process group as @pid, which may not<br>
+ * necessarily be the group leader the @signal.<br>
*<br>
* Returns: zero on success, negative value on raised error.<br>
**/<br>
int<br>
-system_kill (pid_t pid,<br>
- int force)<br>
+system_send_signal (pid_t pid,<br>
+ int signal)<br>
{<br>
- int signal;<br>
pid_t pgid;<br>
<br>
nih_assert (pid > 0);<br>
<br>
- signal = (force ? SIGKILL : SIGTERM);<br>
-<br>
pgid = getpgid (pid);<br>
<br>
if (kill (pgid > 0 ? -pgid : pid, signal) < 0)<br>
</div>--- a/init/system.h<br>
+++ b/init/system.h<br>
<div class="im">@@ -29,7 +29,7 @@<br>
<br>
NIH_BEGIN_EXTERN<br>
<br>
-int system_kill (pid_t pid, int force)<br>
+int system_send_signal (pid_t pid, int signal)<br>
__attribute__ ((warn_unused_result));<br>
<br>
int system_setup_console (ConsoleType type, int reset)<br>
</div>--- a/init/tests/test_parse_job.c<br>
+++ b/init/tests/test_parse_job.c<br>
@@ -4983,6 +4983,38 @@ test_stanza_kill (void)<br>
TEST_EQ (pos, 16);<br>
TEST_EQ (lineno, 1);<br>
nih_free (err);<br>
+<br>
+ /* Check that a kill stanza with the signal argument and signal,<br>
+ * sets the right signal on the jobs class.<br>
+ */<br>
+ TEST_FEATURE ("with signal and argument");<br>
+ strcpy (buf, "kill signal INT\n");<br>
+<br>
+ TEST_ALLOC_FAIL {<br>
+ pos = 0;<br>
+ lineno = 1;<br>
+ job = parse_job (NULL, "test", buf, strlen (buf),<br>
+ &pos, &lineno);<br>
+<br>
+ if (test_alloc_failed) {<br>
+ TEST_EQ_P (job, NULL);<br>
+<br>
+ err = nih_error_get ();<br>
+ TEST_EQ (err->number, ENOMEM);<br>
+ nih_free (err);<br>
+<br>
+ continue;<br>
+ }<br>
+<br>
+ TEST_EQ (pos, strlen (buf));<br>
+ TEST_EQ (lineno, 2);<br>
+<br>
+ TEST_ALLOC_SIZE (job, sizeof (JobClass));<br>
+<br>
+ TEST_EQ (job->kill_signal, SIGINT);<br>
+<br>
+ nih_free (job);<br>
+ }<br>
}<br>
<br>
void<br>
--- a/init/tests/test_system.c<br>
<div class="im">+++ b/init/tests/test_system.c<br>
</div><div><div></div><div class="h5">@@ -35,7 +35,7 @@ test_kill (void)<br>
pid_t pid1, pid2, pid3;<br>
int ret, status;<br>
<br>
- TEST_FUNCTION ("system_kill");<br>
+ TEST_FUNCTION ("system_send_signal");<br>
<br>
/* Check that when we normally kill the process, the TERM signal<br>
* is sent to all processes in its process group.<br>
@@ -51,7 +51,7 @@ test_kill (void)<br>
setpgid (pid1, pid1);<br>
setpgid (pid2, pid1);<br>
<br>
- ret = system_kill (pid1, FALSE);<br>
+ ret = system_send_signal (pid1, SIGTERM);<br>
waitpid (pid1, &status, 0);<br>
<br>
TEST_EQ (ret, 0);<br>
@@ -79,7 +79,7 @@ test_kill (void)<br>
setpgid (pid1, pid1);<br>
setpgid (pid2, pid1);<br>
<br>
- ret = system_kill (pid1, TRUE);<br>
+ ret = system_send_signal (pid1, SIGKILL);<br>
waitpid (pid1, &status, 0);<br>
<br>
TEST_EQ (ret, 0);<br>
@@ -114,7 +114,7 @@ test_kill (void)<br>
kill (pid1, SIGTERM);<br>
waitpid (pid1, &status, 0);<br>
<br>
- ret = system_kill (pid2, FALSE);<br>
+ ret = system_send_signal (pid2, SIGTERM);<br>
waitpid (pid2, &status, 0);<br>
<br>
TEST_EQ (ret, 0);<br>
<br>
<br>
</div></div></blockquote></div><br></div>