Merge authors:
Dmitrijs Ledkovs (xnox)
Stéphane Graber (stgraber)
Related merge proposals:
https://code.launchpad.net/~xnox/upstart/upstart-user-mode/+merge/140258
proposed by: Dmitrijs Ledkovs (xnox)
review: Approve - James Hunt (jamesodhunt)
------------------------------------------------------------
revno: 1414 [merge]
committer: James Hunt <[email protected]>
branch nick: upstart
timestamp: Tue 2012-12-18 16:24:31 +0000
message:
* Merge of lp:~xnox/upstart/upstart-user-mode.
added:
init/tests/test_xdg.c
init/xdg.c
init/xdg.h
modified:
init/Makefile.am
init/main.c
init/man/init.5
init/man/init.8
init/paths.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 'init/Makefile.am'
--- init/Makefile.am 2012-12-11 13:59:01 +0000
+++ init/Makefile.am 2012-12-14 15:54:35 +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-18 14:09:55 +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 = NIH_MUST (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/man/init.5'
--- init/man/init.5 2012-12-17 14:24:22 +0000
+++ init/man/init.5 2012-12-18 13:58:23 +0000
@@ -12,6 +12,10 @@
.B $HOME/.init/
Default location of user job configuration files.
.\"
+.TP
+.B $XDG_CONFIG_HOME/upstart/, $XDG_CONFIG_DIRS/upstart/
+Default locations of user session job configuration files.
+.\"
.SH DESCRIPTION
On startup, the Upstart
.BR init (8)
@@ -25,6 +29,11 @@
.B User Jobs
for further details.
+If Upstart was invoked as a user process with \-\-user option, it will
+run in User Session mode. See
+.B User Session Mode
+for further details.
+
To be considered by Upstart, files in this directory must have a
recognized suffix and may also be present in sub\-directories. There are
two recognized suffixes:
@@ -120,6 +129,20 @@
be used within a chroot environment.
.\"
+.SS User Session Mode
+
+Upstart can manage complete User Session. In this mode upstart is
+running as a user process. It will read configuration files from
+.B $XDG_CONFIG_HOME/upstart/,
+.B $XDG_CONFIG_DIRS/upstart/,
+.B $HOME/.init/ and
+.B /usr/share/upstart/sessions/.
+
+It will then launch the user's session. It will try to parent all
+spawned process with aid from prctl. And kill everything upon logout
+or shutdown.
+
+.\"
.SS Configuration File Format
Each line begins with a configuration stanza and continues until either
the end of the line or a line containing a closing stanza. Line breaks
=== modified file 'init/man/init.8'
--- init/man/init.8 2011-12-09 14:07:11 +0000
+++ init/man/init.8 2012-12-18 13:58:23 +0000
@@ -1,4 +1,4 @@
-.TH init 8 2011-04-06 "Upstart"
+.TH init 8 2012-12-18 "Upstart"
.\"
.SH NAME
init \- Upstart process management daemon
@@ -113,16 +113,35 @@
.BR startup (7) .
.\"
.TP
-.B \-\-verbose
+.B \-\-user
+Starts in user mode, as used for user sessions. Upstart will be run as
+an unprivileged user, reading configuration files from configuration
+locations as per roughly XDG Base Directory Specification. See
+.BR init (5)
+for further details.
+.\"
+.TP
+.B \-q, \-\-quiet
+Reduces output messages to errors only.
+.\"
+.TP
+.B \-v, \-\-verbose
Outputs verbose messages about job state changes and event emissions to the
system console or log, useful for debugging boot.
.\"
+.TP
+.B \-\-version
+Outputs version information and exits.
+.\"
.SH NOTES
.B init
is not normally executed by a user process, and expects to have a process
id of 1. If this is not the case, it will actually execute
.BR telinit (8)
-and pass all arguments to that. See that manual page for further details.
+and pass all arguments to that. See that manual page for further
+details. Unless \-\-user option is used, then it will read alternative
+configuration files and manage the individual user session in a
+similar fashion.
.\"
.SH FILES
.\"
@@ -131,6 +150,8 @@
.I /etc/init/*.conf
.I $HOME/.init/
+
+.I $XDG_CONFIG_DIRS/upstart/, $XDG_CONFIG_HOME/upstart/
.\"
.SH AUTHOR
Written by Scott James Remnant
@@ -141,7 +162,7 @@
.RB < https://launchpad.net/upstart/+bugs >
.\"
.SH COPYRIGHT
-Copyright \(co 2009\-2011 Canonical Ltd.
+Copyright \(co 2009\-2012 Canonical Ltd.
.br
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
=== modified file 'init/paths.h'
--- init/paths.h 2012-09-10 07:50:32 +0000
+++ init/paths.h 2012-12-17 15:46:35 +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-18 14:16:10 +0000
@@ -0,0 +1,306 @@
+/* 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 (test_alloc_failed) {
+ TEST_EQ_P (dir, NULL);
+ } else {
+ TEST_EQ_STR (dir, expected);
+ nih_free (dir);
+ }
+
+ 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 ();
+
+ if (! test_alloc_failed) {
+ TEST_EQ_STR (outname, expected);
+ } else {
+ TEST_EQ_P (outname, NULL);
+ }
+
+ 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;
+ 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 {
+ outname = NULL;
+ 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 {
+ outname = NULL;
+ 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 = NULL;
+ dirs = xdg_get_config_dirs();
+
+ if (test_alloc_failed) {
+ TEST_EQ_P (dirs, NULL);
+ } else {
+ 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 = NULL;
+ dirs = xdg_get_config_dirs();
+
+ if (test_alloc_failed) {
+ TEST_EQ_P (dirs, NULL);
+ } else {
+ 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 = NULL;
+ dirs = xdg_get_config_dirs();
+
+ if (test_alloc_failed) {
+ TEST_EQ_P (dirs, NULL);
+ } else {
+ 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 = NULL;
+ dirs = xdg_get_config_dirs();
+
+ if (test_alloc_failed) {
+ TEST_EQ_P (dirs, NULL);
+ } else {
+ 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 = NULL;
+ dirs = get_user_upstart_dirs ();
+
+ if (test_alloc_failed) {
+ TEST_EQ_P (dirs, NULL);
+ } else {
+ 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-18 16:24:31 +0000
@@ -0,0 +1,182 @@
+/* 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.
+ *
+ * Returns: newly-allocated path, or NULL on error.
+ */
+
+char *
+get_home_subdir (const 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
+ *
+ * Returns: newly-allocated path, or NULL on error.
+ **/
+char *
+xdg_get_config_home (void)
+{
+ nih_local char **env = NULL;
+ 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
+ *
+ * Returns: newly-allocated array of paths, or NULL on error.
+ **/
+char **
+xdg_get_config_dirs (void)
+{
+ char *env_path;
+ 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;
+}
+
+/**
+ * get_user_upstart_dirs:
+ *
+ * Construct an array of user session config source paths to config
+ * dirs for a particular user. This array is sorted in highest
+ * priority order and therefore can be iterated to add each of these
+ * directories as config source dirs, when e.g. upstart is running as
+ * user session init.
+ *
+ * Returns: newly-allocated array of paths, or NULL or error.
+ **/
+char **
+get_user_upstart_dirs (void)
+{
+ char *path = NULL;
+ char **dirs = NULL;
+ char **all_dirs = NULL;
+
+ all_dirs = nih_str_array_new (NULL);
+
+ if (all_dirs == NULL)
+ goto error;
+
+ /* The current order is inline with Enhanced User Sessions Spec */
+
+ /* User's: ~/.config/upstart or XDG_CONFIG_HOME/upstart */
+ path = xdg_get_config_home ();
+ if (path == NULL)
+ goto error;
+ if (path && path[0]) {
+ if (nih_strcat_sprintf (&path, NULL, "/%s", INIT_XDG_SUBDIR) == NULL)
+ goto error;
+ if (nih_str_array_add (&all_dirs, NULL, NULL, path) == NULL)
+ goto error;
+ nih_free (path);
+ path = NULL;
+ }
+
+ /* Legacy User's: ~/.init */
+ path = get_home_subdir (USERCONFDIR);
+ if (path == NULL)
+ goto error;
+ if (path && path[0]) {
+ if (nih_str_array_add (&all_dirs, NULL, NULL, path) == NULL)
+ goto error;
+ nih_free (path);
+ path = NULL;
+ }
+
+ /* Systems': XDG_CONFIG_DIRS/upstart */
+ dirs = xdg_get_config_dirs ();
+ if (dirs == NULL)
+ goto error;
+ for (char **p = dirs; p && *p; p++) {
+ if (nih_strcat_sprintf (p, NULL, "/%s", INIT_XDG_SUBDIR) == NULL)
+ goto error;
+ if (nih_str_array_add (&all_dirs, NULL, NULL, *p) == NULL)
+ goto error;
+ }
+ nih_free (dirs);
+ dirs = NULL;
+
+ /* System's read-only location */
+ if (nih_str_array_add (&all_dirs, NULL, NULL, SYSTEM_USERCONFDIR) == NULL)
+ goto error;
+
+ return all_dirs;
+
+error:
+ if (path != NULL)
+ nih_free (path);
+ if (dirs != NULL)
+ nih_free (dirs);
+ if (all_dirs != NULL)
+ nih_free (all_dirs);
+ return NULL;
+}
+
=== added file 'init/xdg.h'
--- init/xdg.h 1970-01-01 00:00:00 +0000
+++ init/xdg.h 2012-12-18 13:58: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 (const 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