return 0;
}
+int capability_set_to_string_negative(uint64_t set, char **ret) {
+ _cleanup_free_ char *a = NULL, *b = NULL;
+ int r;
+
+ assert(ret);
+
+ /* Format the specified capability mask both in positive way (i.e. just listing caps) and in negative
+ * way (i.e. listing only caps that are missing from the full set) and return the shorter version of
+ * the two. */
+
+ r = capability_set_to_string(set, &a);
+ if (r < 0)
+ return r;
+
+ r = capability_set_to_string(~set & all_capabilities(), &b);
+ if (r < 0)
+ return r;
+
+ if (strlen(a) <= 1 + strlen(b))
+ *ret = TAKE_PTR(a);
+ else {
+ char *c = strjoin("~", b);
+ if (!c)
+ return -ENOMEM;
+
+ *ret = c;
+ }
+
+ return 0;
+}
+
int capability_set_to_strv(uint64_t set, char ***ret) {
_cleanup_strv_free_ char **l = NULL;
int r;
int capability_list_length(void);
int capability_set_to_string(uint64_t set, char **ret);
+int capability_set_to_string_negative(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 "cap-list.h"
#include "capability-util.h"
#include "parse-util.h"
+#include "random-util.h"
#include "string-util.h"
#include "strv.h"
#include "tests.h"
test_capability_set_to_string_invalid(all_capabilities() + 1);
}
+TEST(capability_set_to_string_negative) {
+
+ for (unsigned i = 0; i < 150; i++) {
+ _cleanup_free_ char *a = NULL, *b = NULL;
+
+ uint64_t m =
+ random_u64() % (UINT64_C(1) << (cap_last_cap() + 1));
+
+ assert_se(capability_set_to_string(m, &a) >= 0);
+ assert_se(capability_set_to_string_negative(m, &b) >= 0);
+
+ printf("%s (%zu) → ", a, strlen(a));
+
+ if (streq(a, b))
+ printf("same\n");
+ else
+ printf("%s (%zu)\n", b, strlen(b));
+
+ assert_se(strlen(b) <= strlen(a));
+ }
+}
+
DEFINE_TEST_MAIN(LOG_INFO);