]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
uid-range: add some basic operations on UidRange objects
authorLennart Poettering <lennart@poettering.net>
Thu, 20 Apr 2023 16:51:26 +0000 (18:51 +0200)
committerLennart Poettering <lennart@poettering.net>
Sat, 6 Apr 2024 14:08:23 +0000 (16:08 +0200)
Helpers to compare and get size, and whether the object is empty.

src/basic/uid-range.c
src/basic/uid-range.h
src/test/test-uid-range.c

index f1b086711d8c5960264fd300f1abf206c5809084..4fc79c07c28d35ca7a5f7df4db375ce0c0424015 100644 (file)
@@ -340,3 +340,23 @@ bool uid_range_overlaps(const UIDRange *range, uid_t start, uid_t nr) {
 
         return false;
 }
+
+bool uid_range_equal(const UIDRange *a, const UIDRange *b) {
+        if (a == b)
+                return true;
+
+        if (!a || !b)
+                return false;
+
+        if (a->n_entries != b->n_entries)
+                return false;
+
+        for (size_t i = 0; i < a->n_entries; i++) {
+                if (a->entries[i].start != b->entries[i].start)
+                        return false;
+                if (a->entries[i].nr != b->entries[i].nr)
+                        return false;
+        }
+
+        return true;
+}
index f4d3d41db514ff1d018e53833270ce0c59f34fa9..48dfebbf02beefcc14e340280f232e37ac1c595a 100644 (file)
@@ -33,6 +33,36 @@ static inline bool uid_range_contains(const UIDRange *range, uid_t uid) {
 
 int uid_map_read_one(FILE *f, uid_t *ret_base, uid_t *ret_shift, uid_t *ret_range);
 
+static inline size_t uid_range_entries(const UIDRange *range) {
+        return range ? range->n_entries : 0;
+}
+
+static inline unsigned uid_range_size(const UIDRange *range) {
+        if (!range)
+                return 0;
+
+        unsigned n = 0;
+
+        FOREACH_ARRAY(e, range->entries, range->n_entries)
+                n += e->nr;
+
+        return n;
+}
+
+static inline bool uid_range_is_empty(const UIDRange *range) {
+
+        if (!range)
+                return true;
+
+        FOREACH_ARRAY(e, range->entries, range->n_entries)
+                if (e->nr > 0)
+                        return false;
+
+        return true;
+}
+
+bool uid_range_equal(const UIDRange *a, const UIDRange *b);
+
 typedef enum UIDRangeUsernsMode {
         UID_RANGE_USERNS_INSIDE,
         UID_RANGE_USERNS_OUTSIDE,
index b908cdaf1159a170636d254e527037382c2123fe..c31fb30e7ee756b28486503444e4c54b6697b00f 100644 (file)
@@ -23,9 +23,15 @@ TEST(uid_range) {
         assert_se(!uid_range_covers(p, UINT32_MAX, 1));
         assert_se(!uid_range_covers(p, UINT32_MAX - 10, 11));
 
+        assert_se(uid_range_entries(p) == 0);
+        assert_se(uid_range_size(p) == 0);
+        assert_se(uid_range_is_empty(p));
+
         assert_se(uid_range_add_str(&p, "500-999") >= 0);
         assert_se(p);
-        assert_se(p->n_entries == 1);
+        assert_se(uid_range_entries(p) == 1);
+        assert_se(uid_range_size(p) == 500);
+        assert_se(!uid_range_is_empty(p));
         assert_se(p->entries[0].start == 500);
         assert_se(p->entries[0].nr == 500);
 
@@ -56,19 +62,23 @@ TEST(uid_range) {
         assert_se(uid_range_next_lower(p, &search) == -EBUSY);
 
         assert_se(uid_range_add_str(&p, "1000") >= 0);
-        assert_se(p->n_entries == 1);
+        assert_se(uid_range_entries(p) == 1);
         assert_se(p->entries[0].start == 500);
         assert_se(p->entries[0].nr == 501);
 
         assert_se(uid_range_add_str(&p, "30-40") >= 0);
-        assert_se(p->n_entries == 2);
+        assert_se(uid_range_entries(p) == 2);
+        assert_se(uid_range_size(p) == 500 + 1 + 11);
+        assert_se(!uid_range_is_empty(p));
         assert_se(p->entries[0].start == 30);
         assert_se(p->entries[0].nr == 11);
         assert_se(p->entries[1].start == 500);
         assert_se(p->entries[1].nr == 501);
 
         assert_se(uid_range_add_str(&p, "60-70") >= 0);
-        assert_se(p->n_entries == 3);
+        assert_se(uid_range_entries(p) == 3);
+        assert_se(uid_range_size(p) == 500 + 1 + 11 + 11);
+        assert_se(!uid_range_is_empty(p));
         assert_se(p->entries[0].start == 30);
         assert_se(p->entries[0].nr == 11);
         assert_se(p->entries[1].start == 60);
@@ -77,21 +87,34 @@ TEST(uid_range) {
         assert_se(p->entries[2].nr == 501);
 
         assert_se(uid_range_add_str(&p, "20-2000") >= 0);
-        assert_se(p->n_entries == 1);
+        assert_se(uid_range_entries(p) == 1);
+        assert_se(uid_range_size(p) == 1981);
         assert_se(p->entries[0].start == 20);
         assert_se(p->entries[0].nr == 1981);
 
         assert_se(uid_range_add_str(&p, "2002") >= 0);
-        assert_se(p->n_entries == 2);
+        assert_se(uid_range_entries(p) == 2);
+        assert_se(uid_range_size(p) == 1982);
         assert_se(p->entries[0].start == 20);
         assert_se(p->entries[0].nr == 1981);
         assert_se(p->entries[1].start == 2002);
         assert_se(p->entries[1].nr == 1);
 
+        _cleanup_(uid_range_freep) UIDRange *q = NULL;
+        assert_se(!uid_range_equal(p, q));
+        assert_se(uid_range_add_str(&q, "20-2000") >= 0);
+        assert_se(!uid_range_equal(p, q));
+        assert_se(uid_range_add_str(&q, "2002") >= 0);
+        assert_se(uid_range_equal(p, q));
+
         assert_se(uid_range_add_str(&p, "2001") >= 0);
-        assert_se(p->n_entries == 1);
+        assert_se(uid_range_entries(p) == 1);
+        assert_se(uid_range_size(p) == 1983);
         assert_se(p->entries[0].start == 20);
         assert_se(p->entries[0].nr == 1983);
+
+        assert_se(uid_range_add_str(&q, "2001") >= 0);
+        assert_se(uid_range_equal(p, q));
 }
 
 TEST(load_userns) {