static gboolean dynamic_key_equal (gconstpointer v1, gconstpointer v2) { const DynamicKey *key1 = v1; const DynamicKey *key2 = v2; return strv_equal (key1->argv, key2->argv) && strv_equal (key1->environ, key2->environ); }
static void test_strv_split(void) { _cleanup_strv_free_ char **l = NULL; const char str[] = "one,two,three"; l = strv_split(str, ","); assert_se(l); assert_se(strv_equal(l, (char**) input_table_multiple)); strv_free(l); l = strv_split(" one two\t three", WHITESPACE); assert_se(l); assert_se(strv_equal(l, (char**) input_table_multiple)); strv_free(l); /* Setting NULL for separator is equivalent to WHITESPACE */ l = strv_split(" one two\t three", NULL); assert_se(l); assert_se(strv_equal(l, (char**) input_table_multiple)); strv_free(l); l = strv_split_full(" one two\t three", NULL, 0); assert_se(l); assert_se(strv_equal(l, (char**) input_table_multiple)); strv_free(l); l = strv_split_full(" 'one' \" two\t three \" ' four five'", NULL, SPLIT_QUOTES); assert_se(l); assert_se(strv_equal(l, (char**) input_table_quoted)); strv_free(l); /* missing last quote ignores the last element. */ l = strv_split_full(" 'one' \" two\t three \" ' four five' ' ignored element ", NULL, SPLIT_QUOTES); assert_se(l); assert_se(strv_equal(l, (char**) input_table_quoted)); strv_free(l); /* missing last quote, but the last element is _not_ ignored with SPLIT_RELAX. */ l = strv_split_full(" 'one' \" two\t three \" ' four five", NULL, SPLIT_QUOTES | SPLIT_RELAX); assert_se(l); assert_se(strv_equal(l, (char**) input_table_quoted)); strv_free(l); /* missing separator between */ l = strv_split_full(" 'one' \" two\t three \"' four five'", NULL, SPLIT_QUOTES | SPLIT_RELAX); assert_se(l); assert_se(strv_equal(l, (char**) input_table_quoted)); strv_free(l); l = strv_split_full(" 'one' \" two\t three \"' four five", NULL, SPLIT_QUOTES | SPLIT_RELAX); assert_se(l); assert_se(strv_equal(l, (char**) input_table_quoted)); }
static void test_conf_files_insert(const char *root) { _cleanup_strv_free_ char **s = NULL; log_info("/* %s root=%s */", __func__, strempty(root)); char **dirs = STRV_MAKE("/dir1", "/dir2", "/dir3"); _cleanup_free_ const char *foo1 = prefix_root(root, "/dir1/foo.conf"), *foo2 = prefix_root(root, "/dir2/foo.conf"), *bar2 = prefix_root(root, "/dir2/bar.conf"), *zzz3 = prefix_root(root, "/dir3/zzz.conf"), *whatever = prefix_root(root, "/whatever.conf"); assert_se(conf_files_insert(&s, root, dirs, "/dir2/foo.conf") == 0); assert_se(strv_equal(s, STRV_MAKE(foo2))); /* The same file again, https://github.com/systemd/systemd/issues/11124 */ assert_se(conf_files_insert(&s, root, dirs, "/dir2/foo.conf") == 0); assert_se(strv_equal(s, STRV_MAKE(foo2))); /* Lower priority → new entry is ignored */ assert_se(conf_files_insert(&s, root, dirs, "/dir3/foo.conf") == 0); assert_se(strv_equal(s, STRV_MAKE(foo2))); /* Higher priority → new entry replaces */ assert_se(conf_files_insert(&s, root, dirs, "/dir1/foo.conf") == 0); assert_se(strv_equal(s, STRV_MAKE(foo1))); /* Earlier basename */ assert_se(conf_files_insert(&s, root, dirs, "/dir2/bar.conf") == 0); assert_se(strv_equal(s, STRV_MAKE(bar2, foo1))); /* Later basename */ assert_se(conf_files_insert(&s, root, dirs, "/dir3/zzz.conf") == 0); assert_se(strv_equal(s, STRV_MAKE(bar2, foo1, zzz3))); /* All lower priority → all ignored */ assert_se(conf_files_insert(&s, root, dirs, "/dir3/zzz.conf") == 0); assert_se(conf_files_insert(&s, root, dirs, "/dir2/bar.conf") == 0); assert_se(conf_files_insert(&s, root, dirs, "/dir3/bar.conf") == 0); assert_se(conf_files_insert(&s, root, dirs, "/dir2/foo.conf") == 0); assert_se(strv_equal(s, STRV_MAKE(bar2, foo1, zzz3))); /* Two entries that don't match any of the directories, but match basename */ assert_se(conf_files_insert(&s, root, dirs, "/dir4/zzz.conf") == 0); assert_se(conf_files_insert(&s, root, dirs, "/zzz.conf") == 0); assert_se(strv_equal(s, STRV_MAKE(bar2, foo1, zzz3))); /* An entry that doesn't match any of the directories, no match at all */ assert_se(conf_files_insert(&s, root, dirs, "/whatever.conf") == 0); assert_se(strv_equal(s, STRV_MAKE(bar2, foo1, whatever, zzz3))); }
static void test_config_parse_strv_one(const char *rvalue, char **expected) { char **strv = 0; assert_se(config_parse_strv("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue, &strv, NULL) >= 0); assert_se(strv_equal(expected, strv)); strv_free(strv); }
static int determine_matches(const char *image, char **l, bool allow_any, char ***ret) { _cleanup_strv_free_ char **k = NULL; int r; /* Determine the matches to apply. If the list is empty we derive the match from the image name. If the list * contains exactly the "-" we return a wildcard list (which is the empty list), but only if this is expressly * permitted. */ if (strv_isempty(l)) { char *prefix; r = extract_prefix(image, &prefix); if (r < 0) return log_error_errno(r, "Failed to extract prefix of image name '%s': %m", image); if (!arg_quiet) log_info("(Matching unit files with prefix '%s'.)", prefix); r = strv_consume(&k, prefix); if (r < 0) return log_oom(); } else if (strv_equal(l, STRV_MAKE("-"))) { if (!allow_any) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Refusing all unit file match."); if (!arg_quiet) log_info("(Matching all unit files.)"); } else { k = strv_copy(l); if (!k) return log_oom(); if (!arg_quiet) { _cleanup_free_ char *joined = NULL; joined = strv_join(k, "', '"); if (!joined) return log_oom(); log_info("(Matching unit files with prefixes '%s'.)", joined); } } *ret = TAKE_PTR(k); return 0; }
static void test_specifier_escape_strv_one(char **a, char **b) { _cleanup_strv_free_ char **x = NULL; assert_se(specifier_escape_strv(a, &x) >= 0); assert_se(strv_equal(x, b)); }
static void set_avahi_data (GVfsDnsSdResolver *resolver, const char *host_name, AvahiProtocol protocol, const AvahiAddress *a, uint16_t port, AvahiStringList *txt) { char *address; gboolean changed; AvahiStringList *l; GPtrArray *p; char **txt_records; gboolean is_resolved; changed = FALSE; if (resolver_supports_mdns) { address = g_strdup (host_name); } else { char aa[128]; avahi_address_snprint (aa, sizeof(aa), a); if (protocol == AVAHI_PROTO_INET6) { /* an ipv6 address, follow RFC 2732 */ address = g_strdup_printf ("[%s]", aa); } else { address = g_strdup (aa); } } if (safe_strcmp (resolver->address, address) != 0) { g_free (resolver->address); resolver->address = g_strdup (address); g_object_notify (G_OBJECT (resolver), "address"); changed = TRUE; } g_free (address); if (resolver->port != port) { resolver->port = port; g_object_notify (G_OBJECT (resolver), "port"); changed = TRUE; } p = g_ptr_array_new (); for (l = txt; l != NULL; l = avahi_string_list_get_next (l)) { g_ptr_array_add (p, g_strdup ((const char *) l->text)); } g_ptr_array_add (p, NULL); txt_records = (char **) g_ptr_array_free (p, FALSE); if (strv_equal (resolver->txt_records, txt_records)) { g_strfreev (txt_records); } else { g_strfreev (resolver->txt_records); resolver->txt_records = txt_records; g_object_notify (G_OBJECT (resolver), "txt-records"); changed = TRUE; } is_resolved = has_required_txt_keys (resolver); if (is_resolved != resolver->is_resolved) { resolver->is_resolved = is_resolved; g_object_notify (G_OBJECT (resolver), "is-resolved"); changed = TRUE; } if (changed) g_signal_emit (resolver, signals[CHANGED], 0); }