| 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); |
| |