diff options
author | Thomas Haller <thaller@redhat.com> | 2019-07-26 09:41:00 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2019-07-26 14:45:24 +0200 |
commit | 6a325673cf194accecb48722d810dad39fc266e1 (patch) | |
tree | 774dec9548f70726b738745e164fcc6ec2bf0dba | |
parent | 55c47d4efa5969db32499c769d89709ccef80887 (diff) | |
download | NetworkManager-6a325673cf194accecb48722d810dad39fc266e1.tar.gz |
systemd: update code from upstream (2019-07-26)
This is a direct dump from systemd git.
======
SYSTEMD_DIR=../systemd
COMMIT=608807c163921b0dfbaf646b3ec19fc9b71e6451
(
cd "$SYSTEMD_DIR"
git checkout "$COMMIT"
git reset --hard
git clean -fdx
)
git ls-files -z :/src/systemd/src/ \
:/shared/systemd/src/ \
:/shared/nm-utils/unaligned.h | \
xargs -0 rm -f
nm_copy_sd_shared() {
mkdir -p "./shared/systemd/$(dirname "$1")"
cp "$SYSTEMD_DIR/$1" "./shared/systemd/$1"
}
nm_copy_sd_core() {
mkdir -p "./src/systemd/$(dirname "$1")"
cp "$SYSTEMD_DIR/$1" "./src/systemd/$1"
}
nm_copy_sd_nmutils() {
mkdir -p "./shared/nm-utils/"
cp "$SYSTEMD_DIR/$1" "./shared/nm-utils/${1##*/}"
}
nm_copy_sd_core "src/libsystemd-network/arp-util.c"
nm_copy_sd_core "src/libsystemd-network/arp-util.h"
nm_copy_sd_core "src/libsystemd-network/dhcp-identifier.c"
nm_copy_sd_core "src/libsystemd-network/dhcp-identifier.h"
nm_copy_sd_core "src/libsystemd-network/dhcp-internal.h"
nm_copy_sd_core "src/libsystemd-network/dhcp-lease-internal.h"
nm_copy_sd_core "src/libsystemd-network/dhcp-network.c"
nm_copy_sd_core "src/libsystemd-network/dhcp-option.c"
nm_copy_sd_core "src/libsystemd-network/dhcp-packet.c"
nm_copy_sd_core "src/libsystemd-network/dhcp-protocol.h"
nm_copy_sd_core "src/libsystemd-network/dhcp6-internal.h"
nm_copy_sd_core "src/libsystemd-network/dhcp6-lease-internal.h"
nm_copy_sd_core "src/libsystemd-network/dhcp6-network.c"
nm_copy_sd_core "src/libsystemd-network/dhcp6-option.c"
nm_copy_sd_core "src/libsystemd-network/dhcp6-protocol.h"
nm_copy_sd_core "src/libsystemd-network/lldp-internal.h"
nm_copy_sd_core "src/libsystemd-network/lldp-neighbor.c"
nm_copy_sd_core "src/libsystemd-network/lldp-neighbor.h"
nm_copy_sd_core "src/libsystemd-network/lldp-network.c"
nm_copy_sd_core "src/libsystemd-network/lldp-network.h"
nm_copy_sd_core "src/libsystemd-network/network-internal.c"
nm_copy_sd_core "src/libsystemd-network/network-internal.h"
nm_copy_sd_core "src/libsystemd-network/sd-dhcp-client.c"
nm_copy_sd_core "src/libsystemd-network/sd-dhcp-lease.c"
nm_copy_sd_core "src/libsystemd-network/sd-dhcp6-client.c"
nm_copy_sd_core "src/libsystemd-network/sd-dhcp6-lease.c"
nm_copy_sd_core "src/libsystemd-network/sd-ipv4acd.c"
nm_copy_sd_core "src/libsystemd-network/sd-ipv4ll.c"
nm_copy_sd_core "src/libsystemd-network/sd-lldp.c"
nm_copy_sd_core "src/libsystemd/sd-event/event-source.h"
nm_copy_sd_core "src/libsystemd/sd-event/event-util.c"
nm_copy_sd_core "src/libsystemd/sd-event/event-util.h"
nm_copy_sd_core "src/libsystemd/sd-event/sd-event.c"
nm_copy_sd_core "src/libsystemd/sd-id128/id128-util.c"
nm_copy_sd_core "src/libsystemd/sd-id128/id128-util.h"
nm_copy_sd_core "src/libsystemd/sd-id128/sd-id128.c"
nm_copy_sd_core "src/systemd/_sd-common.h"
nm_copy_sd_core "src/systemd/sd-dhcp-client.h"
nm_copy_sd_core "src/systemd/sd-dhcp-lease.h"
nm_copy_sd_core "src/systemd/sd-dhcp6-client.h"
nm_copy_sd_core "src/systemd/sd-dhcp6-lease.h"
nm_copy_sd_core "src/systemd/sd-event.h"
nm_copy_sd_core "src/systemd/sd-id128.h"
nm_copy_sd_core "src/systemd/sd-ipv4acd.h"
nm_copy_sd_core "src/systemd/sd-ipv4ll.h"
nm_copy_sd_core "src/systemd/sd-lldp.h"
nm_copy_sd_core "src/systemd/sd-ndisc.h"
nm_copy_sd_nmutils "src/basic/unaligned.h"
nm_copy_sd_shared "src/basic/alloc-util.c"
nm_copy_sd_shared "src/basic/alloc-util.h"
nm_copy_sd_shared "src/basic/async.h"
nm_copy_sd_shared "src/basic/env-file.c"
nm_copy_sd_shared "src/basic/env-file.h"
nm_copy_sd_shared "src/basic/env-util.c"
nm_copy_sd_shared "src/basic/env-util.h"
nm_copy_sd_shared "src/basic/errno-util.h"
nm_copy_sd_shared "src/basic/escape.c"
nm_copy_sd_shared "src/basic/escape.h"
nm_copy_sd_shared "src/basic/ether-addr-util.c"
nm_copy_sd_shared "src/basic/ether-addr-util.h"
nm_copy_sd_shared "src/basic/extract-word.c"
nm_copy_sd_shared "src/basic/extract-word.h"
nm_copy_sd_shared "src/basic/fd-util.c"
nm_copy_sd_shared "src/basic/fd-util.h"
nm_copy_sd_shared "src/basic/fileio.c"
nm_copy_sd_shared "src/basic/fileio.h"
nm_copy_sd_shared "src/basic/format-util.c"
nm_copy_sd_shared "src/basic/format-util.h"
nm_copy_sd_shared "src/basic/fs-util.c"
nm_copy_sd_shared "src/basic/fs-util.h"
nm_copy_sd_shared "src/basic/hash-funcs.c"
nm_copy_sd_shared "src/basic/hash-funcs.h"
nm_copy_sd_shared "src/basic/hashmap.c"
nm_copy_sd_shared "src/basic/hashmap.h"
nm_copy_sd_shared "src/basic/hexdecoct.c"
nm_copy_sd_shared "src/basic/hexdecoct.h"
nm_copy_sd_shared "src/basic/hostname-util.c"
nm_copy_sd_shared "src/basic/hostname-util.h"
nm_copy_sd_shared "src/basic/in-addr-util.c"
nm_copy_sd_shared "src/basic/in-addr-util.h"
nm_copy_sd_shared "src/basic/io-util.c"
nm_copy_sd_shared "src/basic/io-util.h"
nm_copy_sd_shared "src/basic/list.h"
nm_copy_sd_shared "src/basic/log.h"
nm_copy_sd_shared "src/basic/macro.h"
nm_copy_sd_shared "src/basic/memory-util.c"
nm_copy_sd_shared "src/basic/memory-util.h"
nm_copy_sd_shared "src/basic/mempool.c"
nm_copy_sd_shared "src/basic/mempool.h"
nm_copy_sd_shared "src/basic/missing_fcntl.h"
nm_copy_sd_shared "src/basic/missing_socket.h"
nm_copy_sd_shared "src/basic/missing_stat.h"
nm_copy_sd_shared "src/basic/missing_type.h"
nm_copy_sd_shared "src/basic/parse-util.c"
nm_copy_sd_shared "src/basic/parse-util.h"
nm_copy_sd_shared "src/basic/path-util.c"
nm_copy_sd_shared "src/basic/path-util.h"
nm_copy_sd_shared "src/basic/prioq.c"
nm_copy_sd_shared "src/basic/prioq.h"
nm_copy_sd_shared "src/basic/process-util.c"
nm_copy_sd_shared "src/basic/process-util.h"
nm_copy_sd_shared "src/basic/random-util.c"
nm_copy_sd_shared "src/basic/random-util.h"
nm_copy_sd_shared "src/basic/set.h"
nm_copy_sd_shared "src/basic/signal-util.h"
nm_copy_sd_shared "src/basic/siphash24.h"
nm_copy_sd_shared "src/basic/socket-util.c"
nm_copy_sd_shared "src/basic/socket-util.h"
nm_copy_sd_shared "src/basic/sort-util.h"
nm_copy_sd_shared "src/basic/sparse-endian.h"
nm_copy_sd_shared "src/basic/stat-util.c"
nm_copy_sd_shared "src/basic/stat-util.h"
nm_copy_sd_shared "src/basic/stdio-util.h"
nm_copy_sd_shared "src/basic/string-table.c"
nm_copy_sd_shared "src/basic/string-table.h"
nm_copy_sd_shared "src/basic/string-util.c"
nm_copy_sd_shared "src/basic/string-util.h"
nm_copy_sd_shared "src/basic/strv.c"
nm_copy_sd_shared "src/basic/strv.h"
nm_copy_sd_shared "src/basic/strxcpyx.c"
nm_copy_sd_shared "src/basic/strxcpyx.h"
nm_copy_sd_shared "src/basic/time-util.c"
nm_copy_sd_shared "src/basic/time-util.h"
nm_copy_sd_shared "src/basic/tmpfile-util.c"
nm_copy_sd_shared "src/basic/tmpfile-util.h"
nm_copy_sd_shared "src/basic/umask-util.h"
nm_copy_sd_shared "src/basic/utf8.c"
nm_copy_sd_shared "src/basic/utf8.h"
nm_copy_sd_shared "src/basic/util.c"
nm_copy_sd_shared "src/basic/util.h"
nm_copy_sd_shared "src/shared/dns-domain.c"
nm_copy_sd_shared "src/shared/dns-domain.h"
43 files changed, 453 insertions, 186 deletions
diff --git a/shared/systemd/src/basic/alloc-util.h b/shared/systemd/src/basic/alloc-util.h index 9b20be4773..64d9e00315 100644 --- a/shared/systemd/src/basic/alloc-util.h +++ b/shared/systemd/src/basic/alloc-util.h @@ -58,7 +58,7 @@ static inline void *mfree(void *memory) { }) void* memdup(const void *p, size_t l) _alloc_(2); -void* memdup_suffix0(const void *p, size_t l) _alloc_(2); +void* memdup_suffix0(const void *p, size_t l); /* We can't use _alloc_() here, since we return a buffer one byte larger than the specified size */ #define memdupa(p, l) \ ({ \ @@ -112,7 +112,9 @@ _alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t size, si return memdup(p, size * need); } -_alloc_(2, 3) static inline void *memdup_suffix0_multiply(const void *p, size_t size, size_t need) { +/* Note that we can't decorate this function with _alloc_() since the returned memory area is one byte larger + * than the product of its parameters. */ +static inline void *memdup_suffix0_multiply(const void *p, size_t size, size_t need) { if (size_multiply_overflow(size, need)) return NULL; diff --git a/shared/systemd/src/basic/env-util.c b/shared/systemd/src/basic/env-util.c index b39b1ed0f8..a6503cf2b6 100644 --- a/shared/systemd/src/basic/env-util.c +++ b/shared/systemd/src/basic/env-util.c @@ -567,7 +567,7 @@ char *replace_env_n(const char *format, size_t n, char **env, unsigned flags) { t = strv_env_get_n(env, word+2, e-word-2, flags); - k = strappend(r, t); + k = strjoin(r, t); if (!k) return NULL; @@ -623,7 +623,7 @@ char *replace_env_n(const char *format, size_t n, char **env, unsigned flags) { else if (!t && state == DEFAULT_VALUE) t = v = replace_env_n(test_value, e-test_value, env, flags); - k = strappend(r, t); + k = strjoin(r, t); if (!k) return NULL; @@ -642,7 +642,7 @@ char *replace_env_n(const char *format, size_t n, char **env, unsigned flags) { t = strv_env_get_n(env, word+1, e-word-1, flags); - k = strappend(r, t); + k = strjoin(r, t); if (!k) return NULL; @@ -661,7 +661,7 @@ char *replace_env_n(const char *format, size_t n, char **env, unsigned flags) { assert(flags & REPLACE_ENV_ALLOW_BRACELESS); t = strv_env_get_n(env, word+1, e-word-1, flags); - return strappend(r, t); + return strjoin(r, t); } else return strnappend(r, word, e-word); } diff --git a/shared/systemd/src/basic/errno-util.h b/shared/systemd/src/basic/errno-util.h index d7a5ea771f..34859d6d8a 100644 --- a/shared/systemd/src/basic/errno-util.h +++ b/shared/systemd/src/basic/errno-util.h @@ -1,6 +1,9 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once +#include <stdlib.h> +#include <string.h> + #include "macro.h" static inline void _reset_errno_(int *saved_errno) { @@ -28,6 +31,22 @@ static inline int negative_errno(void) { return -errno; } +static inline char *strerror_safe(int error) { + /* 'safe' here does NOT mean thread safety. */ + return strerror(abs(error)); +} + +static inline int errno_or_else(int fallback) { + /* To be used when invoking library calls where errno handling is not defined clearly: we return + * errno if it is set, and the specified error otherwise. The idea is that the caller initializes + * errno to zero before doing an API call, and then uses this helper to retrieve a somewhat useful + * error code */ + if (errno > 0) + return -errno; + + return -abs(fallback); +} + /* Hint #1: ENETUNREACH happens if we try to connect to "non-existing" special IP addresses, such as ::5. * * Hint #2: The kernel sends e.g., EHOSTUNREACH or ENONET to userspace in some ICMP error cases. See the diff --git a/shared/systemd/src/basic/extract-word.c b/shared/systemd/src/basic/extract-word.c index 34cfb36a4a..b7ae2ed1cd 100644 --- a/shared/systemd/src/basic/extract-word.c +++ b/shared/systemd/src/basic/extract-word.c @@ -28,6 +28,8 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra assert(p); assert(ret); + /* Those two don't make sense together. */ + assert(!FLAGS_SET(flags, EXTRACT_UNQUOTE|EXTRACT_RETAIN_ESCAPE)); /* Bail early if called after last value or with no input */ if (!*p) diff --git a/shared/systemd/src/basic/fileio.c b/shared/systemd/src/basic/fileio.c index 40a20c2b3b..623e43e4ca 100644 --- a/shared/systemd/src/basic/fileio.c +++ b/shared/systemd/src/basic/fileio.c @@ -298,7 +298,7 @@ int verify_file(const char *fn, const char *blob, bool accept_extra_nl) { errno = 0; k = fread(buf, 1, l + accept_extra_nl + 1, f); if (ferror(f)) - return errno > 0 ? -errno : -EIO; + return errno_or_else(EIO); if (k != l && k != l + accept_extra_nl) return 0; @@ -382,7 +382,7 @@ int read_full_stream_full( l += k; if (ferror(f)) { - r = errno > 0 ? -errno : -EIO; + r = errno_or_else(EIO); goto finalize; } @@ -661,7 +661,7 @@ int fflush_and_check(FILE *f) { fflush(f); if (ferror(f)) - return errno > 0 ? -errno : -EIO; + return errno_or_else(EIO); return 0; } @@ -776,7 +776,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, funlockfile); int read_line_full(FILE *f, size_t limit, ReadLineFlags flags, char **ret) { size_t n = 0, allocated = 0, count = 0; _cleanup_free_ char *buffer = NULL; - int r; + int r, tty = -1; assert(f); @@ -851,6 +851,17 @@ int read_line_full(FILE *f, size_t limit, ReadLineFlags flags, char **ret) { count++; if (eol != EOL_NONE) { + /* If we are on a tty, we can't wait for more input. But we expect only + * \n as the single EOL marker, so there is no need to wait. We check + * this condition last to avoid isatty() check if not necessary. */ + + if (tty < 0) + tty = isatty(fileno(f)); + if (tty > 0) + break; + } + + if (eol != EOL_NONE) { previous_eol |= eol; continue; } @@ -888,7 +899,7 @@ int safe_fgetc(FILE *f, char *ret) { k = fgetc(f); if (k == EOF) { if (ferror(f)) - return errno > 0 ? -errno : -EIO; + return errno_or_else(EIO); if (ret) *ret = 0; diff --git a/shared/systemd/src/basic/hash-funcs.c b/shared/systemd/src/basic/hash-funcs.c index 1be43d41a9..11cd371fad 100644 --- a/shared/systemd/src/basic/hash-funcs.c +++ b/shared/systemd/src/basic/hash-funcs.c @@ -10,6 +10,9 @@ void string_hash_func(const char *p, struct siphash *state) { } DEFINE_HASH_OPS(string_hash_ops, char, string_hash_func, string_compare_func); +DEFINE_HASH_OPS_FULL(string_hash_ops_free_free, + char, string_hash_func, string_compare_func, free, + char, free); void path_hash_func(const char *q, struct siphash *state) { size_t n; diff --git a/shared/systemd/src/basic/hash-funcs.h b/shared/systemd/src/basic/hash-funcs.h index 3d2ae4b55e..0d2d428389 100644 --- a/shared/systemd/src/basic/hash-funcs.h +++ b/shared/systemd/src/basic/hash-funcs.h @@ -76,6 +76,7 @@ struct hash_ops { void string_hash_func(const char *p, struct siphash *state); #define string_compare_func strcmp extern const struct hash_ops string_hash_ops; +extern const struct hash_ops string_hash_ops_free_free; void path_hash_func(const char *p, struct siphash *state); int path_compare_func(const char *a, const char *b) _pure_; diff --git a/shared/systemd/src/basic/hashmap.c b/shared/systemd/src/basic/hashmap.c index f244d767da..3bd94a1320 100644 --- a/shared/systemd/src/basic/hashmap.c +++ b/shared/systemd/src/basic/hashmap.c @@ -733,8 +733,8 @@ bool internal_hashmap_iterate(HashmapBase *h, Iterator *i, void **value, const v return true; } -bool set_iterate(Set *s, Iterator *i, void **value) { - return internal_hashmap_iterate(HASHMAP_BASE(s), i, value, NULL); +bool set_iterate(const Set *s, Iterator *i, void **value) { + return internal_hashmap_iterate(HASHMAP_BASE((Set*) s), i, value, NULL); } #define HASHMAP_FOREACH_IDX(idx, h, i) \ @@ -1768,6 +1768,32 @@ int set_consume(Set *s, void *value) { return r; } +int hashmap_put_strdup(Hashmap **h, const char *k, const char *v) { + int r; + + r = hashmap_ensure_allocated(h, &string_hash_ops_free_free); + if (r < 0) + return r; + + _cleanup_free_ char *kdup = NULL, *vdup = NULL; + kdup = strdup(k); + vdup = strdup(v); + if (!kdup || !vdup) + return -ENOMEM; + + r = hashmap_put(*h, kdup, vdup); + if (r < 0) { + if (r == -EEXIST && streq(v, hashmap_get(*h, kdup))) + return 0; + return r; + } + + assert(r > 0); /* 0 would mean vdup is already in the hashmap, which cannot be */ + kdup = vdup = NULL; + + return 0; +} + int set_put_strdup(Set *s, const char *p) { char *c; diff --git a/shared/systemd/src/basic/hashmap.h b/shared/systemd/src/basic/hashmap.h index 41c8adb16b..65adc92513 100644 --- a/shared/systemd/src/basic/hashmap.h +++ b/shared/systemd/src/basic/hashmap.h @@ -76,7 +76,7 @@ typedef struct { #if ENABLE_DEBUG_HASHMAP # define HASHMAP_DEBUG_PARAMS , const char *func, const char *file, int line -# define HASHMAP_DEBUG_SRC_ARGS , __func__, __FILE__, __LINE__ +# define HASHMAP_DEBUG_SRC_ARGS , __func__, PROJECT_FILE, __LINE__ # define HASHMAP_DEBUG_PASS_ARGS , func, file, line #else # define HASHMAP_DEBUG_PARAMS @@ -147,6 +147,8 @@ static inline int ordered_hashmap_put(OrderedHashmap *h, const void *key, void * return hashmap_put(PLAIN_HASHMAP(h), key, value); } +int hashmap_put_strdup(Hashmap **h, const char *k, const char *v); + int hashmap_update(Hashmap *h, const void *key, void *value); static inline int ordered_hashmap_update(OrderedHashmap *h, const void *key, void *value) { return hashmap_update(PLAIN_HASHMAP(h), key, value); diff --git a/shared/systemd/src/basic/in-addr-util.c b/shared/systemd/src/basic/in-addr-util.c index c1fab51b5e..06b92db579 100644 --- a/shared/systemd/src/basic/in-addr-util.c +++ b/shared/systemd/src/basic/in-addr-util.c @@ -9,6 +9,7 @@ #include <stdlib.h> #include "alloc-util.h" +#include "errno-util.h" #include "in-addr-util.h" #include "macro.h" #include "parse-util.h" @@ -91,12 +92,19 @@ int in_addr_is_localhost(int family, const union in_addr_union *u) { return -EAFNOSUPPORT; } +bool in4_addr_equal(const struct in_addr *a, const struct in_addr *b) { + assert(a); + assert(b); + + return a->s_addr == b->s_addr; +} + int in_addr_equal(int family, const union in_addr_union *a, const union in_addr_union *b) { assert(a); assert(b); if (family == AF_INET) - return a->in.s_addr == b->in.s_addr; + return in4_addr_equal(&a->in, &b->in); if (family == AF_INET6) return @@ -315,7 +323,7 @@ int in_addr_to_string(int family, const union in_addr_union *u, char **ret) { errno = 0; if (!inet_ntop(family, u, x, l)) - return errno > 0 ? -errno : -EINVAL; + return errno_or_else(EINVAL); *ret = TAKE_PTR(x); return 0; @@ -345,7 +353,7 @@ int in_addr_prefix_to_string(int family, const union in_addr_union *u, unsigned errno = 0; if (!inet_ntop(family, u, x, l)) - return errno > 0 ? -errno : -EINVAL; + return errno_or_else(EINVAL); p = x + strlen(x); l -= strlen(x); @@ -384,7 +392,7 @@ int in_addr_ifindex_to_string(int family, const union in_addr_union *u, int ifin errno = 0; if (!inet_ntop(family, u, x, l)) - return errno > 0 ? -errno : -EINVAL; + return errno_or_else(EINVAL); sprintf(strchr(x, 0), "%%%i", ifindex); @@ -404,7 +412,7 @@ int in_addr_from_string(int family, const char *s, union in_addr_union *ret) { errno = 0; if (inet_pton(family, s, ret ?: &buffer) <= 0) - return errno > 0 ? -errno : -EINVAL; + return errno_or_else(EINVAL); return 0; } diff --git a/shared/systemd/src/basic/in-addr-util.h b/shared/systemd/src/basic/in-addr-util.h index 2ca7f4b32f..28afc7d86c 100644 --- a/shared/systemd/src/basic/in-addr-util.h +++ b/shared/systemd/src/basic/in-addr-util.h @@ -32,6 +32,7 @@ int in_addr_is_localhost(int family, const union in_addr_union *u); bool in4_addr_is_non_local(const struct in_addr *a); +bool in4_addr_equal(const struct in_addr *a, const struct in_addr *b); int in_addr_equal(int family, const union in_addr_union *a, const union in_addr_union *b); int in_addr_prefix_intersect(int family, const union in_addr_union *a, unsigned aprefixlen, const union in_addr_union *b, unsigned bprefixlen); int in_addr_prefix_next(int family, union in_addr_union *u, unsigned prefixlen); diff --git a/shared/systemd/src/basic/io-util.c b/shared/systemd/src/basic/io-util.c index d19c78c2ca..4acd17df84 100644 --- a/shared/systemd/src/basic/io-util.c +++ b/shared/systemd/src/basic/io-util.c @@ -257,7 +257,7 @@ ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length) { char* set_iovec_string_field(struct iovec *iovec, size_t *n_iovec, const char *field, const char *value) { char *x; - x = strappend(field, value); + x = strjoin(field, value); if (x) iovec[(*n_iovec)++] = IOVEC_MAKE_STRING(x); return x; @@ -312,7 +312,7 @@ int iovw_put_string_field(struct iovec_wrapper *iovw, const char *field, const c _cleanup_free_ char *x = NULL; int r; - x = strappend(field, value); + x = strjoin(field, value); if (!x) return log_oom(); diff --git a/shared/systemd/src/basic/log.h b/shared/systemd/src/basic/log.h index aa3d5b75f1..625be22402 100644 --- a/shared/systemd/src/basic/log.h +++ b/shared/systemd/src/basic/log.h @@ -73,6 +73,9 @@ int log_get_max_level_realm(LogRealm realm) _pure_; * for the application itself. */ +assert_cc(STRLEN(__FILE__) > STRLEN(RELATIVE_SOURCE_PATH) + 1); +#define PROJECT_FILE (__FILE__ + STRLEN(RELATIVE_SOURCE_PATH) + 1) + int log_open(void); void log_close(void); void log_forget_fds(void); @@ -210,7 +213,7 @@ void log_assert_failed_return_realm( log_assert_failed_return_realm(LOG_REALM, (text), __VA_ARGS__) #define log_dispatch(level, error, buffer) \ - log_dispatch_internal(level, error, __FILE__, __LINE__, __func__, NULL, NULL, NULL, NULL, buffer) + log_dispatch_internal(level, error, PROJECT_FILE, __LINE__, __func__, NULL, NULL, NULL, NULL, buffer) /* Logging with level */ #define log_full_errno_realm(realm, level, error, ...) \ @@ -218,7 +221,7 @@ void log_assert_failed_return_realm( int _level = (level), _e = (error), _realm = (realm); \ (log_get_max_level_realm(_realm) >= LOG_PRI(_level)) \ ? log_internal_realm(LOG_REALM_PLUS_LEVEL(_realm, _level), _e, \ - __FILE__, __LINE__, __func__, __VA_ARGS__) \ + PROJECT_FILE, __LINE__, __func__, __VA_ARGS__) \ : -ERRNO_VALUE(_e); \ }) @@ -254,20 +257,20 @@ int log_emergency_level(void); /* Structured logging */ #define log_struct_errno(level, error, ...) \ log_struct_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, level), \ - error, __FILE__, __LINE__, __func__, __VA_ARGS__, NULL) + error, PROJECT_FILE, __LINE__, __func__, __VA_ARGS__, NULL) #define log_struct(level, ...) log_struct_errno(level, 0, __VA_ARGS__) #define log_struct_iovec_errno(level, error, iovec, n_iovec) \ log_struct_iovec_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, level), \ - error, __FILE__, __LINE__, __func__, iovec, n_iovec) + error, PROJECT_FILE, __LINE__, __func__, iovec, n_iovec) #define log_struct_iovec(level, iovec, n_iovec) log_struct_iovec_errno(level, 0, iovec, n_iovec) /* This modifies the buffer passed! */ #define log_dump(level, buffer) \ log_dump_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, level), \ - 0, __FILE__, __LINE__, __func__, buffer) + 0, PROJECT_FILE, __LINE__, __func__, buffer) -#define log_oom() log_oom_internal(LOG_REALM, __FILE__, __LINE__, __func__) +#define log_oom() log_oom_internal(LOG_REALM, PROJECT_FILE, __LINE__, __func__) bool log_on_console(void) _pure_; @@ -320,7 +323,7 @@ int log_syntax_invalid_utf8_internal( ({ \ int _level = (level), _e = (error); \ (log_get_max_level() >= LOG_PRI(_level)) \ - ? log_syntax_internal(unit, _level, config_file, config_line, _e, __FILE__, __LINE__, __func__, __VA_ARGS__) \ + ? log_syntax_internal(unit, _level, config_file, config_line, _e, PROJECT_FILE, __LINE__, __func__, __VA_ARGS__) \ : -ERRNO_VALUE(_e); \ }) @@ -328,7 +331,7 @@ int log_syntax_invalid_utf8_internal( ({ \ int _level = (level); \ (log_get_max_level() >= LOG_PRI(_level)) \ - ? log_syntax_invalid_utf8_internal(unit, _level, config_file, config_line, __FILE__, __LINE__, __func__, rvalue) \ + ? log_syntax_invalid_utf8_internal(unit, _level, config_file, config_line, PROJECT_FILE, __LINE__, __func__, rvalue) \ : -EINVAL; \ }) diff --git a/shared/systemd/src/basic/macro.h b/shared/systemd/src/basic/macro.h index ae8907db04..336cb3a099 100644 --- a/shared/systemd/src/basic/macro.h +++ b/shared/systemd/src/basic/macro.h @@ -324,12 +324,12 @@ static inline int __coverity_check__(int condition) { #define assert_message_se(expr, message) \ do { \ if (_unlikely_(!(expr))) \ - log_assert_failed(message, __FILE__, __LINE__, __PRETTY_FUNCTION__); \ + log_assert_failed(message, PROJECT_FILE, __LINE__, __PRETTY_FUNCTION__); \ } while (false) #define assert_log(expr, message) ((_likely_(expr)) \ ? (true) \ - : (log_assert_failed_return(message, __FILE__, __LINE__, __PRETTY_FUNCTION__), false)) + : (log_assert_failed_return(message, PROJECT_FILE, __LINE__, __PRETTY_FUNCTION__), false)) #endif /* __COVERITY__ */ @@ -344,18 +344,16 @@ static inline int __coverity_check__(int condition) { #endif #define assert_not_reached(t) \ - do { \ - log_assert_failed_unreachable(t, __FILE__, __LINE__, __PRETTY_FUNCTION__); \ - } while (false) + log_assert_failed_unreachable(t, PROJECT_FILE, __LINE__, __PRETTY_FUNCTION__) #if defined(static_assert) #define assert_cc(expr) \ - static_assert(expr, #expr); + static_assert(expr, #expr) #else #define assert_cc(expr) \ struct CONCATENATE(_assert_struct_, __COUNTER__) { \ char x[(expr) ? 0 : -1]; \ - }; + } #endif #define assert_return(expr, r) \ @@ -464,7 +462,8 @@ static inline int __coverity_check__(int condition) { * type for the array, in the hope that checkers such as ubsan don't complain that the initializers for \ * the array are not representable by the base type. Ideally we'd use typeof(x) as base type, but that \ * doesn't work, as we want to use this on bitfields and gcc refuses typeof() on bitfields.) */ \ - assert_cc((sizeof((long double[]){__VA_ARGS__})/sizeof(long double)) <= 20); \ + static const long double __assert_in_set[] _unused_ = { __VA_ARGS__ }; \ + assert_cc(ELEMENTSOF(__assert_in_set) <= 20); \ switch(x) { \ FOR_EACH_MAKE_CASE(__VA_ARGS__) \ _found = true; \ diff --git a/shared/systemd/src/basic/memory-util.h b/shared/systemd/src/basic/memory-util.h index 0e8957b783..9cb8ac3c10 100644 --- a/shared/systemd/src/basic/memory-util.h +++ b/shared/systemd/src/basic/memory-util.h @@ -2,6 +2,7 @@ #pragma once #include <inttypes.h> +#include <malloc.h> #include <stdbool.h> #include <string.h> #include <sys/types.h> @@ -78,6 +79,16 @@ static inline void* explicit_bzero_safe(void *p, size_t l) { void *explicit_bzero_safe(void *p, size_t l); #endif +static inline void erase_and_freep(void *p) { + void *ptr = *(void**) p; + + if (ptr) { + size_t l = malloc_usable_size(ptr); + explicit_bzero_safe(ptr, l); + free(ptr); + } +} + /* Use with _cleanup_ to erase a single 'char' when leaving scope */ static inline void erase_char(char *p) { explicit_bzero_safe(p, sizeof(char)); diff --git a/shared/systemd/src/basic/path-util.c b/shared/systemd/src/basic/path-util.c index 570f88627d..18c7dabbae 100644 --- a/shared/systemd/src/basic/path-util.c +++ b/shared/systemd/src/basic/path-util.c @@ -207,6 +207,18 @@ int path_make_relative(const char *from_dir, const char *to_path, char **_r) { return 0; } +char* path_startswith_strv(const char *p, char **set) { + char **s, *t; + + STRV_FOREACH(s, set) { + t = path_startswith(p, *s); + if (t) + return t; + } + + return NULL; +} + int path_strv_make_absolute_cwd(char **l) { char **s; int r; @@ -382,6 +394,52 @@ char *path_simplify(char *path, bool kill_dots) { return path; } +int path_simplify_and_warn( + char *path, + unsigned flag, + const char *unit, + const char *filename, + unsigned line, + const char *lvalue) { + + bool fatal = flag & PATH_CHECK_FATAL; + + assert(!FLAGS_SET(flag, PATH_CHECK_ABSOLUTE | PATH_CHECK_RELATIVE)); + + if (!utf8_is_valid(path)) + return log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, path); + + if (flag & (PATH_CHECK_ABSOLUTE | PATH_CHECK_RELATIVE)) { + bool absolute; + + absolute = path_is_absolute(path); + + if (!absolute && (flag & PATH_CHECK_ABSOLUTE)) + return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL), + "%s= path is not absolute%s: %s", + lvalue, fatal ? "" : ", ignoring", path); + + if (absolute && (flag & PATH_CHECK_RELATIVE)) + return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL), + "%s= path is absolute%s: %s", + lvalue, fatal ? "" : ", ignoring", path); + } + + path_simplify(path, true); + + if (!path_is_valid(path)) + return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL), + "%s= path has invalid length (%zu bytes)%s.", + lvalue, strlen(path), fatal ? "" : ", ignoring"); + + if (!path_is_normalized(path)) + return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL), + "%s= path is not normalized%s: %s", + lvalue, fatal ? "" : ", ignoring", path); + + return 0; +} + char* path_startswith(const char *path, const char *prefix) { assert(path); assert(prefix); @@ -1058,49 +1116,3 @@ bool empty_or_root(const char *root) { return root[strspn(root, "/")] == 0; } - -int path_simplify_and_warn( - char *path, - unsigned flag, - const char *unit, - const char *filename, - unsigned line, - const char *lvalue) { - - bool fatal = flag & PATH_CHECK_FATAL; - - assert(!FLAGS_SET(flag, PATH_CHECK_ABSOLUTE | PATH_CHECK_RELATIVE)); - - if (!utf8_is_valid(path)) - return log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, path); - - if (flag & (PATH_CHECK_ABSOLUTE | PATH_CHECK_RELATIVE)) { - bool absolute; - - absolute = path_is_absolute(path); - - if (!absolute && (flag & PATH_CHECK_ABSOLUTE)) - return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL), - "%s= path is not absolute%s: %s", - lvalue, fatal ? "" : ", ignoring", path); - - if (absolute && (flag & PATH_CHECK_RELATIVE)) - return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL), - "%s= path is absolute%s: %s", - lvalue, fatal ? "" : ", ignoring", path); - } - - path_simplify(path, true); - - if (!path_is_valid(path)) - return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL), - "%s= path has invalid length (%zu bytes)%s.", - lvalue, strlen(path), fatal ? "" : ", ignoring"); - - if (!path_is_normalized(path)) - return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL), - "%s= path is not normalized%s: %s", - lvalue, fatal ? "" : ", ignoring", path); - - return 0; -} diff --git a/shared/systemd/src/basic/path-util.h b/shared/systemd/src/basic/path-util.h index 4a1ed0a1a8..1f46cd65c9 100644 --- a/shared/systemd/src/basic/path-util.h +++ b/shared/systemd/src/basic/path-util.h @@ -54,6 +54,14 @@ char* path_join_internal(const char *first, ...); char* path_simplify(char *path, bool kill_dots); +enum { + PATH_CHECK_FATAL = 1 << 0, /* If not set, then error message is appended with 'ignoring'. */ + PATH_CHECK_ABSOLUTE = 1 << 1, + PATH_CHECK_RELATIVE = 1 << 2, +}; + +int path_simplify_and_warn(char *path, unsigned flag, const char *unit, const char *filename, unsigned line, const char *lvalue); + static inline bool path_equal_ptr(const char *a, const char *b) { return !!a == !!b && (!a || path_equal(a, b)); } @@ -71,17 +79,8 @@ static inline bool path_equal_ptr(const char *a, const char *b) { _found; \ }) -#define PATH_STARTSWITH_SET(p, ...) \ - ({ \ - const char *_p = (p); \ - char *_found = NULL, **_i; \ - STRV_FOREACH(_i, STRV_MAKE(__VA_ARGS__)) { \ - _found = path_startswith(_p, *_i); \ - if (_found) \ - break; \ - } \ - _found; \ - }) +char* path_startswith_strv(const char *p, char **set); +#define PATH_STARTSWITH_SET(p, ...) path_startswith_strv(p, STRV_MAKE(__VA_ARGS__)) int path_strv_make_absolute_cwd(char **l); char** path_strv_resolve(char **l, const char *root); @@ -178,11 +177,3 @@ bool empty_or_root(const char *root); static inline const char *empty_to_root(const char *path) { return isempty(path) ? "/" : path; } - -enum { - PATH_CHECK_FATAL = 1 << 0, /* If not set, then error message is appended with 'ignoring'. */ - PATH_CHECK_ABSOLUTE = 1 << 1, - PATH_CHECK_RELATIVE = 1 << 2, -}; - -int path_simplify_and_warn(char *path, unsigned flag, const char *unit, const char *filename, unsigned line, const char *lvalue); diff --git a/shared/systemd/src/basic/process-util.h b/shared/systemd/src/basic/process-util.h index 4adf254808..41d4759c97 100644 --- a/shared/systemd/src/basic/process-util.h +++ b/shared/systemd/src/basic/process-util.h @@ -189,7 +189,7 @@ int set_oom_score_adjust(int value); #error "Unknown pid_t size" #endif -assert_cc(TASKS_MAX <= (unsigned long) PID_T_MAX) +assert_cc(TASKS_MAX <= (unsigned long) PID_T_MAX); /* Like TAKE_PTR() but for child PIDs, resetting them to 0 */ #define TAKE_PID(pid) \ diff --git a/shared/systemd/src/basic/set.h b/shared/systemd/src/basic/set.h index 2a80632b79..2bb26c68b8 100644 --- a/shared/systemd/src/basic/set.h +++ b/shared/systemd/src/basic/set.h @@ -28,13 +28,13 @@ int internal_set_ensure_allocated(Set **s, const struct hash_ops *hash_ops HASHM int set_put(Set *s, const void *key); /* no set_update */ /* no set_replace */ -static inline void *set_get(Set *s, void *key) { - return internal_hashmap_get(HASHMAP_BASE(s), key); +static inline void *set_get(const Set *s, void *key) { + return internal_hashmap_get(HASHMAP_BASE((Set *) s), key); } /* no set_get2 */ -static inline bool set_contains(Set *s, const void *key) { - return internal_hashmap_contains(HASHMAP_BASE(s), key); +static inline bool set_contains(const Set *s, const void *key) { + return internal_hashmap_contains(HASHMAP_BASE((Set *) s), key); } static inline void *set_remove(Set *s, const void *key) { @@ -59,19 +59,19 @@ static inline int set_move_one(Set *s, Set *other, const void *key) { return internal_hashmap_move_one(HASHMAP_BASE(s), HASHMAP_BASE(other), key); } -static inline unsigned set_size(Set *s) { - return internal_hashmap_size(HASHMAP_BASE(s)); +static inline unsigned set_size(const Set *s) { + return internal_hashmap_size(HASHMAP_BASE((Set *) s)); } -static inline bool set_isempty(Set *s) { +static inline bool set_isempty(const Set *s) { return set_size(s) == 0; } -static inline unsigned set_buckets(Set *s) { - return internal_hashmap_buckets(HASHMAP_BASE(s)); +static inline unsigned set_buckets(const Set *s) { + return internal_hashmap_buckets(HASHMAP_BASE((Set *) s)); } -bool set_iterate(Set *s, Iterator *i, void **value); +bool set_iterate(const Set *s, Iterator *i, void **value); static inline void set_clear(Set *s) { internal_hashmap_clear(HASHMAP_BASE(s), NULL, NULL); diff --git a/shared/systemd/src/basic/socket-util.c b/shared/systemd/src/basic/socket-util.c index e1636bca6e..82bda64801 100644 --- a/shared/systemd/src/basic/socket-util.c +++ b/shared/systemd/src/basic/socket-util.c @@ -78,7 +78,7 @@ int socket_address_parse(SocketAddress *a, const char *s) { errno = 0; if (inet_pton(AF_INET6, n, &a->sockaddr.in6.sin6_addr) <= 0) - return errno > 0 ? -errno : -EINVAL; + return errno_or_else(EINVAL); e++; if (*e != ':') diff --git a/shared/systemd/src/basic/socket-util.h b/shared/systemd/src/basic/socket-util.h index 36ec422f2c..48a22415df 100644 --- a/shared/systemd/src/basic/socket-util.h +++ b/shared/systemd/src/basic/socket-util.h @@ -3,9 +3,9 @@ #include <inttypes.h> #include <linux/netlink.h> +#include <linux/if_ether.h> #include <linux/if_infiniband.h> #include <linux/if_packet.h> -#include <netinet/ether.h> #include <netinet/in.h> #include <stdbool.h> #include <stddef.h> diff --git a/shared/systemd/src/basic/string-util.c b/shared/systemd/src/basic/string-util.c index 779048904a..9586b3940e 100644 --- a/shared/systemd/src/basic/string-util.c +++ b/shared/systemd/src/basic/string-util.c @@ -206,10 +206,6 @@ char *strnappend(const char *s, const char *suffix, size_t b) { return r; } -char *strappend(const char *s, const char *suffix) { - return strnappend(s, suffix, strlen_ptr(suffix)); -} - char *strjoin_real(const char *x, ...) { va_list ap; size_t l; @@ -729,10 +725,17 @@ char *strreplace(const char *text, const char *old_string, const char *new_strin return ret; } -static void advance_offsets(ssize_t diff, size_t offsets[static 2], size_t shift[static 2], size_t size) { +static void advance_offsets( + ssize_t diff, + size_t offsets[2], /* note: we can't use [static 2] here, since this may be NULL */ + size_t shift[static 2], + size_t size) { + if (!offsets) return; + assert(shift); + if ((size_t) diff < offsets[0]) shift[0] += size; if ((size_t) diff < offsets[1]) @@ -848,8 +851,7 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]) { fclose(f); - free(*ibuf); - *ibuf = obuf; + free_and_replace(*ibuf, obuf); if (_isz) *_isz = osz; @@ -859,7 +861,7 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]) { highlight[1] += shift[1]; } - return obuf; + return *ibuf; } char *strextend_with_separator(char **x, const char *separator, ...) { @@ -1032,20 +1034,6 @@ int free_and_strndup(char **p, const char *s, size_t l) { return 1; } -char* string_erase(char *x) { - if (!x) - return NULL; - - /* A delicious drop of snake-oil! To be called on memory where - * we stored passphrases or so, after we used them. */ - explicit_bzero_safe(x, strlen(x)); - return x; -} - -char *string_free_erase(char *s) { - return mfree(string_erase(s)); -} - bool string_is_safe(const char *p) { const char *t; diff --git a/shared/systemd/src/basic/string-util.h b/shared/systemd/src/basic/string-util.h index 47b17c9d3e..76767afcac 100644 --- a/shared/systemd/src/basic/string-util.h +++ b/shared/systemd/src/basic/string-util.h @@ -108,7 +108,6 @@ const char* split(const char **state, size_t *l, const char *separator, SplitFla #define _FOREACH_WORD(word, length, s, separator, flags, state) \ for ((state) = (s), (word) = split(&(state), &(length), (separator), (flags)); (word); (word) = split(&(state), &(length), (separator), (flags))) -char *strappend(const char *s, const char *suffix); char *strnappend(const char *s, const char *suffix, size_t length); char *strjoin_real(const char *x, ...) _sentinel_; @@ -197,12 +196,6 @@ static inline int free_and_strdup_warn(char **p, const char *s) { } int free_and_strndup(char **p, const char *s, size_t l); -char *string_erase(char *x); - -char *string_free_erase(char *s); -DEFINE_TRIVIAL_CLEANUP_FUNC(char *, string_free_erase); -#define _cleanup_string_free_erase_ _cleanup_(string_free_erasep) - bool string_is_safe(const char *p) _pure_; static inline size_t strlen_ptr(const char *s) { diff --git a/shared/systemd/src/basic/strv.c b/shared/systemd/src/basic/strv.c index 21c106149b..88b85867bb 100644 --- a/shared/systemd/src/basic/strv.c +++ b/shared/systemd/src/basic/strv.c @@ -11,6 +11,7 @@ #include "escape.h" #include "extract-word.h" #include "fileio.h" +#include "memory-util.h" #include "nulstr-util.h" #include "sort-util.h" #include "string-util.h" @@ -78,9 +79,9 @@ char **strv_free_erase(char **l) { char **i; STRV_FOREACH(i, l) - string_erase(*i); + erase_and_freep(i); - return strv_free(l); + return mfree(l); } char **strv_copy(char * const *l) { @@ -232,7 +233,7 @@ int strv_extend_strv_concat(char ***a, char **b, const char *suffix) { STRV_FOREACH(s, b) { char *v; - v = strappend(*s, suffix); + v = strjoin(*s, suffix); if (!v) return -ENOMEM; @@ -888,3 +889,63 @@ int fputstrv(FILE *f, char **l, const char *separator, bool *space) { return 0; } + +static int string_strv_hashmap_put_internal(Hashmap *h, const char *key, const char *value) { + char **l; + int r; + + l = hashmap_get(h, key); + if (l) { + /* A list for this key already exists, let's append to it if it is not listed yet */ + if (strv_contains(l, value)) + return 0; + + r = strv_extend(&l, value); + if (r < 0) + return r; + + assert_se(hashmap_update(h, key, l) >= 0); + } else { + /* No list for this key exists yet, create one */ + _cleanup_strv_free_ char **l2 = NULL; + _cleanup_free_ char *t = NULL; + + t = strdup(key); + if (!t) + return -ENOMEM; + + r = strv_extend(&l2, value); + if (r < 0) + return r; + + r = hashmap_put(h, t, l2); + if (r < 0) + return r; + TAKE_PTR(t); + TAKE_PTR(l2); + } + + return 1; +} + +int string_strv_hashmap_put(Hashmap **h, const char *key, const char *value) { + int r; + + r = hashmap_ensure_allocated(h, &string_strv_hash_ops); + if (r < 0) + return r; + + return string_strv_hashmap_put_internal(*h, key, value); +} + +int string_strv_ordered_hashmap_put(OrderedHashmap **h, const char *key, const char *value) { + int r; + + r = ordered_hashmap_ensure_allocated(h, &string_strv_hash_ops); + if (r < 0) + return r; + + return string_strv_hashmap_put_internal(PLAIN_HASHMAP(*h), key, value); +} + +DEFINE_HASH_OPS_FULL(string_strv_hash_ops, char, string_hash_func, string_compare_func, free, char*, strv_free); diff --git a/shared/systemd/src/basic/strv.h b/shared/systemd/src/basic/strv.h index aa5f95ab72..e80964acd1 100644 --- a/shared/systemd/src/basic/strv.h +++ b/shared/systemd/src/basic/strv.h @@ -9,6 +9,7 @@ #include "alloc-util.h" #include "extract-word.h" +#include "hashmap.h" #include "macro.h" #include "string-util.h" @@ -188,3 +189,7 @@ int fputstrv(FILE *f, char **l, const char *separator, bool *space); (b) = NULL; \ 0; \ }) + +extern const struct hash_ops string_strv_hash_ops; +int string_strv_hashmap_put(Hashmap **h, const char *key, const char *value); +int string_strv_ordered_hashmap_put(OrderedHashmap **h, const char *key, const char *value); diff --git a/shared/systemd/src/basic/strxcpyx.c b/shared/systemd/src/basic/strxcpyx.c new file mode 100644 index 0000000000..ef6d3fa324 --- /dev/null +++ b/shared/systemd/src/basic/strxcpyx.c @@ -0,0 +1,116 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +/* + * Concatenates/copies strings. In any case, terminates in all cases + * with '\0' and moves the @dest pointer forward to the added '\0'. + * Returns the remaining size, and 0 if the string was truncated. + * + * Due to the intended usage, these helpers silently noop invocations + * having zero size. This is technically an exception to the above + * statement "terminates in all cases". It's unexpected for such calls to + * occur outside of a loop where this is the preferred behavior. + */ + +#include <stdarg.h> +#include <stdio.h> +#include <string.h> + +#include "strxcpyx.h" + +size_t strnpcpy(char **dest, size_t size, const char *src, size_t len) { + assert(dest); + assert(src); + + if (size == 0) + return 0; + + if (len >= size) { + if (size > 1) + *dest = mempcpy(*dest, src, size-1); + size = 0; + } else if (len > 0) { + *dest = mempcpy(*dest, src, len); + size -= len; + } + + *dest[0] = '\0'; + return size; +} + +size_t strpcpy(char **dest, size_t size, const char *src) { + assert(dest); + assert(src); + + return strnpcpy(dest, size, src, strlen(src)); +} + +size_t strpcpyf(char **dest, size_t size, const char *src, ...) { + va_list va; + int i; + + assert(dest); + assert(src); + + if (size == 0) + return 0; + + va_start(va, src); + i = vsnprintf(*dest, size, src, va); + if (i < (int)size) { + *dest += i; + size -= i; + } else + size = 0; + va_end(va); + return size; +} + +size_t strpcpyl(char **dest, size_t size, const char *src, ...) { + va_list va; + + assert(dest); + assert(src); + + va_start(va, src); + do { + size = strpcpy(dest, size, src); + src = va_arg(va, char *); + } while (src); + va_end(va); + return size; +} + +size_t strnscpy(char *dest, size_t size, const char *src, size_t len) { + char *s; + + assert(dest); + assert(src); + + s = dest; + return strnpcpy(&s, size, src, len); +} + +size_t strscpy(char *dest, size_t size, const char *src) { + assert(dest); + assert(src); + + return strnscpy(dest, size, src, strlen(src)); +} + +size_t strscpyl(char *dest, size_t size, const char *src, ...) { + va_list va; + char *s; + + assert(dest); + assert(src); + + va_start(va, src); + s = dest; + do { + size = strpcpy(&s, size, src); + src = va_arg(va, char *); + } while (src); + va_end(va); + + return size; +} diff --git a/shared/systemd/src/basic/strxcpyx.h b/shared/systemd/src/basic/strxcpyx.h new file mode 100644 index 0000000000..9b66841246 --- /dev/null +++ b/shared/systemd/src/basic/strxcpyx.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +#pragma once + +#include <stddef.h> + +#include "macro.h" + +size_t strnpcpy(char **dest, size_t size, const char *src, size_t len); +size_t strpcpy(char **dest, size_t size, const char *src); +size_t strpcpyf(char **dest, size_t size, const char *src, ...) _printf_(3, 4); +size_t strpcpyl(char **dest, size_t size, const char *src, ...) _sentinel_; +size_t strnscpy(char *dest, size_t size, const char *src, size_t len); +size_t strscpy(char *dest, size_t size, const char *src); +size_t strscpyl(char *dest, size_t size, const char *src, ...) _sentinel_; diff --git a/shared/systemd/src/basic/time-util.c b/shared/systemd/src/basic/time-util.c index 8ccb4a941a..434159f41c 100644 --- a/shared/systemd/src/basic/time-util.c +++ b/shared/systemd/src/basic/time-util.c @@ -267,13 +267,12 @@ static char *format_timestamp_internal( assert(buf); - if (l < - 3 + /* week day */ - 1 + 10 + /* space and date */ - 1 + 8 + /* space and time */ - (us ? 1 + 6 : 0) + /* "." and microsecond part */ - 1 + 1 + /* space and shortest possible zone */ - 1) + if (l < (size_t) (3 + /* week day */ + 1 + 10 + /* space and date */ + 1 + 8 + /* space and time */ + (us ? 1 + 6 : 0) + /* "." and microsecond part */ + 1 + 1 + /* space and shortest possible zone */ + 1)) return NULL; /* Not enough space even for the shortest form. */ if (t <= 0 || t == USEC_INFINITY) return NULL; /* Timestamp is unset */ diff --git a/shared/systemd/src/basic/time-util.h b/shared/systemd/src/basic/time-util.h index a238f6914d..e3a529d970 100644 --- a/shared/systemd/src/basic/time-util.h +++ b/shared/systemd/src/basic/time-util.h @@ -81,15 +81,19 @@ triple_timestamp* triple_timestamp_from_realtime(triple_timestamp *ts, usec_t u) #define TRIPLE_TIMESTAMP_HAS_CLOCK(clock) \ IN_SET(clock, CLOCK_REALTIME, CLOCK_REALTIME_ALARM, CLOCK_MONOTONIC, CLOCK_BOOTTIME, CLOCK_BOOTTIME_ALARM) +static inline bool timestamp_is_set(usec_t timestamp) { + return timestamp > 0 && timestamp != USEC_INFINITY; +} + static inline bool dual_timestamp_is_set(const dual_timestamp *ts) { - return ((ts->realtime > 0 && ts->realtime != USEC_INFINITY) || - (ts->monotonic > 0 && ts->monotonic != USEC_INFINITY)); + return timestamp_is_set(ts->realtime) || + timestamp_is_set(ts->monotonic); } static inline bool triple_timestamp_is_set(const triple_timestamp *ts) { - return ((ts->realtime > 0 && ts->realtime != USEC_INFINITY) || - (ts->monotonic > 0 && ts->monotonic != USEC_INFINITY) || - (ts->boottime > 0 && ts->boottime != USEC_INFINITY)); + return timestamp_is_set(ts->realtime) || + timestamp_is_set(ts->monotonic) || + timestamp_is_set(ts->boottime); } usec_t triple_timestamp_by_clock(triple_timestamp *ts, clockid_t clock); diff --git a/src/systemd/src/shared/dns-domain.c b/shared/systemd/src/shared/dns-domain.c index f62ad0a0f5..f62ad0a0f5 100644 --- a/src/systemd/src/shared/dns-domain.c +++ b/shared/systemd/src/shared/dns-domain.c diff --git a/src/systemd/src/shared/dns-domain.h b/shared/systemd/src/shared/dns-domain.h index 6ed512c6b1..6ed512c6b1 100644 --- a/src/systemd/src/shared/dns-domain.h +++ b/shared/systemd/src/shared/dns-domain.h diff --git a/src/systemd/src/libsystemd-network/arp-util.c b/src/systemd/src/libsystemd-network/arp-util.c index 3a86f3f077..ac601a4efa 100644 --- a/src/systemd/src/libsystemd-network/arp-util.c +++ b/src/systemd/src/libsystemd-network/arp-util.c @@ -3,8 +3,9 @@ Copyright © 2014 Axis Communications AB. All rights reserved. ***/ -#include <linux/filter.h> #include <arpa/inet.h> +#include <linux/filter.h> +#include <netinet/if_ether.h> #include "arp-util.h" #include "fd-util.h" diff --git a/src/systemd/src/libsystemd-network/dhcp-internal.h b/src/systemd/src/libsystemd-network/dhcp-internal.h index a0f9c2299f..e0269b5456 100644 --- a/src/systemd/src/libsystemd-network/dhcp-internal.h +++ b/src/systemd/src/libsystemd-network/dhcp-internal.h @@ -51,5 +51,5 @@ int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum, ui #define DHCP_CLIENT_DONT_DESTROY(client) \ _cleanup_(sd_dhcp_client_unrefp) _unused_ sd_dhcp_client *_dont_destroy_##client = sd_dhcp_client_ref(client) -#define log_dhcp_client_errno(client, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "DHCP CLIENT (0x%x): " fmt, client->xid, ##__VA_ARGS__) +#define log_dhcp_client_errno(client, error, fmt, ...) log_internal(LOG_DEBUG, error, PROJECT_FILE, __LINE__, __func__, "DHCP CLIENT (0x%x): " fmt, client->xid, ##__VA_ARGS__) #define log_dhcp_client(client, fmt, ...) log_dhcp_client_errno(client, 0, fmt, ##__VA_ARGS__) diff --git a/src/systemd/src/libsystemd-network/dhcp6-internal.h b/src/systemd/src/libsystemd-network/dhcp6-internal.h index 157fc0aadd..f28ba68dd1 100644 --- a/src/systemd/src/libsystemd-network/dhcp6-internal.h +++ b/src/systemd/src/libsystemd-network/dhcp6-internal.h @@ -79,7 +79,7 @@ struct DHCP6IA { typedef struct DHCP6IA DHCP6IA; -#define log_dhcp6_client_errno(p, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "DHCPv6 CLIENT: " fmt, ##__VA_ARGS__) +#define log_dhcp6_client_errno(p, error, fmt, ...) log_internal(LOG_DEBUG, error, PROJECT_FILE, __LINE__, __func__, "DHCPv6 CLIENT: " fmt, ##__VA_ARGS__) #define log_dhcp6_client(p, fmt, ...) log_dhcp6_client_errno(p, 0, fmt, ##__VA_ARGS__) int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code, diff --git a/src/systemd/src/libsystemd-network/lldp-internal.h b/src/systemd/src/libsystemd-network/lldp-internal.h index 88b54933c3..9598438dba 100644 --- a/src/systemd/src/libsystemd-network/lldp-internal.h +++ b/src/systemd/src/libsystemd-network/lldp-internal.h @@ -32,7 +32,7 @@ struct sd_lldp { struct ether_addr filter_address; }; -#define log_lldp_errno(error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "LLDP: " fmt, ##__VA_ARGS__) +#define log_lldp_errno(error, fmt, ...) log_internal(LOG_DEBUG, error, PROJECT_FILE, __LINE__, __func__, "LLDP: " fmt, ##__VA_ARGS__) #define log_lldp(fmt, ...) log_lldp_errno(0, fmt, ##__VA_ARGS__) const char* lldp_event_to_string(sd_lldp_event e) _const_; diff --git a/src/systemd/src/libsystemd-network/network-internal.c b/src/systemd/src/libsystemd-network/network-internal.c index 1f2e5c7e65..f18ec88300 100644 --- a/src/systemd/src/libsystemd-network/network-internal.c +++ b/src/systemd/src/libsystemd-network/network-internal.c @@ -254,7 +254,7 @@ int config_parse_match_strv( for (;;) { _cleanup_free_ char *word = NULL, *k = NULL; - r = extract_first_word(&p, &word, NULL, EXTRACT_UNQUOTE|EXTRACT_RETAIN_ESCAPE); + r = extract_first_word(&p, &word, NULL, EXTRACT_UNQUOTE); if (r == 0) return 0; if (r == -ENOMEM) diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-client.c b/src/systemd/src/libsystemd-network/sd-dhcp-client.c index b0f0f84937..85238c21d1 100644 --- a/src/systemd/src/libsystemd-network/sd-dhcp-client.c +++ b/src/systemd/src/libsystemd-network/sd-dhcp-client.c @@ -576,7 +576,7 @@ static void client_stop(sd_dhcp_client *client, int error) { assert(client); if (error < 0) - log_dhcp_client(client, "STOPPED: %s", strerror(-error)); + log_dhcp_client_errno(client, error, "STOPPED: %m"); else if (error == SD_DHCP_CLIENT_EVENT_STOP) log_dhcp_client(client, "STOPPED"); else diff --git a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c index 68b41dfb6c..d7a5349c70 100644 --- a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c @@ -6,6 +6,7 @@ #include <errno.h> #include <string.h> #include <sys/ioctl.h> +#include <linux/if_arp.h> #include <linux/if_infiniband.h> #include "sd-dhcp6-client.h" diff --git a/src/systemd/src/libsystemd-network/sd-dhcp6-lease.c b/src/systemd/src/libsystemd-network/sd-dhcp6-lease.c index 8b424811ad..8aebb53c87 100644 --- a/src/systemd/src/libsystemd-network/sd-dhcp6-lease.c +++ b/src/systemd/src/libsystemd-network/sd-dhcp6-lease.c @@ -205,12 +205,8 @@ int dhcp6_lease_set_dns(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen) { r = dhcp6_option_parse_ip6addrs(optval, optlen, &lease->dns, lease->dns_count, &lease->dns_allocated); - if (r < 0) { - log_dhcp6_client(client, "Invalid DNS server option: %s", - strerror(-r)); - - return r; - } + if (r < 0) + return log_dhcp6_client_errno(client, r, "Invalid DNS server option: %m"); lease->dns_count = r; @@ -336,12 +332,8 @@ int dhcp6_lease_set_sntp(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen) r = dhcp6_option_parse_ip6addrs(optval, optlen, &lease->ntp, lease->ntp_count, &lease->ntp_allocated); - if (r < 0) { - log_dhcp6_client(client, "Invalid SNTP server option: %s", - strerror(-r)); - - return r; - } + if (r < 0) + return log_dhcp6_client_errno(client, r, "Invalid SNTP server option: %m"); lease->ntp_count = r; diff --git a/src/systemd/src/libsystemd-network/sd-ipv4acd.c b/src/systemd/src/libsystemd-network/sd-ipv4acd.c index c8e34497fd..5a24f38ae9 100644 --- a/src/systemd/src/libsystemd-network/sd-ipv4acd.c +++ b/src/systemd/src/libsystemd-network/sd-ipv4acd.c @@ -5,6 +5,7 @@ #include <arpa/inet.h> #include <errno.h> +#include <netinet/if_ether.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -72,7 +73,7 @@ struct sd_ipv4acd { void* userdata; }; -#define log_ipv4acd_errno(acd, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "IPV4ACD: " fmt, ##__VA_ARGS__) +#define log_ipv4acd_errno(acd, error, fmt, ...) log_internal(LOG_DEBUG, error, PROJECT_FILE, __LINE__, __func__, "IPV4ACD: " fmt, ##__VA_ARGS__) #define log_ipv4acd(acd, fmt, ...) log_ipv4acd_errno(acd, 0, fmt, ##__VA_ARGS__) static void ipv4acd_set_state(sd_ipv4acd *acd, IPv4ACDState st, bool reset_counter) { diff --git a/src/systemd/src/libsystemd-network/sd-ipv4ll.c b/src/systemd/src/libsystemd-network/sd-ipv4ll.c index a59a952326..3104d8c5a8 100644 --- a/src/systemd/src/libsystemd-network/sd-ipv4ll.c +++ b/src/systemd/src/libsystemd-network/sd-ipv4ll.c @@ -50,7 +50,7 @@ struct sd_ipv4ll { void* userdata; }; -#define log_ipv4ll_errno(ll, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "IPV4LL: " fmt, ##__VA_ARGS__) +#define log_ipv4ll_errno(ll, error, fmt, ...) log_internal(LOG_DEBUG, error, PROJECT_FILE, __LINE__, __func__, "IPV4LL: " fmt, ##__VA_ARGS__) #define log_ipv4ll(ll, fmt, ...) log_ipv4ll_errno(ll, 0, fmt, ##__VA_ARGS__) static void ipv4ll_on_acd(sd_ipv4acd *ll, int event, void *userdata); diff --git a/src/systemd/src/libsystemd/sd-event/sd-event.c b/src/systemd/src/libsystemd/sd-event/sd-event.c index 09285c19d8..5adbceeb02 100644 --- a/src/systemd/src/libsystemd/sd-event/sd-event.c +++ b/src/systemd/src/libsystemd/sd-event/sd-event.c @@ -23,6 +23,7 @@ #include "signal-util.h" #include "string-table.h" #include "string-util.h" +#include "strxcpyx.h" #include "time-util.h" #define DEFAULT_ACCURACY_USEC (250 * USEC_PER_MSEC) @@ -3248,15 +3249,16 @@ _public_ int sd_event_dispatch(sd_event *e) { } static void event_log_delays(sd_event *e) { - char b[ELEMENTSOF(e->delays) * DECIMAL_STR_MAX(unsigned) + 1]; - unsigned i; - int o; + char b[ELEMENTSOF(e->delays) * DECIMAL_STR_MAX(unsigned) + 1], *p; + size_t l, i; - for (i = o = 0; i < ELEMENTSOF(e->delays); i++) { - o += snprintf(&b[o], sizeof(b) - o, "%u ", e->delays[i]); + p = b; + l = sizeof(b); + for (i = 0; i < ELEMENTSOF(e->delays); i++) { + l = strpcpyf(&p, l, "%u ", e->delays[i]); e->delays[i] = 0; } - log_debug("Event loop iterations: %.*s", o, b); + log_debug("Event loop iterations: %s", b); } _public_ int sd_event_run(sd_event *e, uint64_t timeout) { diff --git a/src/systemd/src/systemd/sd-id128.h b/src/systemd/src/systemd/sd-id128.h index c5fbe0a4f1..9b00b76ea6 100644 --- a/src/systemd/src/systemd/sd-id128.h +++ b/src/systemd/src/systemd/sd-id128.h @@ -54,7 +54,6 @@ int sd_id128_get_boot_app_specific(sd_id128_t app_id, sd_id128_t *ret); #define SD_ID128_MAKE(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) \ ((const sd_id128_t) SD_ID128_ARRAY(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)) - /* Note that SD_ID128_FORMAT_VAL will evaluate the passed argument 16 * times. It is hence not a good idea to call this macro with an * expensive function as parameter or an expression with side |