From: Mike Yuan Date: Sun, 25 Aug 2024 18:07:12 +0000 (+0200) Subject: path-lookup: unify acquire_{config,control,attached}_dir() X-Git-Tag: v257-rc1~317^2~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=716fab66ab07d8a594544b52d16f87d11e7c6013;p=thirdparty%2Fsystemd.git path-lookup: unify acquire_{config,control,attached}_dir() Note that -ENXIO reported by xdg_user_config_dir() is now properly propagated rather than ignored, as unlike XDG_RUNTIME_DIR, XDG_CONFIG_HOME has a default value hence ENXIO is not really expected. --- diff --git a/src/libsystemd/sd-path/path-lookup.c b/src/libsystemd/sd-path/path-lookup.c index 6f6a7cb4b0f..d37da14ec61 100644 --- a/src/libsystemd/sd-path/path-lookup.c +++ b/src/libsystemd/sd-path/path-lookup.c @@ -250,137 +250,91 @@ static int acquire_transient_dir(RuntimeScope scope, const char *tempdir, char * return 0; } -static int acquire_config_dirs(RuntimeScope scope, char **persistent, char **runtime) { - _cleanup_free_ char *a = NULL, *b = NULL; - int r; - - assert(persistent); - assert(runtime); - - switch (scope) { - - case RUNTIME_SCOPE_SYSTEM: - a = strdup(SYSTEM_CONFIG_UNIT_DIR); - b = strdup("/run/systemd/system"); - break; - - case RUNTIME_SCOPE_GLOBAL: - a = strdup(USER_CONFIG_UNIT_DIR); - b = strdup("/run/systemd/user"); - break; - - case RUNTIME_SCOPE_USER: - r = xdg_user_config_dir("/systemd/user", &a); - if (r < 0 && r != -ENXIO) - return r; - - r = xdg_user_runtime_dir("/systemd/user", runtime); - if (r < 0) { - if (r != -ENXIO) - return r; - - /* If XDG_RUNTIME_DIR is not set, don't consider that fatal, simply initialize the runtime - * directory to NULL */ - *runtime = NULL; - } - - *persistent = TAKE_PTR(a); - - return 0; - - default: - assert_not_reached(); - } - - if (!a || !b) - return -ENOMEM; - - *persistent = TAKE_PTR(a); - *runtime = TAKE_PTR(b); +typedef enum LookupDirType { + LOOKUP_DIR_CONFIG, + LOOKUP_DIR_CONTROL, + LOOKUP_DIR_ATTACHED, + _LOOKUP_DIR_MAX, + _LOOKUP_DIR_INVALID = -EINVAL, +} LookupDirType; + +static int acquire_lookup_dirs( + LookupDirType type, + RuntimeScope scope, + char **ret_persistent, + char **ret_runtime) { - return 0; -} + /* RUNTIME_SCOPE_USER dirs are relative to XDG_CONFIG_DIR and XDG_RUNTIME_DIR, respectively */ + static const struct { + const char *persistent; + const char *runtime; + } dirs[_LOOKUP_DIR_MAX][_RUNTIME_SCOPE_MAX] = { + [LOOKUP_DIR_CONFIG] = { + [RUNTIME_SCOPE_SYSTEM] = { SYSTEM_CONFIG_UNIT_DIR, "/run/systemd/system" }, + [RUNTIME_SCOPE_GLOBAL] = { USER_CONFIG_UNIT_DIR, "/run/systemd/user" }, + [RUNTIME_SCOPE_USER] = { "systemd/user", "systemd/user" }, + }, + [LOOKUP_DIR_CONTROL] = { + [RUNTIME_SCOPE_SYSTEM] = { "/etc/systemd/system.control", "/run/systemd/system.control" }, + [RUNTIME_SCOPE_USER] = { "systemd/user.control", "systemd/user.control" }, + }, + [LOOKUP_DIR_ATTACHED] = { + [RUNTIME_SCOPE_SYSTEM] = { "/etc/systemd/system.attached", "/run/systemd/system.attached" }, + /* Portable services are not available to regular users for now. */ + }, + }; -static int acquire_control_dirs(RuntimeScope scope, char **persistent, char **runtime) { - _cleanup_free_ char *a = NULL; + _cleanup_free_ char *a = NULL, *b = NULL; int r; - assert(persistent); - assert(runtime); + assert(type >= 0 && type < _LOOKUP_DIR_MAX); + assert(IN_SET(scope, RUNTIME_SCOPE_SYSTEM, RUNTIME_SCOPE_USER, RUNTIME_SCOPE_GLOBAL)); + assert(ret_persistent); + assert(ret_runtime); - switch (scope) { + const char *persistent = dirs[type][scope].persistent; + const char *runtime = dirs[type][scope].runtime; + assert(!persistent == !runtime); - case RUNTIME_SCOPE_SYSTEM: { - _cleanup_free_ char *b = NULL; + if (!persistent) + return -EOPNOTSUPP; - a = strdup("/etc/systemd/system.control"); - if (!a) - return -ENOMEM; + switch (scope) { - b = strdup("/run/systemd/system.control"); - if (!b) + case RUNTIME_SCOPE_SYSTEM: + case RUNTIME_SCOPE_GLOBAL: + a = strdup(persistent); + b = strdup(runtime); + if (!a || !b) return -ENOMEM; - *runtime = TAKE_PTR(b); + *ret_persistent = TAKE_PTR(a); + *ret_runtime = TAKE_PTR(b); - break; - } + return 0; case RUNTIME_SCOPE_USER: - r = xdg_user_config_dir("/systemd/user.control", &a); - if (r < 0 && r != -ENXIO) + r = xdg_user_config_dir(persistent, &a); + if (r < 0) return r; - r = xdg_user_runtime_dir("/systemd/user.control", runtime); + r = xdg_user_runtime_dir(runtime, ret_runtime); if (r < 0) { if (r != -ENXIO) return r; - /* If XDG_RUNTIME_DIR is not set, don't consider this fatal, simply initialize the directory to - * NULL */ - *runtime = NULL; + /* If XDG_RUNTIME_DIR is not set, don't consider that fatal, simply initialize + * the runtime directory to NULL. */ + *ret_runtime = NULL; } - break; + *ret_persistent = TAKE_PTR(a); - case RUNTIME_SCOPE_GLOBAL: - return -EOPNOTSUPP; + return 0; default: assert_not_reached(); } - - *persistent = TAKE_PTR(a); - - return 0; -} - -static int acquire_attached_dirs( - RuntimeScope scope, - char **ret_persistent, - char **ret_runtime) { - - _cleanup_free_ char *a = NULL, *b = NULL; - - assert(ret_persistent); - assert(ret_runtime); - - /* Portable services are not available to regular users for now. */ - if (scope != RUNTIME_SCOPE_SYSTEM) - return -EOPNOTSUPP; - - a = strdup("/etc/systemd/system.attached"); - if (!a) - return -ENOMEM; - - b = strdup("/run/systemd/system.attached"); - if (!b) - return -ENOMEM; - - *ret_persistent = TAKE_PTR(a); - *ret_runtime = TAKE_PTR(b); - - return 0; } static int patch_root_prefix(char **p, const char *root_dir) { @@ -489,16 +443,24 @@ int lookup_paths_init( } /* Note: when XDG_RUNTIME_DIR is not set this will not return -ENXIO, but simply set runtime_config to NULL */ - r = acquire_config_dirs(scope, &persistent_config, &runtime_config); + r = acquire_lookup_dirs(LOOKUP_DIR_CONFIG, scope, &persistent_config, &runtime_config); if (r < 0) return r; if (scope == RUNTIME_SCOPE_USER) { - r = acquire_config_dirs(RUNTIME_SCOPE_GLOBAL, &global_persistent_config, &global_runtime_config); + r = acquire_lookup_dirs(LOOKUP_DIR_CONFIG, RUNTIME_SCOPE_GLOBAL, &global_persistent_config, &global_runtime_config); if (r < 0) return r; } + r = acquire_lookup_dirs(LOOKUP_DIR_CONTROL, scope, &persistent_control, &runtime_control); + if (r < 0 && r != -EOPNOTSUPP) + return r; + + r = acquire_lookup_dirs(LOOKUP_DIR_ATTACHED, scope, &persistent_attached, &runtime_attached); + if (r < 0 && r != -EOPNOTSUPP) + return r; + if ((flags & LOOKUP_PATHS_EXCLUDE_GENERATED) == 0) { /* Note: if XDG_RUNTIME_DIR is not set, this will fail completely with ENXIO */ r = acquire_generator_dirs(scope, tempdir, @@ -512,15 +474,6 @@ int lookup_paths_init( if (r < 0 && !IN_SET(r, -EOPNOTSUPP, -ENXIO)) return r; - /* Note: when XDG_RUNTIME_DIR is not set this will not return -ENXIO, but simply set runtime_control to NULL */ - r = acquire_control_dirs(scope, &persistent_control, &runtime_control); - if (r < 0 && r != -EOPNOTSUPP) - return r; - - r = acquire_attached_dirs(scope, &persistent_attached, &runtime_attached); - if (r < 0 && r != -EOPNOTSUPP) - return r; - /* First priority is whatever has been passed to us via env vars */ r = get_paths_from_environ("SYSTEMD_UNIT_PATH", &paths, &append); if (r < 0)