blob: 89568f192d9dd5476ea16bf46147595547906883 [file] [log] [blame]
=== modified file 'init/errors.h'
--- init/errors.h 2011-05-05 10:13:49 +0000
+++ init/errors.h 2011-05-12 20:42:28 +0000
@@ -40,6 +40,7 @@
/* Errors while parsing configuration files */
PARSE_ILLEGAL_INTERVAL,
PARSE_ILLEGAL_EXIT,
+ PARSE_ILLEGAL_SIGNAL,
PARSE_ILLEGAL_UMASK,
PARSE_ILLEGAL_NICE,
PARSE_ILLEGAL_OOM,
@@ -60,6 +61,7 @@
#define ENVIRON_MISMATCHED_BRACES_STR N_("Mismatched braces")
#define PARSE_ILLEGAL_INTERVAL_STR N_("Illegal interval, expected number of seconds")
#define PARSE_ILLEGAL_EXIT_STR N_("Illegal exit status, expected integer")
+#define PARSE_ILLEGAL_SIGNAL_STR N_("Illegal signal status, expected integer")
#define PARSE_ILLEGAL_UMASK_STR N_("Illegal file creation mask, expected octal integer")
#define PARSE_ILLEGAL_NICE_STR N_("Illegal nice value, expected -20 to 19")
#define PARSE_ILLEGAL_OOM_STR N_("Illegal oom adjustment, expected -16 to 15 or 'never'")
=== modified file 'init/job_class.c'
--- init/job_class.c 2011-05-05 10:13:49 +0000
+++ init/job_class.c 2011-05-12 20:42:28 +0000
@@ -26,6 +26,7 @@
#include <errno.h>
#include <string.h>
+#include <signal.h>
#include <nih/macros.h>
#include <nih/alloc.h>
@@ -199,6 +200,7 @@
class->task = FALSE;
class->kill_timeout = JOB_DEFAULT_KILL_TIMEOUT;
+ class->kill_signal = SIGTERM;
class->respawn = FALSE;
class->respawn_limit = JOB_DEFAULT_RESPAWN_LIMIT;
=== modified file 'init/job_class.h'
--- init/job_class.h 2011-05-12 19:31:50 +0000
+++ init/job_class.h 2011-05-12 20:42:28 +0000
@@ -85,6 +85,7 @@
* @expect: what to expect before entering the next state after spawned,
* @task: start requests are not unblocked until instances have finished,
* @kill_timeout: time to wait between sending TERM and KILL signals,
+ * @kill_signal: first signal to send (usually SIGTERM),
* @respawn: instances should be restarted if main process fails,
* @respawn_limit: number of respawns in @respawn_interval that we permit,
* @respawn_interval: barrier for @respawn_limit,
@@ -129,6 +130,7 @@
int task;
time_t kill_timeout;
+ int kill_signal;
int respawn;
int respawn_limit;
=== modified file 'init/job_process.c'
--- init/job_process.c 2011-05-12 19:31:50 +0000
+++ init/job_process.c 2011-05-12 20:42:28 +0000
@@ -802,9 +802,9 @@
* @process: process to be killed.
*
* This function forces a @job to leave its current state by sending
- * @process the TERM signal, and maybe later the KILL signal. The actual
- * state changes are performed by job_child_reaper when the process
- * has actually terminated.
+ * @process the "kill signal" defined signal (TERM by default), and maybe
+ * later the KILL signal. The actual state changes are performed by
+ * job_child_reaper when the process has actually terminated.
**/
void
job_process_kill (Job *job,
@@ -815,15 +815,17 @@
nih_assert (job->kill_timer == NULL);
nih_assert (job->kill_process = -1);
- nih_info (_("Sending TERM signal to %s %s process (%d)"),
+ nih_info (_("Sending %s signal to %s %s process (%d)"),
+ nih_signal_to_name (job->class->kill_signal),
job_name (job), process_name (process), job->pid[process]);
- if (system_kill (job->pid[process], FALSE) < 0) {
+ if (system_kill (job->pid[process], job->class->kill_signal) < 0) {
NihError *err;
err = nih_error_get ();
if (err->number != ESRCH)
- nih_warn (_("Failed to send TERM signal to %s %s process (%d): %s"),
+ nih_warn (_("Failed to send %s signal to %s %s process (%d): %s"),
+ nih_signal_to_name (job->class->kill_signal),
job_name (job), process_name (process),
job->pid[process], err->message);
nih_free (err);
@@ -863,15 +865,17 @@
job->kill_timer = NULL;
job->kill_process = -1;
- nih_info (_("Sending KILL signal to %s %s process (%d)"),
+ nih_info (_("Sending %s signal to %s %s process (%d)"),
+ "KILL",
job_name (job), process_name (process), job->pid[process]);
- if (system_kill (job->pid[process], TRUE) < 0) {
+ if (system_kill (job->pid[process], SIGKILL) < 0) {
NihError *err;
err = nih_error_get ();
if (err->number != ESRCH)
- nih_warn (_("Failed to send KILL signal to %s %s process (%d): %s"),
+ nih_warn (_("Failed to send %s signal to %s %s process (%d): %s"),
+ "KILL",
job_name (job), process_name (process),
job->pid[process], err->message);
nih_free (err);
=== modified file 'init/man/init.5'
--- init/man/init.5 2011-05-12 19:31:50 +0000
+++ init/man/init.5 2011-05-12 20:42:28 +0000
@@ -563,10 +563,20 @@
.\"
.SS Miscellaneous
.TP
+.B kill signal \fISIGNAL
+Specifies the stopping signal,
+.I SIGTERM
+by default, a job's main process will receive when stopping the
+running job.
+
+.nf
+kill signal INT
+.fi
+.\"
+.TP
.B kill timeout \fIINTERVAL
Specifies the interval between sending the job's main process the
-.I SIGTERM
-and
+"stopping" (see above) and
.I SIGKILL
signals when stopping the running job.
.\"
=== modified file 'init/parse_job.c'
--- init/parse_job.c 2011-05-12 19:31:50 +0000
+++ init/parse_job.c 2011-05-12 20:42:28 +0000
@@ -1782,6 +1782,7 @@
{
size_t a_pos, a_lineno;
int ret = -1;
+ char *endptr;
nih_local char *arg = NULL;
nih_assert (class != NULL);
@@ -1799,7 +1800,6 @@
if (! strcmp (arg, "timeout")) {
nih_local char *timearg = NULL;
- char *endptr;
/* Update error position to the timeout value */
*pos = a_pos;
@@ -1816,14 +1816,40 @@
if (errno || *endptr || (class->kill_timeout < 0))
nih_return_error (-1, PARSE_ILLEGAL_INTERVAL,
_(PARSE_ILLEGAL_INTERVAL_STR));
-
- ret = nih_config_skip_comment (file, len, &a_pos, &a_lineno);
-
+ } else if (! strcmp (arg, "signal")) {
+ unsigned long status;
+ nih_local char *sigarg = NULL;
+ int signal;
+
+ /* Update error position to the exit status */
+ *pos = a_pos;
+ if (lineno)
+ *lineno = a_lineno;
+
+ sigarg = nih_config_next_arg (NULL, file, len, &a_pos,
+ &a_lineno);
+
+ if (! sigarg)
+ goto finish;
+
+ signal = nih_signal_from_name (sigarg);
+ if (signal < 0) {
+ errno = 0;
+ status = strtoul (sigarg, &endptr, 10);
+ if (errno || *endptr || (status > INT_MAX))
+ nih_return_error (-1, PARSE_ILLEGAL_SIGNAL,
+ _(PARSE_ILLEGAL_SIGNAL_STR));
+ }
+
+ /* Set the signal */
+ class->kill_signal = signal;
} else {
nih_return_error (-1, NIH_CONFIG_UNKNOWN_STANZA,
_(NIH_CONFIG_UNKNOWN_STANZA_STR));
}
+ ret = nih_config_skip_comment (file, len, &a_pos, &a_lineno);
+
finish:
*pos = a_pos;
if (lineno)
=== modified file 'init/system.c'
--- init/system.c 2010-02-26 15:29:07 +0000
+++ init/system.c 2011-05-12 20:42:28 +0000
@@ -48,27 +48,21 @@
/**
* system_kill:
* @pid: process id of process,
- * @force: force the death.
- *
- * Kill all processes in the same process group as @pid, which may not
- * necessarily be the group leader.
- *
- * When @force is FALSE, the TERM signal is sent; when it is TRUE, KILL
- * is sent instead.
+ * @signal: signal to send.
+ *
+ * Send all processes in the same process group as @pid, which may not
+ * necessarily be the group leader the @signal.
*
* Returns: zero on success, negative value on raised error.
**/
int
system_kill (pid_t pid,
- int force)
+ int signal)
{
- int signal;
pid_t pgid;
nih_assert (pid > 0);
- signal = (force ? SIGKILL : SIGTERM);
-
pgid = getpgid (pid);
if (kill (pgid > 0 ? -pgid : pid, signal) < 0)
=== modified file 'init/system.h'
--- init/system.h 2010-02-26 15:29:07 +0000
+++ init/system.h 2011-05-12 20:42:28 +0000
@@ -29,7 +29,7 @@
NIH_BEGIN_EXTERN
-int system_kill (pid_t pid, int force)
+int system_kill (pid_t pid, int signal)
__attribute__ ((warn_unused_result));
int system_setup_console (ConsoleType type, int reset)
=== modified file 'init/tests/test_job_class.c'
--- init/tests/test_job_class.c 2011-05-05 10:13:49 +0000
+++ init/tests/test_job_class.c 2011-05-12 20:42:28 +0000
@@ -121,6 +121,7 @@
TEST_EQ (class->task, FALSE);
TEST_EQ (class->kill_timeout, 5);
+ TEST_EQ (class->kill_signal, SIGTERM);
TEST_EQ (class->respawn, FALSE);
TEST_EQ (class->respawn_limit, 10);
=== modified file 'init/tests/test_parse_job.c'
--- init/tests/test_parse_job.c 2011-05-12 19:31:50 +0000
+++ init/tests/test_parse_job.c 2011-05-12 20:42:28 +0000
@@ -4799,6 +4799,39 @@
}
+ /* Check that a kill stanza with the signal argument and signal,
+ * sets the right signal on the jobs class.
+ */
+ TEST_FEATURE ("with signal and single argument");
+ strcpy (buf, "kill signal INT\n");
+
+ TEST_ALLOC_FAIL {
+ pos = 0;
+ lineno = 1;
+ job = parse_job (NULL, "test", buf, strlen (buf),
+ &pos, &lineno);
+
+ if (test_alloc_failed) {
+ TEST_EQ_P (job, NULL);
+
+ err = nih_error_get ();
+ TEST_EQ (err->number, ENOMEM);
+ nih_free (err);
+
+ continue;
+ }
+
+ TEST_EQ (pos, strlen (buf));
+ TEST_EQ (lineno, 2);
+
+ TEST_ALLOC_SIZE (job, sizeof (JobClass));
+
+ TEST_EQ (job->kill_signal, SIGINT);
+
+ nih_free (job);
+ }
+
+
/* Check that the last of multiple kill stanzas is used.
*/
TEST_FEATURE ("with multiple timeout and single argument stanzas");
@@ -4832,6 +4865,37 @@
}
+ TEST_FEATURE ("with multiple signal and single argument stanzas");
+ strcpy (buf, "kill signal INT\n");
+ strcat (buf, "kill signal TERM\n");
+
+ TEST_ALLOC_FAIL {
+ pos = 0;
+ lineno = 1;
+ job = parse_job (NULL, "test", buf, strlen (buf),
+ &pos, &lineno);
+
+ if (test_alloc_failed) {
+ TEST_EQ_P (job, NULL);
+
+ err = nih_error_get ();
+ TEST_EQ (err->number, ENOMEM);
+ nih_free (err);
+
+ continue;
+ }
+
+ TEST_EQ (pos, strlen (buf));
+ TEST_EQ (lineno, 3);
+
+ TEST_ALLOC_SIZE (job, sizeof (JobClass));
+
+ TEST_EQ (job->kill_signal, SIGTERM);
+
+ nih_free (job);
+ }
+
+
/* Check that a kill stanza without an argument results in a syntax
* error.
*/
@@ -4889,6 +4953,25 @@
nih_free (err);
+ /* Check that a kill stanza with the timeout argument but no timeout
+ * results in a syntax error.
+ */
+ TEST_FEATURE ("with signal and missing argument");
+ strcpy (buf, "kill signal\n");
+
+ pos = 0;
+ lineno = 1;
+ job = parse_job (NULL, "test", buf, strlen (buf), &pos, &lineno);
+
+ TEST_EQ_P (job, NULL);
+
+ err = nih_error_get ();
+ TEST_EQ (err->number, NIH_CONFIG_EXPECTED_TOKEN);
+ TEST_EQ (pos, 11);
+ TEST_EQ (lineno, 1);
+ nih_free (err);
+
+
/* Check that a kill timeout stanza with a non-integer argument
* results in a syntax error.
*/
@@ -4965,6 +5048,25 @@
nih_free (err);
+ /* Check that a kill signal stanza with an unknown signal argument
+ * results in a syntax error.
+ */
+ TEST_FEATURE ("with signal and unknown signal argument");
+ strcpy (buf, "kill signal foo\n");
+
+ pos = 0;
+ lineno = 1;
+ job = parse_job (NULL, "test", buf, strlen (buf), &pos, &lineno);
+
+ TEST_EQ_P (job, NULL);
+
+ err = nih_error_get ();
+ TEST_EQ (err->number, PARSE_ILLEGAL_SIGNAL);
+ TEST_EQ (pos, 12);
+ TEST_EQ (lineno, 1);
+ nih_free (err);
+
+
/* Check that a kill stanza with the timeout argument and timeout,
* but with an extra argument afterwards results in a syntax
* error.
@@ -4983,6 +5085,26 @@
TEST_EQ (pos, 16);
TEST_EQ (lineno, 1);
nih_free (err);
+
+
+ /* Check that a kill stanza with the signal argument and signal,
+ * but with an extra argument afterwards results in a syntax
+ * error.
+ */
+ TEST_FEATURE ("with signal and extra argument");
+ strcpy (buf, "kill signal INT foo\n");
+
+ pos = 0;
+ lineno = 1;
+ job = parse_job (NULL, "test", buf, strlen (buf), &pos, &lineno);
+
+ TEST_EQ_P (job, NULL);
+
+ err = nih_error_get ();
+ TEST_EQ (err->number, NIH_CONFIG_UNEXPECTED_TOKEN);
+ TEST_EQ (pos, 16);
+ TEST_EQ (lineno, 1);
+ nih_free (err);
}
void
=== modified file 'init/tests/test_system.c'
--- init/tests/test_system.c 2009-06-23 09:29:35 +0000
+++ init/tests/test_system.c 2011-05-12 20:42:28 +0000
@@ -51,7 +51,7 @@
setpgid (pid1, pid1);
setpgid (pid2, pid1);
- ret = system_kill (pid1, FALSE);
+ ret = system_kill (pid1, SIGTERM);
waitpid (pid1, &status, 0);
TEST_EQ (ret, 0);
@@ -79,7 +79,7 @@
setpgid (pid1, pid1);
setpgid (pid2, pid1);
- ret = system_kill (pid1, TRUE);
+ ret = system_kill (pid1, SIGKILL);
waitpid (pid1, &status, 0);
TEST_EQ (ret, 0);
@@ -114,7 +114,7 @@
kill (pid1, SIGTERM);
waitpid (pid1, &status, 0);
- ret = system_kill (pid2, FALSE);
+ ret = system_kill (pid2, SIGTERM);
waitpid (pid2, &status, 0);
TEST_EQ (ret, 0);
=== modified file 'po/ChangeLog'
--- po/ChangeLog 2011-03-17 01:03:01 +0000
+++ po/ChangeLog 2011-05-12 20:42:28 +0000
@@ -1,3 +1,7 @@
+2011-05-12 Marc - A. Dahlhaus <mad@wol.de>
+
+ * POTFILES.in: Add errors.h
+
2011-03-16 Scott James Remnant <scott@netsplit.com>
* Makevars.template (COPYRIGHT_HOLDER): Update copyright.
=== modified file 'po/POTFILES.in'
--- po/POTFILES.in 2010-02-04 03:42:29 +0000
+++ po/POTFILES.in 2011-05-05 09:06:21 +0000
@@ -3,6 +3,7 @@
init/conf.c
init/control.c
init/environ.c
+init/errors.h
init/event.c
init/event_operator.c
init/job.c