blob: 91ca5f8c0f2ee879ae65d4e20927d701b6cc207c [file] [log] [blame]
Add import stanza in job definitions.
Explicitly declare environment variables to import in job classes.
This allows to filter environment imported from events and IPC to give
the job a more predictable enviroment.
See also http://crbug.com/818032
--- a/init/control.c
+++ b/init/control.c
@@ -510,6 +510,9 @@ control_emit_event_with_file (void *data,
{
Event *event;
Blocked *blocked;
+ char **sanitized_env;
+ size_t len = 0;
+ char * const *e;
nih_assert (message != NULL);
nih_assert (name != NULL);
@@ -531,8 +534,27 @@ control_emit_event_with_file (void *data,
return -1;
}
+ /* Filter out variables generated by upstart internally */
+ sanitized_env = nih_str_array_new (message);
+ if (! sanitized_env) {
+ nih_error_raise_system ();
+ close (file);
+ return -1;
+ }
+
+ for (e = env; e && *e; e++) {
+ if ( environ_is_upstart_key(*e))
+ continue;
+
+ if (! environ_add (&sanitized_env, message, &len, TRUE, *e)) {
+ nih_error_raise_system ();
+ close (file);
+ return -1;
+ }
+ }
+
/* Make the event and block the message on it */
- event = event_new (NULL, name, (char **)env);
+ event = event_new (NULL, name, sanitized_env);
if (! event) {
nih_error_raise_system ();
close (file);
--- a/init/environ.c
+++ b/init/environ.c
@@ -385,6 +385,42 @@ environ_all_valid (char * const *env)
return TRUE;
}
+/**
+ * environ_is_upstart_key:
+ * @var: An environment variable or value in KEY=VALUE form.
+ *
+ * Checks whether @var names an environment variable that is internally used by
+ * upstart.
+ *
+ * Returns: TRUE if @var is an upstart-internal variable, FALSE otherwise.
+ **/
+int
+environ_is_upstart_key (const char *var)
+{
+ static const char * const upstart_keys[] = {
+ "JOB",
+ "INSTANCE",
+ "RESULT",
+ "PROCESS",
+ "EXIT_SIGNAL",
+ "EXIT_STATUS",
+ NULL,
+ };
+ static const char upstart_prefix[] = "UPSTART_";
+ const char * const *e;
+ size_t key_len;
+
+ key_len = strcspn (var, "=");
+ for (e = upstart_keys; *e; e++) {
+ if ((strncmp (*e, var, key_len) == 0) && !((*e)[key_len]))
+ return TRUE;
+ }
+
+ if ( strncmp(var, upstart_prefix, sizeof (upstart_prefix) - 1) == 0)
+ return TRUE;
+
+ return FALSE;
+}
/**
* environ_expand:
--- a/init/environ.h
+++ b/init/environ.h
@@ -45,6 +45,7 @@ const char * environ_getn (char * const *env, const char *key,
size_t len);
int environ_all_valid (char * const *env);
+int environ_is_upstart_key (const char *key);
char * environ_expand (const void *parent, const char *string,
char * const *env)
--- a/init/event.c
+++ b/init/event.c
@@ -279,6 +279,48 @@ event_pending (Event *event)
}
/**
+ * event_environment_init
+ * @root: event context
+ * @class: job class
+ * @env: environment to construct
+ * @parent: Parent for @env allocations
+ * @len: length of @env
+ * @event_list_key: the environment key to store event names in
+ *
+ * Constructs a the environment a job of @class should receive when it gets
+ * triggered by the event represented in @root. In particular, only
+ * upstart-internal enviroment variables and environment variables explicitly
+ * imported by the job a re copied over. Updates @env to hold the constructed
+ * environment.
+ **/
+static void
+event_environment_init (EventOperator *root,
+ JobClass *class,
+ char ***env,
+ void *parent,
+ size_t *len,
+ const char *event_list_key) {
+ nih_local char **event_op_env = NULL;
+ size_t event_op_env_len = 0;
+ char *const *event_list = NULL;
+ char **e = NULL;
+
+ NIH_MUST (event_operator_environment (root, &event_op_env, NULL,
+ &event_op_env_len,
+ event_list_key));
+
+ /* Copy all variables specifically whitelisted by the job. */
+ NIH_MUST (job_class_import_environment (class, env, parent, len,
+ event_op_env));
+
+ /* Copy over upstart-internal environment variables. */
+ for (e = event_op_env; e && *e; e++) {
+ if (environ_is_upstart_key (*e))
+ NIH_MUST (environ_add (env, parent, len, TRUE, *e));
+ }
+}
+
+/**
* event_pending_handle_jobs:
* @event: event to be handled.
*
@@ -326,9 +368,10 @@ event_pending_handle_jobs (Event *event)
* since this is appended to the
* existing job environment.
*/
- NIH_MUST (event_operator_environment (
- job->stop_on, &job->stop_env,
- job, &len, "UPSTART_STOP_EVENTS"));
+ event_environment_init (
+ job->stop_on, class,
+ &job->stop_env, job, &len,
+ "UPSTART_STOP_EVENTS");
job_finished (job, FALSE);
@@ -360,9 +403,8 @@ event_pending_handle_jobs (Event *event)
*/
env = NIH_MUST (job_class_environment (
NULL, class, &len));
- NIH_MUST (event_operator_environment (class->start_on,
- &env, NULL, &len,
- "UPSTART_EVENTS"));
+ event_environment_init (class->start_on, class, &env,
+ NULL, &len, "UPSTART_EVENTS");
/* Expand the instance name against the environment */
name = NIH_SHOULD (environ_expand (NULL,
--- a/init/job_class.c
+++ b/init/job_class.c
@@ -142,6 +142,7 @@ job_class_new (const void *parent,
class->env = NULL;
class->export = NULL;
+ class->import = NULL;
class->start_on = NULL;
class->stop_on = NULL;
@@ -442,6 +443,67 @@ error:
return NULL;
}
+/**
+ * job_class_import_environment:
+ * @class: class to import environment for.
+ * @env: pointer to environment table,
+ * @len: length of @env,
+ * @new_env: environment table to append to import into @env.
+ *
+ * Updates the environment table @env to add any entries in @new_env
+ * that are imported per import declarations in @class.
+ *
+ * Both the array and the new strings within it are allocated using
+ * nih_alloc().
+ *
+ * @len will be updated to contain the new array length and @env will
+ * be updated to point to the new array pointer; use the return value
+ * simply to check for success.
+ *
+ * Returns: new array pointer or NULL if insufficient memory.
+ **/
+char**
+job_class_import_environment (JobClass *class,
+ char ***env,
+ void *parent,
+ size_t *len,
+ char * const *new_env)
+{
+ char * const *e;
+
+ nih_assert (env != NULL);
+
+ if (! *env) {
+ *env = nih_str_array_new (parent);
+ if (! *env)
+ return NULL;
+ if (len)
+ *len = 0;
+ }
+
+ for (e = new_env; e && *e; e++) {
+ char * const *match = NULL;
+ size_t elen;
+
+ if (environ_is_upstart_key (*e))
+ continue;
+
+ elen = strcspn(*e, "=");
+ for (match = class->import; match && *match; match++) {
+ if ((strncmp (*match, *e, elen) == 0) && ! (*match)[elen])
+ break;
+ }
+
+ if (! match || ! *match)
+ continue;
+
+ if (! environ_add (env, parent, len, TRUE, *e))
+ return NULL;
+ }
+
+ return *env;
+}
+
/**
* job_class_get_instance:
@@ -490,7 +552,8 @@ job_class_get_instance (JobClass *class,
if (! instance_env)
nih_return_system_error (-1);
- if (! environ_append (&instance_env, NULL, &len, TRUE, env))
+ if (! job_class_import_environment (class, &instance_env, NULL, &len,
+ env))
nih_return_system_error (-1);
/* Use the environment to expand the instance name and look it up
@@ -678,7 +741,7 @@ job_class_start (JobClass *class,
if (! start_env)
nih_return_system_error (-1);
- if (! environ_append (&start_env, NULL, &len, TRUE, env))
+ if (! job_class_import_environment (class, &start_env, NULL, &len, env))
nih_return_system_error (-1);
/* Use the environment to expand the instance name and look it up
@@ -798,7 +861,7 @@ job_class_stop (JobClass *class,
if (! stop_env)
nih_return_system_error (-1);
- if (! environ_append (&stop_env, NULL, &len, TRUE, env))
+ if (! job_class_import_environment (class, &stop_env, NULL, &len, env))
nih_return_system_error (-1);
/* Use the environment to expand the instance name and look it up
@@ -845,7 +908,7 @@ job_class_stop (JobClass *class,
if (job->stop_env)
nih_unref (job->stop_env, job);
- job->stop_env = (char **)env;
+ job->stop_env = stop_env;
nih_ref (job->stop_env, job);
job_finished (job, FALSE);
@@ -921,7 +984,8 @@ job_class_restart (JobClass *class,
if (! restart_env)
nih_return_system_error (-1);
- if (! environ_append (&restart_env, NULL, &len, TRUE, env))
+ if (! job_class_import_environment (class, &restart_env, NULL, &len,
+ env))
nih_return_system_error (-1);
/* Use the environment to expand the instance name and look it up
--- a/init/job_class.h
+++ b/init/job_class.h
@@ -134,6 +134,7 @@ typedef enum console_type {
* @version: version; intended for humans,
* @env: NULL-terminated array of default environment variables,
* @export: NULL-terminated array of environment exported to events,
+ * @import: NULL-terminated array of environment to be imported from IPC,
* @start_on: event operator expression that can start an instance,
* @stop_on: event operator expression that stops instances,
* @emits: NULL-terminated array of events that may be emitted by instances,
@@ -176,6 +177,7 @@ typedef struct job_class {
char **env;
char **export;
+ char **import;
EventOperator *start_on;
EventOperator *stop_on;
@@ -231,7 +233,11 @@ void job_class_unregister (JobClass *class,
char **job_class_environment (const void *parent,
JobClass *class, size_t *len)
__attribute__ ((warn_unused_result, malloc));
-
+char** job_class_import_environment (JobClass *class,
+ char ***env,
+ void *parent,
+ size_t *len,
+ char * const *new_env);
int job_class_get_instance (JobClass *class,
NihDBusMessage *message,
--- a/init/man/init.5
+++ b/init/man/init.5
@@ -307,9 +307,20 @@ automatically started. When specified, the only way to start such a job
is via \fBstart\fP (8).
.SS Job environment
-Each job is run with the environment from the events or commands that
-started it. In addition, you may define defaults in the job which may
-be overridden later and specify which environment variables are exported
+Each job is run with an environment constructed by init that includes
+additional information about the context the job was invoked in. The
+job inherits a basic environment from the init process including some
+important variables, typically
+.B PATH
+and
+.BR TERM.
+The job can use the
+.B import
+stanza in its definition to declare additional variables it wants to
+import. Values for imported variables may be supplied by events handled
+by the job or by commands that start or stop the job. In addition, you
+may define defaults for additional variables in the job which may be
+overridden later and specify which environment variables are exported
into the events generated for the job.
The special
@@ -358,6 +369,21 @@ and to all resultant events
.ft
(not just those relating to the current job).
.\"
+.TP
+.B import \fIKEY\fR
+Imports an environment variable from the event or command that started
+the job. The job must declare all environment variables that it expects
+to be supplied by events or commands. Variables that are present in
+events or commands but are not mentioned in
+.B import
+stanzas will not propagate into the job environment. Variables
+that are provided by init (such as the various
+.B UPSTART_
+variables mentioned above) are entirely unaffected by import
+declarations: They are automatically present in the job environment if
+applicable but never allowed to be overriden by events or commands,
+regardless of the presence of corresponding import declarations.
+
.SS Services, tasks and respawning
Jobs are
.I services
--- a/init/parse_job.c
+++ b/init/parse_job.c
@@ -118,6 +118,10 @@ static int stanza_export (JobClass *class, NihConfigStanza *stanza,
const char *file, size_t len,
size_t *pos, size_t *lineno)
__attribute__ ((warn_unused_result));
+static int stanza_import (JobClass *class, NihConfigStanza *stanza,
+ const char *file, size_t len,
+ size_t *pos, size_t *lineno)
+ __attribute__ ((warn_unused_result));
static int stanza_start (JobClass *class, NihConfigStanza *stanza,
const char *file, size_t len,
@@ -232,6 +236,7 @@ static NihConfigStanza stanzas[] = {
{ "version", (NihConfigHandler)stanza_version },
{ "env", (NihConfigHandler)stanza_env },
{ "export", (NihConfigHandler)stanza_export },
+ { "import", (NihConfigHandler)stanza_import },
{ "start", (NihConfigHandler)stanza_start },
{ "stop", (NihConfigHandler)stanza_stop },
{ "emits", (NihConfigHandler)stanza_emits },
@@ -1298,6 +1303,52 @@ stanza_export (JobClass *class,
return 0;
}
+/**
+ * stanza_import:
+ * @class: job class being parsed,
+ * @stanza: stanza found,
+ * @file: file or string to parse,
+ * @len: length of @file,
+ * @pos: offset within @file,
+ * @lineno: line number.
+ *
+ * Parse an import stanza from @file, extracting one or more arguments
+ * containing environment variable names. These are stored in the import
+ * array, which is increased in size to accommodate the new values.
+ *
+ * Returns: zero on success, negative value on error.
+ **/
+static int
+stanza_import (JobClass *class,
+ NihConfigStanza *stanza,
+ const char *file,
+ size_t len,
+ size_t *pos,
+ size_t *lineno)
+{
+ nih_local char **args = NULL;
+ char **arg;
+
+ nih_assert (class != NULL);
+ nih_assert (stanza != NULL);
+ nih_assert (file != NULL);
+ nih_assert (pos != NULL);
+
+ if (! nih_config_has_token (file, len, pos, lineno))
+ nih_return_error (-1, NIH_CONFIG_EXPECTED_TOKEN,
+ _(NIH_CONFIG_EXPECTED_TOKEN_STR));
+
+ args = nih_config_parse_args (NULL, file, len, pos, lineno);
+ if (! args)
+ return -1;
+
+ for (arg = args; *arg; arg++)
+ if (! nih_str_array_addp (&class->import, class, NULL, *arg))
+ nih_return_system_error (-1);
+
+ return 0;
+}
+
/**
* stanza_start:
--- a/init/tests/test_event.c
+++ b/init/tests/test_event.c
@@ -427,7 +427,7 @@ test_pending_handle_jobs (void)
TEST_NE_P (job->env, NULL);
TEST_ALLOC_PARENT (job->env, job);
- TEST_ALLOC_SIZE (job->env, sizeof (char *) * 6);
+ TEST_ALLOC_SIZE (job->env, sizeof (char *) * 5);
TEST_ALLOC_PARENT (job->env[0], job->env);
TEST_EQ_STRN (job->env[0], "PATH=");
TEST_ALLOC_PARENT (job->env[1], job->env);
@@ -481,7 +481,7 @@ test_pending_handle_jobs (void)
/* Check that the environment variables from the event are also copied
- * into the job's environment.
+ * into the job's environment if imported.
*/
TEST_FEATURE ("with environment in start event");
TEST_ALLOC_FAIL {
@@ -510,6 +510,10 @@ test_pending_handle_jobs (void)
assert (nih_str_array_add (&(class->env), class,
NULL, "BAR=BAZ"));
+ class->import = nih_str_array_new (class);
+ assert (nih_str_array_add (&class->import, class, NULL,
+ "FRODO"));
+
class->start_on = event_operator_new (
class, EVENT_AND, NULL, NULL);
@@ -547,7 +551,7 @@ test_pending_handle_jobs (void)
TEST_NE_P (job->env, NULL);
TEST_ALLOC_PARENT (job->env, job);
- TEST_ALLOC_SIZE (job->env, sizeof (char *) * 9);
+ TEST_ALLOC_SIZE (job->env, sizeof (char *) * 7);
TEST_ALLOC_PARENT (job->env[0], job->env);
TEST_EQ_STRN (job->env[0], "PATH=");
TEST_ALLOC_PARENT (job->env[1], job->env);
@@ -559,12 +563,8 @@ test_pending_handle_jobs (void)
TEST_ALLOC_PARENT (job->env[4], job->env);
TEST_EQ_STR (job->env[4], "FRODO=brandybuck");
TEST_ALLOC_PARENT (job->env[5], job->env);
- TEST_EQ_STR (job->env[5], "BILBO=took");
- TEST_ALLOC_PARENT (job->env[6], job->env);
- TEST_EQ_STR (job->env[6], "TEA=MILK");
- TEST_ALLOC_PARENT (job->env[7], job->env);
- TEST_EQ_STR (job->env[7], "UPSTART_EVENTS=wibble wobble");
- TEST_EQ_P (job->env[8], NULL);
+ TEST_EQ_STR (job->env[5], "UPSTART_EVENTS=wibble wobble");
+ TEST_EQ_P (job->env[6], NULL);
TEST_EQ_P (job->start_env, NULL);
@@ -714,7 +714,7 @@ test_pending_handle_jobs (void)
TEST_NE_P (job->start_env, NULL);
TEST_ALLOC_PARENT (job->start_env, job);
- TEST_ALLOC_SIZE (job->start_env, sizeof (char *) * 9);
+ TEST_ALLOC_SIZE (job->start_env, sizeof (char *) * 6);
TEST_ALLOC_PARENT (job->start_env[0], job->start_env);
TEST_EQ_STRN (job->start_env[0], "PATH=");
TEST_ALLOC_PARENT (job->start_env[1], job->start_env);
@@ -724,14 +724,8 @@ test_pending_handle_jobs (void)
TEST_ALLOC_PARENT (job->start_env[3], job->start_env);
TEST_EQ_STR (job->start_env[3], "BAR=BAZ");
TEST_ALLOC_PARENT (job->start_env[4], job->start_env);
- TEST_EQ_STR (job->start_env[4], "FRODO=brandybuck");
- TEST_ALLOC_PARENT (job->start_env[5], job->start_env);
- TEST_EQ_STR (job->start_env[5], "BILBO=took");
- TEST_ALLOC_PARENT (job->start_env[6], job->start_env);
- TEST_EQ_STR (job->start_env[6], "TEA=MILK");
- TEST_ALLOC_PARENT (job->start_env[7], job->start_env);
- TEST_EQ_STR (job->start_env[7], "UPSTART_EVENTS=wibble wobble");
- TEST_EQ_P (job->start_env[8], NULL);
+ TEST_EQ_STR (job->start_env[4], "UPSTART_EVENTS=wibble wobble");
+ TEST_EQ_P (job->start_env[5], NULL);
oper = class->start_on;
TEST_EQ (oper->value, FALSE);
@@ -925,6 +919,10 @@ test_pending_handle_jobs (void)
class->instance = "$FRODO";
class->task = TRUE;
+ class->import = nih_str_array_new (class);
+ assert (nih_str_array_add (&class->import, class, NULL,
+ "FRODO"));
+
class->start_on = event_operator_new (
class, EVENT_MATCH, "wibble", NULL);
@@ -949,7 +947,7 @@ test_pending_handle_jobs (void)
TEST_NE_P (job->env, NULL);
TEST_ALLOC_PARENT (job->env, job);
- TEST_ALLOC_SIZE (job->env, sizeof (char *) * 6);
+ TEST_ALLOC_SIZE (job->env, sizeof (char *) * 5);
TEST_ALLOC_PARENT (job->env[0], job->env);
TEST_EQ_STRN (job->env[0], "PATH=");
TEST_ALLOC_PARENT (job->env[1], job->env);
@@ -957,10 +955,8 @@ test_pending_handle_jobs (void)
TEST_ALLOC_PARENT (job->env[2], job->env);
TEST_EQ_STR (job->env[2], "FRODO=baggins");
TEST_ALLOC_PARENT (job->env[3], job->env);
- TEST_EQ_STR (job->env[3], "BILBO=took");
- TEST_ALLOC_PARENT (job->env[4], job->env);
- TEST_EQ_STR (job->env[4], "UPSTART_EVENTS=wibble");
- TEST_EQ_P (job->env[5], NULL);
+ TEST_EQ_STR (job->env[3], "UPSTART_EVENTS=wibble");
+ TEST_EQ_P (job->env[4], NULL);
TEST_EQ_P (job->start_env, NULL);
@@ -1004,6 +1000,10 @@ test_pending_handle_jobs (void)
class->instance = "$FRODO";
class->task = TRUE;
+ class->import = nih_str_array_new (class);
+ assert (nih_str_array_add (&class->import, class, NULL,
+ "FRODO"));
+
class->start_on = event_operator_new (
class, EVENT_MATCH, "wibble", NULL);
@@ -1237,7 +1237,7 @@ test_pending_handle_jobs (void)
/* Check that the environment variables from the event are also copied
- * into the job's stop_env member.
+ * into the job's stop_env member if imported.
*/
TEST_FEATURE ("with environment in stop event");
TEST_ALLOC_FAIL {
@@ -1253,6 +1253,10 @@ test_pending_handle_jobs (void)
class = job_class_new (NULL, "test");
class->task = TRUE;
+ class->import = nih_str_array_new (class);
+ assert (nih_str_array_add (&class->import, class, NULL,
+ "FOO"));
+
class->process[PROCESS_POST_STOP] = process_new (class);
class->process[PROCESS_POST_STOP]->command = "echo";
@@ -1284,14 +1288,12 @@ test_pending_handle_jobs (void)
TEST_NE_P (job->stop_env, NULL);
TEST_ALLOC_PARENT (job->stop_env, job);
- TEST_ALLOC_SIZE (job->stop_env, sizeof (char *) * 4);
+ TEST_ALLOC_SIZE (job->stop_env, sizeof (char *) * 3);
TEST_ALLOC_PARENT (job->stop_env[0], job->stop_env);
TEST_EQ_STR (job->stop_env[0], "FOO=foo");
TEST_ALLOC_PARENT (job->stop_env[1], job->stop_env);
- TEST_EQ_STR (job->stop_env[1], "BAR=bar");
- TEST_ALLOC_PARENT (job->stop_env[2], job->stop_env);
- TEST_EQ_STR (job->stop_env[2], "UPSTART_STOP_EVENTS=wibble");
- TEST_EQ_P (job->stop_env[3], NULL);
+ TEST_EQ_STR (job->stop_env[1], "UPSTART_STOP_EVENTS=wibble");
+ TEST_EQ_P (job->stop_env[2], NULL);
oper = job->stop_on;
@@ -1389,14 +1391,10 @@ test_pending_handle_jobs (void)
TEST_NE_P (job->stop_env, NULL);
TEST_ALLOC_PARENT (job->stop_env, job);
- TEST_ALLOC_SIZE (job->stop_env, sizeof (char *) * 4);
+ TEST_ALLOC_SIZE (job->stop_env, sizeof (char *) * 2);
TEST_ALLOC_PARENT (job->stop_env[0], job->stop_env);
- TEST_EQ_STR (job->stop_env[0], "FOO=foo");
- TEST_ALLOC_PARENT (job->stop_env[1], job->stop_env);
- TEST_EQ_STR (job->stop_env[1], "BAR=bar");
- TEST_ALLOC_PARENT (job->stop_env[2], job->stop_env);
- TEST_EQ_STR (job->stop_env[2], "UPSTART_STOP_EVENTS=wibble");
- TEST_EQ_P (job->stop_env[3], NULL);
+ TEST_EQ_STR (job->stop_env[0], "UPSTART_STOP_EVENTS=wibble");
+ TEST_EQ_P (job->stop_env[1], NULL);
oper = job->stop_on;
@@ -1567,14 +1565,10 @@ test_pending_handle_jobs (void)
TEST_NE_P (job->stop_env, NULL);
TEST_ALLOC_PARENT (job->stop_env, job);
- TEST_ALLOC_SIZE (job->stop_env, sizeof (char *) * 4);
+ TEST_ALLOC_SIZE (job->stop_env, sizeof (char *) * 2);
TEST_ALLOC_PARENT (job->stop_env[0], job->stop_env);
- TEST_EQ_STR (job->stop_env[0], "SNITCH=GOLD");
- TEST_ALLOC_PARENT (job->stop_env[1], job->stop_env);
- TEST_EQ_STR (job->stop_env[1], "SEAKER=WIZARD");
- TEST_ALLOC_PARENT (job->stop_env[2], job->stop_env);
- TEST_EQ_STR (job->stop_env[2], "UPSTART_STOP_EVENTS=wibble");
- TEST_EQ_P (job->stop_env[3], NULL);
+ TEST_EQ_STR (job->stop_env[0], "UPSTART_STOP_EVENTS=wibble");
+ TEST_EQ_P (job->stop_env[1], NULL);
oper = job->stop_on;
--- a/init/tests/test_job_class.c
+++ b/init/tests/test_job_class.c
@@ -1149,6 +1149,9 @@ test_get_instance (void)
TEST_ALLOC_SAFE {
class = job_class_new (NULL, "test");
class->instance = "$FOO";
+ class->import = nih_str_array_new (class);
+ assert (nih_str_array_add (&class->import, class, NULL,
+ "FOO"));
job = job_new (class, "wibble");
@@ -1829,6 +1832,8 @@ test_start (void)
TEST_FEATURE ("with environment");
class = job_class_new (NULL, "test");
class->instance = "$FOO";
+ class->import = nih_str_array_new (class);
+ assert (nih_str_array_add (&class->import, class, NULL, "FOO"));
method = dbus_message_new_method_call (
dbus_bus_get_unique_name (conn),
@@ -1876,8 +1881,7 @@ test_start (void)
TEST_EQ_STRN (job->env[0], "PATH=");
TEST_EQ_STRN (job->env[1], "TERM=");
TEST_EQ_STR (job->env[2], "FOO=wibble");
- TEST_EQ_STR (job->env[3], "BAR=wobble");
- TEST_EQ_P (job->env[4], NULL);
+ TEST_EQ_P (job->env[3], NULL);
TEST_LIST_NOT_EMPTY (&job->blocking);
@@ -2275,6 +2279,8 @@ test_stop (void)
TEST_FEATURE ("with environment");
class = job_class_new (NULL, "test");
class->instance = "$FOO";
+ class->import = nih_str_array_new (class);
+ assert (nih_str_array_add (&class->import, class, NULL, "FOO"));
job = job_new (class, "wibble");
job->goal = JOB_START;
@@ -2317,9 +2323,10 @@ test_stop (void)
TEST_EQ (job->goal, JOB_STOP);
TEST_EQ (job->state, JOB_STOPPING);
- TEST_EQ_STR (job->stop_env[0], "FOO=wibble");
- TEST_EQ_STR (job->stop_env[1], "BAR=wobble");
- TEST_EQ_P (job->stop_env[2], NULL);
+ TEST_EQ_STRN (job->stop_env[0], "PATH=");
+ TEST_EQ_STRN (job->stop_env[1], "TERM=");
+ TEST_EQ_STR (job->stop_env[2], "FOO=wibble");
+ TEST_EQ_P (job->stop_env[3], NULL);
TEST_LIST_NOT_EMPTY (&job->blocking);
@@ -2737,6 +2744,8 @@ test_restart (void)
TEST_FEATURE ("with environment");
class = job_class_new (NULL, "test");
class->instance = "$FOO";
+ class->import = nih_str_array_new (class);
+ assert (nih_str_array_add (&class->import, class, NULL, "FOO"));
job = job_new (class, "wibble");
job->goal = JOB_START;
@@ -2780,8 +2789,7 @@ test_restart (void)
TEST_EQ_STRN (job->start_env[0], "PATH=");
TEST_EQ_STRN (job->start_env[1], "TERM=");
TEST_EQ_STR (job->start_env[2], "FOO=wibble");
- TEST_EQ_STR (job->start_env[3], "BAR=wobble");
- TEST_EQ_P (job->start_env[4], NULL);
+ TEST_EQ_P (job->start_env[3], NULL);
TEST_LIST_NOT_EMPTY (&job->blocking);
@@ -2806,8 +2814,7 @@ test_restart (void)
TEST_EQ_STRN (job->env[0], "PATH=");
TEST_EQ_STRN (job->env[1], "TERM=");
TEST_EQ_STR (job->env[2], "FOO=wibble");
- TEST_EQ_STR (job->env[3], "BAR=wobble");
- TEST_EQ_P (job->env[4], NULL);
+ TEST_EQ_P (job->env[3], NULL);
TEST_NOT_FREE (blocked);