summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2019-04-02 11:05:44 +0200
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2019-07-19 16:49:41 +0200
commitb124d3f2ce87cc71065fde589caafd5ceb4764b6 (patch)
tree98b5f4ef4e4b7919afc416647ad12a947cf6aea5
parent69de5c16ff89050bc5b4cc9e02eb8e8d082a641a (diff)
downloadsystemd-b124d3f2ce87cc71065fde589caafd5ceb4764b6.tar.gz
basic/unit-name: allow unit_name_to_instance() to be used to classify units
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.
-rw-r--r--src/basic/unit-name.c21
-rw-r--r--src/basic/unit-name.h13
-rw-r--r--src/test/test-unit-name.c10
3 files changed, 25 insertions, 19 deletions
diff --git a/src/basic/unit-name.c b/src/basic/unit-name.c
index af873d0ffd..4226f3014d 100644
--- a/src/basic/unit-name.c
+++ b/src/basic/unit-name.c
@@ -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) {
diff --git a/src/basic/unit-name.h b/src/basic/unit-name.h
index 2bbf73b42a..2e060ff3e8 100644
--- a/src/basic/unit-name.h
+++ b/src/basic/unit-name.h
@@ -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_;
diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c
index fd2443e3cb..7fe732cf2f 100644
--- a/src/test/test-unit-name.c
+++ b/src/test/test-unit-name.c
@@ -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) {