diff --git a/man/rules/meson.build b/man/rules/meson.build
index c21f1b6b4c1..05b087db3e6 100644
--- a/man/rules/meson.build
+++ b/man/rules/meson.build
@@ -128,6 +128,9 @@ manpages = [
'SD_ID128_NULL',
'SD_ID128_UUID_FORMAT_STR',
'sd_id128_equal',
+ 'sd_id128_in_set',
+ 'sd_id128_in_set_sentinel',
+ 'sd_id128_in_setv',
'sd_id128_is_allf',
'sd_id128_is_null',
'sd_id128_t'],
diff --git a/man/sd-id128.xml b/man/sd-id128.xml
index c448d60a940..1890f6d6a55 100644
--- a/man/sd-id128.xml
+++ b/man/sd-id128.xml
@@ -27,6 +27,9 @@
SD_ID128_NULL
SD_ID128_UUID_FORMAT_STR
sd_id128_equal
+ sd_id128_in_set
+ sd_id128_in_set_sentinel
+ sd_id128_in_setv
sd_id128_is_allf
sd_id128_is_null
sd_id128_t
@@ -148,6 +151,32 @@ int main(int argc, char **argv) {
assert(sd_id128_is_allf(SD_ID128_ALLF));
+ For convenience, sd_id128_in_set() takes a list of IDs and
+ returns true if any are equal to the first argument:
+
+ int main(int argc, char *argv[]) {
+ sd_id12_t a = SD_ID128_MAKE(ee,89,be,71,bd,6e,43,d6,91,e6,c5,5d,eb,03,02,07);
+ assert(sd_id128_in_set(a, a));
+ assert(sd_id128_in_set(a, a, a));
+ assert(!sd_id128_in_set(a));
+ assert(!sd_id128_in_set(a,
+ SD_ID128_MAKE(f2,28,88,9c,5f,09,44,15,9d,d7,04,77,58,cb,e7,3e)
+ SD_ID128_MAKE(2f,88,28,5f,9c,44,09,9d,d7,15,77,04,bc,85,7e,e3)
+ SD_ID128_ALLF));
+ return 0;
+}
+
+
+ sd_id128_in_set() is defined as a macro over
+ sd_id128_in_set_sentinel(), adding the SD_ID128_NULL
+ sentinel. Since sd_id128_in_set_sentinel() uses SD_ID128_NULL
+ as the sentinel, SD_ID128_NULL cannot be otherwise placed in the argument list.
+
+
+ sd_id128_in_setv() is similar to
+ sd_id128_in_set_sentinel(), but takes a struct varargs
+ argument.
+
Note that new, randomized IDs may be generated with
systemd-id1281's
new command.
diff --git a/src/systemd/sd-id128.h b/src/systemd/sd-id128.h
index 02aa318a060..ab209c8c7da 100644
--- a/src/systemd/sd-id128.h
+++ b/src/systemd/sd-id128.h
@@ -18,6 +18,7 @@
***/
#include
+#include
#include
#include "_sd-common.h"
@@ -119,6 +120,32 @@ _sd_pure_ static __inline__ int sd_id128_is_allf(sd_id128_t a) {
#define SD_ID128_NULL ((const sd_id128_t) { .qwords = { 0, 0 }})
#define SD_ID128_ALLF ((const sd_id128_t) { .qwords = { UINT64_C(0xFFFFFFFFFFFFFFFF), UINT64_C(0xFFFFFFFFFFFFFFFF) }})
+_sd_pure_ static __inline__ int sd_id128_in_setv(sd_id128_t a, va_list ap) {
+ for (;;) {
+ sd_id128_t b = va_arg(ap, sd_id128_t);
+
+ if (sd_id128_is_null(b))
+ return 0;
+
+ if (sd_id128_equal(a, b))
+ return 1;
+ }
+}
+
+_sd_pure_ static __inline__ int sd_id128_in_set_sentinel(sd_id128_t a, ...) {
+ va_list ap;
+ int r;
+
+ va_start(ap, a);
+ r = sd_id128_in_setv(a, ap);
+ va_end(ap);
+
+ return r;
+}
+
+#define sd_id128_in_set(a, ...) \
+ sd_id128_in_set_sentinel(a, ##__VA_ARGS__, SD_ID128_NULL)
+
_SD_END_DECLARATIONS;
#endif
diff --git a/src/test/test-id128.c b/src/test/test-id128.c
index a0649b9deb0..a61b35b9a33 100644
--- a/src/test/test-id128.c
+++ b/src/test/test-id128.c
@@ -31,6 +31,13 @@ int main(int argc, char *argv[]) {
assert_se(sd_id128_from_string(t, &id2) == 0);
assert_se(sd_id128_equal(id, id2));
+ assert_se(sd_id128_in_set(id, id));
+ assert_se(sd_id128_in_set(id, id2));
+ assert_se(sd_id128_in_set(id, id2, id));
+ assert_se(sd_id128_in_set(id, ID128_WALDI, id));
+ assert_se(!sd_id128_in_set(id));
+ assert_se(!sd_id128_in_set(id, ID128_WALDI));
+ assert_se(!sd_id128_in_set(id, ID128_WALDI, ID128_WALDI));
if (sd_booted() > 0) {
assert_se(sd_id128_get_machine(&id) == 0);