[PATCH] strv: Add l_strv_eq
by Andrew Zaborowski
---
ell/ell.sym | 1 +
ell/strv.c | 20 ++++++++++++++++++++
ell/strv.h | 1 +
3 files changed, 22 insertions(+)
diff --git a/ell/ell.sym b/ell/ell.sym
index 9fcf334..10865af 100644
--- a/ell/ell.sym
+++ b/ell/ell.sym
@@ -40,6 +40,7 @@ global:
l_strv_append_printf;
l_strv_append_vprintf;
l_strv_copy;
+ l_strv_eq;
/* utf8 */
l_ascii_table;
l_utf8_get_codepoint;
diff --git a/ell/strv.c b/ell/strv.c
index 3df47be..1343519 100644
--- a/ell/strv.c
+++ b/ell/strv.c
@@ -359,3 +359,23 @@ LIB_EXPORT char **l_strv_copy(char **str_array)
return copy;
}
+
+/**
+ * l_strv_eq:
+ * @a: a %NULL terminated array of strings or %NULL
+ * @b: another %NULL terminated array of strings or %NULL
+ *
+ * Returns: Whether @a and @b's contents are identical, including the
+ * order, or @a and @b are both %NULL.
+ */
+LIB_EXPORT bool l_strv_eq(char **a, char **b)
+{
+ if (!a || !b)
+ return a == b;
+
+ for (; *a; a++, b++)
+ if (!*b || strcmp(*a, *b))
+ return false;
+
+ return !*b;
+}
diff --git a/ell/strv.h b/ell/strv.h
index e673fec..db15cc7 100644
--- a/ell/strv.h
+++ b/ell/strv.h
@@ -46,6 +46,7 @@ char **l_strv_append_vprintf(char **str_array, const char *format,
va_list args)
__attribute__((format(printf, 2, 0)));
char **l_strv_copy(char **str_array);
+bool l_strv_eq(char **a, char **b);
#ifdef __cplusplus
}
--
2.30.2
3 months, 4 weeks
[PATCH v2 1/2] uintset: add l_uintset_size
by James Prestwood
This counts the number of set elements
---
ell/ell.sym | 1 +
ell/uintset.c | 24 ++++++++++++++++++++++++
ell/uintset.h | 1 +
3 files changed, 26 insertions(+)
diff --git a/ell/ell.sym b/ell/ell.sym
index d9b48ee..febb855 100644
--- a/ell/ell.sym
+++ b/ell/ell.sym
@@ -530,6 +530,7 @@ global:
l_uintset_clone;
l_uintset_intersect;
l_uintset_isempty;
+ l_uintset_size;
/* uuid */
l_uuid_v3;
l_uuid_v4;
diff --git a/ell/uintset.c b/ell/uintset.c
index 74de420..863bc56 100644
--- a/ell/uintset.c
+++ b/ell/uintset.c
@@ -555,3 +555,27 @@ LIB_EXPORT bool l_uintset_isempty(const struct l_uintset *set)
return true;
}
+
+/**
+ * l_uintset_size
+ *
+ * @set: The set of numbers
+ *
+ * Returns the number of set elements
+ */
+LIB_EXPORT uint32_t l_uintset_size(const struct l_uintset *set)
+{
+ uint16_t i;
+ uint32_t offset_max;
+ uint32_t count = 0;
+
+ if (unlikely(!set))
+ return 0;
+
+ offset_max = (set->size + BITS_PER_LONG - 1) / BITS_PER_LONG;
+
+ for (i = 0; i < offset_max; i++)
+ count += __builtin_popcountl(set->bits[i]);
+
+ return count;
+}
diff --git a/ell/uintset.h b/ell/uintset.h
index 07ed778..aa9de48 100644
--- a/ell/uintset.h
+++ b/ell/uintset.h
@@ -61,6 +61,7 @@ struct l_uintset *l_uintset_clone(const struct l_uintset *original);
struct l_uintset *l_uintset_intersect(const struct l_uintset *set_a,
const struct l_uintset *set_b);
bool l_uintset_isempty(const struct l_uintset *set);
+uint32_t l_uintset_size(const struct l_uintset *set);
#ifdef __cplusplus
}
--
2.31.1
7 months
[PATCH 1/2] uintset: add l_uintset_count
by James Prestwood
This counts the number of true bits in a set.
---
ell/ell.sym | 1 +
ell/uintset.c | 26 ++++++++++++++++++++++++++
ell/uintset.h | 1 +
3 files changed, 28 insertions(+)
diff --git a/ell/ell.sym b/ell/ell.sym
index d9b48ee..cb6eadf 100644
--- a/ell/ell.sym
+++ b/ell/ell.sym
@@ -530,6 +530,7 @@ global:
l_uintset_clone;
l_uintset_intersect;
l_uintset_isempty;
+ l_uintset_count;
/* uuid */
l_uuid_v3;
l_uuid_v4;
diff --git a/ell/uintset.c b/ell/uintset.c
index 74de420..693f58c 100644
--- a/ell/uintset.c
+++ b/ell/uintset.c
@@ -555,3 +555,29 @@ LIB_EXPORT bool l_uintset_isempty(const struct l_uintset *set)
return true;
}
+
+
+#include <ell/ell.h>
+/**
+ * l_uintset_count
+ *
+ * @set: The set of numbers
+ *
+ * Returns the number of true bits in the set.
+ */
+LIB_EXPORT uint32_t l_uintset_count(const struct l_uintset *set)
+{
+ uint16_t i;
+ uint32_t offset_max;
+ uint32_t count = 0;
+
+ if (unlikely(!set))
+ return 0;
+
+ offset_max = (set->size + BITS_PER_LONG - 1) / BITS_PER_LONG;
+
+ for (i = 0; i < offset_max; i++)
+ count += __builtin_popcountl(set->bits[i]);
+
+ return count;
+}
diff --git a/ell/uintset.h b/ell/uintset.h
index 07ed778..79f3358 100644
--- a/ell/uintset.h
+++ b/ell/uintset.h
@@ -61,6 +61,7 @@ struct l_uintset *l_uintset_clone(const struct l_uintset *original);
struct l_uintset *l_uintset_intersect(const struct l_uintset *set_a,
const struct l_uintset *set_b);
bool l_uintset_isempty(const struct l_uintset *set);
+uint32_t l_uintset_count(const struct l_uintset *set);
#ifdef __cplusplus
}
--
2.31.1
7 months
[PATCH 1/2] base64: Null terminate encoding
by James Prestwood
l_base64_encode was returning a char* without any NULL terminator. This
appeared to be written to satisfy the only use in ELL (pem.c) but made
for a confusing public API. Anyone using this API would expect a char*
return to be NULL terminated.
Now l_base64_encode will NULL terminate which also removes the need for
the length out parameter.
pem.c was updated to use strlen rather than rely on the out parameter.
---
ell/base64.c | 8 ++++----
ell/base64.h | 3 +--
ell/pem.c | 3 ++-
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/ell/base64.c b/ell/base64.c
index c241869..e430470 100644
--- a/ell/base64.c
+++ b/ell/base64.c
@@ -107,8 +107,7 @@ LIB_EXPORT uint8_t *l_base64_decode(const char *in, size_t in_len,
return out_buf;
}
-LIB_EXPORT char *l_base64_encode(const uint8_t *in, size_t in_len,
- int columns, size_t *n_written)
+LIB_EXPORT char *l_base64_encode(const uint8_t *in, size_t in_len, int columns)
{
const uint8_t *in_end = in + in_len;
char *out_buf, *out;
@@ -127,8 +126,7 @@ LIB_EXPORT char *l_base64_encode(const uint8_t *in, size_t in_len,
if (columns && out_len)
out_len += (out_len - 4) / columns;
- out_buf = l_malloc(out_len);
- *n_written = out_len;
+ out_buf = l_malloc(out_len + 1);
out = out_buf;
@@ -169,5 +167,7 @@ LIB_EXPORT char *l_base64_encode(const uint8_t *in, size_t in_len,
for (; pad < 4; pad++)
*out++ = '=';
+ *out = '\0';
+
return out_buf;
}
diff --git a/ell/base64.h b/ell/base64.h
index 74dae8f..8564cdd 100644
--- a/ell/base64.h
+++ b/ell/base64.h
@@ -27,8 +27,7 @@ extern "C" {
uint8_t *l_base64_decode(const char *in, size_t in_len, size_t *n_written);
-char *l_base64_encode(const uint8_t *in, size_t in_len, int columns,
- size_t *n_written);
+char *l_base64_encode(const uint8_t *in, size_t in_len, int columns);
#ifdef __cplusplus
}
diff --git a/ell/pem.c b/ell/pem.c
index 2b09c2b..9804b91 100644
--- a/ell/pem.c
+++ b/ell/pem.c
@@ -379,7 +379,8 @@ static bool pem_write_one_cert(struct l_cert *cert, void *user_data)
iov[0].iov_base = "-----BEGIN CERTIFICATE-----\n";
iov[0].iov_len = strlen(iov[0].iov_base);
- iov[1].iov_base = l_base64_encode(der, der_len, 64, &iov[1].iov_len);
+ iov[1].iov_base = l_base64_encode(der, der_len, 64);
+ iov[1].iov_len = strlen(iov[1].iov_base);
iov[2].iov_base = "\n-----END CERTIFICATE-----\n";
iov[2].iov_len = strlen(iov[2].iov_base);
r = L_TFR(writev(*fd, iov, 3));
--
2.31.1
7 months, 2 weeks
Re: [PATCH] pem.c: do not use rawmemchr()
by Denis Kenzior
Hi Alexander,
On 11/18/21 7:03 AM, Alexander Kanavin wrote:
> From: Alexander Kanavin <alex.kanavin(a)gmail.com>
>
> This is a glibc-only function, and causes build failures with
> alternative libc implementations such as musl.
I believe ell builds just fine on musl. We already have an alternate
implementation of rawmemchr in ell/missing.h and it should be used automagically
in case its absence is detected at configure time. Is this not working for you ?
> ---
> ell/pem.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
Regards,
-Denis
7 months, 2 weeks
[PATCH 0/3] rtnl: Fix address conversion buffer overflow.
by Ossama Othman
Some l_rtnl functions that return a stringified address could
potentially overrun a user supplied buffer of insufficient length.
Add a buffer length argument to prevent ELL from making incorrect
assumptions. Impacted functions are l_rtnl_address_get_address(),
l_rtnl_route_get_gateway(), and l_rtnl_route_get_prefsrc().
Ossama Othman (3):
rtnl: Fix address conversion buffer overflow.
unit: Add l_rtnl_address_get_address() test case.
Makefile: Bump library 'current' version.
Makefile.am | 4 ++--
ell/rtnl.c | 28 +++++++++++++++++-----------
ell/rtnl.h | 8 +++++---
unit/test-rtnl.c | 26 ++++++++++++++++++++++++++
4 files changed, 50 insertions(+), 16 deletions(-)
--
2.32.0
7 months, 2 weeks
[PATCH] log: Set retain attribute on __ell_debug
by Fangrui Song
LLD 13 and GNU ld 2.37 support -z start-stop-gc which allows garbage
collection of C identifier name sections despite the __start_/__stop_
references. GNU ld before 2015-10 had the behavior as well. Simply set
the retain attribute so that GCC 11 (if configure-time binutils is 2.36
or newer)/Clang 13 will set the SHF_GNU_RETAIN section attribute to
prevent garbage collection.
Without the patch, there are linker errors with -z start-stop-gc (LLD default):
```
ld.lld: error: undefined symbol: __start___ell_debug
>>> referenced by log.c
>>> log.o:(register_debug_section) in archive ell/.libs/libell-private.a
```
---
ell/log.h | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/ell/log.h b/ell/log.h
index 924523b..32d6b8a 100644
--- a/ell/log.h
+++ b/ell/log.h
@@ -61,12 +61,18 @@ struct l_debug_desc {
unsigned int flags;
} __attribute__((aligned(8)));
+// Set the retain attribute so that the section cannot be discarded by ld
+// --gc-sections -z start-stop-gc. Older compilers would warn for the unknown
+// attribute, so just disable -Wattributes.
#define L_DEBUG_SYMBOL(symbol, format, ...) do { \
+_Pragma("GCC diagnostic push") \
+_Pragma("GCC diagnostic ignored \"-Wattributes\"") \
static struct l_debug_desc symbol \
- __attribute__((used, section("__ell_debug"), aligned(8))) = { \
+ __attribute__((used, retain, section("__ell_debug"), aligned(8))) = { \
.file = __FILE__, .func = __func__, \
.flags = L_DEBUG_FLAG_DEFAULT, \
}; \
+_Pragma("GCC diagnostic pop") \
if (symbol.flags & L_DEBUG_FLAG_PRINT) \
l_log(L_LOG_DEBUG, "%s:%s() " format, __FILE__, \
__func__ , ##__VA_ARGS__); \
--
2.34
7 months, 3 weeks
[PATCH] dhcp6: Switch to BOUND before LEASE_OBTAINED
by Andrew Zaborowski
Reorder actions so that when we obtain the lease, we first switch to
DHCP6_STATE_BOUND and configure the address + emit
L_DHCP6_CLIENT_EVENT_LEASE_OBTAINED after that. This allows the event
handler to use l_dhcp6_client_get_lease(). l_dhcp6_client_get_lease is
hardwired to return NULL in DHCP6_STATE_REQUESTING.
Issue reported by Térence Clastres.
---
ell/dhcp6.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ell/dhcp6.c b/ell/dhcp6.c
index 67d4628..7dfc664 100644
--- a/ell/dhcp6.c
+++ b/ell/dhcp6.c
@@ -1401,8 +1401,8 @@ static void dhcp6_client_rx_message(const void *data, size_t len,
if (r == DHCP6_STATE_BOUND) {
l_timeout_remove(client->timeout_send);
client->timeout_send = NULL;
- dhcp6_client_setup_lease(client);
dhcp6_client_new_transaction(client, r);
+ dhcp6_client_setup_lease(client);
return;
}
--
2.32.0
7 months, 3 weeks