diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/shared/cgroup-util.c | 62 | ||||
-rw-r--r-- | src/shared/cgroup-util.h | 2 | ||||
-rw-r--r-- | src/test/test-cgroup-util.c | 27 |
3 files changed, 54 insertions, 37 deletions
diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c index af5227848d..f0d0d4855b 100644 --- a/src/shared/cgroup-util.c +++ b/src/shared/cgroup-util.c @@ -1211,69 +1211,57 @@ int cg_pid_get_cgroup(pid_t pid, char **root, char **cgroup) { return 0; } -static int instance_unit_from_cgroup(char **cgroup){ +static int instance_unit_from_cgroup(char *cgroup){ char *at; assert(cgroup); - at = memchr(*cgroup, '@', strlen(*cgroup)); - if (at && at[1] == '.') { - char *i, *s; - + at = strstr(cgroup, "@."); + if (at) { /* This is a templated service */ - i = memchr(at, '/', strlen(at)); - if(!i) - return -EIO; - s = strndup(at + 1, i - at); - if (!s) - return -ENOMEM; + char *i; + char _cleanup_free_ *i2 = NULL, *s = NULL; - i = strdup(i + 1); - if (!i) { - free(s); - return -ENOMEM; - } + i = strchr(at, '/'); + if (!i || !i[1]) /* disallow empty instances */ + return -EINVAL; - strcpy(at + 1, i); - strcpy(at + strlen(i) + 1, s); - at[strlen(at) - 1] = '\0'; + s = strndup(at + 1, i - at - 1); + i2 = strdup(i + 1); + if (!s || !i2) + return -ENOMEM; - free(i); - free(s); + strcpy(at + 1, i2); + strcat(at + 1, s); } return 0; } -static int cgroup_to_unit(char *cgroup, char **unit){ +/* non-static only for testing purposes */ +int cgroup_to_unit(char *cgroup, char **unit){ int r; - char *b, *p; - size_t k; + char *p; assert(cgroup); assert(unit); - r = instance_unit_from_cgroup(&cgroup); + r = instance_unit_from_cgroup(cgroup); if (r < 0) return r; - p = strrchr(cgroup, '/') + 1; - k = strlen(p); + p = strrchr(cgroup, '/'); + assert(p); - b = strndup(p, k); + r = unit_name_is_valid(p + 1, true); + if (!r) + return -EINVAL; - if (!b) + *unit = strdup(p + 1); + if (!*unit) return -ENOMEM; - r = unit_name_is_valid(b, true); - if (!r) { - free(b); - return -ENOENT; - } - - *unit = b; - return 0; } diff --git a/src/shared/cgroup-util.h b/src/shared/cgroup-util.h index 2429ba2430..920cf631e5 100644 --- a/src/shared/cgroup-util.h +++ b/src/shared/cgroup-util.h @@ -73,4 +73,6 @@ int cg_pid_get_cgroup(pid_t pid, char **root, char **cgroup); int cg_pid_get_unit(pid_t pid, char **unit); int cg_pid_get_user_unit(pid_t pid, char **unit); +int cgroup_to_unit(char *cgroup, char **unit); + char **cg_shorten_controllers(char **controllers); diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c new file mode 100644 index 0000000000..b30bf23a80 --- /dev/null +++ b/src/test/test-cgroup-util.c @@ -0,0 +1,27 @@ +#include <assert.h> + +#include "util.h" +#include "cgroup-util.h" + +#define check_c_t_u(path, code, result) \ +{ \ + char a[] = path; \ + char *unit = NULL; \ + assert_se(cgroup_to_unit(a, &unit) == code); \ + assert(code < 0 || streq(unit, result)); \ +} + + +static void test_cgroup_to_unit(void) { + check_c_t_u("/system/getty@.service/tty2", 0, "getty@tty2.service"); + check_c_t_u("/system/getty@.service/", -EINVAL, "getty@tty2.service"); + check_c_t_u("/system/getty@.service", -EINVAL, "getty@tty2.service"); + check_c_t_u("/system/getty.service", 0, "getty.service"); + check_c_t_u("/system/getty", -EINVAL, "getty.service"); +} + +int main(void) { + test_cgroup_to_unit(); + + return 0; +} |