------------------------------------------------------------ revno: 1421 committer: James Hunt <[email protected]> branch nick: upstart-setenv+getenv timestamp: Fri 2013-01-25 20:08:49 +0000 message: * dbus/com.ubuntu.Upstart.xml: - Added 'job_details' string array as first parameter for GetEnv, SetEnv, UnsetEnv, ListEnv and ResetEnv to allow methods to either act globally or on a specific job environment. * init/control.c: - control_set_env(): - control_unset_env(): - control_get_env(): - control_list_env(): - control_reset_env(): - Disallow setting for PID 1. - Operate globally or on specified job. * init/control.h: control_get_job(): Macro to simplify extracting job from provided job details. * init/job.c: job_find(): New function. * init/job_class.c: - job_class_environment_set(): Delimiter handling now moved to control_set_env() so it can be shared by job and global logic. - job_class_find(): New function. * init/state.c: - Removed state_get_job() and replaced calls with job_find(). * util/initctl.c: - Updated *_action() functions for new D-Bus parameters and made use of new function get_job_details(). modified: ChangeLog dbus/com.ubuntu.Upstart.xml init/control.c init/control.h init/job.c init/job.h init/job_class.c init/job_class.h init/state.c util/initctl.c
-- lp:upstart https://code.launchpad.net/~upstart-devel/upstart/trunk Your team Upstart Reviewers is subscribed to branch lp:upstart. To unsubscribe from this branch go to https://code.launchpad.net/~upstart-devel/upstart/trunk/+edit-subscription
=== modified file 'ChangeLog' --- ChangeLog 2013-01-25 20:02:26 +0000 +++ ChangeLog 2013-01-25 20:08:49 +0000 @@ -1,5 +1,32 @@ 2013-01-25 James Hunt <[email protected]> + * dbus/com.ubuntu.Upstart.xml: + - Added 'job_details' string array as first parameter for GetEnv, + SetEnv, UnsetEnv, ListEnv and ResetEnv to allow methods to either + act globally or on a specific job environment. + * init/control.c: + - control_set_env(): + - control_unset_env(): + - control_get_env(): + - control_list_env(): + - control_reset_env(): + - Disallow setting for PID 1. + - Operate globally or on specified job. + * init/control.h: control_get_job(): Macro to simplify extracting job + from provided job details. + * init/job.c: job_find(): New function. + * init/job_class.c: + - job_class_environment_set(): Delimiter handling now moved to + control_set_env() so it can be shared by job and global logic. + - job_class_find(): New function. + * init/state.c: + - Removed state_get_job() and replaced calls with job_find(). + * util/initctl.c: + - Updated *_action() functions for new D-Bus parameters and made use + of new function get_job_details(). + +2013-01-25 James Hunt <[email protected]> + * init/control.c: - control_reload_configuration(): Added missing permission checks. - control_emit_event_with_file(): Added missing permission checks. === modified file 'dbus/com.ubuntu.Upstart.xml' --- dbus/com.ubuntu.Upstart.xml 2013-01-08 15:57:31 +0000 +++ dbus/com.ubuntu.Upstart.xml 2013-01-25 20:08:49 +0000 @@ -43,24 +43,30 @@ </method> <method name="GetEnv"> + <arg name="job_details" type="as" direction="in" /> <arg name="name" type="s" direction="in" /> <arg name="value" type="s" direction="out" /> </method> <method name="SetEnv"> + <arg name="job_details" type="as" direction="in" /> <arg name="var" type="s" direction="in" /> <arg name="replace" type="b" direction="in" /> </method> <method name="UnsetEnv"> + <arg name="job_details" type="as" direction="in" /> <arg name="name" type="s" direction="in" /> </method> <method name="ListEnv"> + <arg name="job_details" type="as" direction="in" /> <arg name="env" type="as" direction="out" /> </method> - <method name="ResetEnv"/> + <method name="ResetEnv"> + <arg name="job_details" type="as" direction="in" /> + </method> <!-- Signals for changes to the job list --> <signal name="JobAdded"> === modified file 'init/control.c' --- init/control.c 2013-01-25 20:02:26 +0000 +++ init/control.c 2013-01-25 20:08:49 +0000 @@ -50,6 +50,7 @@ #include "environ.h" #include "session.h" #include "job_class.h" +#include "job.h" #include "blocked.h" #include "conf.h" #include "control.h" @@ -1233,6 +1234,9 @@ return -1; } + /* Lookup the job */ + control_get_job (job, job_name, instance); + /* If variable does not contain a delimiter, add one to ensure * it gets entered into the job environment table. Without the * delimiter, the variable will be silently ignored unless it's @@ -1335,6 +1339,9 @@ return -1; } + /* Lookup the job */ + control_get_job (job, job_name, instance); + if (job) { /* Modify job-specific environment */ @@ -1434,6 +1441,9 @@ return -1; } + /* Lookup the job */ + control_get_job (job, job_name, instance); + if (job) { tmp = environ_get (job->env, name); if (! tmp) @@ -1526,6 +1536,9 @@ return -1; } + /* Lookup the job */ + control_get_job (job, job_name, instance); + if (job) { *env = nih_str_array_copy (job, NULL, job->env); if (! *env) @@ -1613,6 +1626,10 @@ return -1; } + /* Lookup the job */ + control_get_job (job, job_name, instance); + + if (job) { size_t len; if (job->env) { === modified file 'init/control.h' --- init/control.h 2013-01-25 20:02:26 +0000 +++ init/control.h 2013-01-25 20:08:49 +0000 @@ -44,6 +44,45 @@ #define USE_SESSION_BUS_ENV "UPSTART_USE_SESSION_BUS" #endif +/** + * control_get_job: + * + * @job: Job that will be set, + * @job_name: name of job to search for, + * @instance: instance of @job_name to search for. + * + * Determine the Job associated with @job_name and @instance and set it + * to @job. + * + * Returns: -1 on raised error, or nothing on success. + **/ +#define control_get_job(job, job_name, instance) \ +{ \ + if (job_name != NULL ) { \ + JobClass *class; \ + \ + class = job_class_find (session, job_name); \ + if (! class) { \ + nih_dbus_error_raise_printf ( \ + DBUS_INTERFACE_UPSTART \ + ".Error.UnknownJob", \ + _("Unknown job: %s"), \ + job_name); \ + return -1; \ + } \ + \ + job = job_find (session, class, NULL, instance); \ + if (! job) { \ + nih_dbus_error_raise_printf ( \ + DBUS_INTERFACE_UPSTART \ + ".Error.UnknownJobInstance", \ + _("Unknown instance: %s of job %s"), \ + job_name, instance); \ + return -1; \ + } \ + } \ +} + NIH_BEGIN_EXTERN extern DBusServer *control_server; === modified file 'init/job.c' --- init/job.c 2013-01-25 09:01:00 +0000 +++ init/job.c 2013-01-25 20:08:49 +0000 @@ -2211,3 +2211,43 @@ nih_free (timer); return NULL; } + +/** + * job_find: + * + * @session: session of job class, + * @job_class: name of job class, + * @job_name: name of job instance. + * + * Lookup job based on parent class name and + * job instance name. + * + * Returns: existing Job on success, or NULL if job class or + * job are not found in @session. + **/ +Job * +job_find (const Session *session, + JobClass *class, + char *job_class, + const char *job_name) +{ + Job *job; + + nih_assert (class || job_class); + nih_assert (job_classes); + + if (! class) + class = job_class_find (session, job_class); + + if (! class) + goto error; + + job = (Job *)nih_hash_lookup (class->instances, job_name); + if (! job) + goto error; + + return job; + +error: + return NULL; +} === modified file 'init/job.h' --- init/job.h 2012-09-20 13:07:53 +0000 +++ init/job.h 2013-01-25 20:08:49 +0000 @@ -220,6 +220,12 @@ int job_deserialise_all (JobClass *parent, json_object *json) __attribute__ ((warn_unused_result)); +Job * job_find (const Session *session, + JobClass *class, + char *job_class, + const char *job_name) + __attribute__ ((warn_unused_result)); + NIH_END_EXTERN #endif /* INIT_JOB_H */ === modified file 'init/job_class.c' --- init/job_class.c 2013-01-25 20:02:26 +0000 +++ init/job_class.c 2013-01-25 20:08:49 +0000 @@ -151,25 +151,11 @@ int job_class_environment_set (const char *var, int replace) { - nih_local char *envvar = NULL; - nih_assert (var); job_class_environment_init (); - /* If variable does not contain a delimiter, add one to ensure - * it gets entered into the job environment table. Without the - * delimiter, the variable will be silently ignored unless it's - * already set in inits environment. But in that case there is - * no point in setting such a variable to its already existing - * value. - */ - if (! strchr (var, '=')) - envvar = NIH_MUST (nih_sprintf (NULL, "%s=", var)); - else - envvar = NIH_MUST (nih_strdup (NULL, var)); - - if (! environ_add (&job_environ, NULL, NULL, replace, envvar)) + if (! environ_add (&job_environ, NULL, NULL, replace, var)) return -1; return 0; @@ -226,7 +212,6 @@ * * Returns: pointer to static storage value of @name, or NULL if @name * does not exist in job environment. - * **/ const char * job_class_environment_get (const char *name) @@ -2336,3 +2321,29 @@ error: nih_warn (_("unable to clear CLOEXEC bit on log fd")); } + +/** + * job_class_find: + * + * @session: session, + * @name: name of JobClass. + * + * Lookup a JobClass by session and name. + * + * Returns: JobClass associated with @session, or NULL if not found. + */ +JobClass * +job_class_find (const Session *session, + const char *name) +{ + JobClass *class; + + nih_assert (name); + + do { + class = (JobClass *)nih_hash_search (job_classes, + name, class ? &class->entry : NULL); + } while (class && class->session != session); + + return class; +} === modified file 'init/job_class.h' --- init/job_class.h 2013-01-08 15:57:31 +0000 +++ init/job_class.h 2013-01-25 20:08:49 +0000 @@ -356,6 +356,9 @@ void job_class_prepare_reexec (void); +JobClass * job_class_find (const Session *session, const char *name) + __attribute__ ((warn_unused_result)); + NIH_END_EXTERN #endif /* INIT_JOB_CLASS_H */ === modified file 'init/state.c' --- init/state.c 2013-01-21 22:44:27 +0000 +++ init/state.c 2013-01-25 20:08:49 +0000 @@ -72,11 +72,6 @@ state_index_to_job_class (int job_class_index) __attribute__ ((warn_unused_result)); -static Job * -state_get_job (const Session *session, const char *job_class, - const char *job_name) - __attribute__ ((warn_unused_result)); - static void state_write_file (NihIoBuffer *buffer); /** @@ -1214,7 +1209,7 @@ goto error; /* lookup job */ - job = state_get_job (class->session, class->name, job_name); + job = job_find (class->session, NULL, class->name, job_name); if (! job) goto error; @@ -1507,7 +1502,7 @@ session = session_from_index (session_index); - job = state_get_job (session, job_class_name, job_name); + job = job_find (session, NULL, job_class_name, job_name); if (! job) goto error; @@ -1706,48 +1701,6 @@ } /** - * state_get_job: - * - * @session: session of job class, - * @job_class: name of job class, - * @job_name: name of job instance. - * - * Lookup job based on parent class name and - * job instance name. - * - * Returns: existing Job on success, or NULL if job class or - * job not found. - **/ -static Job * -state_get_job (const Session *session, - const char *job_class, - const char *job_name) -{ - JobClass *class = NULL; - Job *job; - - nih_assert (job_class); - nih_assert (job_classes); - - do { - class = (JobClass *)nih_hash_search (job_classes, - job_class, class ? &class->entry : NULL); - } while (class && class->session != session); - - if (! class) - goto error; - - job = (Job *)nih_hash_lookup (class->instances, job_name); - if (! job) - goto error; - - return job; - -error: - return NULL; -} - -/** * state_data_to_hex: * * @parent: parent, === modified file 'util/initctl.c' --- util/initctl.c 2013-01-25 20:02:26 +0000 +++ util/initctl.c 2013-01-25 20:08:49 +0000 @@ -103,6 +103,8 @@ static int allow_job (const char *job); static int allow_event (const char *event); +static char **get_job_details (void) + __attribute__ ((warn_unused_result)); #ifndef TEST @@ -1393,6 +1395,7 @@ { nih_local NihDBusProxy *upstart = NULL; nih_local char *envvar = NULL; + nih_local char **job_details = NULL; NihError *err; char *name; @@ -1407,11 +1410,17 @@ return 1; } + job_details = get_job_details (); + if (! job_details) + return 1; + upstart = upstart_open (NULL); if (! upstart) return 1; - if (upstart_get_env_sync (NULL, upstart, name, &envvar) < 0) + job_details = NIH_MUST (nih_str_array_new (NULL)); + + if (upstart_get_env_sync (NULL, upstart, job_details, name, &envvar) < 0) goto error; nih_message ("%s", envvar); @@ -1441,23 +1450,32 @@ nih_local NihDBusProxy *upstart = NULL; NihError *err; char *envvar; + nih_local char **job_details = NULL; + int ret; nih_assert (command != NULL); nih_assert (args != NULL); + if (! args[0]) { + fprintf (stderr, _("%s: missing variable value\n"), program_name); + nih_main_suggest_help (); + return 1; + } + + job_details = get_job_details (); + if (! job_details) + return 1; + envvar = args[0]; - if (! envvar) { - fprintf (stderr, _("%s: missing variable value\n"), program_name); - nih_main_suggest_help (); - return 1; - } - upstart = upstart_open (NULL); if (! upstart) return 1; - if (upstart_set_env_sync (NULL, upstart, envvar, ! retain_var) < 0) + ret = upstart_set_env_sync (NULL, upstart, job_details, + envvar, ! retain_var); + + if (ret < 0) goto error; return 0; @@ -1485,6 +1503,7 @@ nih_local NihDBusProxy *upstart = NULL; NihError *err; char *name; + nih_local char **job_details = NULL; nih_assert (command != NULL); nih_assert (args != NULL); @@ -1497,11 +1516,15 @@ return 1; } + job_details = get_job_details (); + if (! job_details) + return 1; + upstart = upstart_open (NULL); if (! upstart) return 1; - if (upstart_unset_env_sync (NULL, upstart, name) < 0) + if (upstart_unset_env_sync (NULL, upstart, job_details, name) < 0) goto error; return 0; @@ -1527,15 +1550,20 @@ { nih_local NihDBusProxy *upstart = NULL; NihError *err; + nih_local char **job_details = NULL; nih_assert (command != NULL); nih_assert (args != NULL); + job_details = get_job_details (); + if (! job_details) + return 1; + upstart = upstart_open (NULL); if (! upstart) return 1; - if (upstart_reset_env_sync (NULL, upstart) < 0) + if (upstart_reset_env_sync (NULL, upstart, job_details) < 0) goto error; return 0; @@ -1580,15 +1608,20 @@ char **e; NihError *err; size_t len; + nih_local char **job_details = NULL; nih_assert (command != NULL); nih_assert (args != NULL); + job_details = get_job_details (); + if (! job_details) + return 1; + upstart = upstart_open (NULL); if (! upstart) return 1; - if (upstart_list_env_sync (NULL, upstart, &env) < 0) + if (upstart_list_env_sync (NULL, upstart, job_details, &env) < 0) goto error; /* Determine array size */ @@ -2636,6 +2669,65 @@ return TRUE; } +/** + * get_job_details: + * + * Determine the job and job instance name that the caller should act + * upon. Used by the job environment commands. The caller can determine + * how to react based on the values in the returned array: + * + * - If user has requested global operation via the command line, return + * an allocated array with zero elements. + * + * - If user has specified a job name and possible instance value via the + * command line, return an array containing first the job name, then the + * instance value. + * + * - If no command-line options have been specified, try to extract the + * job and instance names from the environment variables set within a + * jobs environment. + * + * Returns: Newly-allocated array containing job name and job + * instance, or an empty array if job and instance cannot be resolved, + * or NULL on error. + **/ +char ** +get_job_details (void) +{ + char **details; + const char *upstart_job = NULL; + const char *upstart_instance = NULL; + + details = nih_str_array_new (NULL); + + if (! details) + return NULL; + + /* The global option trounces all others */ + if (apply_globally) { + upstart_job = upstart_instance = NULL; + } else if (job_name) { + upstart_job = job_name; + upstart_instance = job_instance ? job_instance : ""; + } else { + upstart_job = getenv ("UPSTART_JOB"); + upstart_instance = getenv ("UPSTART_INSTANCE"); + + if (! (upstart_job && upstart_instance)) { + fprintf (stderr, _("%s: missing job name\n"), program_name); + nih_main_suggest_help (); + return NULL; + } + } + + if (upstart_job) { + NIH_MUST (nih_str_array_add (&details, NULL, NULL, upstart_job)); + NIH_MUST (nih_str_array_add (&details, NULL, NULL, upstart_instance)); + } + + return details; +} + #ifndef TEST /**
-- upstart-devel mailing list [email protected] Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/upstart-devel
