James Hunt has proposed merging lp:~jamesodhunt/upstart/add-session-file into lp:upstart.
Requested reviews: Upstart Reviewers (upstart-reviewers) For more details, see: https://code.launchpad.net/~jamesodhunt/upstart/add-session-file/+merge/144881 This branch introduces a session file which the Session Init creates on startup and removes on shutdown. It is of no value to the Session Init and as such errors creating the file are ignored. The files will be used by the upcoming initctl 'list-sessions' command as an aid to determine if there are any running Session Inits. This allows Upstart running as a Session Init to conform to the XDG specification and remove the XDG_RUNTIME_DIR when no remaining session exist. -- https://code.launchpad.net/~jamesodhunt/upstart/add-session-file/+merge/144881 Your team Upstart Reviewers is requested to review the proposed merge of lp:~jamesodhunt/upstart/add-session-file into lp:upstart.
=== modified file 'ChangeLog' --- ChangeLog 2013-01-24 08:37:53 +0000 +++ ChangeLog 2013-01-25 10:12:21 +0000 @@ -1,3 +1,31 @@ +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-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-23 12:56:00 +0000 +++ init/control.c 2013-01-25 10:12:21 +0000 @@ -56,15 +56,19 @@ #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 void control_bus_flush (void); +static void control_session_file_create (void); +static void control_session_file_remove (void); /** * use_session_bus: @@ -108,6 +112,8 @@ /* External definitions */ extern int user_mode; +extern char *session_file; + /** * control_init: * @@ -120,14 +126,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: @@ -1117,3 +1136,53 @@ NIH_ZERO (control_emit_restarted (conn, DBUS_PATH_UPSTART)); } } + +/** + * 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-25 10:12:21 +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-25 10:12:21 +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-23 12:40:36 +0000 +++ init/man/init.5 2013-01-25 10:12:21 +0000 @@ -1050,6 +1050,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:12:21 +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 10:12:21 +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-25 10:12:21 +0000 @@ -42,37 +42,74 @@ 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) + 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 +119,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 +151,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 +171,60 @@ } /** + * xdg_get_runtime_dir: + * + * Determine an XDG compliant XDG_RUNTIME_DIR. + * + * 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] == '/') { + mkdir (dir, INIT_XDG_PATH_MODE); + dir = nih_strdup (NULL, dir); + return 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 +278,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 +350,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-25 10:12:21 +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
