Merge authors:
  James Hunt (jamesodhunt)
Related merge proposals:
  https://code.launchpad.net/~jamesodhunt/upstart/add-session-file/+merge/144881
  proposed by: James Hunt (jamesodhunt)
  review: Approve - Steve Langasek (vorlon)
  review: Approve - Dmitrijs Ledkovs (xnox)
------------------------------------------------------------
revno: 1432 [merge]
committer: James Hunt <[email protected]>
branch nick: upstart
timestamp: Wed 2013-01-30 16:28:07 +0000
message:
  * Merge of lp:~jamesodhunt/upstart/add-session-file.
modified:
  ChangeLog
  init/control.c
  init/control.h
  init/main.c
  init/man/init.5
  init/paths.h
  init/tests/test_xdg.c
  init/xdg.c
  init/xdg.h


--
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-30 14:13:49 +0000
+++ ChangeLog	2013-01-30 16:28:07 +0000
@@ -15,6 +15,25 @@
 
 	* init/control.c: More careful uid checking.
 
+2013-01-28  James Hunt  <[email protected]>
+
+	* init/xdg.c:
+	  - get_subdir(): Remove double-check on @dir.
+	  - xdg_get_runtime_dir():
+	    - Don't attempt to create as unlikely to be able to if it
+	      doesn't already exist.
+	    - Simplify logic.
+
+2013-01-25  James Hunt  <[email protected]>
+
+	* init/tests/test_xdg.c: Added test_get_session_dir().
+	* init/xdg.c: get_home_subdir(): Handle unset 'HOME' immediately.
+	* init/control.c: Make use of SESSION_EXT.
+	* init/man/init.5: Added session files.
+	* init/paths.h:
+	  - Comments.
+	  - Added SESSION_EXT.
+
 2013-01-25  James Hunt  <[email protected]>
 
 	* init/control.c:
@@ -46,6 +65,24 @@
 	* util/tests/test_user_sessions.sh: Removed.
 	* init/man/init.5: Updated to reflect removal of user jobs.
 
+2013-01-24  James Hunt  <[email protected]>
+
+	* init/control.c:
+	  - control_init(): Create session file in user mode.
+	  - control_cleanup(): New function for cleanup activities.
+	  - control_session_file_create(): Create session file containing
+	    UPSTART_SESSION details.
+	  - control_session_file_remove(): Delete the session file.
+	* init/main.c: Call control_cleanup() to remove session file.
+	* init/paths.h: Added INIT_XDG_SESSION_SUBDIR and SESSION_ENV.
+	* init/xdg.c:
+	  - get_subdir(): Refactor of get_home_subdir().
+	  - get_home_subdir(): Now calls get_subdir().
+	  - Replaced mkdir mode values with INIT_XDG_PATH_MODE.
+	  - xdg_get_runtime_dir(): Obtain XDG_RUNTIME_DIR value.
+	  - get_session_dir(): Obtain path to session directory.
+	* init/xdg.h: Added INIT_XDG_PATH_MODE.
+
 2013-01-21  Dmitrijs Ledkovs  <[email protected]>
 
 	* init/xdg.[ch]: add xdg_get_cache_home and get_user_log_dir

=== modified file 'init/control.c'
--- init/control.c	2013-01-30 16:13:04 +0000
+++ init/control.c	2013-01-30 16:28:07 +0000
@@ -56,19 +56,23 @@
 #include "errors.h"
 #include "state.h"
 #include "event.h"
+#include "paths.h"
+#include "xdg.h"
 
 #include "com.ubuntu.Upstart.h"
 
 /* Prototypes for static functions */
-static int   control_server_connect   (DBusServer *server, DBusConnection *conn);
-static void  control_disconnected     (DBusConnection *conn);
-static void  control_register_all     (DBusConnection *conn);
+static int   control_server_connect      (DBusServer *server, DBusConnection *conn);
+static void  control_disconnected        (DBusConnection *conn);
+static void  control_register_all        (DBusConnection *conn);
 
-static void  control_bus_flush        (void);
-static int   control_get_origin_uid   (NihDBusMessage *message, uid_t *uid)
-	__attribute__ ((warn_unused_result));
-static int   control_check_permission (NihDBusMessage *message)
-	__attribute__ ((warn_unused_result));
+static void  control_bus_flush           (void);
+static int   control_get_origin_uid      (NihDBusMessage *message, uid_t *uid)
+	__attribute__ ((warn_unused_result));
+static int   control_check_permission    (NihDBusMessage *message)
+	__attribute__ ((warn_unused_result));
+static void  control_session_file_create (void);
+static void  control_session_file_remove (void);
 
 /**
  * use_session_bus:
@@ -112,6 +116,8 @@
 /* External definitions */
 extern int user_mode;
 
+extern char *session_file;
+
 /**
  * control_init:
  *
@@ -124,14 +130,27 @@
 		control_conns = NIH_MUST (nih_list_new (NULL));
 
 	if (! control_server_address) {
-		if (user_mode)
+		if (user_mode) {
 			NIH_MUST (nih_strcat_sprintf (&control_server_address, NULL,
 					    "%s-session/%d/%d", DBUS_ADDRESS_UPSTART, getuid (), getpid ()));
-		else
-			control_server_address = nih_strdup (NULL, DBUS_ADDRESS_UPSTART);
+
+			control_session_file_create ();
+		} else {
+			control_server_address = NIH_MUST (nih_strdup (NULL, DBUS_ADDRESS_UPSTART));
+		}
 	}
 }
 
+/**
+ * control_cleanup:
+ *
+ * Perform cleanup operations.
+ **/
+void
+control_cleanup (void)
+{
+	control_session_file_remove ();
+}
 
 /**
  * control_server_open:
@@ -1215,3 +1234,53 @@
 
 	return FALSE;
 }
+
+/**
+ * control_session_file_create:
+ *
+ * Create session file if possible.
+ *
+ * Errors are not fatal - the file is just not created.
+ **/
+static void
+control_session_file_create (void)
+{
+	nih_local char *session_dir = NULL;
+	FILE           *f;
+
+	nih_assert (control_server_address);
+
+	session_dir = get_session_dir ();
+
+	if (! session_dir)
+		return;
+
+	NIH_MUST (nih_strcat_sprintf (&session_file, NULL, "%s/%d%s",
+				session_dir, (int)getpid (), SESSION_EXT));
+
+	f = fopen (session_file, "w");
+	if (! f) {
+		nih_error ("%s: %s", _("unable to create session file"), session_file);
+		return;
+	}
+
+	if (fprintf (f, SESSION_ENV "=%s\n", control_server_address) < 0) {
+		nih_error ("%s: %s", _("unable to write session file"), session_file);
+	}
+
+	fclose (f);
+}
+
+/**
+ * control_session_file_remove:
+ *
+ * Delete session file.
+ *
+ * Errors are not fatal.
+ **/
+static void
+control_session_file_remove (void)
+{
+	if (session_file)
+		(void)unlink (session_file);
+}

=== modified file 'init/control.h'
--- init/control.h	2012-12-14 23:43:15 +0000
+++ init/control.h	2013-01-24 19:08:49 +0000
@@ -54,6 +54,7 @@
 
 
 void control_init                 (void);
+void control_cleanup              (void);
 
 int  control_server_open          (void)
 	__attribute__ ((warn_unused_result));

=== modified file 'init/main.c'
--- init/main.c	2013-01-23 12:40:36 +0000
+++ init/main.c	2013-01-24 19:08:49 +0000
@@ -651,6 +651,8 @@
 	nih_main_loop_interrupt ();
 	ret = nih_main_loop ();
 
+	control_cleanup ();
+
 	return ret;
 }
 

=== modified file 'init/man/init.5'
--- init/man/init.5	2013-01-25 09:19:42 +0000
+++ init/man/init.5	2013-01-30 16:28:07 +0000
@@ -1013,6 +1013,9 @@
 .TP
 .I $XDG_CACHE_HOME/upstart/*.log
 Default location of user session job output logs.
+.TP
+.I $XDG_RUNTIME_DIR/upstart/sessions/*.session
+Location of session files created when running in User Session mode.
 .RE
 .\"
 .SH AUTHOR

=== modified file 'init/paths.h'
--- init/paths.h	2012-12-17 15:46:35 +0000
+++ init/paths.h	2013-01-25 10:08:19 +0000
@@ -116,6 +116,16 @@
 #endif
 
 /**
+ * INIT_XDG_SESSION_SUBDIR:
+ *
+ * Directory below XDG_RUNTIME_DIR/INIT_XDG_SUBDIR used to
+ * store session details.
+ **/
+#ifndef INIT_XDG_SESSION_SUBDIR
+#define INIT_XDG_SESSION_SUBDIR "sessions"
+#endif
+
+/**
  * SHELL:
  *
  * This is the shell binary used whenever we need special processing for
@@ -166,13 +176,25 @@
 #define LOGDIR_ENV "UPSTART_LOGDIR" 
 #endif
 
+/**
+ * SESSION_ENV:
+ *
+ * Environment variable that is set when running as a Session Init.
+ **/
+#ifndef SESSION_ENV
+#define SESSION_ENV "UPSTART_SESSION"
+#endif
 
 /**
+ * CONF_EXT_STD:
+ *
  * File extension for standard configuration files.
  **/
 #define CONF_EXT_STD ".conf"
 
 /**
+ * CONF_EXT_OVERRIDE:
+ *
  * File extension for override files.
  *
  * Note that override files are not stored in the ConfSource 'files' hash:
@@ -182,6 +204,15 @@
 #define CONF_EXT_OVERRIDE ".override"
 
 /**
+ * SESSION_EXT:
+ *
+ * File extension for session files.
+ **/
+#ifndef SESSION_EXT
+#define SESSION_EXT ".session"
+#endif
+
+/**
  * Determine if specified path extension representes a standard
  * configuration file.
  *

=== modified file 'init/tests/test_xdg.c'
--- init/tests/test_xdg.c	2013-01-22 12:01:56 +0000
+++ init/tests/test_xdg.c	2013-01-25 09:59:44 +0000
@@ -435,6 +435,49 @@
 	rmdir (dirname);
 }
 
+void
+test_get_session_dir (void)
+{
+	char dirname[PATH_MAX];
+	char         *expected;
+	char             *path;
+
+	TEST_FUNCTION ("get_session_dir");
+
+	TEST_FEATURE ("with XDG_RUNTIME_DIR set");
+
+	TEST_FILENAME (dirname);
+	assert0 (setenv ("XDG_RUNTIME_DIR", dirname, 1));
+	TEST_EQ (mkdir (dirname, 0755), 0);
+
+	expected = nih_sprintf (NULL, "%s/upstart/sessions", dirname);
+
+	TEST_ALLOC_FAIL {
+		path = get_session_dir ();
+		if (test_alloc_failed) {
+			TEST_EQ_P (path, NULL);
+		} else {
+			TEST_EQ_STR (path, expected);
+			_test_dir_created (expected);
+			nih_free (path);
+		}
+	}
+
+	TEST_FEATURE ("with XDG_RUNTIME_DIR unset");
+	assert0 (unsetenv ("XDG_RUNTIME_DIR"));
+
+	/* no fallback */
+	path = get_session_dir ();
+	TEST_EQ_P (path, NULL);
+
+	rmdir (expected);
+	nih_free (expected);
+	path = nih_sprintf (NULL, "%s/upstart", dirname);
+	rmdir (path);
+	nih_free (path);
+	rmdir (dirname);
+}
+
 int
 main (int   argc,
       char *argv[])
@@ -445,6 +488,7 @@
 	test_get_user_upstart_dirs ();
 	test_get_cache_home ();
 	test_get_user_log_dir ();
+	test_get_session_dir ();
 
 	return 0;
 }

=== modified file 'init/xdg.c'
--- init/xdg.c	2013-01-22 12:01:56 +0000
+++ init/xdg.c	2013-01-29 09:29:28 +0000
@@ -42,37 +42,75 @@
 int user_mode = FALSE;
 
 /**
- * get_home_subdir:
- * @suffix: sub-directory name
- * @create: flag to create sub-directory
- * 
- * Construct path to @suffix directory in user's HOME dir. If @create
- * flag is TRUE, also attempt to create that directory. Errors upon
- * directory creation are ignored.
- * 
- * Returns: newly-allocated path, or NULL on error.
+ * session_file:
+ *
+ * Full path to file containing UPSTART_SESSION details (only set when
+ * user_mode in operation).
+ *
+ * File is created on startup and removed on clean shutdown.
+ **/
+const char *session_file = NULL;
+
+/**
+ * get_subdir:
+ * @dir: initial directory,
+ * @suffix: sub-directory of @dir,
+ * @create: flag to create sub-directory.
+ * 
+ * Construct path by appending @suffix to @dir. If @create
+ * flag is TRUE, also attempt to create that directory.
+ *
+ * Errors upon directory creation are ignored.
+ * 
+ * Returns: Newly-allocated path, or NULL on error.
  **/
 char *
-get_home_subdir (const char * suffix, int create)
+get_subdir (const char *dir, const char *suffix, int create)
 {
-	char *dir;
+	char *newdir;
+
+	nih_assert (dir != NULL);
 	nih_assert (suffix != NULL);
 	nih_assert (suffix[0]);
 	
-	dir = getenv ("HOME");
-	if (dir && dir[0] == '/') {
-		dir = nih_sprintf (NULL, "%s/%s", dir, suffix);
-		if (! dir)
+	if (dir[0] == '/') {
+		newdir = nih_sprintf (NULL, "%s/%s", dir, suffix);
+		if (! newdir)
 			return NULL;
 		if (create)
-			mkdir (dir, 0700);
-		return dir;
+			mkdir (newdir, INIT_XDG_PATH_MODE);
+		return newdir;
 	}
 
 	return NULL;
 }
 
 /**
+ * get_home_subdir:
+ *
+ * @suffix: sub-directory name,
+ * @create: flag to create sub-directory.
+ *
+ * Construct path to @suffix directory in user's HOME directory.
+ * If @create is TRUE, also attempt to create that directory.
+ *
+ * Errors upon directory creation are ignored.
+ * 
+ * Returns: Newly-allocated path, or NULL on error.
+ **/
+char *
+get_home_subdir (const char *suffix, int create)
+{
+	char *env;
+
+	env = getenv ("HOME");
+	if (! env)
+		return NULL;
+
+	return get_subdir (env, suffix, create);
+}
+
+/**
  * xdg_get_cache_home:
  *
  * Determine an XDG compliant XDG_CACHE_HOME
@@ -82,13 +120,12 @@
 char *
 xdg_get_cache_home (void)
 {
-	nih_local char  **env = NULL;
 	char             *dir;
 
 	dir = getenv ("XDG_CACHE_HOME");
 	
 	if (dir && dir[0] == '/') {
-		mkdir (dir, 0700);
+		mkdir (dir, INIT_XDG_PATH_MODE);
 		dir = nih_strdup (NULL, dir);
 		return dir;
 	}
@@ -115,13 +152,12 @@
 char *
 xdg_get_config_home (void)
 {
-	nih_local char  **env = NULL;
-	char             *dir;
+	char  *dir;
 
 	dir = getenv ("XDG_CONFIG_HOME");
 	
 	if (dir && dir[0] == '/') {
-		mkdir (dir, 0700);
+		mkdir (dir, INIT_XDG_PATH_MODE);
 		dir = nih_strdup (NULL, dir);
 		return dir;
 	}
@@ -136,6 +172,60 @@
 }
 
 /**
+ * xdg_get_runtime_dir:
+ *
+ * Determine an XDG compliant XDG_RUNTIME_DIR.
+ *
+ * Note: No attempt is made to create this directory since if it does
+ * not exist, a non-priv user is unlikely be able to create it anyway.
+ *
+ * Returns: newly-allocated path, or NULL on error.
+ **/
+char *
+xdg_get_runtime_dir (void)
+{
+	char *dir;
+
+	dir = getenv ("XDG_RUNTIME_DIR");
+
+	if (dir && dir[0] == '/')
+		dir = nih_strdup (NULL, dir);
+
+	return dir;
+}
+
+/**
+ * get_session_dir:
+ *
+ * Determine full path to XDG-compliant session directory used to store
+ * session files.
+ *
+ * Returns: Newly-allocated path, or NULL on error.
+ **/
+char *
+get_session_dir (void)
+{
+	nih_local char  *runtime_dir = NULL;
+	nih_local char  *dir = NULL;
+	char            *session_dir;
+
+	runtime_dir = xdg_get_runtime_dir ();
+
+	if (runtime_dir && runtime_dir[0] == '/') {
+		dir = get_subdir (runtime_dir, INIT_XDG_SUBDIR, TRUE);
+		if (! dir)
+			return NULL;
+
+		session_dir = get_subdir (dir, INIT_XDG_SESSION_SUBDIR,
+				TRUE);
+
+		return session_dir;
+	}
+
+	return NULL;
+}
+
+/**
  * xdg_get_config_dirs:
  *
  * Determine a list of XDG compliant XDG_CONFIG_DIRS
@@ -189,7 +279,7 @@
 	if (path && path[0]) {
 	        if (! nih_strcat_sprintf (&path, NULL, "/%s", INIT_XDG_SUBDIR))
 			goto error;
-		mkdir (path, 0700);
+		mkdir (path, INIT_XDG_PATH_MODE);
 		if (! nih_str_array_add (&all_dirs, NULL, NULL, path))
 			goto error;
 		nih_free (path);
@@ -261,7 +351,7 @@
 		dir = nih_sprintf (NULL, "%s/%s", path, INIT_XDG_SUBDIR);
 		if (! dir)
 			return NULL;
-		mkdir (dir, 0700);
+		mkdir (dir, INIT_XDG_PATH_MODE);
 		return dir;
 	}
 	return NULL;

=== modified file 'init/xdg.h'
--- init/xdg.h	2013-01-23 12:56:00 +0000
+++ init/xdg.h	2013-01-24 19:08:49 +0000
@@ -23,8 +23,19 @@
 #include "paths.h"
 #include <nih/macros.h>
 
+/**
+ * INIT_XDG_PATH_MODE:
+ *
+ * Absolute mode to create XDG-compliant directory elements with.
+ **/
+#define INIT_XDG_PATH_MODE 0700
+
 NIH_BEGIN_EXTERN
 
+char *    get_env_subdir (const char *envvar, const char *suffix,
+			  int create)
+	__attribute__ ((malloc, warn_unused_result));
+
 char *    get_home_subdir        (const char * suffix, int create)
 	__attribute__ ((malloc, warn_unused_result));
 
@@ -34,6 +45,9 @@
 char *    xdg_get_cache_home     (void)
 	__attribute__ ((malloc, warn_unused_result));
 
+char *    xdg_get_runtime_dir (void)
+	__attribute__ ((malloc, warn_unused_result));
+
 char **   xdg_get_config_dirs    (void)
 	__attribute__ ((malloc, warn_unused_result));
 
@@ -43,6 +57,9 @@
 char *    get_user_log_dir       (void)
 	__attribute__ ((malloc, warn_unused_result));
 
+char *    get_session_dir        (void)
+	__attribute__ ((malloc, warn_unused_result));
+
 NIH_END_EXTERN
 
 #endif /* INIT_XDG_H */

-- 
upstart-devel mailing list
[email protected]
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/upstart-devel

Reply via email to