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>