const char *capability_to_name(int id) {
if (id < 0)
return NULL;
-
if ((size_t) id >= ELEMENTSOF(capability_names))
return NULL;
return capability_names[id];
}
+const char *capability_to_string(int id, char buf[static CAPABILITY_TO_STRING_MAX]) {
+ const char *p;
+
+ if (id < 0)
+ return NULL;
+ if (id >= 63) /* refuse caps >= 63 since we can't store them in a uint64_t mask anymore, and still retain UINT64_MAX as marker for "unset" */
+ return NULL;
+
+ p = capability_to_name(id);
+ if (p)
+ return p;
+
+ sprintf(buf, "0x%x", (unsigned) id); /* numerical fallback */
+ return buf;
+}
+
int capability_from_name(const char *name) {
const struct capability_name *sc;
int r, i;
#include <inttypes.h>
+/* Space for capability_to_string() in case we write out a numeric capability because we don't know the name
+ * for it. "0x3e" is the largest string we might output, in both sensese of the word "largest": two chars for
+ * "0x", two bytes for the hex value, and one trailing NUL byte. */
+#define CAPABILITY_TO_STRING_MAX (2 + 2 + 1)
+
const char *capability_to_name(int id);
+const char *capability_to_string(int id, char buf[static CAPABILITY_TO_STRING_MAX]);
+#define CAPABILITY_TO_STRING(id) capability_to_string(id, (char[CAPABILITY_TO_STRING_MAX]) {})
+
int capability_from_name(const char *name);
int capability_list_length(void);
TEST(cap_list) {
assert_se(!capability_to_name(-1));
assert_se(!capability_to_name(capability_list_length()));
+ assert_se(!capability_to_name(63));
+ assert_se(!capability_to_name(64));
+
+ assert_se(!CAPABILITY_TO_STRING(-1));
+ if (capability_list_length() <= 62)
+ assert_se(streq(CAPABILITY_TO_STRING(62), "0x3e"));
+ assert_se(!CAPABILITY_TO_STRING(64));
for (int i = 0; i < capability_list_length(); i++) {
const char *n;
assert_se(n = capability_to_name(i));
assert_se(capability_from_name(n) == i);
printf("%s = %i\n", n, i);
+
+ assert_se(streq(CAPABILITY_TO_STRING(i), n));
}
assert_se(capability_from_name("asdfbsd") == -EINVAL);