[systemd-devel] [PATCH 5/6] Add trivial templated args to [Install] WantedBy and RequiredBy fields

Oleksii Shevchuk alxchk at gmail.com
Sat Nov 3 12:52:03 PDT 2012


Example:
> cat ~/.config/systemd/user/mpop at .timer
[Unit]
Description=Fetch mail via POP3 mpop timer
StopWhenUnneeded=yes

[Timer]
OnUnitInactiveSec=5m
OnBootSec=0

[Install]
WantedBy=services@%i.target

> systemctl --user enable mpop at work.timer
---
 src/shared/install.c | 49 +++++++++++++++++++++++++++++++++++++++++++++----
 src/shared/install.h |  2 ++
 2 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/src/shared/install.c b/src/shared/install.c
index a9d75f3..a7244f4 100644
--- a/src/shared/install.c
+++ b/src/shared/install.c
@@ -36,6 +36,7 @@
 #include "install.h"
 #include "conf-parser.h"
 #include "conf-files.h"
+#include "specifier.h"
 
 typedef struct {
         char *name;
@@ -51,6 +52,30 @@ typedef struct {
         Hashmap *have_installed;
 } InstallContext;
 
+char *name_printf(char * prefix, char * instance, char* format) {
+
+        /*
+         * This will use the passed string as format string and
+         * replace the following specifiers, if any:
+         *
+         * %p: the unit prefix                         (foo)
+         * %i: the instance                            (bar)
+         */
+
+        char empty_prefix[]   = "%p";
+        char empty_instance[] = "%i";
+
+        const Specifier table[] = {
+                { 'p', specifier_string, prefix   ? : empty_prefix},
+                { 'i', specifier_string, instance ? : empty_instance},
+                { 0, NULL, NULL }
+        };
+
+        assert(format);
+
+        return specifier_printf(format, table, NULL);
+}
+
 static int lookup_paths_init_from_scope(LookupPaths *paths, UnitFileScope scope) {
         assert(paths);
         assert(scope >= 0);
@@ -1271,13 +1296,21 @@ static int install_info_symlink_wants(
 
         STRV_FOREACH(s, i->wanted_by) {
                 char *path;
+                char *instance = NULL;
+                char *prefix   = NULL;
+                char *dst      = NULL;
+
+                unit_name_to_instance(i->name, &instance);
+                prefix = unit_name_to_prefix(i->name);
 
-                if (!unit_name_is_valid(*s, true)) {
+                dst = name_printf(prefix, instance, *s);
+
+                if (!unit_name_is_valid(dst, true)) {
                         r = -EINVAL;
                         continue;
                 }
 
-                if (asprintf(&path, "%s/%s.wants/%s", config_path, *s, i->name) < 0)
+                if (asprintf(&path, "%s/%s.wants/%s", config_path, dst, i->name) < 0)
                         return -ENOMEM;
 
                 q = create_symlink(i->path, path, force, changes, n_changes);
@@ -1305,13 +1338,21 @@ static int install_info_symlink_requires(
 
         STRV_FOREACH(s, i->required_by) {
                 char *path;
+                char *instance = NULL;
+                char *prefix   = NULL;
+                char *dst      = NULL;
+
+                unit_name_to_instance(i->name, &instance);
+                prefix = unit_name_to_prefix(i->name);
+
+                dst = name_printf(prefix, instance, *s);
 
-                if (!unit_name_is_valid(*s, true)) {
+                if (!unit_name_is_valid(dst, true)) {
                         r = -EINVAL;
                         continue;
                 }
 
-                if (asprintf(&path, "%s/%s.requires/%s", config_path, *s, i->name) < 0)
+                if (asprintf(&path, "%s/%s.requires/%s", config_path, dst, i->name) < 0)
                         return -ENOMEM;
 
                 q = create_symlink(i->path, path, force, changes, n_changes);
diff --git a/src/shared/install.h b/src/shared/install.h
index 5524991..b43367a 100644
--- a/src/shared/install.h
+++ b/src/shared/install.h
@@ -85,3 +85,5 @@ UnitFileState unit_file_state_from_string(const char *s);
 
 const char *unit_file_change_type_to_string(UnitFileChangeType s);
 UnitFileChangeType unit_file_change_type_from_string(const char *s);
+
+char *name_printf(char * prefix, char * instance, char * format);
-- 
1.7.12.4



More information about the systemd-devel mailing list