Dmitrijs Ledkovs has proposed merging lp:~xnox/upstart/xdg into lp:upstart.
Requested reviews: Upstart Reviewers (upstart-reviewers) For more details, see: https://code.launchpad.net/~xnox/upstart/xdg/+merge/139943 https://wiki.ubuntu.com/FoundationsTeam/Specs/RaringUpstartUserSessions#Configuration_Files_for_User_Jobs When we get `--user' option, we will need to setup configuration file sources. This branch implements get_user_upstart_dirs, which returns an array of paths in priority order. It doesn't implement the location under "/usr" as the name hasn't been agreed yet, but it will be easy to add later. Currently it relies on environment variable HOME to be set. Depending on how we implement, --user, we may have environ object with HOME,XDG_CONFIG_HOME,XDG_CONFIG_DIRS variables in it, then we can use environ_expand instead of current processing. I am not entirely sure about the tests, especially about TEST_ALLOC_FAIL (see comments in the test file). Under valgrind get_user_upstart_dirs seems to leak memory, not sure if I am using api form nih/strings.h correctly there. Next, I'll work on .override processing from any-dir, but exclude those beyond the jobfile itself. -- https://code.launchpad.net/~xnox/upstart/xdg/+merge/139943 Your team Upstart Reviewers is requested to review the proposed merge of lp:~xnox/upstart/xdg into lp:upstart.
=== modified file 'ChangeLog' --- ChangeLog 2012-12-11 13:59:01 +0000 +++ ChangeLog 2012-12-14 16:07:48 +0000 @@ -1,3 +1,8 @@ +2012-12-14 Dmitrijs Ledkovs <[email protected]> + + * init/xdg.c: Add functions to construct user session config + source paths. + 2012-12-11 James Hunt <[email protected]> * init/Makefile.am: Add explicit -lrt for tests (LP: #1088863) === modified file 'init/Makefile.am' --- init/Makefile.am 2012-12-11 13:59:01 +0000 +++ init/Makefile.am 2012-12-14 16:07:48 +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/paths.h' --- init/paths.h 2012-09-10 07:50:32 +0000 +++ init/paths.h 2012-12-14 16:07:48 +0000 @@ -96,6 +96,15 @@ #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 /** * 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-14 16:07:48 +0000 @@ -0,0 +1,311 @@ +/* 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 (dirs[3], 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-14 16:07:48 +0000 @@ -0,0 +1,144 @@ +/* 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)); + } + + return all_dirs; +} + === added file 'init/xdg.h' --- init/xdg.h 1970-01-01 00:00:00 +0000 +++ init/xdg.h 2012-12-14 16:07:48 +0000 @@ -0,0 +1,41 @@ +/* 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 <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
