]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Add %j/%J unit specifiers
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 23 Apr 2018 20:43:20 +0000 (22:43 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 24 Apr 2018 08:05:04 +0000 (10:05 +0200)
Those are quite similar to %i/%I, but refer to the last dash-separated
component of the name prefix.

The new functionality of dash-dropins could largely supersede the template
functionality, so it would be tempting to overload %i/%I. But that would
not be backwards compatible. So let's add the two new letters instead.

man/systemd.unit.xml
src/core/unit-printf.c
src/shared/install-printf.c
src/test/test-unit-file.c
src/test/test-unit-name.c

index d66b6aad0833d824bf7e3ecb541ccde5435b546d..02e0f499e8a08217b1cded6580c208fe11d5f859 100644 (file)
     </variablelist>
 
     <para>The following specifiers are interpreted in the Install
-    section: %n, %N, %p, %i, %U, %u, %m, %H, %b, %v. For their meaning
+    section: %n, %N, %p, %i, %j, %U, %u, %m, %H, %b, %v. For their meaning
     see the next section.
     </para>
   </refsect1>
             <entry>Unescaped instance name</entry>
             <entry>Same as <literal>%i</literal>, but with escaping undone.</entry>
           </row>
+          <row>
+            <entry><literal>%j</literal></entry>
+            <entry>Final component of the prefix</entry>
+            <entry>This is the string between the last <literal>-</literal> and the end of the prefix name. If there is no <literal>-</literal>, this is the same as <literal>%p</literal>.</entry>
+          </row>
+          <row>
+            <entry><literal>%J</literal></entry>
+            <entry>Unescaped final component of the prefix</entry>
+            <entry>Same as <literal>%j</literal>, but with escaping undone.</entry>
+          </row>
           <row>
             <entry><literal>%f</literal></entry>
             <entry>Unescaped filename</entry>
index 1e260dd9bc8ef820e0913fc54ca130bc45780678..d2948ab6aad29902c724375b5473b4354e6da5e8 100644 (file)
@@ -55,6 +55,37 @@ static int specifier_instance_unescaped(char specifier, void *data, void *userda
         return unit_name_unescape(strempty(u->instance), ret);
 }
 
+static int specifier_last_component(char specifier, void *data, void *userdata, char **ret) {
+        Unit *u = userdata;
+        _cleanup_free_ char *prefix = NULL;
+        char *dash;
+        int r;
+
+        assert(u);
+
+        r = unit_name_to_prefix(u->id, &prefix);
+        if (r < 0)
+                return r;
+
+        dash = strrchr(prefix, '-');
+        if (dash)
+                return specifier_string(specifier, dash + 1, userdata, ret);
+
+        *ret = TAKE_PTR(prefix);
+        return 0;
+}
+
+static int specifier_last_component_unescaped(char specifier, void *data, void *userdata, char **ret) {
+        _cleanup_free_ char *p = NULL;
+        int r;
+
+        r = specifier_last_component(specifier, data, userdata, &p);
+        if (r < 0)
+                return r;
+
+        return unit_name_unescape(p, ret);
+}
+
 static int specifier_filename(char specifier, void *data, void *userdata, char **ret) {
         Unit *u = userdata;
 
@@ -213,31 +244,33 @@ int unit_full_printf(Unit *u, const char *format, char **ret) {
          */
 
         const Specifier table[] = {
-                { 'n', specifier_string,              u->id },
-                { 'N', specifier_prefix_and_instance, NULL },
-                { 'p', specifier_prefix,              NULL },
-                { 'P', specifier_prefix_unescaped,    NULL },
-                { 'i', specifier_string,              u->instance },
-                { 'I', specifier_instance_unescaped,  NULL },
-
-                { 'f', specifier_filename,            NULL },
-                { 'c', specifier_cgroup,              NULL },
-                { 'r', specifier_cgroup_slice,        NULL },
-                { 'R', specifier_cgroup_root,         NULL },
-                { 't', specifier_special_directory,   UINT_TO_PTR(EXEC_DIRECTORY_RUNTIME) },
-                { 'S', specifier_special_directory,   UINT_TO_PTR(EXEC_DIRECTORY_STATE) },
-                { 'C', specifier_special_directory,   UINT_TO_PTR(EXEC_DIRECTORY_CACHE) },
-                { 'L', specifier_special_directory,   UINT_TO_PTR(EXEC_DIRECTORY_LOGS) },
-
-                { 'U', specifier_user_id,             NULL },
-                { 'u', specifier_user_name,           NULL },
-                { 'h', specifier_user_home,           NULL },
-                { 's', specifier_user_shell,          NULL },
-
-                { 'm', specifier_machine_id,          NULL },
-                { 'H', specifier_host_name,           NULL },
-                { 'b', specifier_boot_id,             NULL },
-                { 'v', specifier_kernel_release,      NULL },
+                { 'n', specifier_string,                   u->id },
+                { 'N', specifier_prefix_and_instance,      NULL },
+                { 'p', specifier_prefix,                   NULL },
+                { 'P', specifier_prefix_unescaped,         NULL },
+                { 'i', specifier_string,                   u->instance },
+                { 'I', specifier_instance_unescaped,       NULL },
+                { 'j', specifier_last_component,           NULL },
+                { 'J', specifier_last_component_unescaped, NULL },
+
+                { 'f', specifier_filename,                 NULL },
+                { 'c', specifier_cgroup,                   NULL },
+                { 'r', specifier_cgroup_slice,             NULL },
+                { 'R', specifier_cgroup_root,              NULL },
+                { 't', specifier_special_directory,        UINT_TO_PTR(EXEC_DIRECTORY_RUNTIME) },
+                { 'S', specifier_special_directory,        UINT_TO_PTR(EXEC_DIRECTORY_STATE) },
+                { 'C', specifier_special_directory,        UINT_TO_PTR(EXEC_DIRECTORY_CACHE) },
+                { 'L', specifier_special_directory,        UINT_TO_PTR(EXEC_DIRECTORY_LOGS) },
+
+                { 'U', specifier_user_id,                  NULL },
+                { 'u', specifier_user_name,                NULL },
+                { 'h', specifier_user_home,                NULL },
+                { 's', specifier_user_shell,               NULL },
+
+                { 'm', specifier_machine_id,               NULL },
+                { 'H', specifier_host_name,                NULL },
+                { 'b', specifier_boot_id,                  NULL },
+                { 'v', specifier_kernel_release,           NULL },
                 {}
         };
 
index c2cbf348e2fff860425cd4806dc02e8a07fb5f65..599300ceb43d100b08ca9b501b140c441eefb511 100644 (file)
@@ -88,6 +88,27 @@ static int specifier_instance(char specifier, void *data, void *userdata, char *
         return 0;
 }
 
+static int specifier_last_component(char specifier, void *data, void *userdata, char **ret) {
+        _cleanup_free_ char *prefix = NULL;
+        char *dash;
+        int r;
+
+        r = specifier_prefix(specifier, data, userdata, &prefix);
+        if (r < 0)
+                return r;
+
+        dash = strrchr(prefix, '-');
+        if (dash) {
+                dash = strdup(dash + 1);
+                if (!dash)
+                        return -ENOMEM;
+                *ret = dash;
+        } else
+                *ret = TAKE_PTR(prefix);
+
+        return 0;
+}
+
 int install_full_printf(UnitFileInstallInfo *i, const char *format, char **ret) {
 
         /* This is similar to unit_full_printf() but does not support
@@ -111,6 +132,7 @@ int install_full_printf(UnitFileInstallInfo *i, const char *format, char **ret)
                 { 'N', specifier_prefix_and_instance, NULL },
                 { 'p', specifier_prefix,              NULL },
                 { 'i', specifier_instance,            NULL },
+                { 'j', specifier_last_component,      NULL },
 
                 { 'U', specifier_user_id,             NULL },
                 { 'u', specifier_user_name,           NULL },
index 6b72fc90fd2fb00a350172d6868dcea2323d89f5..3fd4ac9e5dae532eedd90e6017178aba968ddd87 100644 (file)
@@ -662,6 +662,7 @@ static void test_install_printf(void) {
         expect(i, "%N", "name");
         expect(i, "%p", "name");
         expect(i, "%i", "");
+        expect(i, "%j", "name");
         expect(i, "%u", user);
         expect(i, "%U", uid);
 
index 347c58666304259679c5c9ac9bc76ffae0a86324..300a1c5a82ea7ce5447c3937f44e1d164339beaa 100644 (file)
@@ -198,7 +198,7 @@ static void test_unit_name_mangle(void) {
 static int test_unit_printf(void) {
         _cleanup_free_ char *mid = NULL, *bid = NULL, *host = NULL, *uid = NULL, *user = NULL, *shell = NULL, *home = NULL;
         _cleanup_(manager_freep) Manager *m = NULL;
-        Unit *u, *u2;
+        Unit *u;
         int r;
 
         assert_se(specifier_machine_id('m', NULL, NULL, &mid) >= 0 && mid);
@@ -245,6 +245,9 @@ static int test_unit_printf(void) {
         expect(u, "%p", "blah");
         expect(u, "%P", "blah");
         expect(u, "%i", "");
+        expect(u, "%I", "");
+        expect(u, "%j", "blah");
+        expect(u, "%J", "blah");
         expect(u, "%u", user);
         expect(u, "%U", uid);
         expect(u, "%h", home);
@@ -254,24 +257,41 @@ static int test_unit_printf(void) {
         expect(u, "%t", "/run/user/*");
 
         /* templated */
-        assert_se(u2 = unit_new(m, sizeof(Service)));
-        assert_se(unit_add_name(u2, "blah@foo-foo.service") == 0);
-        assert_se(unit_add_name(u2, "blah@foo-foo.service") == 0);
-
-        expect(u2, "%n", "blah@foo-foo.service");
-        expect(u2, "%N", "blah@foo-foo");
-        expect(u2, "%f", "/foo/foo");
-        expect(u2, "%p", "blah");
-        expect(u2, "%P", "blah");
-        expect(u2, "%i", "foo-foo");
-        expect(u2, "%I", "foo/foo");
-        expect(u2, "%u", user);
-        expect(u2, "%U", uid);
-        expect(u2, "%h", home);
-        expect(u2, "%m", mid);
-        expect(u2, "%b", bid);
-        expect(u2, "%H", host);
-        expect(u2, "%t", "/run/user/*");
+        assert_se(u = unit_new(m, sizeof(Service)));
+        assert_se(unit_add_name(u, "blah@foo-foo.service") == 0);
+        assert_se(unit_add_name(u, "blah@foo-foo.service") == 0);
+
+        expect(u, "%n", "blah@foo-foo.service");
+        expect(u, "%N", "blah@foo-foo");
+        expect(u, "%f", "/foo/foo");
+        expect(u, "%p", "blah");
+        expect(u, "%P", "blah");
+        expect(u, "%i", "foo-foo");
+        expect(u, "%I", "foo/foo");
+        expect(u, "%j", "blah");
+        expect(u, "%J", "blah");
+        expect(u, "%u", user);
+        expect(u, "%U", uid);
+        expect(u, "%h", home);
+        expect(u, "%m", mid);
+        expect(u, "%b", bid);
+        expect(u, "%H", host);
+        expect(u, "%t", "/run/user/*");
+
+        /* templated with components */
+        assert_se(u = unit_new(m, sizeof(Slice)));
+        assert_se(unit_add_name(u, "blah-blah\\x2d.slice") == 0);
+
+        expect(u, "%n", "blah-blah\\x2d.slice");
+        expect(u, "%N", "blah-blah\\x2d");
+        expect(u, "%f", "/blah/blah-");
+        expect(u, "%p", "blah-blah\\x2d");
+        expect(u, "%P", "blah/blah-");
+        expect(u, "%i", "");
+        expect(u, "%I", "");
+        expect(u, "%j", "blah\\x2d");
+        expect(u, "%J", "blah-");
+
 #undef expect
 
         return 0;