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

Reply via email to