]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
basic/unit-name: allow unit_name_to_instance() to be used to classify units
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 2 Apr 2019 09:05:44 +0000 (11:05 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 19 Jul 2019 14:49:41 +0000 (16:49 +0200)
This could already be done by calling unit_name_is_*(), but if we don't know
if the argument is a valid unit name, it is more convenient to have a single
function which returns the type or possibly an error if the unit name is not
valid.

The values in the enum are sorted "by length". Not really important, but it
seems more natural to me.

src/basic/unit-name.c
src/basic/unit-name.h
src/test/test-unit-name.c

index af873d0ffd752ce1399db42ba035ff4a252174ba..4226f3014d5c24c9dcadc0ac943c1ad3e8e699eb 100644 (file)
@@ -140,12 +140,10 @@ int unit_name_to_prefix(const char *n, char **ret) {
         return 0;
 }
 
-int unit_name_to_instance(const char *n, char **instance) {
+int unit_name_to_instance(const char *n, char **ret) {
         const char *p, *d;
-        char *i;
 
         assert(n);
-        assert(instance);
 
         if (!unit_name_is_valid(n, UNIT_NAME_ANY))
                 return -EINVAL;
@@ -153,8 +151,9 @@ int unit_name_to_instance(const char *n, char **instance) {
         /* Everything past the first @ and before the last . is the instance */
         p = strchr(n, '@');
         if (!p) {
-                *instance = NULL;
-                return 0;
+                if (ret)
+                        *ret = NULL;
+                return UNIT_NAME_PLAIN;
         }
 
         p++;
@@ -163,12 +162,14 @@ int unit_name_to_instance(const char *n, char **instance) {
         if (!d)
                 return -EINVAL;
 
-        i = strndup(p, d-p);
-        if (!i)
-                return -ENOMEM;
+        if (ret) {
+                char *i = strndup(p, d-p);
+                if (!i)
+                        return -ENOMEM;
 
-        *instance = i;
-        return 1;
+                *ret = i;
+        }
+        return d > p ? UNIT_NAME_INSTANCE : UNIT_NAME_TEMPLATE;
 }
 
 int unit_name_to_prefix_and_instance(const char *n, char **ret) {
index 2bbf73b42a1ad6007d57a56a24c639478cdc3413..2e060ff3e830e2d387d7a7c13751a8a997695fa4 100644 (file)
@@ -10,9 +10,9 @@
 
 typedef enum UnitNameFlags {
         UNIT_NAME_PLAIN    = 1 << 0, /* Allow foo.service */
-        UNIT_NAME_INSTANCE = 1 << 1, /* Allow foo@bar.service */
-        UNIT_NAME_TEMPLATE = 1 << 2, /* Allow foo@.service */
-        UNIT_NAME_ANY = UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE|UNIT_NAME_TEMPLATE,
+        UNIT_NAME_TEMPLATE = 1 << 1, /* Allow foo@.service */
+        UNIT_NAME_INSTANCE = 1 << 2, /* Allow foo@bar.service */
+        UNIT_NAME_ANY = UNIT_NAME_PLAIN|UNIT_NAME_TEMPLATE|UNIT_NAME_INSTANCE,
 } UnitNameFlags;
 
 bool unit_name_is_valid(const char *n, UnitNameFlags flags) _pure_;
@@ -20,8 +20,11 @@ bool unit_prefix_is_valid(const char *p) _pure_;
 bool unit_instance_is_valid(const char *i) _pure_;
 bool unit_suffix_is_valid(const char *s) _pure_;
 
-int unit_name_to_prefix(const char *n, char **prefix);
-int unit_name_to_instance(const char *n, char **instance);
+int unit_name_to_prefix(const char *n, char **ret);
+int unit_name_to_instance(const char *n, char **ret);
+static inline int unit_name_classify(const char *n) {
+        return unit_name_to_instance(n, NULL);
+}
 int unit_name_to_prefix_and_instance(const char *n, char **ret);
 
 UnitType unit_name_to_type(const char *n) _pure_;
index fd2443e3cbc7e9aad617485e172e3c2641e3af35..7fe732cf2ffe9b32bfd3960f81f2cbde51a4c22e 100644 (file)
@@ -430,29 +430,31 @@ static void test_unit_name_to_instance(void) {
         int r;
 
         r = unit_name_to_instance("foo@bar.service", &instance);
-        assert_se(r >= 0);
+        assert_se(r == UNIT_NAME_INSTANCE);
         assert_se(streq(instance, "bar"));
         free(instance);
 
         r = unit_name_to_instance("foo@.service", &instance);
-        assert_se(r >= 0);
+        assert_se(r == UNIT_NAME_TEMPLATE);
         assert_se(streq(instance, ""));
         free(instance);
 
         r = unit_name_to_instance("fo0-stUff_b@b.service", &instance);
-        assert_se(r >= 0);
+        assert_se(r == UNIT_NAME_INSTANCE);
         assert_se(streq(instance, "b"));
         free(instance);
 
         r = unit_name_to_instance("foo.service", &instance);
-        assert_se(r == 0);
+        assert_se(r == UNIT_NAME_PLAIN);
         assert_se(!instance);
 
         r = unit_name_to_instance("fooj@unk", &instance);
         assert_se(r < 0);
+        assert_se(!instance);
 
         r = unit_name_to_instance("foo@", &instance);
         assert_se(r < 0);
+        assert_se(!instance);
 }
 
 static void test_unit_name_escape(void) {