summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/basic/hashmap.c25
-rw-r--r--src/basic/set.h2
-rw-r--r--src/libsystemd/sd-device/sd-device.c6
-rw-r--r--src/test/test-set.c67
-rwxr-xr-xtest/units/testsuite-55.sh44
5 files changed, 87 insertions, 57 deletions
diff --git a/src/basic/hashmap.c b/src/basic/hashmap.c
index e38e580530..cdc6847edf 100644
--- a/src/basic/hashmap.c
+++ b/src/basic/hashmap.c
@@ -1977,23 +1977,33 @@ IteratedCache* iterated_cache_free(IteratedCache *cache) {
return mfree(cache);
}
-int set_strjoin(Set *s, const char *separator, char **ret) {
+int set_strjoin(Set *s, const char *separator, bool wrap_with_separator, char **ret) {
size_t separator_len, allocated = 0, len = 0;
_cleanup_free_ char *str = NULL;
const char *value;
- bool first = true;
+ bool first;
assert(ret);
+ if (set_isempty(s)) {
+ *ret = NULL;
+ return 0;
+ }
+
separator_len = strlen_ptr(separator);
+ if (separator_len == 0)
+ wrap_with_separator = false;
+
+ first = !wrap_with_separator;
+
SET_FOREACH(value, s) {
size_t l = strlen_ptr(value);
if (l == 0)
continue;
- if (!GREEDY_REALLOC(str, allocated, len + l + (first ? 0 : separator_len) + 1))
+ if (!GREEDY_REALLOC(str, allocated, len + l + (first ? 0 : separator_len) + (wrap_with_separator ? separator_len : 0) + 1))
return -ENOMEM;
if (separator_len > 0 && !first) {
@@ -2005,8 +2015,13 @@ int set_strjoin(Set *s, const char *separator, char **ret) {
len += l;
first = false;
}
- if (str)
- str[len] = '\0';
+
+ if (wrap_with_separator) {
+ memcpy(str + len, separator, separator_len);
+ len += separator_len;
+ }
+
+ str[len] = '\0';
*ret = TAKE_PTR(str);
return 0;
diff --git a/src/basic/set.h b/src/basic/set.h
index 2b06c39cbe..57ff713039 100644
--- a/src/basic/set.h
+++ b/src/basic/set.h
@@ -151,4 +151,4 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Set*, set_free_free);
#define _cleanup_set_free_ _cleanup_(set_freep)
#define _cleanup_set_free_free_ _cleanup_(set_free_freep)
-int set_strjoin(Set *s, const char *separator, char **ret);
+int set_strjoin(Set *s, const char *separator, bool wrap_with_separator, char **ret);
diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c
index 005801e1a6..d1aa3282bf 100644
--- a/src/libsystemd/sd-device/sd-device.c
+++ b/src/libsystemd/sd-device/sd-device.c
@@ -1534,7 +1534,7 @@ int device_properties_prepare(sd_device *device) {
if (device->property_devlinks_outdated) {
_cleanup_free_ char *devlinks = NULL;
- r = set_strjoin(device->devlinks, " ", &devlinks);
+ r = set_strjoin(device->devlinks, " ", false, &devlinks);
if (r < 0)
return r;
@@ -1550,7 +1550,7 @@ int device_properties_prepare(sd_device *device) {
if (device->property_tags_outdated) {
_cleanup_free_ char *tags = NULL;
- r = set_strjoin(device->all_tags, ":", &tags);
+ r = set_strjoin(device->all_tags, ":", true, &tags);
if (r < 0)
return r;
@@ -1561,7 +1561,7 @@ int device_properties_prepare(sd_device *device) {
}
tags = mfree(tags);
- r = set_strjoin(device->current_tags, ":", &tags);
+ r = set_strjoin(device->current_tags, ":", true, &tags);
if (r < 0)
return r;
diff --git a/src/test/test-set.c b/src/test/test-set.c
index 8979408242..b4d07b2078 100644
--- a/src/test/test-set.c
+++ b/src/test/test-set.c
@@ -154,50 +154,77 @@ static void test_set_strjoin(void) {
_cleanup_set_free_ Set *m = NULL;
_cleanup_free_ char *joined = NULL;
- assert_se(set_strjoin(m, NULL, &joined) >= 0);
+ /* Empty set */
+ assert_se(set_strjoin(m, NULL, false, &joined) >= 0);
assert_se(!joined);
- assert_se(set_strjoin(m, "", &joined) >= 0);
+ assert_se(set_strjoin(m, "", false, &joined) >= 0);
assert_se(!joined);
- assert_se(set_strjoin(m, " ", &joined) >= 0);
+ assert_se(set_strjoin(m, " ", false, &joined) >= 0);
assert_se(!joined);
- assert_se(set_strjoin(m, "xxx", &joined) >= 0);
+ assert_se(set_strjoin(m, "xxx", false, &joined) >= 0);
+ assert_se(!joined);
+ assert_se(set_strjoin(m, NULL, true, &joined) >= 0);
+ assert_se(!joined);
+ assert_se(set_strjoin(m, "", true, &joined) >= 0);
+ assert_se(!joined);
+ assert_se(set_strjoin(m, " ", true, &joined) >= 0);
+ assert_se(!joined);
+ assert_se(set_strjoin(m, "xxx", true, &joined) >= 0);
assert_se(!joined);
+ /* Single entry */
assert_se(set_put_strdup(&m, "aaa") == 1);
-
- assert_se(set_strjoin(m, NULL, &joined) >= 0);
+ assert_se(set_strjoin(m, NULL, false, &joined) >= 0);
assert_se(streq(joined, "aaa"));
-
joined = mfree(joined);
- assert_se(set_strjoin(m, "", &joined) >= 0);
+ assert_se(set_strjoin(m, "", false, &joined) >= 0);
assert_se(streq(joined, "aaa"));
-
joined = mfree(joined);
- assert_se(set_strjoin(m, " ", &joined) >= 0);
+ assert_se(set_strjoin(m, " ", false, &joined) >= 0);
+ assert_se(streq(joined, "aaa"));
+ joined = mfree(joined);
+ assert_se(set_strjoin(m, "xxx", false, &joined) >= 0);
+ assert_se(streq(joined, "aaa"));
+ joined = mfree(joined);
+ assert_se(set_strjoin(m, NULL, true, &joined) >= 0);
assert_se(streq(joined, "aaa"));
-
joined = mfree(joined);
- assert_se(set_strjoin(m, "xxx", &joined) >= 0);
+ assert_se(set_strjoin(m, "", true, &joined) >= 0);
assert_se(streq(joined, "aaa"));
+ joined = mfree(joined);
+ assert_se(set_strjoin(m, " ", true, &joined) >= 0);
+ assert_se(streq(joined, " aaa "));
+ joined = mfree(joined);
+ assert_se(set_strjoin(m, "xxx", true, &joined) >= 0);
+ assert_se(streq(joined, "xxxaaaxxx"));
+ /* Two entries */
assert_se(set_put_strdup(&m, "bbb") == 1);
assert_se(set_put_strdup(&m, "aaa") == 0);
-
joined = mfree(joined);
- assert_se(set_strjoin(m, NULL, &joined) >= 0);
+ assert_se(set_strjoin(m, NULL, false, &joined) >= 0);
assert_se(STR_IN_SET(joined, "aaabbb", "bbbaaa"));
-
joined = mfree(joined);
- assert_se(set_strjoin(m, "", &joined) >= 0);
+ assert_se(set_strjoin(m, "", false, &joined) >= 0);
assert_se(STR_IN_SET(joined, "aaabbb", "bbbaaa"));
-
joined = mfree(joined);
- assert_se(set_strjoin(m, " ", &joined) >= 0);
+ assert_se(set_strjoin(m, " ", false, &joined) >= 0);
assert_se(STR_IN_SET(joined, "aaa bbb", "bbb aaa"));
-
joined = mfree(joined);
- assert_se(set_strjoin(m, "xxx", &joined) >= 0);
+ assert_se(set_strjoin(m, "xxx", false, &joined) >= 0);
assert_se(STR_IN_SET(joined, "aaaxxxbbb", "bbbxxxaaa"));
+ joined = mfree(joined);
+ assert_se(set_strjoin(m, NULL, true, &joined) >= 0);
+ assert_se(STR_IN_SET(joined, "aaabbb", "bbbaaa"));
+ joined = mfree(joined);
+ assert_se(set_strjoin(m, "", true, &joined) >= 0);
+ assert_se(STR_IN_SET(joined, "aaabbb", "bbbaaa"));
+ joined = mfree(joined);
+ assert_se(set_strjoin(m, " ", true, &joined) >= 0);
+ assert_se(STR_IN_SET(joined, " aaa bbb ", " bbb aaa "));
+ joined = mfree(joined);
+ assert_se(set_strjoin(m, "xxx", true, &joined) >= 0);
+ assert_se(STR_IN_SET(joined, "xxxaaaxxxbbbxxx", "xxxbbbxxxaaaxxx"));
}
int main(int argc, const char *argv[]) {
diff --git a/test/units/testsuite-55.sh b/test/units/testsuite-55.sh
index 19f5683f57..ffceefb6a5 100755
--- a/test/units/testsuite-55.sh
+++ b/test/units/testsuite-55.sh
@@ -2,26 +2,14 @@
set -ex
set -o pipefail
-function has_tag_internal() {
- udevadm info /dev/null | sed -n '/E: '$1'=/ {s/E: '$1'=/:/; s/$/:/; p}' | grep -q ":$2:"
-}
-
-function has_tag() {
- has_tag_internal TAGS $1
-}
-
-function has_current_tag() {
- has_tag_internal CURRENT_TAGS $1
-}
-
mkdir -p /run/udev/rules.d/
! test -f /run/udev/tags/added/c1:3 &&
! test -f /run/udev/tags/changed/c1:3 &&
- ! has_tag added &&
- ! has_current_tag added &&
- ! has_tag changed &&
- ! has_current_tag changed
+ udevadm info /dev/null | grep -q -v 'E: TAGS=.*:added:.*' &&
+ udevadm info /dev/null | grep -q -v 'E: CURRENT_TAGS=.*:added:.*' &&
+ udevadm info /dev/null | grep -q -v 'E: TAGS=.*:changed:.*' &&
+ udevadm info /dev/null | grep -q -v 'E: CURRENT_TAGS=.*:changed:.*'
cat > /run/udev/rules.d/50-testsuite.rules <<EOF
ACTION=="add", SUBSYSTEM=="mem", KERNEL=="null", TAG+="added"
@@ -34,10 +22,10 @@ udevadm trigger -c add /dev/null
while : ; do
test -f /run/udev/tags/added/c1:3 &&
! test -f /run/udev/tags/changed/c1:3 &&
- has_tag added &&
- has_current_tag added &&
- ! has_tag changed &&
- ! has_current_tag changed &&
+ udevadm info /dev/null | grep -q 'E: TAGS=.*:added:.*' &&
+ udevadm info /dev/null | grep -q 'E: CURRENT_TAGS=.*:added:.*' &&
+ udevadm info /dev/null | grep -q -v 'E: TAGS=.*:changed:.*' &&
+ udevadm info /dev/null | grep -q -v 'E: CURRENT_TAGS=.*:changed:.*' &&
break
sleep .5
@@ -49,10 +37,10 @@ udevadm trigger -c change /dev/null
while : ; do
test -f /run/udev/tags/added/c1:3 &&
test -f /run/udev/tags/changed/c1:3 &&
- has_tag added &&
- ! has_current_tag added &&
- has_tag changed &&
- has_current_tag changed &&
+ udevadm info /dev/null | grep -q 'E: TAGS=.*:added:.*' &&
+ udevadm info /dev/null | grep -q -v 'E: CURRENT_TAGS=.*:added:.*' &&
+ udevadm info /dev/null | grep -q 'E: TAGS=.*:changed:.*' &&
+ udevadm info /dev/null | grep -q 'E: CURRENT_TAGS=.*:changed:.*' &&
break
sleep .5
@@ -64,10 +52,10 @@ udevadm trigger -c add /dev/null
while : ; do
test -f /run/udev/tags/added/c1:3 &&
test -f /run/udev/tags/changed/c1:3 &&
- has_tag added &&
- has_current_tag added &&
- has_tag changed &&
- ! has_current_tag changed &&
+ udevadm info /dev/null | grep -q 'E: TAGS=.*:added:.*' &&
+ udevadm info /dev/null | grep -q 'E: CURRENT_TAGS=.*:added:.*' &&
+ udevadm info /dev/null | grep -q 'E: TAGS=.*:changed:.*' &&
+ udevadm info /dev/null | grep -q -v 'E: CURRENT_TAGS=.*:changed:.*' &&
break
sleep .5