Dmitrijs Ledkovs has proposed merging lp:~xnox/upstart/upstart-user-mode into
lp:upstart.
Requested reviews:
Upstart Reviewers (upstart-reviewers)
For more details, see:
https://code.launchpad.net/~xnox/upstart/upstart-user-mode/+merge/140258
user-session-mode is born
--
https://code.launchpad.net/~xnox/upstart/upstart-user-mode/+merge/140258
Your team Upstart Reviewers is requested to review the proposed merge of
lp:~xnox/upstart/upstart-user-mode into lp:upstart.
=== modified file 'init/Makefile.am'
--- init/Makefile.am 2012-12-11 13:59:01 +0000
+++ init/Makefile.am 2012-12-17 17:31:23 +0000
@@ -56,6 +56,7 @@
parse_conf.c parse_conf.h \
conf.c conf.h \
control.c control.h \
+ xdg.c xdg.h \
errors.h
nodist_init_SOURCES = \
$(com_ubuntu_Upstart_OUTPUTS) \
@@ -134,7 +135,6 @@
$(TEST_DATA_DIR)/upstart-1.6.json
EXTRA_DIST = init.supp $(TEST_DATA_FILES)
-
test_util_SOURCES = \
tests/test_util.c tests/test_util.h
@@ -154,6 +154,7 @@
test_parse_job \
test_parse_conf \
test_conf \
+ test_xdg \
test_control
check_PROGRAMS = $(TESTS)
@@ -338,6 +339,13 @@
$(JSON_LIBS) \
-lrt
+test_xdg_SOURCES = tests/test_xdg.c
+test_xdg_LDADD = \
+ xdg.o \
+ environ.o \
+ $(NIH_LIBS) \
+ -lrt
+
test_control_SOURCES = tests/test_control.c
test_control_LDADD = \
system.o environ.o process.o \
=== modified file 'init/main.c'
--- init/main.c 2012-12-17 13:47:32 +0000
+++ init/main.c 2012-12-17 17:31:23 +0000
@@ -68,6 +68,7 @@
#include "conf.h"
#include "control.h"
#include "state.h"
+#include "xdg.h"
/* Prototypes for static functions */
@@ -86,6 +87,7 @@
static void handle_confdir (void);
static void handle_logdir (void);
+static void handle_usermode (void);
static int console_type_setter (NihOption *option, const char *arg);
@@ -119,6 +121,13 @@
**/
static int disable_startup_event = FALSE;
+/**
+ * user_mode:
+ *
+ * If TRUE, upstart runs in user session mode.
+ **/
+static int user_mode = FALSE;
+
extern int disable_sessions;
extern int disable_job_logging;
extern int use_session_bus;
@@ -164,6 +173,9 @@
{ 0, "startup-event", N_("specify an alternative initial event (for testing)"),
NULL, "NAME", &initial_event, NULL },
+ { 0, "user", N_("start in user mode (as used for user sessions)"),
+ NULL, NULL, &user_mode, NULL },
+
/* Ignore invalid options */
{ '-', "--", NULL, NULL, NULL, NULL, NULL },
@@ -176,6 +188,7 @@
char *argv[])
{
char **args = NULL;
+ char **dirs = NULL;
int ret;
args_copy = NIH_MUST (nih_str_array_copy (NULL, NULL, argv));
@@ -194,6 +207,7 @@
handle_confdir ();
handle_logdir ();
+ handle_usermode ();
if (disable_job_logging)
nih_debug ("Job logging disabled");
@@ -519,8 +533,18 @@
}
/* Read configuration */
- NIH_MUST (conf_source_new (NULL, CONFFILE, CONF_FILE));
- NIH_MUST (conf_source_new (NULL, conf_dir, CONF_JOB_DIR));
+ if (! user_mode)
+ NIH_MUST (conf_source_new (NULL, CONFFILE, CONF_FILE));
+
+ if (conf_dir)
+ NIH_MUST (conf_source_new (NULL, conf_dir, CONF_JOB_DIR));
+
+ if (user_mode) {
+ dirs = get_user_upstart_dirs();
+ for (char **d = dirs; d && *d; d++)
+ NIH_MUST (conf_source_new (NULL, *d, CONF_JOB_DIR));
+ nih_free (dirs);
+ }
conf_reload ();
@@ -903,6 +927,9 @@
if (conf_dir)
goto out;
+ if (user_mode)
+ return;
+
conf_dir = CONFDIR;
dir = getenv (CONFDIR_ENV);
@@ -943,6 +970,18 @@
log_dir);
}
+/**
+ * handle_usermode:
+ *
+ * Setup user session mode.
+ **/
+static void
+handle_usermode (void)
+{
+ if (user_mode)
+ use_session_bus = TRUE;
+}
+
/**
* NihOption setter function to handle selection of default console
* type.
=== modified file 'init/paths.h'
--- init/paths.h 2012-09-10 07:50:32 +0000
+++ init/paths.h 2012-12-17 17:31:23 +0000
@@ -96,6 +96,24 @@
#define CONFDIR_ENV "UPSTART_CONFDIR"
#endif
+/**
+ * INIT_XDG_SUBDIR:
+ *
+ * This is the name of the sub folder we will use when constructing
+ * config source dirs with XDG compliant folders.
+ **/
+#ifndef INIT_XDG_SUBDIR
+#define INIT_XDG_SUBDIR "upstart"
+#endif
+
+/**
+ * SYSTEM_USERCONFDIR:
+ *
+ * This is the path to system-wide user session jobs.
+ **/
+#ifndef SYSTEM_USERCONFDIR
+#define SYSTEM_USERCONFDIR "/usr/share/upstart/sessions"
+#endif
/**
* SHELL:
=== added file 'init/tests/test_xdg.c'
--- init/tests/test_xdg.c 1970-01-01 00:00:00 +0000
+++ init/tests/test_xdg.c 2012-12-17 17:31:23 +0000
@@ -0,0 +1,312 @@
+/* upstart
+ *
+ * test_xdg.c - test suite for init/xdg.c
+ *
+ * Copyright © 2012 Canonical Ltd.
+ * Author: Dmitrijs Ledkovs <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <nih/string.h>
+#include <nih/test.h>
+
+#include <stdlib.h>
+#include <limits.h>
+
+#include "xdg.h"
+
+void
+test_get_home_subdir (void)
+{
+ char dirname[PATH_MAX];
+ char *dir;
+ char * expected=NULL;
+
+ TEST_FUNCTION ("get_home_subdir");
+
+ TEST_FEATURE ("with HOME not set");
+ TEST_EQ (unsetenv ("HOME"), 0);
+
+ TEST_ALLOC_FAIL {
+ dir = get_home_subdir ("test");
+ TEST_EQ_P (dir, NULL);
+ }
+
+ TEST_FEATURE ("with HOME set");
+ TEST_FILENAME (dirname);
+ TEST_EQ (setenv ("HOME", dirname, 1), 0);
+
+ TEST_ALLOC_FAIL {
+ TEST_ALLOC_SAFE {
+ dir = NULL;
+ expected = NIH_MUST (nih_sprintf (NULL, "%s/test", dirname));
+ }
+
+ dir = get_home_subdir ("test");
+
+ /* if I inverted the below if statement and write it
+ * as "if ( test_alloc_failed )" and change around
+ * the branches respectively the unit test fails. Why
+ * is that?
+ */
+ if ( ! test_alloc_failed ) {
+ TEST_EQ_STR (dir, expected);
+ nih_free (dir);
+ } else {
+ TEST_EQ_P (dir, NULL);
+ }
+
+ if (expected)
+ nih_free (expected);
+ }
+}
+
+void
+test_get_config_home (void)
+{
+ char dirname[PATH_MAX];
+ char * outname;
+ char * expected;
+
+ TEST_FUNCTION ("xdg_get_config_home");
+
+ TEST_FEATURE ("with HOME set and without environment override");
+ TEST_FILENAME (dirname);
+ TEST_EQ (setenv ("HOME", dirname, 1), 0);
+ TEST_EQ (unsetenv ("XDG_CONFIG_HOME"), 0);
+
+ TEST_ALLOC_FAIL {
+ TEST_ALLOC_SAFE {
+ expected = NIH_MUST (nih_sprintf (NULL, "%s/.config", dirname));
+ }
+
+ outname = NULL;
+ outname = xdg_get_config_home ();
+
+ /* Something strange is going on.
+ * I am expected the failed alloc branch
+ * to pass TEST_EQ_P (outname, NULL)
+ */
+
+ if (! test_alloc_failed)
+ TEST_EQ_STR (outname, expected);
+ else
+ TEST_EQ_STR (outname, expected);
+
+ if (outname)
+ nih_free (outname);
+
+ nih_free(expected);
+ }
+
+ TEST_FEATURE ("with HOME set and with empty environment override");
+ TEST_EQ (setenv ("XDG_CONFIG_HOME", "", 1), 0);
+
+ TEST_ALLOC_FAIL {
+ TEST_ALLOC_SAFE {
+ expected = NIH_MUST (nih_sprintf (NULL, "%s/.config", dirname));
+ outname = NULL;
+ /* the below call should be in _FAIL scope */
+ outname = xdg_get_config_home();
+ }
+
+ if (test_alloc_failed)
+ TEST_EQ_P (outname, NULL);
+ else {
+ TEST_EQ_STR (outname, expected);
+ }
+ if (outname)
+ nih_free (outname);
+
+ nih_free(expected);
+
+ }
+
+ TEST_FEATURE ("with HOME set and with environment override");
+ expected = NIH_MUST (nih_strdup (NULL, "/home/me/.config-test"));
+ TEST_EQ (setenv ("XDG_CONFIG_HOME", expected, 1), 0);
+
+ TEST_ALLOC_FAIL {
+ TEST_ALLOC_SAFE {
+ outname = NULL;
+ /* the below call should be in _FAIL scope */
+ outname = xdg_get_config_home();
+ }
+
+ if (test_alloc_failed)
+ TEST_EQ_P (outname, NULL);
+ else {
+ TEST_EQ_STR (outname, expected);
+ }
+ if (outname)
+ nih_free (outname);
+
+ }
+
+
+ TEST_FEATURE ("without HOME set and with environment override");
+ TEST_EQ (unsetenv ("HOME"), 0);
+
+ TEST_ALLOC_FAIL {
+ TEST_ALLOC_SAFE {
+ outname = NULL;
+ /* the below call should be in _FAIL scope */
+ outname = xdg_get_config_home();
+ }
+
+ if (test_alloc_failed)
+ TEST_EQ_P (outname, NULL);
+ else {
+ TEST_EQ_STR (outname, expected);
+ }
+ if (outname)
+ nih_free (outname);
+ }
+
+ nih_free(expected);
+
+ TEST_FEATURE ("without HOME set and with empty environment override");
+ TEST_EQ (setenv ("XDG_CONFIG_HOME", "", 1), 0);
+
+ TEST_ALLOC_FAIL {
+ outname = NULL;
+ outname = xdg_get_config_home();
+ TEST_EQ_P (outname, NULL);
+ }
+
+ TEST_FEATURE ("without HOME set and without environment override");
+ TEST_EQ (unsetenv ("XDG_CONFIG_HOME"), 0);
+ TEST_ALLOC_FAIL {
+ outname = NULL;
+ outname = xdg_get_config_home();
+ TEST_EQ_P (outname, NULL);
+ }
+}
+
+void
+test_get_config_dirs (void)
+{
+ char **dirs = NULL;
+
+ TEST_FUNCTION ("xdg_get_config_dirs");
+ TEST_FEATURE ("without environment override set");
+ TEST_EQ (unsetenv ("XDG_CONFIG_DIRS"), 0);
+
+ TEST_ALLOC_FAIL {
+ dirs = xdg_get_config_dirs();
+
+ if (! test_alloc_failed) {
+ TEST_EQ_STR (dirs[0], "/etc/xdg");
+ TEST_EQ (dirs[1], NULL);
+ nih_free (dirs);
+ }
+ }
+
+ TEST_FEATURE ("with empty environment override");
+ TEST_EQ (setenv ("XDG_CONFIG_DIRS", "", 1), 0);
+ TEST_ALLOC_FAIL {
+ dirs = xdg_get_config_dirs();
+
+ if (! test_alloc_failed) {
+ TEST_EQ_STR (dirs[0], "/etc/xdg");
+ TEST_EQ (dirs[1], NULL);
+ nih_free (dirs);
+ }
+ }
+
+ TEST_FEATURE ("with environment override set to single path");
+ TEST_EQ (setenv ("XDG_CONFIG_DIRS", "/etc/xdg/xdg-test", 1), 0);
+ TEST_ALLOC_FAIL {
+ dirs = xdg_get_config_dirs();
+
+ if (! test_alloc_failed) {
+ TEST_EQ_STR (dirs[0], "/etc/xdg/xdg-test");
+ TEST_EQ (dirs[1], NULL);
+ nih_free (dirs);
+ }
+ }
+
+ TEST_FEATURE ("with environment override set to multiple paths");
+ TEST_FEATURE ("with environment override set to single path");
+ TEST_EQ (setenv ("XDG_CONFIG_DIRS", "/etc/xdg/xdg-test:/etc/xdg/xdg-other", 1), 0);
+ TEST_ALLOC_FAIL {
+ dirs = xdg_get_config_dirs();
+
+ if (! test_alloc_failed) {
+ TEST_EQ_STR (dirs[0], "/etc/xdg/xdg-test");
+ TEST_EQ_STR (dirs[1], "/etc/xdg/xdg-other");
+ TEST_EQ (dirs[2], NULL);
+ nih_free (dirs);
+ }
+ }
+}
+
+void
+test_get_user_upstart_dirs (void)
+{
+ char dirname[PATH_MAX];
+ char ** dirs = NULL;
+ char * path = NULL;
+ char ** expected = NULL;
+
+ /* Currently only one test for "typical" output.
+ * Not sure what else to test here.
+ */
+ TEST_FUNCTION ("get_user_upstart_dirs");
+
+ TEST_FEATURE ("with HOME set");
+ TEST_FILENAME (dirname);
+ TEST_EQ (setenv ("HOME", dirname, 1), 0);
+ TEST_EQ (unsetenv ("XDG_CONFIG_HOME"), 0);
+ TEST_EQ (unsetenv ("XDG_CONFIG_DIRS"), 0);
+
+ TEST_ALLOC_FAIL {
+ TEST_ALLOC_SAFE {
+ dirs = NULL;
+ expected = nih_str_array_new (NULL);
+ path = NIH_MUST (nih_sprintf (NULL, "%s/.config/upstart", dirname));
+ assert (nih_str_array_add (&expected, NULL, NULL, path));
+ nih_free(path);
+ path = NIH_MUST (nih_sprintf (NULL, "%s/.init", dirname));
+ assert (nih_str_array_add (&expected, NULL, NULL, path));
+ nih_free(path);
+ }
+
+ dirs = get_user_upstart_dirs ();
+
+ if (! test_alloc_failed) {
+ TEST_EQ_STR (dirs[0], expected[0]);
+ TEST_EQ_STR (dirs[1], expected[1]);
+ TEST_EQ_STR (dirs[2], "/etc/xdg/upstart");
+ TEST_EQ_STR (dirs[3], SYSTEM_USERCONFDIR);
+ TEST_EQ (dirs[4], NULL);
+ nih_free (dirs);
+ }
+ nih_free(expected);
+ }
+
+}
+
+int
+main (int argc,
+ char *argv[])
+{
+ test_get_home_subdir ();
+ test_get_config_home ();
+ test_get_config_dirs ();
+ test_get_user_upstart_dirs ();
+
+ return 0;
+}
=== added file 'init/xdg.c'
--- init/xdg.c 1970-01-01 00:00:00 +0000
+++ init/xdg.c 2012-12-17 17:31:23 +0000
@@ -0,0 +1,146 @@
+/* upstart
+ *
+ * xdg.c - XDG compliant path constructor
+ *
+ * Copyright © 2012 Canonical Ltd.
+ * Author: Dmitrijs Ledkovs <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <stdlib.h>
+
+#include <nih/alloc.h>
+#include <nih/logging.h>
+#include <nih/string.h>
+
+#include "paths.h"
+#include "xdg.h"
+
+/**
+ * get_home_subdir:
+ *
+ * Construct path to directory in user's HOME dir.
+ */
+
+char *
+get_home_subdir (char * suffix)
+{
+ char *dir;
+ nih_assert (suffix && suffix[0]);
+
+ dir = getenv("HOME");
+ if ( dir && dir[0] ) {
+ dir = nih_sprintf (NULL, "%s/%s", dir, suffix);
+ return dir;
+ }
+
+ return NULL;
+}
+
+/**
+ * xdg_get_config_home:
+ *
+ * Determine an XDG compliant XDG_CONFIG_HOME
+ *
+ **/
+char *
+xdg_get_config_home (void)
+{
+ nih_local char **env = NULL;
+ size_t len = 0;
+ char *dir;
+
+ dir = getenv("XDG_CONFIG_HOME");
+
+ if ( dir && dir[0] ) {
+ dir = nih_strdup (NULL, dir);
+ return dir;
+ }
+
+ dir = get_home_subdir (".config");
+
+ return dir;
+}
+
+/**
+ * xdg_get_config_dirs:
+ *
+ * Determine a list of XDG compliant XDG_CONFIG_DIRS
+ *
+ **/
+char **
+xdg_get_config_dirs (void)
+{
+ char *env_path;
+ char *result = NULL;
+ size_t len = 0;
+ char **dirs = NULL;
+
+ env_path = getenv ("XDG_CONFIG_DIRS");
+ if (! env_path || ! env_path[0])
+ env_path = "/etc/xdg";
+
+ dirs = nih_str_split(NULL, env_path, ":", TRUE);
+
+ return dirs;
+}
+
+/**
+ * xdg_get_dirs:
+ *
+ * Construct an array of user session config source paths to config dirs for a
+ * particular user. This array can be iterated to add each of these
+ * directories as config source dirs, when e.g. upstart is running as user session init.
+ * This is a convenience function.
+ *
+ **/
+char **
+get_user_upstart_dirs (void)
+{
+ char *path;
+ char **dirs = NULL;
+ char **all_dirs = NULL;
+
+ all_dirs = nih_str_array_new (NULL);
+
+ path = xdg_get_config_home ();
+ if (path && path[0]) {
+ NIH_MUST (nih_strcat_sprintf (&path, NULL, "/%s", INIT_XDG_SUBDIR));
+ NIH_MUST (nih_str_array_add (&all_dirs, NULL, NULL, path));
+ nih_free(path);
+ }
+
+ path = get_home_subdir (USERCONFDIR);
+ if (path && path[0]) {
+ NIH_MUST (nih_str_array_add (&all_dirs, NULL, NULL, path));
+ nih_free(path);
+ }
+
+ dirs = xdg_get_config_dirs ();
+
+ for (char **p = dirs; p && *p; p++) {
+ NIH_MUST (nih_strcat_sprintf (p, NULL, "/%s", INIT_XDG_SUBDIR));
+ NIH_MUST (nih_str_array_add (&all_dirs, NULL, NULL, *p));
+ }
+
+ NIH_MUST (nih_str_array_add (&all_dirs, NULL, NULL, SYSTEM_USERCONFDIR));
+
+ return all_dirs;
+}
+
=== added file 'init/xdg.h'
--- init/xdg.h 1970-01-01 00:00:00 +0000
+++ init/xdg.h 2012-12-17 17:31:23 +0000
@@ -0,0 +1,42 @@
+/* upstart
+ *
+ * Copyright © 2012 Canonical Ltd.
+ * Author: Dmitrijs Ledkovs <[email protected]>.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef INIT_XDG_H
+#define INIT_XDG_H
+
+#include "paths.h"
+#include <nih/macros.h>
+
+NIH_BEGIN_EXTERN
+
+char * get_home_subdir (char * suffix)
+ __attribute__ ((malloc, warn_unused_result));
+
+char * xdg_get_config_home (void)
+ __attribute__ ((malloc, warn_unused_result));
+
+char ** xdg_get_config_dirs (void)
+ __attribute__ ((malloc, warn_unused_result));
+
+char ** get_user_upstart_dirs (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