#include "parse-util.h"
#include "stdio-util.h"
#include "string-util.h"
+#include "strv.h"
static const struct capability_name* lookup_capability(register const char *str, register GPERF_LEN_TYPE len);
return 0;
}
+int capability_set_to_strv(uint64_t set, char ***ret) {
+ _cleanup_strv_free_ char **l = NULL;
+ int r;
+
+ assert(ret);
+
+ for (unsigned i = 0; i <= cap_last_cap(); i++) {
+ const char *p;
+
+ if (!FLAGS_SET(set, UINT64_C(1) << i))
+ continue;
+
+ p = CAPABILITY_TO_STRING(i);
+ assert(p);
+
+ r = strv_extend(&l, p);
+ if (r < 0)
+ return r;
+ }
+
+ *ret = TAKE_PTR(l);
+ return 0;
+}
+
int capability_set_from_string(const char *s, uint64_t *ret) {
uint64_t val = 0;
bool good = true;
int capability_list_length(void);
int capability_set_to_string(uint64_t set, char **ret);
+int capability_set_to_strv(uint64_t set, char ***ret);
int capability_set_from_string(const char *s, uint64_t *ret);
#include "capability-util.h"
#include "parse-util.h"
#include "string-util.h"
+#include "strv.h"
#include "tests.h"
/* verify the capability parser */
assert_se(c == (UINT64_C(1) << 4) - 1);
}
+static void test_capability_set_to_strv_one(uint64_t m, char **l) {
+ _cleanup_strv_free_ char **b = NULL;
+
+ assert_se(capability_set_to_strv(m, &b) >= 0);
+ assert_se(strv_equal(l, b));
+}
+
+TEST(capability_set_to_strv) {
+ test_capability_set_to_strv_one(0, STRV_MAKE(NULL));
+ test_capability_set_to_strv_one(UINT64_C(1) << CAP_MKNOD, STRV_MAKE("cap_mknod"));
+ test_capability_set_to_strv_one((UINT64_C(1) << CAP_MKNOD) |
+ (UINT64_C(1) << CAP_NET_BIND_SERVICE), STRV_MAKE("cap_net_bind_service", "cap_mknod"));
+ test_capability_set_to_strv_one((UINT64_C(1) << CAP_MKNOD) |
+ (UINT64_C(1) << CAP_NET_BIND_SERVICE) |
+ (UINT64_C(1) << CAP_IPC_OWNER), STRV_MAKE("cap_net_bind_service", "cap_ipc_owner", "cap_mknod"));
+}
+
static void test_capability_set_to_string_invalid(uint64_t invalid_cap_set) {
uint64_t c;