summaryrefslogtreecommitdiff
path: root/shared/systemd/src/basic
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2020-12-22 21:04:52 +0100
committerThomas Haller <thaller@redhat.com>2020-12-23 17:13:47 +0100
commit0d3f8ded9d97586238bbc1f98174158a3f30c391 (patch)
treee3dd9573cb0e828bc40960bf303fcba1ec673a0a /shared/systemd/src/basic
parent8258ff91c9ee3a321f671a6427c032eec016949c (diff)
downloadNetworkManager-0d3f8ded9d97586238bbc1f98174158a3f30c391.tar.gz
systemd: update code from upstream (2020-12-23)
This is a direct dump from systemd git. ====== SYSTEMD_DIR=../systemd COMMIT=227acf0009bde2cd7f8bc371615b05e84137847d ( cd "$SYSTEMD_DIR" git checkout "$COMMIT" git reset --hard git clean -fdx ) git ls-files -z :/src/systemd/src/ \ :/shared/systemd/src/ \ :/shared/nm-std-aux/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_stdaux() { mkdir -p "./shared/nm-std-aux/" cp "$SYSTEMD_DIR/$1" "./shared/nm-std-aux/${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-dhcp-option.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-dhcp6-option.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_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/cgroup-util.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_random.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_syscall.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/ratelimit.c" nm_copy_sd_shared "src/basic/ratelimit.h" nm_copy_sd_shared "src/basic/set.h" nm_copy_sd_shared "src/basic/signal-util.c" 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/user-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" nm_copy_sd_shared "src/shared/log-link.h" nm_copy_sd_shared "src/shared/web-util.c" nm_copy_sd_shared "src/shared/web-util.h" nm_copy_sd_stdaux "src/basic/unaligned.h"
Diffstat (limited to 'shared/systemd/src/basic')
-rw-r--r--shared/systemd/src/basic/alloc-util.c2
-rw-r--r--shared/systemd/src/basic/alloc-util.h14
-rw-r--r--shared/systemd/src/basic/async.h8
-rw-r--r--shared/systemd/src/basic/cgroup-util.h15
-rw-r--r--shared/systemd/src/basic/env-file.c2
-rw-r--r--shared/systemd/src/basic/env-file.h2
-rw-r--r--shared/systemd/src/basic/env-util.c28
-rw-r--r--shared/systemd/src/basic/env-util.h5
-rw-r--r--shared/systemd/src/basic/errno-util.h10
-rw-r--r--shared/systemd/src/basic/escape.c2
-rw-r--r--shared/systemd/src/basic/escape.h4
-rw-r--r--shared/systemd/src/basic/ether-addr-util.c17
-rw-r--r--shared/systemd/src/basic/ether-addr-util.h26
-rw-r--r--shared/systemd/src/basic/extract-word.c2
-rw-r--r--shared/systemd/src/basic/extract-word.h2
-rw-r--r--shared/systemd/src/basic/fd-util.c88
-rw-r--r--shared/systemd/src/basic/fd-util.h2
-rw-r--r--shared/systemd/src/basic/fileio.c93
-rw-r--r--shared/systemd/src/basic/fileio.h35
-rw-r--r--shared/systemd/src/basic/format-util.c2
-rw-r--r--shared/systemd/src/basic/format-util.h7
-rw-r--r--shared/systemd/src/basic/fs-util.c81
-rw-r--r--shared/systemd/src/basic/fs-util.h4
-rw-r--r--shared/systemd/src/basic/hash-funcs.c15
-rw-r--r--shared/systemd/src/basic/hash-funcs.h4
-rw-r--r--shared/systemd/src/basic/hashmap.c64
-rw-r--r--shared/systemd/src/basic/hashmap.h7
-rw-r--r--shared/systemd/src/basic/hexdecoct.c2
-rw-r--r--shared/systemd/src/basic/hexdecoct.h2
-rw-r--r--shared/systemd/src/basic/hostname-util.c171
-rw-r--r--shared/systemd/src/basic/hostname-util.h26
-rw-r--r--shared/systemd/src/basic/in-addr-util.c2
-rw-r--r--shared/systemd/src/basic/in-addr-util.h2
-rw-r--r--shared/systemd/src/basic/io-util.c6
-rw-r--r--shared/systemd/src/basic/io-util.h2
-rw-r--r--shared/systemd/src/basic/list.h2
-rw-r--r--shared/systemd/src/basic/log.h14
-rw-r--r--shared/systemd/src/basic/macro.h30
-rw-r--r--shared/systemd/src/basic/memory-util.c2
-rw-r--r--shared/systemd/src/basic/memory-util.h2
-rw-r--r--shared/systemd/src/basic/mempool.c2
-rw-r--r--shared/systemd/src/basic/mempool.h2
-rw-r--r--shared/systemd/src/basic/missing_fcntl.h2
-rw-r--r--shared/systemd/src/basic/missing_random.h2
-rw-r--r--shared/systemd/src/basic/missing_socket.h10
-rw-r--r--shared/systemd/src/basic/missing_stat.h2
-rw-r--r--shared/systemd/src/basic/missing_syscall.h493
-rw-r--r--shared/systemd/src/basic/missing_type.h2
-rw-r--r--shared/systemd/src/basic/parse-util.c44
-rw-r--r--shared/systemd/src/basic/parse-util.h22
-rw-r--r--shared/systemd/src/basic/path-util.c58
-rw-r--r--shared/systemd/src/basic/path-util.h10
-rw-r--r--shared/systemd/src/basic/prioq.c2
-rw-r--r--shared/systemd/src/basic/prioq.h2
-rw-r--r--shared/systemd/src/basic/process-util.c2
-rw-r--r--shared/systemd/src/basic/process-util.h2
-rw-r--r--shared/systemd/src/basic/random-util.c19
-rw-r--r--shared/systemd/src/basic/random-util.h2
-rw-r--r--shared/systemd/src/basic/ratelimit.c38
-rw-r--r--shared/systemd/src/basic/ratelimit.h24
-rw-r--r--shared/systemd/src/basic/set.h14
-rw-r--r--shared/systemd/src/basic/signal-util.c13
-rw-r--r--shared/systemd/src/basic/signal-util.h2
-rw-r--r--shared/systemd/src/basic/siphash24.h2
-rw-r--r--shared/systemd/src/basic/socket-util.c117
-rw-r--r--shared/systemd/src/basic/socket-util.h44
-rw-r--r--shared/systemd/src/basic/sort-util.h4
-rw-r--r--shared/systemd/src/basic/stat-util.c5
-rw-r--r--shared/systemd/src/basic/stat-util.h2
-rw-r--r--shared/systemd/src/basic/stdio-util.h2
-rw-r--r--shared/systemd/src/basic/string-table.c2
-rw-r--r--shared/systemd/src/basic/string-table.h9
-rw-r--r--shared/systemd/src/basic/string-util.c57
-rw-r--r--shared/systemd/src/basic/string-util.h12
-rw-r--r--shared/systemd/src/basic/strv.c57
-rw-r--r--shared/systemd/src/basic/strv.h5
-rw-r--r--shared/systemd/src/basic/strxcpyx.c2
-rw-r--r--shared/systemd/src/basic/strxcpyx.h2
-rw-r--r--shared/systemd/src/basic/time-util.c4
-rw-r--r--shared/systemd/src/basic/time-util.h10
-rw-r--r--shared/systemd/src/basic/tmpfile-util.c2
-rw-r--r--shared/systemd/src/basic/tmpfile-util.h2
-rw-r--r--shared/systemd/src/basic/umask-util.h2
-rw-r--r--shared/systemd/src/basic/user-util.h2
-rw-r--r--shared/systemd/src/basic/utf8.c2
-rw-r--r--shared/systemd/src/basic/utf8.h2
-rw-r--r--shared/systemd/src/basic/util.c8
-rw-r--r--shared/systemd/src/basic/util.h2
88 files changed, 1242 insertions, 689 deletions
diff --git a/shared/systemd/src/basic/alloc-util.c b/shared/systemd/src/basic/alloc-util.c
index 5951e8c3d5..bad15cc204 100644
--- a/shared/systemd/src/basic/alloc-util.c
+++ b/shared/systemd/src/basic/alloc-util.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <malloc.h>
#include <stdint.h>
diff --git a/shared/systemd/src/basic/alloc-util.h b/shared/systemd/src/basic/alloc-util.h
index 64d9e00315..f3e192ddaf 100644
--- a/shared/systemd/src/basic/alloc-util.h
+++ b/shared/systemd/src/basic/alloc-util.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <alloca.h>
@@ -27,7 +27,7 @@ typedef void (*free_func_t)(void *p);
size_t _n_ = n; \
assert(!size_multiply_overflow(sizeof(t), _n_)); \
assert(sizeof(t)*_n_ <= ALLOCA_MAX); \
- (t*) alloca(sizeof(t)*_n_); \
+ (t*) alloca((sizeof(t)*_n_) ?: 1); \
})
#define newa0(t, n) \
@@ -35,14 +35,14 @@ typedef void (*free_func_t)(void *p);
size_t _n_ = n; \
assert(!size_multiply_overflow(sizeof(t), _n_)); \
assert(sizeof(t)*_n_ <= ALLOCA_MAX); \
- (t*) alloca0(sizeof(t)*_n_); \
+ (t*) alloca0((sizeof(t)*_n_) ?: 1); \
})
#define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n)))
#define newdup_suffix0(t, p, n) ((t*) memdup_suffix0_multiply(p, sizeof(t), (n)))
-#define malloc0(n) (calloc(1, (n)))
+#define malloc0(n) (calloc(1, (n) ?: 1))
static inline void *mfree(void *memory) {
free(memory);
@@ -65,7 +65,7 @@ void* memdup_suffix0(const void *p, size_t l); /* We can't use _alloc_() here, s
void *_q_; \
size_t _l_ = l; \
assert(_l_ <= ALLOCA_MAX); \
- _q_ = alloca(_l_); \
+ _q_ = alloca(_l_ ?: 1); \
memcpy(_q_, p, _l_); \
})
@@ -135,7 +135,7 @@ void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size);
char *_new_; \
size_t _len_ = n; \
assert(_len_ <= ALLOCA_MAX); \
- _new_ = alloca(_len_); \
+ _new_ = alloca(_len_ ?: 1); \
(void *) memset(_new_, 0, _len_); \
})
@@ -146,7 +146,7 @@ void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size);
size_t _mask_ = (align) - 1; \
size_t _size_ = size; \
assert(_size_ <= ALLOCA_MAX); \
- _ptr_ = alloca(_size_ + _mask_); \
+ _ptr_ = alloca((_size_ + _mask_) ?: 1); \
(void*)(((uintptr_t)_ptr_ + _mask_) & ~_mask_); \
})
diff --git a/shared/systemd/src/basic/async.h b/shared/systemd/src/basic/async.h
index 3160613184..e0bbaa5658 100644
--- a/shared/systemd/src/basic/async.h
+++ b/shared/systemd/src/basic/async.h
@@ -1,7 +1,13 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
+#include <sys/types.h>
+
+#include "macro.h"
+
int asynchronous_job(void* (*func)(void *p), void *arg);
int asynchronous_sync(pid_t *ret_pid);
int asynchronous_close(int fd);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(int, asynchronous_close);
diff --git a/shared/systemd/src/basic/cgroup-util.h b/shared/systemd/src/basic/cgroup-util.h
index 2b88571bc1..bdc0d0d086 100644
--- a/shared/systemd/src/basic/cgroup-util.h
+++ b/shared/systemd/src/basic/cgroup-util.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <dirent.h>
@@ -208,6 +208,9 @@ static inline int cg_get_keyed_attribute_graceful(
int cg_get_attribute_as_uint64(const char *controller, const char *path, const char *attribute, uint64_t *ret);
+/* Does a parse_boolean() on the attribute contents and sets ret accordingly */
+int cg_get_attribute_as_bool(const char *controller, const char *path, const char *attribute, bool *ret);
+
int cg_set_access(const char *controller, const char *path, uid_t uid, gid_t gid);
int cg_set_xattr(const char *controller, const char *path, const char *name, const void *value, size_t size, int flags);
@@ -275,3 +278,13 @@ CGroupController cgroup_controller_from_string(const char *s) _pure_;
bool is_cgroup_fs(const struct statfs *s);
bool fd_is_cgroup_fs(int fd);
+
+typedef enum ManagedOOMMode {
+ MANAGED_OOM_AUTO,
+ MANAGED_OOM_KILL,
+ _MANAGED_OOM_MODE_MAX,
+ _MANAGED_OOM_MODE_INVALID = -1,
+} ManagedOOMMode;
+
+const char* managed_oom_mode_to_string(ManagedOOMMode m) _const_;
+ManagedOOMMode managed_oom_mode_from_string(const char *s) _pure_;
diff --git a/shared/systemd/src/basic/env-file.c b/shared/systemd/src/basic/env-file.c
index dc92b13a6f..99c3e3f4a3 100644
--- a/shared/systemd/src/basic/env-file.c
+++ b/shared/systemd/src/basic/env-file.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "alloc-util.h"
#include "env-file.h"
diff --git a/shared/systemd/src/basic/env-file.h b/shared/systemd/src/basic/env-file.h
index e1ca195ff0..de475885ac 100644
--- a/shared/systemd/src/basic/env-file.h
+++ b/shared/systemd/src/basic/env-file.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <stdarg.h>
diff --git a/shared/systemd/src/basic/env-util.c b/shared/systemd/src/basic/env-util.c
index 179408c399..a84863ff22 100644
--- a/shared/systemd/src/basic/env-util.c
+++ b/shared/systemd/src/basic/env-util.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <errno.h>
#include <limits.h>
@@ -16,7 +16,8 @@
#include "strv.h"
#include "utf8.h"
-#define VALID_CHARS_ENV_NAME \
+/* We follow bash for the character set. Different shells have different rules. */
+#define VALID_BASH_ENV_NAME_CHARS \
DIGITS LETTERS \
"_"
@@ -41,17 +42,14 @@ static bool env_name_is_valid_n(const char *e, size_t n) {
return false;
for (p = e; p < e + n; p++)
- if (!strchr(VALID_CHARS_ENV_NAME, *p))
+ if (!strchr(VALID_BASH_ENV_NAME_CHARS, *p))
return false;
return true;
}
bool env_name_is_valid(const char *e) {
- if (!e)
- return false;
-
- return env_name_is_valid_n(e, strlen(e));
+ return env_name_is_valid_n(e, strlen_ptr(e));
}
bool env_value_is_valid(const char *e) {
@@ -546,7 +544,7 @@ char *replace_env_n(const char *format, size_t n, char **env, unsigned flags) {
word = e+1;
state = WORD;
- } else if (flags & REPLACE_ENV_ALLOW_BRACELESS && strchr(VALID_CHARS_ENV_NAME, *e)) {
+ } else if (flags & REPLACE_ENV_ALLOW_BRACELESS && strchr(VALID_BASH_ENV_NAME_CHARS, *e)) {
k = strnappend(r, word, e-word-1);
if (!k)
return NULL;
@@ -636,7 +634,7 @@ char *replace_env_n(const char *format, size_t n, char **env, unsigned flags) {
case VARIABLE_RAW:
assert(flags & REPLACE_ENV_ALLOW_BRACELESS);
- if (!strchr(VALID_CHARS_ENV_NAME, *e)) {
+ if (!strchr(VALID_BASH_ENV_NAME_CHARS, *e)) {
const char *t;
t = strv_env_get_n(env, word+1, e-word-1, flags);
@@ -749,3 +747,15 @@ int getenv_bool_secure(const char *p) {
return parse_boolean(e);
}
+
+int set_unset_env(const char *name, const char *value, bool overwrite) {
+ int r;
+
+ if (value)
+ r = setenv(name, value, overwrite);
+ else
+ r = unsetenv(name);
+ if (r < 0)
+ return -errno;
+ return 0;
+}
diff --git a/shared/systemd/src/basic/env-util.h b/shared/systemd/src/basic/env-util.h
index 92802ed774..6684b3350f 100644
--- a/shared/systemd/src/basic/env-util.h
+++ b/shared/systemd/src/basic/env-util.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <stdbool.h>
@@ -52,3 +52,6 @@ char *strv_env_get(char **x, const char *n) _pure_;
int getenv_bool(const char *p);
int getenv_bool_secure(const char *p);
+
+/* Like setenv, but calls unsetenv if value == NULL. */
+int set_unset_env(const char *name, const char *value, bool overwrite);
diff --git a/shared/systemd/src/basic/errno-util.h b/shared/systemd/src/basic/errno-util.h
index 0ca650f48f..5609820b88 100644
--- a/shared/systemd/src/basic/errno-util.h
+++ b/shared/systemd/src/basic/errno-util.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <stdlib.h>
@@ -50,7 +50,10 @@ static inline int errno_or_else(int 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
- * icmp_err_convert[] in net/ipv4/icmp.c in the kernel sources */
+ * icmp_err_convert[] in net/ipv4/icmp.c in the kernel sources.
+ *
+ * Hint #3: When asynchronous connect() on TCP fails because the host never acknowledges a single packet,
+ * kernel tells us that with ETIMEDOUT, see tcp(7). */
static inline bool ERRNO_IS_DISCONNECT(int r) {
return IN_SET(abs(r),
ECONNABORTED,
@@ -66,7 +69,8 @@ static inline bool ERRNO_IS_DISCONNECT(int r) {
ENOTCONN,
EPIPE,
EPROTO,
- ESHUTDOWN);
+ ESHUTDOWN,
+ ETIMEDOUT);
}
/* Transient errors we might get on accept() that we should ignore. As per error handling comment in
diff --git a/shared/systemd/src/basic/escape.c b/shared/systemd/src/basic/escape.c
index 7589d597a2..31f3cda472 100644
--- a/shared/systemd/src/basic/escape.c
+++ b/shared/systemd/src/basic/escape.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <errno.h>
#include <stdlib.h>
diff --git a/shared/systemd/src/basic/escape.h b/shared/systemd/src/basic/escape.h
index fa267813b3..691b6d802c 100644
--- a/shared/systemd/src/basic/escape.h
+++ b/shared/systemd/src/basic/escape.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <inttypes.h>
@@ -16,7 +16,7 @@
/* Those that can be escaped or double-quoted.
*
- * Stricly speaking, ! does not need to be escaped, except in interactive
+ * Strictly speaking, ! does not need to be escaped, except in interactive
* mode, but let's be extra nice to the user and quote ! in case this
* output is ever used in interactive mode. */
#define SHELL_NEED_QUOTES SHELL_NEED_ESCAPE GLOB_CHARS "'()<>|&;!"
diff --git a/shared/systemd/src/basic/ether-addr-util.c b/shared/systemd/src/basic/ether-addr-util.c
index e875696a1a..c8094b6e45 100644
--- a/shared/systemd/src/basic/ether-addr-util.c
+++ b/shared/systemd/src/basic/ether-addr-util.c
@@ -1,6 +1,7 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <errno.h>
+#include <inttypes.h>
#include <net/ethernet.h>
#include <stdio.h>
#include <sys/types.h>
@@ -9,6 +10,20 @@
#include "macro.h"
#include "string-util.h"
+char* hw_addr_to_string(const hw_addr_data *addr, char buffer[HW_ADDR_TO_STRING_MAX]) {
+ assert(addr);
+ assert(buffer);
+ assert(addr->length <= HW_ADDR_MAX_SIZE);
+
+ for (size_t i = 0; i < addr->length; i++) {
+ sprintf(&buffer[3*i], "%02"PRIx8, addr->addr.bytes[i]);
+ if (i < addr->length - 1)
+ buffer[3*i + 2] = ':';
+ }
+
+ return buffer;
+}
+
char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]) {
assert(addr);
assert(buffer);
diff --git a/shared/systemd/src/basic/ether-addr-util.h b/shared/systemd/src/basic/ether-addr-util.h
index 4e44b30be9..942ce55621 100644
--- a/shared/systemd/src/basic/ether-addr-util.h
+++ b/shared/systemd/src/basic/ether-addr-util.h
@@ -1,11 +1,35 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
+#include <linux/if_infiniband.h>
#include <net/ethernet.h>
#include <stdbool.h>
#include "hash-funcs.h"
+/* This is MAX_ADDR_LEN as defined in linux/netdevice.h, but net/if_arp.h
+ * defines a macro of the same name with a much lower size. */
+#define HW_ADDR_MAX_SIZE 32
+
+union hw_addr_union {
+ struct ether_addr ether;
+ uint8_t infiniband[INFINIBAND_ALEN];
+ uint8_t bytes[HW_ADDR_MAX_SIZE];
+};
+
+typedef struct hw_addr_data {
+ union hw_addr_union addr;
+ size_t length;
+} hw_addr_data;
+
+#define HW_ADDR_TO_STRING_MAX (3*HW_ADDR_MAX_SIZE)
+char* hw_addr_to_string(const hw_addr_data *addr, char buffer[HW_ADDR_TO_STRING_MAX]);
+
+/* Use only as function argument, never stand-alone! */
+#define HW_ADDR_TO_STR(hw_addr) hw_addr_to_string((hw_addr), (char[HW_ADDR_TO_STRING_MAX]){})
+
+#define HW_ADDR_NULL ((const hw_addr_data){})
+
#define ETHER_ADDR_FORMAT_STR "%02X%02X%02X%02X%02X%02X"
#define ETHER_ADDR_FORMAT_VAL(x) (x).ether_addr_octet[0], (x).ether_addr_octet[1], (x).ether_addr_octet[2], (x).ether_addr_octet[3], (x).ether_addr_octet[4], (x).ether_addr_octet[5]
diff --git a/shared/systemd/src/basic/extract-word.c b/shared/systemd/src/basic/extract-word.c
index d64dddd641..76b3fe12e3 100644
--- a/shared/systemd/src/basic/extract-word.c
+++ b/shared/systemd/src/basic/extract-word.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <errno.h>
#include <stdarg.h>
diff --git a/shared/systemd/src/basic/extract-word.h b/shared/systemd/src/basic/extract-word.h
index f028577c40..d1de32e580 100644
--- a/shared/systemd/src/basic/extract-word.h
+++ b/shared/systemd/src/basic/extract-word.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include "macro.h"
diff --git a/shared/systemd/src/basic/fd-util.c b/shared/systemd/src/basic/fd-util.c
index db869cbd54..a03ba83e19 100644
--- a/shared/systemd/src/basic/fd-util.c
+++ b/shared/systemd/src/basic/fd-util.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <errno.h>
#include <fcntl.h>
@@ -21,6 +21,7 @@
#include "path-util.h"
#include "process-util.h"
#include "socket-util.h"
+#include "sort-util.h"
#include "stat-util.h"
#include "stdio-util.h"
#include "tmpfile-util.h"
@@ -211,12 +212,97 @@ static int get_max_fd(void) {
}
int close_all_fds(const int except[], size_t n_except) {
+ static bool have_close_range = true; /* Assume we live in the future */
_cleanup_closedir_ DIR *d = NULL;
struct dirent *de;
int r = 0;
assert(n_except == 0 || except);
+ if (have_close_range) {
+ /* In the best case we have close_range() to close all fds between a start and an end fd,
+ * which we can use on the "inverted" exception array, i.e. all intervals between all
+ * adjacent pairs from the sorted exception array. This changes loop complexity from O(n)
+ * where n is number of open fds to O(m⋅log(m)) where m is the number of fds to keep
+ * open. Given that we assume n ≫ m that's preferable to us. */
+
+ if (n_except == 0) {
+ /* Close everything. Yay! */
+
+ if (close_range(3, -1, 0) >= 0)
+ return 1;
+
+ if (!ERRNO_IS_NOT_SUPPORTED(errno) && !ERRNO_IS_PRIVILEGE(errno))
+ return -errno;
+
+ have_close_range = false;
+ } else {
+ _cleanup_free_ int *sorted_malloc = NULL;
+ size_t n_sorted;
+ int *sorted;
+
+ assert(n_except < SIZE_MAX);
+ n_sorted = n_except + 1;
+
+ if (n_sorted > 64) /* Use heap for large numbers of fds, stack otherwise */
+ sorted = sorted_malloc = new(int, n_sorted);
+ else
+ sorted = newa(int, n_sorted);
+
+ if (sorted) {
+ int c = 0;
+
+ memcpy(sorted, except, n_except * sizeof(int));
+
+ /* Let's add fd 2 to the list of fds, to simplify the loop below, as this
+ * allows us to cover the head of the array the same way as the body */
+ sorted[n_sorted-1] = 2;
+
+ typesafe_qsort(sorted, n_sorted, cmp_int);
+
+ for (size_t i = 0; i < n_sorted-1; i++) {
+ int start, end;
+
+ start = MAX(sorted[i], 2); /* The first three fds shall always remain open */
+ end = MAX(sorted[i+1], 2);
+
+ assert(end >= start);
+
+ if (end - start <= 1)
+ continue;
+
+ /* Close everything between the start and end fds (both of which shall stay open) */
+ if (close_range(start + 1, end - 1, 0) < 0) {
+ if (!ERRNO_IS_NOT_SUPPORTED(errno) && !ERRNO_IS_PRIVILEGE(errno))
+ return -errno;
+
+ have_close_range = false;
+ break;
+ }
+
+ c += end - start - 1;
+ }
+
+ if (have_close_range) {
+ /* The loop succeeded. Let's now close everything beyond the end */
+
+ if (sorted[n_sorted-1] >= INT_MAX) /* Dont let the addition below overflow */
+ return c;
+
+ if (close_range(sorted[n_sorted-1] + 1, -1, 0) >= 0)
+ return c + 1;
+
+ if (!ERRNO_IS_NOT_SUPPORTED(errno) && !ERRNO_IS_PRIVILEGE(errno))
+ return -errno;
+
+ have_close_range = false;
+ }
+ }
+ }
+
+ /* Fallback on OOM or if close_range() is not supported */
+ }
+
d = opendir("/proc/self/fd");
if (!d) {
int fd, max_fd;
diff --git a/shared/systemd/src/basic/fd-util.h b/shared/systemd/src/basic/fd-util.h
index 93ce95cd03..2162537b80 100644
--- a/shared/systemd/src/basic/fd-util.h
+++ b/shared/systemd/src/basic/fd-util.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <dirent.h>
diff --git a/shared/systemd/src/basic/fileio.c b/shared/systemd/src/basic/fileio.c
index c5a093a857..f4708bc05f 100644
--- a/shared/systemd/src/basic/fileio.c
+++ b/shared/systemd/src/basic/fileio.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <ctype.h>
#include <errno.h>
@@ -117,7 +117,7 @@ int write_string_stream_ts(
FILE *f,
const char *line,
WriteStringFileFlags flags,
- struct timespec *ts) {
+ const struct timespec *ts) {
bool needs_nl;
int r, fd;
@@ -161,7 +161,7 @@ int write_string_stream_ts(
return r;
if (ts) {
- struct timespec twice[2] = {*ts, *ts};
+ const struct timespec twice[2] = {*ts, *ts};
if (futimens(fd, twice) < 0)
return -errno;
@@ -174,7 +174,7 @@ static int write_string_file_atomic(
const char *fn,
const char *line,
WriteStringFileFlags flags,
- struct timespec *ts) {
+ const struct timespec *ts) {
_cleanup_fclose_ FILE *f = NULL;
_cleanup_free_ char *p = NULL;
@@ -221,7 +221,7 @@ int write_string_file_ts(
const char *fn,
const char *line,
WriteStringFileFlags flags,
- struct timespec *ts) {
+ const struct timespec *ts) {
_cleanup_fclose_ FILE *f = NULL;
int q, r, fd;
@@ -252,7 +252,8 @@ int write_string_file_ts(
/* We manually build our own version of fopen(..., "we") that works without O_CREAT and with O_NOFOLLOW if needed. */
fd = open(fn, O_WRONLY|O_CLOEXEC|O_NOCTTY |
(FLAGS_SET(flags, WRITE_STRING_FILE_NOFOLLOW) ? O_NOFOLLOW : 0) |
- (FLAGS_SET(flags, WRITE_STRING_FILE_CREATE) ? O_CREAT : 0),
+ (FLAGS_SET(flags, WRITE_STRING_FILE_CREATE) ? O_CREAT : 0) |
+ (FLAGS_SET(flags, WRITE_STRING_FILE_TRUNCATE) ? O_TRUNC : 0),
(FLAGS_SET(flags, WRITE_STRING_FILE_MODE_0600) ? 0600 : 0666));
if (fd < 0) {
r = -errno;
@@ -471,12 +472,13 @@ int read_full_virtual_file(const char *filename, char **ret_contents, size_t *re
int read_full_stream_full(
FILE *f,
const char *filename,
+ uint64_t offset,
+ size_t size,
ReadFullFileFlags flags,
char **ret_contents,
size_t *ret_size) {
_cleanup_free_ char *buf = NULL;
- struct stat st;
size_t n, n_next, l;
int fd, r;
@@ -484,32 +486,45 @@ int read_full_stream_full(
assert(ret_contents);
assert(!FLAGS_SET(flags, READ_FULL_FILE_UNBASE64 | READ_FULL_FILE_UNHEX));
- n_next = LINE_MAX; /* Start size */
+ if (offset != UINT64_MAX && offset > LONG_MAX)
+ return -ERANGE;
+
+ n_next = size != SIZE_MAX ? size : LINE_MAX; /* Start size */
fd = fileno(f);
- if (fd >= 0) { /* If the FILE* object is backed by an fd (as opposed to memory or such, see fmemopen()), let's
- * optimize our buffering */
+ if (fd >= 0) { /* If the FILE* object is backed by an fd (as opposed to memory or such, see
+ * fmemopen()), let's optimize our buffering */
+ struct stat st;
if (fstat(fd, &st) < 0)
return -errno;
if (S_ISREG(st.st_mode)) {
-
- /* Safety check */
- if (st.st_size > READ_FULL_BYTES_MAX)
- return -E2BIG;
-
- /* Start with the right file size. Note that we increase the size
- * to read here by one, so that the first read attempt already
- * makes us notice the EOF. */
- if (st.st_size > 0)
- n_next = st.st_size + 1;
+ if (size == SIZE_MAX) {
+ uint64_t rsize =
+ LESS_BY((uint64_t) st.st_size, offset == UINT64_MAX ? 0 : offset);
+
+ /* Safety check */
+ if (rsize > READ_FULL_BYTES_MAX)
+ return -E2BIG;
+
+ /* Start with the right file size. Note that we increase the size to read
+ * here by one, so that the first read attempt already makes us notice the
+ * EOF. If the reported size of the file is zero, we avoid this logic
+ * however, since quite likely it might be a virtual file in procfs that all
+ * report a zero file size. */
+ if (st.st_size > 0)
+ n_next = rsize + 1;
+ }
if (flags & READ_FULL_FILE_WARN_WORLD_READABLE)
(void) warn_file_is_world_accessible(filename, &st, NULL, 0);
}
}
+ if (offset != UINT64_MAX && fseek(f, offset, SEEK_SET) < 0)
+ return -errno;
+
n = l = 0;
for (;;) {
char *t;
@@ -546,6 +561,11 @@ int read_full_stream_full(
if (feof(f))
break;
+ if (size != SIZE_MAX) { /* If we got asked to read some specific size, we already sized the buffer right, hence leave */
+ assert(l == size);
+ break;
+ }
+
assert(k > 0); /* we can't have read zero bytes because that would have been EOF */
/* Safety check */
@@ -601,12 +621,21 @@ finalize:
return r;
}
-int read_full_file_full(int dir_fd, const char *filename, ReadFullFileFlags flags, char **contents, size_t *size) {
+int read_full_file_full(
+ int dir_fd,
+ const char *filename,
+ uint64_t offset,
+ size_t size,
+ ReadFullFileFlags flags,
+ const char *bind_name,
+ char **ret_contents,
+ size_t *ret_size) {
+
_cleanup_fclose_ FILE *f = NULL;
int r;
assert(filename);
- assert(contents);
+ assert(ret_contents);
r = xfopenat(dir_fd, filename, "re", 0, &f);
if (r < 0) {
@@ -621,6 +650,10 @@ int read_full_file_full(int dir_fd, const char *filename, ReadFullFileFlags flag
if (!FLAGS_SET(flags, READ_FULL_FILE_CONNECT_SOCKET))
return -ENXIO;
+ /* Seeking is not supported on AF_UNIX sockets */
+ if (offset != UINT64_MAX)
+ return -ESPIPE;
+
if (dir_fd == AT_FDCWD)
r = sockaddr_un_set_path(&sa.un, filename);
else {
@@ -644,6 +677,20 @@ int read_full_file_full(int dir_fd, const char *filename, ReadFullFileFlags flag
if (sk < 0)
return -errno;
+ if (bind_name) {
+ /* If the caller specified a socket name to bind to, do so before connecting. This is
+ * useful to communicate some minor, short meta-information token from the client to
+ * the server. */
+ union sockaddr_union bsa;
+
+ r = sockaddr_un_set_path(&bsa.un, bind_name);
+ if (r < 0)
+ return r;
+
+ if (bind(sk, &bsa.sa, r) < 0)
+ return r;
+ }
+
if (connect(sk, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0)
return errno == ENOTSOCK ? -ENXIO : -errno; /* propagate original error if this is
* not a socket after all */
@@ -660,7 +707,7 @@ int read_full_file_full(int dir_fd, const char *filename, ReadFullFileFlags flag
(void) __fsetlocking(f, FSETLOCKING_BYCALLER);
- return read_full_stream_full(f, filename, flags, contents, size);
+ return read_full_stream_full(f, filename, offset, size, flags, ret_contents, ret_size);
}
int executable_is_script(const char *path, char **interpreter) {
diff --git a/shared/systemd/src/basic/fileio.h b/shared/systemd/src/basic/fileio.h
index 9cba5a90e3..498e880354 100644
--- a/shared/systemd/src/basic/fileio.h
+++ b/shared/systemd/src/basic/fileio.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <dirent.h>
@@ -16,14 +16,15 @@
typedef enum {
WRITE_STRING_FILE_CREATE = 1 << 0,
- WRITE_STRING_FILE_ATOMIC = 1 << 1,
- WRITE_STRING_FILE_AVOID_NEWLINE = 1 << 2,
- WRITE_STRING_FILE_VERIFY_ON_FAILURE = 1 << 3,
- WRITE_STRING_FILE_SYNC = 1 << 4,
- WRITE_STRING_FILE_DISABLE_BUFFER = 1 << 5,
- WRITE_STRING_FILE_NOFOLLOW = 1 << 6,
- WRITE_STRING_FILE_MKDIR_0755 = 1 << 7,
- WRITE_STRING_FILE_MODE_0600 = 1 << 8,
+ WRITE_STRING_FILE_TRUNCATE = 1 << 1,
+ WRITE_STRING_FILE_ATOMIC = 1 << 2,
+ WRITE_STRING_FILE_AVOID_NEWLINE = 1 << 3,
+ WRITE_STRING_FILE_VERIFY_ON_FAILURE = 1 << 4,
+ WRITE_STRING_FILE_SYNC = 1 << 5,
+ WRITE_STRING_FILE_DISABLE_BUFFER = 1 << 6,
+ WRITE_STRING_FILE_NOFOLLOW = 1 << 7,
+ WRITE_STRING_FILE_MKDIR_0755 = 1 << 8,
+ WRITE_STRING_FILE_MODE_0600 = 1 << 9,
/* And before you wonder, why write_string_file_atomic_label_ts() is a separate function instead of just one
more flag here: it's about linking: we don't want to pull -lselinux into all users of write_string_file()
@@ -47,11 +48,11 @@ DIR* take_fdopendir(int *dfd);
FILE* open_memstream_unlocked(char **ptr, size_t *sizeloc);
FILE* fmemopen_unlocked(void *buf, size_t size, const char *mode);
-int write_string_stream_ts(FILE *f, const char *line, WriteStringFileFlags flags, struct timespec *ts);
+int write_string_stream_ts(FILE *f, const char *line, WriteStringFileFlags flags, const struct timespec *ts);
static inline int write_string_stream(FILE *f, const char *line, WriteStringFileFlags flags) {
return write_string_stream_ts(f, line, flags, NULL);
}
-int write_string_file_ts(const char *fn, const char *line, WriteStringFileFlags flags, struct timespec *ts);
+int write_string_file_ts(const char *fn, const char *line, WriteStringFileFlags flags, const struct timespec *ts);
static inline int write_string_file(const char *fn, const char *line, WriteStringFileFlags flags) {
return write_string_file_ts(fn, line, flags, NULL);
}
@@ -59,14 +60,14 @@ static inline int write_string_file(const char *fn, const char *line, WriteStrin
int write_string_filef(const char *fn, WriteStringFileFlags flags, const char *format, ...) _printf_(3, 4);
int read_one_line_file(const char *filename, char **line);
-int read_full_file_full(int dir_fd, const char *filename, ReadFullFileFlags flags, char **contents, size_t *size);
-static inline int read_full_file(const char *filename, char **contents, size_t *size) {
- return read_full_file_full(AT_FDCWD, filename, 0, contents, size);
+int read_full_file_full(int dir_fd, const char *filename, uint64_t offset, size_t size, ReadFullFileFlags flags, const char *bind_name, char **ret_contents, size_t *ret_size);
+static inline int read_full_file(const char *filename, char **ret_contents, size_t *ret_size) {
+ return read_full_file_full(AT_FDCWD, filename, UINT64_MAX, SIZE_MAX, 0, NULL, ret_contents, ret_size);
}
int read_full_virtual_file(const char *filename, char **ret_contents, size_t *ret_size);
-int read_full_stream_full(FILE *f, const char *filename, ReadFullFileFlags flags, char **contents, size_t *size);
-static inline int read_full_stream(FILE *f, char **contents, size_t *size) {
- return read_full_stream_full(f, NULL, 0, contents, size);
+int read_full_stream_full(FILE *f, const char *filename, uint64_t offset, size_t size, ReadFullFileFlags flags, char **ret_contents, size_t *ret_size);
+static inline int read_full_stream(FILE *f, char **ret_contents, size_t *ret_size) {
+ return read_full_stream_full(f, NULL, UINT64_MAX, SIZE_MAX, 0, ret_contents, ret_size);
}
int verify_file(const char *fn, const char *blob, bool accept_extra_nl);
diff --git a/shared/systemd/src/basic/format-util.c b/shared/systemd/src/basic/format-util.c
index b4144e0352..bf23037792 100644
--- a/shared/systemd/src/basic/format-util.c
+++ b/shared/systemd/src/basic/format-util.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "format-util.h"
#include "memory-util.h"
diff --git a/shared/systemd/src/basic/format-util.h b/shared/systemd/src/basic/format-util.h
index c47fa76ea8..b7e18768e3 100644
--- a/shared/systemd/src/basic/format-util.h
+++ b/shared/systemd/src/basic/format-util.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <inttypes.h>
@@ -72,11 +72,14 @@ typedef enum {
FORMAT_BYTES_TRAILING_B = 1 << 2,
} FormatBytesFlag;
-#define FORMAT_BYTES_MAX 16
+#define FORMAT_BYTES_MAX 16U
+
char *format_bytes_full(char *buf, size_t l, uint64_t t, FormatBytesFlag flag);
+
static inline char *format_bytes(char *buf, size_t l, uint64_t t) {
return format_bytes_full(buf, l, t, FORMAT_BYTES_USE_IEC | FORMAT_BYTES_BELOW_POINT | FORMAT_BYTES_TRAILING_B);
}
+
static inline char *format_bytes_cgroup_protection(char *buf, size_t l, uint64_t t) {
if (t == CGROUP_LIMIT_MAX) {
(void) snprintf(buf, l, "%s", "infinity");
diff --git a/shared/systemd/src/basic/fs-util.c b/shared/systemd/src/basic/fs-util.c
index 587b3504ee..f240f84322 100644
--- a/shared/systemd/src/basic/fs-util.c
+++ b/shared/systemd/src/basic/fs-util.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <errno.h>
#include <stddef.h>
@@ -810,7 +810,7 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
*
* 3. With CHASE_STEP: in this case only a single step of the normalization is executed, i.e. only the first
* symlink or ".." component of the path is resolved, and the resulting path is returned. This is useful if
- * a caller wants to trace the a path through the file system verbosely. Returns < 0 on error, > 0 if the
+ * a caller wants to trace the path through the file system verbosely. Returns < 0 on error, > 0 if the
* path is fully normalized, and == 0 for each normalization step. This may be combined with
* CHASE_NONEXISTENT, in which case 1 is returned when a component is not found.
*
@@ -1613,3 +1613,80 @@ int path_is_encrypted(const char *path) {
return blockdev_is_encrypted(p, 10 /* safety net: maximum recursion depth */);
}
+
+int conservative_rename(
+ int olddirfd, const char *oldpath,
+ int newdirfd, const char *newpath) {
+
+ _cleanup_close_ int old_fd = -1, new_fd = -1;
+ struct stat old_stat, new_stat;
+
+ /* Renames the old path to thew new path, much like renameat() — except if both are regular files and
+ * have the exact same contents and basic file attributes already. In that case remove the new file
+ * instead. This call is useful for reducing inotify wakeups on files that are updated but don't
+ * actually change. This function is written in a style that we rather rename too often than suppress
+ * too much. i.e. whenever we are in doubt we rather rename than fail. After all reducing inotify
+ * events is an optimization only, not more. */
+
+ old_fd = openat(olddirfd, oldpath, O_CLOEXEC|O_RDONLY|O_NOCTTY|O_NOFOLLOW);
+ if (old_fd < 0)
+ goto do_rename;
+
+ new_fd = openat(newdirfd, newpath, O_CLOEXEC|O_RDONLY|O_NOCTTY|O_NOFOLLOW);
+ if (new_fd < 0)
+ goto do_rename;
+
+ if (fstat(old_fd, &old_stat) < 0)
+ goto do_rename;
+
+ if (!S_ISREG(old_stat.st_mode))
+ goto do_rename;
+
+ if (fstat(new_fd, &new_stat) < 0)
+ goto do_rename;
+
+ if (new_stat.st_ino == old_stat.st_ino &&
+ new_stat.st_dev == old_stat.st_dev)
+ goto is_same;
+
+ if (old_stat.st_mode != new_stat.st_mode ||
+ old_stat.st_size != new_stat.st_size ||
+ old_stat.st_uid != new_stat.st_uid ||
+ old_stat.st_gid != new_stat.st_gid)
+ goto do_rename;
+
+ for (;;) {
+ char buf1[16*1024];
+ char buf2[sizeof(buf1) + 1];
+ ssize_t l1, l2;
+
+ l1 = read(old_fd, buf1, sizeof(buf1));
+ if (l1 < 0)
+ goto do_rename;
+
+ l2 = read(new_fd, buf2, l1 + 1);
+ if (l1 != l2)
+ goto do_rename;
+
+ if (l1 == 0) /* EOF on both! And everything's the same so far, yay! */
+ break;
+
+ if (memcmp(buf1, buf2, l1) != 0)
+ goto do_rename;
+ }
+
+is_same:
+ /* Everything matches? Then don't rename, instead remove the source file, and leave the existing
+ * destination in place */
+
+ if (unlinkat(olddirfd, oldpath, 0) < 0)
+ goto do_rename;
+
+ return 0;
+
+do_rename:
+ if (renameat(olddirfd, oldpath, newdirfd, newpath) < 0)
+ return -errno;
+
+ return 1;
+}
diff --git a/shared/systemd/src/basic/fs-util.h b/shared/systemd/src/basic/fs-util.h
index 241cc6ef62..9a39473567 100644
--- a/shared/systemd/src/basic/fs-util.h
+++ b/shared/systemd/src/basic/fs-util.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <dirent.h>
@@ -132,3 +132,5 @@ int syncfs_path(int atfd, const char *path);
int open_parent(const char *path, int flags, mode_t mode);
int path_is_encrypted(const char *path);
+
+int conservative_rename(int olddirfd, const char *oldpath, int newdirfd, const char *newpath);
diff --git a/shared/systemd/src/basic/hash-funcs.c b/shared/systemd/src/basic/hash-funcs.c
index cf279e5cbe..e033de1ae1 100644
--- a/shared/systemd/src/basic/hash-funcs.c
+++ b/shared/systemd/src/basic/hash-funcs.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <string.h>
@@ -71,6 +71,19 @@ const struct hash_ops trivial_hash_ops = {
.compare = trivial_compare_func,
};
+const struct hash_ops trivial_hash_ops_free = {
+ .hash = trivial_hash_func,
+ .compare = trivial_compare_func,
+ .free_key = free,
+};
+
+const struct hash_ops trivial_hash_ops_free_free = {
+ .hash = trivial_hash_func,
+ .compare = trivial_compare_func,
+ .free_key = free,
+ .free_value = free,
+};
+
void uint64_hash_func(const uint64_t *p, struct siphash *state) {
siphash24_compress(p, sizeof(uint64_t), state);
}
diff --git a/shared/systemd/src/basic/hash-funcs.h b/shared/systemd/src/basic/hash-funcs.h
index 005d1b21d2..5672df1da4 100644
--- a/shared/systemd/src/basic/hash-funcs.h
+++ b/shared/systemd/src/basic/hash-funcs.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include "alloc-util.h"
@@ -88,6 +88,8 @@ extern const struct hash_ops path_hash_ops_free;
void trivial_hash_func(const void *p, struct siphash *state);
int trivial_compare_func(const void *a, const void *b) _const_;
extern const struct hash_ops trivial_hash_ops;
+extern const struct hash_ops trivial_hash_ops_free;
+extern const struct hash_ops trivial_hash_ops_free_free;
/* 32bit values we can always just embed in the pointer itself, but in order to support 32bit archs we need store 64bit
* values indirectly, since they don't fit in a pointer. */
diff --git a/shared/systemd/src/basic/hashmap.c b/shared/systemd/src/basic/hashmap.c
index 77cebd9f15..cdc6847edf 100644
--- a/shared/systemd/src/basic/hashmap.c
+++ b/shared/systemd/src/basic/hashmap.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <errno.h>
#include <pthread.h>
@@ -1794,10 +1794,10 @@ int set_consume(Set *s, void *value) {
return r;
}
-int _hashmap_put_strdup(Hashmap **h, const char *k, const char *v HASHMAP_DEBUG_PARAMS) {
+int _hashmap_put_strdup_full(Hashmap **h, const struct hash_ops *hash_ops, const char *k, const char *v HASHMAP_DEBUG_PARAMS) {
int r;
- r = _hashmap_ensure_allocated(h, &string_hash_ops_free_free HASHMAP_DEBUG_PASS_ARGS);
+ r = _hashmap_ensure_allocated(h, hash_ops HASHMAP_DEBUG_PASS_ARGS);
if (r < 0)
return r;
@@ -1828,14 +1828,14 @@ int _hashmap_put_strdup(Hashmap **h, const char *k, const char *v HASHMAP_DEBUG
return r;
}
-int _set_put_strdup(Set **s, const char *p HASHMAP_DEBUG_PARAMS) {
+int _set_put_strdup_full(Set **s, const struct hash_ops *hash_ops, const char *p HASHMAP_DEBUG_PARAMS) {
char *c;
int r;
assert(s);
assert(p);
- r = _set_ensure_allocated(s, &string_hash_ops_free HASHMAP_DEBUG_PASS_ARGS);
+ r = _set_ensure_allocated(s, hash_ops HASHMAP_DEBUG_PASS_ARGS);
if (r < 0)
return r;
@@ -1849,14 +1849,14 @@ int _set_put_strdup(Set **s, const char *p HASHMAP_DEBUG_PARAMS) {
return set_consume(*s, c);
}
-int _set_put_strdupv(Set **s, char **l HASHMAP_DEBUG_PARAMS) {
+int _set_put_strdupv_full(Set **s, const struct hash_ops *hash_ops, char **l HASHMAP_DEBUG_PARAMS) {
int n = 0, r;
char **i;
assert(s);
STRV_FOREACH(i, l) {
- r = _set_put_strdup(s, *i HASHMAP_DEBUG_PASS_ARGS);
+ r = _set_put_strdup_full(s, hash_ops, *i HASHMAP_DEBUG_PASS_ARGS);
if (r < 0)
return r;
@@ -1976,3 +1976,53 @@ IteratedCache* iterated_cache_free(IteratedCache *cache) {
return mfree(cache);
}
+
+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;
+
+ 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) + (wrap_with_separator ? separator_len : 0) + 1))
+ return -ENOMEM;
+
+ if (separator_len > 0 && !first) {
+ memcpy(str + len, separator, separator_len);
+ len += separator_len;
+ }
+
+ memcpy(str + len, value, l);
+ len += l;
+ first = false;
+ }
+
+ 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/shared/systemd/src/basic/hashmap.h b/shared/systemd/src/basic/hashmap.h
index 890f90a9d1..e99448375e 100644
--- a/shared/systemd/src/basic/hashmap.h
+++ b/shared/systemd/src/basic/hashmap.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <limits.h>
@@ -153,8 +153,9 @@ 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 HASHMAP_DEBUG_PARAMS);
-#define hashmap_put_strdup(h, k, v) _hashmap_put_strdup(h, k, v HASHMAP_DEBUG_SRC_ARGS)
+int _hashmap_put_strdup_full(Hashmap **h, const struct hash_ops *hash_ops, const char *k, const char *v HASHMAP_DEBUG_PARAMS);
+#define hashmap_put_strdup_full(h, hash_ops, k, v) _hashmap_put_strdup_full(h, hash_ops, k, v HASHMAP_DEBUG_SRC_ARGS)
+#define hashmap_put_strdup(h, k, v) hashmap_put_strdup_full(h, &string_hash_ops_free_free, k, v)
int hashmap_update(Hashmap *h, const void *key, void *value);
static inline int ordered_hashmap_update(OrderedHashmap *h, const void *key, void *value) {
diff --git a/shared/systemd/src/basic/hexdecoct.c b/shared/systemd/src/basic/hexdecoct.c
index 96f7b9ed0f..da60202e57 100644
--- a/shared/systemd/src/basic/hexdecoct.c
+++ b/shared/systemd/src/basic/hexdecoct.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <ctype.h>
#include <errno.h>
diff --git a/shared/systemd/src/basic/hexdecoct.h b/shared/systemd/src/basic/hexdecoct.h
index dfdff1e9bb..7e2a6892c0 100644
--- a/shared/systemd/src/basic/hexdecoct.h
+++ b/shared/systemd/src/basic/hexdecoct.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <stdbool.h>
diff --git a/shared/systemd/src/basic/hostname-util.c b/shared/systemd/src/basic/hostname-util.c
index 90a3dfc864..d7aba2c263 100644
--- a/shared/systemd/src/basic/hostname-util.c
+++ b/shared/systemd/src/basic/hostname-util.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <errno.h>
#include <limits.h>
@@ -7,28 +7,10 @@
#include <unistd.h>
#include "alloc-util.h"
-#include "fd-util.h"
-#include "fileio.h"
#include "hostname-util.h"
-#include "macro.h"
#include "string-util.h"
#include "strv.h"
-bool hostname_is_set(void) {
- struct utsname u;
-
- assert_se(uname(&u) >= 0);
-
- if (isempty(u.nodename))
- return false;
-
- /* This is the built-in kernel default hostname */
- if (streq(u.nodename, "(none)"))
- return false;
-
- return true;
-}
-
char* gethostname_malloc(void) {
struct utsname u;
const char *s;
@@ -89,6 +71,8 @@ int gethostname_strict(char **ret) {
}
bool valid_ldh_char(char c) {
+ /* "LDH" → "Letters, digits, hyphens", as per RFC 5890, Section 2.3.1 */
+
return
(c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
@@ -96,28 +80,24 @@ bool valid_ldh_char(char c) {
c == '-';
}
-/**
- * Check if s looks like a valid hostname or FQDN. This does not do
- * full DNS validation, but only checks if the name is composed of
- * allowed characters and the length is not above the maximum allowed
- * by Linux (c.f. dns_name_is_valid()). Trailing dot is allowed if
- * allow_trailing_dot is true and at least two components are present
- * in the name. Note that due to the restricted charset and length
- * this call is substantially more conservative than
- * dns_name_is_valid().
- */
-bool hostname_is_valid(const char *s, bool allow_trailing_dot) {
+bool hostname_is_valid(const char *s, ValidHostnameFlags flags) {
unsigned n_dots = 0;
const char *p;
bool dot, hyphen;
+ /* Check if s looks like a valid hostname or FQDN. This does not do full DNS validation, but only
+ * checks if the name is composed of allowed characters and the length is not above the maximum
+ * allowed by Linux (c.f. dns_name_is_valid()). A trailing dot is allowed if
+ * VALID_HOSTNAME_TRAILING_DOT flag is set and at least two components are present in the name. Note
+ * that due to the restricted charset and length this call is substantially more conservative than
+ * dns_name_is_valid(). Doesn't accept empty hostnames, hostnames with leading dots, and hostnames
+ * with multiple dots in a sequence. Doesn't allow hyphens at the beginning or end of label. */
+
if (isempty(s))
return false;
- /* Doesn't accept empty hostnames, hostnames with
- * leading dots, and hostnames with multiple dots in a
- * sequence. Also ensures that the length stays below
- * HOST_NAME_MAX. */
+ if (streq(s, ".host")) /* Used by the container logic to denote the "root container" */
+ return FLAGS_SET(flags, VALID_HOSTNAME_DOT_HOST);
for (p = s, dot = hyphen = true; *p; p++)
if (*p == '.') {
@@ -143,14 +123,13 @@ bool hostname_is_valid(const char *s, bool allow_trailing_dot) {
hyphen = false;
}
- if (dot && (n_dots < 2 || !allow_trailing_dot))
+ if (dot && (n_dots < 2 || !FLAGS_SET(flags, VALID_HOSTNAME_TRAILING_DOT)))
return false;
if (hyphen)
return false;
- if (p-s > HOST_NAME_MAX) /* Note that HOST_NAME_MAX is 64 on
- * Linux, but DNS allows domain names
- * up to 255 characters */
+ if (p-s > HOST_NAME_MAX) /* Note that HOST_NAME_MAX is 64 on Linux, but DNS allows domain names up to
+ * 255 characters */
return false;
return true;
@@ -211,119 +190,3 @@ bool is_localhost(const char *hostname) {
endswith_no_case(hostname, ".localhost.localdomain") ||
endswith_no_case(hostname, ".localhost.localdomain.");
}
-
-bool is_gateway_hostname(const char *hostname) {
- assert(hostname);
-
- /* This tries to identify the valid syntaxes for the our
- * synthetic "gateway" host. */
-
- return
- strcaseeq(hostname, "_gateway") || strcaseeq(hostname, "_gateway.")
-#if ENABLE_COMPAT_GATEWAY_HOSTNAME
- || strcaseeq(hostname, "gateway") || strcaseeq(hostname, "gateway.")
-#endif
- ;
-}
-
-int sethostname_idempotent(const char *s) {
- char buf[HOST_NAME_MAX + 1] = {};
-
- assert(s);
-
- if (gethostname(buf, sizeof(buf)) < 0)
- return -errno;
-
- if (streq(buf, s))
- return 0;
-
- if (sethostname(s, strlen(s)) < 0)
- return -errno;
-
- return 1;
-}
-
-int shorten_overlong(const char *s, char **ret) {
- char *h, *p;
-
- /* Shorten an overlong name to HOST_NAME_MAX or to the first dot,
- * whatever comes earlier. */
-
- assert(s);
-
- h = strdup(s);
- if (!h)
- return -ENOMEM;
-
- if (hostname_is_valid(h, false)) {
- *ret = h;
- return 0;
- }
-
- p = strchr(h, '.');
- if (p)
- *p = 0;
-
- strshorten(h, HOST_NAME_MAX);
-
- if (!hostname_is_valid(h, false)) {
- free(h);
- return -EDOM;
- }
-
- *ret = h;
- return 1;
-}
-
-int read_etc_hostname_stream(FILE *f, char **ret) {
- int r;
-
- assert(f);
- assert(ret);
-
- for (;;) {
- _cleanup_free_ char *line = NULL;
- char *p;
-
- r = read_line(f, LONG_LINE_MAX, &line);
- if (r < 0)
- return r;
- if (r == 0) /* EOF without any hostname? the file is empty, let's treat that exactly like no file at all: ENOENT */
- return -ENOENT;
-
- p = strstrip(line);
-
- /* File may have empty lines or comments, ignore them */
- if (!IN_SET(*p, '\0', '#')) {
- char *copy;
-
- hostname_cleanup(p); /* normalize the hostname */
-
- if (!hostname_is_valid(p, true)) /* check that the hostname we return is valid */
- return -EBADMSG;
-
- copy = strdup(p);
- if (!copy)
- return -ENOMEM;
-
- *ret = copy;
- return 0;
- }
- }
-}
-
-int read_etc_hostname(const char *path, char **ret) {
- _cleanup_fclose_ FILE *f = NULL;
-
- assert(ret);
-
- if (!path)
- path = "/etc/hostname";
-
- f = fopen(path, "re");
- if (!f)
- return -errno;
-
- return read_etc_hostname_stream(f, ret);
-
-}
diff --git a/shared/systemd/src/basic/hostname-util.h b/shared/systemd/src/basic/hostname-util.h
index cafd6f020b..6cff9c1d4c 100644
--- a/shared/systemd/src/basic/hostname-util.h
+++ b/shared/systemd/src/basic/hostname-util.h
@@ -1,29 +1,29 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <stdbool.h>
#include <stdio.h>
#include "macro.h"
-
-bool hostname_is_set(void);
+#include "strv.h"
char* gethostname_malloc(void);
char* gethostname_short_malloc(void);
int gethostname_strict(char **ret);
bool valid_ldh_char(char c) _const_;
-bool hostname_is_valid(const char *s, bool allow_trailing_dot) _pure_;
-char* hostname_cleanup(char *s);
-
-#define machine_name_is_valid(s) hostname_is_valid(s, false)
-bool is_localhost(const char *hostname);
-bool is_gateway_hostname(const char *hostname);
+typedef enum ValidHostnameFlags {
+ VALID_HOSTNAME_TRAILING_DOT = 1 << 0, /* Accept trailing dot on multi-label names */
+ VALID_HOSTNAME_DOT_HOST = 1 << 1, /* Accept ".host" as valid hostname */
+} ValidHostnameFlags;
-int sethostname_idempotent(const char *s);
+bool hostname_is_valid(const char *s, ValidHostnameFlags flags) _pure_;
+char* hostname_cleanup(char *s);
-int shorten_overlong(const char *s, char **ret);
+bool is_localhost(const char *hostname);
-int read_etc_hostname_stream(FILE *f, char **ret);
-int read_etc_hostname(const char *path, char **ret);
+static inline bool is_gateway_hostname(const char *hostname) {
+ /* This tries to identify the valid syntaxes for the our synthetic "gateway" host. */
+ return STRCASE_IN_SET(hostname, "_gateway", "_gateway.");
+}
diff --git a/shared/systemd/src/basic/in-addr-util.c b/shared/systemd/src/basic/in-addr-util.c
index c102504fdd..a4f13b620a 100644
--- a/shared/systemd/src/basic/in-addr-util.c
+++ b/shared/systemd/src/basic/in-addr-util.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <arpa/inet.h>
#include <endian.h>
diff --git a/shared/systemd/src/basic/in-addr-util.h b/shared/systemd/src/basic/in-addr-util.h
index 45c93a0056..24308b702e 100644
--- a/shared/systemd/src/basic/in-addr-util.h
+++ b/shared/systemd/src/basic/in-addr-util.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <netinet/in.h>
diff --git a/shared/systemd/src/basic/io-util.c b/shared/systemd/src/basic/io-util.c
index 460649deda..4d7405296b 100644
--- a/shared/systemd/src/basic/io-util.c
+++ b/shared/systemd/src/basic/io-util.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <errno.h>
#include <limits.h>
@@ -291,7 +291,7 @@ int iovw_put(struct iovec_wrapper *iovw, void *data, size_t len) {
return -E2BIG;
if (!GREEDY_REALLOC(iovw->iovec, iovw->size_bytes, iovw->count + 1))
- return log_oom();
+ return -ENOMEM;
iovw->iovec[iovw->count++] = IOVEC_MAKE(data, len);
return 0;
@@ -303,7 +303,7 @@ int iovw_put_string_field(struct iovec_wrapper *iovw, const char *field, const c
x = strjoin(field, value);
if (!x)
- return log_oom();
+ return -ENOMEM;
r = iovw_put(iovw, x, strlen(x));
if (r >= 0)
diff --git a/shared/systemd/src/basic/io-util.h b/shared/systemd/src/basic/io-util.h
index 719e19e85d..d817714b05 100644
--- a/shared/systemd/src/basic/io-util.h
+++ b/shared/systemd/src/basic/io-util.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <stdbool.h>
diff --git a/shared/systemd/src/basic/list.h b/shared/systemd/src/basic/list.h
index b62c374985..256b7187c2 100644
--- a/shared/systemd/src/basic/list.h
+++ b/shared/systemd/src/basic/list.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include "macro.h"
diff --git a/shared/systemd/src/basic/log.h b/shared/systemd/src/basic/log.h
index ce8bb42ea1..41d828fd98 100644
--- a/shared/systemd/src/basic/log.h
+++ b/shared/systemd/src/basic/log.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <stdarg.h>
@@ -44,10 +44,17 @@ typedef enum LogTarget{
#define ERRNO_VALUE(val) (abs(val) & 255)
void log_set_target(LogTarget target);
+
void log_set_max_level_realm(LogRealm realm, int level);
+
#define log_set_max_level(level) \
log_set_max_level_realm(LOG_REALM, (level))
+static inline void log_set_max_level_all_realms(int level) {
+ for (LogRealm realm = 0; realm < _LOG_REALM_MAX; realm++)
+ log_set_max_level_realm(realm, level);
+}
+
void log_set_facility(int facility);
int log_set_target_from_string(const char *e);
@@ -161,7 +168,7 @@ int log_struct_internal(
const char *format, ...) _printf_(6,0) _sentinel_;
int log_oom_internal(
- LogRealm realm,
+ int level,
const char *file,
int line,
const char *func);
@@ -279,7 +286,8 @@ int log_emergency_level(void);
log_dump_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, level), \
0, PROJECT_FILE, __LINE__, __func__, buffer)
-#define log_oom() log_oom_internal(LOG_REALM, PROJECT_FILE, __LINE__, __func__)
+#define log_oom() log_oom_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, LOG_ERR), PROJECT_FILE, __LINE__, __func__)
+#define log_oom_debug() log_oom_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, LOG_DEBUG), PROJECT_FILE, __LINE__, __func__)
bool log_on_console(void) _pure_;
diff --git a/shared/systemd/src/basic/macro.h b/shared/systemd/src/basic/macro.h
index 41c2c3289e..2782553756 100644
--- a/shared/systemd/src/basic/macro.h
+++ b/shared/systemd/src/basic/macro.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <assert.h>
@@ -93,6 +93,10 @@
#endif
/* Temporarily disable some warnings */
+#define DISABLE_WARNING_DEPRECATED_DECLARATIONS \
+ _Pragma("GCC diagnostic push"); \
+ _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
+
#define DISABLE_WARNING_FORMAT_NONLITERAL \
_Pragma("GCC diagnostic push"); \
_Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"")
@@ -277,6 +281,12 @@ static inline size_t GREEDY_ALLOC_ROUND_UP(size_t l) {
MAX(_c, z); \
})
+#define MAX4(x, y, z, a) \
+ ({ \
+ const typeof(x) _d = MAX3(x, y, z); \
+ MAX(_d, a); \
+ })
+
#undef MIN
#define MIN(a, b) __MIN(UNIQ, (a), UNIQ, (b))
#define __MIN(aq, a, bq, b) \
@@ -440,6 +450,9 @@ static inline int __coverity_check_and_return__(int condition) {
#define PTR_TO_ULONG(p) ((unsigned long) ((uintptr_t) (p)))
#define ULONG_TO_PTR(u) ((void *) ((uintptr_t) (u)))
+#define PTR_TO_UINT8(p) ((uint8_t) ((uintptr_t) (p)))
+#define UINT8_TO_PTR(u) ((void *) ((uintptr_t) (u)))
+
#define PTR_TO_INT32(p) ((int32_t) ((intptr_t) (p)))
#define INT32_TO_PTR(u) ((void *) ((intptr_t) (u)))
#define PTR_TO_UINT32(p) ((uint32_t) ((uintptr_t) (p)))
@@ -541,10 +554,13 @@ static inline int __coverity_check_and_return__(int condition) {
#define STRV_MAKE(...) ((char**) ((const char*[]) { __VA_ARGS__, NULL }))
#define STRV_MAKE_EMPTY ((char*[1]) { NULL })
-/* Iterates through a specified list of pointers. Accepts NULL pointers, but uses (void*) -1 as internal marker for EOL. */
-#define FOREACH_POINTER(p, x, ...) \
- for (typeof(p) *_l = (typeof(p)[]) { ({ p = x; }), ##__VA_ARGS__, (void*) -1 }; \
- p != (typeof(p)) (void*) -1; \
+/* Pointers range from NULL to POINTER_MAX */
+#define POINTER_MAX ((void*) UINTPTR_MAX)
+
+/* Iterates through a specified list of pointers. Accepts NULL pointers, but uses POINTER_MAX as internal marker for EOL. */
+#define FOREACH_POINTER(p, x, ...) \
+ for (typeof(p) *_l = (typeof(p)[]) { ({ p = x; }), ##__VA_ARGS__, POINTER_MAX }; \
+ p != (typeof(p)) POINTER_MAX; \
p = *(++_l))
/* Define C11 thread_local attribute even on older gcc compiler
@@ -634,4 +650,8 @@ static inline int __coverity_check_and_return__(int condition) {
_copy; \
})
+static inline size_t size_add(size_t x, size_t y) {
+ return y >= SIZE_MAX - x ? SIZE_MAX : x + y;
+}
+
#include "log.h"
diff --git a/shared/systemd/src/basic/memory-util.c b/shared/systemd/src/basic/memory-util.c
index 5f327ef0d7..3338e355f7 100644
--- a/shared/systemd/src/basic/memory-util.c
+++ b/shared/systemd/src/basic/memory-util.c
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
#include <unistd.h>
#include "memory-util.h"
diff --git a/shared/systemd/src/basic/memory-util.h b/shared/systemd/src/basic/memory-util.h
index 4f596cffb7..179edd247b 100644
--- a/shared/systemd/src/basic/memory-util.h
+++ b/shared/systemd/src/basic/memory-util.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <inttypes.h>
diff --git a/shared/systemd/src/basic/mempool.c b/shared/systemd/src/basic/mempool.c
index 22df42105b..9eedc20c4f 100644
--- a/shared/systemd/src/basic/mempool.c
+++ b/shared/systemd/src/basic/mempool.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <stdint.h>
#include <stdlib.h>
diff --git a/shared/systemd/src/basic/mempool.h b/shared/systemd/src/basic/mempool.h
index 0eecca0f92..0fe2f2789c 100644
--- a/shared/systemd/src/basic/mempool.h
+++ b/shared/systemd/src/basic/mempool.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <stdbool.h>
diff --git a/shared/systemd/src/basic/missing_fcntl.h b/shared/systemd/src/basic/missing_fcntl.h
index 5d1c6352f4..00937d2af0 100644
--- a/shared/systemd/src/basic/missing_fcntl.h
+++ b/shared/systemd/src/basic/missing_fcntl.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <fcntl.h>
diff --git a/shared/systemd/src/basic/missing_random.h b/shared/systemd/src/basic/missing_random.h
index 17af87a3ae..443b913685 100644
--- a/shared/systemd/src/basic/missing_random.h
+++ b/shared/systemd/src/basic/missing_random.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#if USE_SYS_RANDOM_H
diff --git a/shared/systemd/src/basic/missing_socket.h b/shared/systemd/src/basic/missing_socket.h
index c4f33449a3..30ac297e17 100644
--- a/shared/systemd/src/basic/missing_socket.h
+++ b/shared/systemd/src/basic/missing_socket.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <sys/socket.h>
@@ -67,6 +67,14 @@ struct sockaddr_vm {
#define IPV6_FREEBIND 78
#endif
+#ifndef IP_RECVFRAGSIZE
+#define IP_RECVFRAGSIZE 25
+#endif
+
+#ifndef IPV6_RECVFRAGSIZE
+#define IPV6_RECVFRAGSIZE 77
+#endif
+
/* linux/sockios.h */
#ifndef SIOCGSKNS
#define SIOCGSKNS 0x894C
diff --git a/shared/systemd/src/basic/missing_stat.h b/shared/systemd/src/basic/missing_stat.h
index 7bdc8a7efa..372fdf90bd 100644
--- a/shared/systemd/src/basic/missing_stat.h
+++ b/shared/systemd/src/basic/missing_stat.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <linux/types.h>
diff --git a/shared/systemd/src/basic/missing_syscall.h b/shared/systemd/src/basic/missing_syscall.h
index 7427b632ac..06166b3fb3 100644
--- a/shared/systemd/src/basic/missing_syscall.h
+++ b/shared/systemd/src/basic/missing_syscall.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
/* Missing glibc definitions to access certain kernel APIs */
@@ -15,6 +15,26 @@
#include <asm/sgidefs.h>
#endif
+#if defined(__alpha__)
+# define systemd_SC_arch_bias(x) (110 + (x))
+#elif defined(__ia64__)
+# define systemd_SC_arch_bias(x) (1024 + (x))
+#elif defined(_MIPS_SIM)
+# if _MIPS_SIM == _MIPS_SIM_ABI32
+# define systemd_SC_arch_bias(x) (4000 + (x))
+# elif _MIPS_SIM == _MIPS_SIM_NABI32
+# define systemd_SC_arch_bias(x) (6000 + (x))
+# elif _MIPS_SIM == _MIPS_SIM_ABI64
+# define systemd_SC_arch_bias(x) (5000 + (x))
+# else
+# error "Unknown MIPS ABI"
+# endif
+#elif defined(__x86_64__) && defined(__ILP32__)
+# define systemd_SC_arch_bias(x) ((x) | /* __X32_SYSCALL_BIT */ 0x40000000)
+#else
+# define systemd_SC_arch_bias(x) (x)
+#endif
+
#include "missing_keyctl.h"
#include "missing_stat.h"
@@ -33,32 +53,38 @@ static inline int missing_pivot_root(const char *new_root, const char *put_old)
/* ======================================================================= */
-#if defined __x86_64__
-# define systemd_NR_memfd_create 319
-#elif defined __arm__
-# define systemd_NR_memfd_create 385
-#elif defined __aarch64__
+#if defined(__aarch64__)
# define systemd_NR_memfd_create 279
+#elif defined(__alpha__)
+# define systemd_NR_memfd_create 512
+#elif defined(__arc__) || defined(__tilegx__)
+# define systemd_NR_memfd_create 279
+#elif defined(__arm__)
+# define systemd_NR_memfd_create 385
+#elif defined(__i386__)
+# define systemd_NR_memfd_create 356
+#elif defined(__ia64__)
+# define systemd_NR_memfd_create systemd_SC_arch_bias(316)
+#elif defined(__m68k__)
+# define systemd_NR_memfd_create 353
+#elif defined(_MIPS_SIM)
+# if _MIPS_SIM == _MIPS_SIM_ABI32
+# define systemd_NR_memfd_create systemd_SC_arch_bias(354)
+# elif _MIPS_SIM == _MIPS_SIM_NABI32
+# define systemd_NR_memfd_create systemd_SC_arch_bias(318)
+# elif _MIPS_SIM == _MIPS_SIM_ABI64
+# define systemd_NR_memfd_create systemd_SC_arch_bias(314)
+# endif
#elif defined(__powerpc__)
# define systemd_NR_memfd_create 360
-#elif defined __s390__
+#elif defined(__s390__)
# define systemd_NR_memfd_create 350
-#elif defined _MIPS_SIM
-# if _MIPS_SIM == _MIPS_SIM_ABI32
-# define systemd_NR_memfd_create 4354
-# endif
-# if _MIPS_SIM == _MIPS_SIM_NABI32
-# define systemd_NR_memfd_create 6318
-# endif
-# if _MIPS_SIM == _MIPS_SIM_ABI64
-# define systemd_NR_memfd_create 5314
-# endif
-#elif defined __i386__
-# define systemd_NR_memfd_create 356
-#elif defined __arc__
-# define systemd_NR_memfd_create 279
+#elif defined(__sparc__)
+# define systemd_NR_memfd_create 348
+#elif defined(__x86_64__)
+# define systemd_NR_memfd_create systemd_SC_arch_bias(319)
#else
-# warning "memfd_create() syscall number unknown for your architecture"
+# warning "memfd_create() syscall number is unknown for your architecture"
#endif
/* may be (invalid) negative number due to libseccomp, see PR 13319 */
@@ -90,36 +116,38 @@ static inline int missing_memfd_create(const char *name, unsigned int flags) {
/* ======================================================================= */
-#if defined __x86_64__
-# define systemd_NR_getrandom 318
-#elif defined(__i386__)
-# define systemd_NR_getrandom 355
+#if defined(__aarch64__)
+# define systemd_NR_getrandom 278
+#elif defined(__alpha__)
+# define systemd_NR_getrandom 511
+#elif defined(__arc__) || defined(__tilegx__)
+# define systemd_NR_getrandom 278
#elif defined(__arm__)
# define systemd_NR_getrandom 384
-#elif defined(__aarch64__)
-# define systemd_NR_getrandom 278
+#elif defined(__i386__)
+# define systemd_NR_getrandom 355
#elif defined(__ia64__)
-# define systemd_NR_getrandom 1339
+# define systemd_NR_getrandom systemd_SC_arch_bias(318)
#elif defined(__m68k__)
# define systemd_NR_getrandom 352
-#elif defined(__s390x__)
-# define systemd_NR_getrandom 349
-#elif defined(__powerpc__)
-# define systemd_NR_getrandom 359
-#elif defined _MIPS_SIM
+#elif defined(_MIPS_SIM)
# if _MIPS_SIM == _MIPS_SIM_ABI32
-# define systemd_NR_getrandom 4353
-# endif
-# if _MIPS_SIM == _MIPS_SIM_NABI32
-# define systemd_NR_getrandom 6317
+# define systemd_NR_getrandom systemd_SC_arch_bias(353)
+# elif _MIPS_SIM == _MIPS_SIM_NABI32
+# define systemd_NR_getrandom systemd_SC_arch_bias(317)
+# elif _MIPS_SIM == _MIPS_SIM_ABI64
+# define systemd_NR_getrandom systemd_SC_arch_bias(313)
# endif
-# if _MIPS_SIM == _MIPS_SIM_ABI64
-# define systemd_NR_getrandom 5313
-# endif
-#elif defined(__arc__)
-# define systemd_NR_getrandom 278
+#elif defined(__powerpc__)
+# define systemd_NR_getrandom 359
+#elif defined(__s390__)
+# define systemd_NR_getrandom 349
+#elif defined(__sparc__)
+# define systemd_NR_getrandom 347
+#elif defined(__x86_64__)
+# define systemd_NR_getrandom systemd_SC_arch_bias(318)
#else
-# warning "getrandom() syscall number unknown for your architecture"
+# warning "getrandom() syscall number is unknown for your architecture"
#endif
/* may be (invalid) negative number due to libseccomp, see PR 13319 */
@@ -166,22 +194,38 @@ static inline pid_t missing_gettid(void) {
/* ======================================================================= */
-#if defined(__x86_64__)
-# define systemd_NR_name_to_handle_at 303
-#elif defined(__i386__)
-# define systemd_NR_name_to_handle_at 341
+#if defined(__aarch64__)
+# define systemd_NR_name_to_handle_at 264
+#elif defined(__alpha__)
+# define systemd_NR_name_to_handle_at 497
+#elif defined(__arc__) || defined(__tilegx__)
+# define systemd_NR_name_to_handle_at 264
#elif defined(__arm__)
# define systemd_NR_name_to_handle_at 370
-#elif defined __aarch64__
-# define systemd_NR_name_to_handle_at 264
+#elif defined(__i386__)
+# define systemd_NR_name_to_handle_at 341
+#elif defined(__ia64__)
+# define systemd_NR_name_to_handle_at systemd_SC_arch_bias(302)
+#elif defined(__m68k__)
+# define systemd_NR_name_to_handle_at 340
+#elif defined(_MIPS_SIM)
+# if _MIPS_SIM == _MIPS_SIM_ABI32
+# define systemd_NR_name_to_handle_at systemd_SC_arch_bias(339)
+# elif _MIPS_SIM == _MIPS_SIM_NABI32
+# define systemd_NR_name_to_handle_at systemd_SC_arch_bias(303)
+# elif _MIPS_SIM == _MIPS_SIM_ABI64
+# define systemd_NR_name_to_handle_at systemd_SC_arch_bias(298)
+# endif
#elif defined(__powerpc__)
# define systemd_NR_name_to_handle_at 345
-#elif defined __s390__ || defined __s390x__
+#elif defined(__s390__)
# define systemd_NR_name_to_handle_at 335
-#elif defined(__arc__)
-# define systemd_NR_name_to_handle_at 264
+#elif defined(__sparc__)
+# define systemd_NR_name_to_handle_at 332
+#elif defined(__x86_64__)
+# define systemd_NR_name_to_handle_at systemd_SC_arch_bias(303)
#else
-# warning "name_to_handle_at number is not defined"
+# warning "name_to_handle_at() syscall number is unknown for your architecture"
#endif
/* may be (invalid) negative number due to libseccomp, see PR 13319 */
@@ -219,22 +263,38 @@ static inline int missing_name_to_handle_at(int fd, const char *name, struct fil
/* ======================================================================= */
-#if defined __aarch64__
+#if defined(__aarch64__)
+# define systemd_NR_setns 268
+#elif defined(__alpha__)
+# define systemd_NR_setns 501
+#elif defined(__arc__) || defined(__tilegx__)
# define systemd_NR_setns 268
-#elif defined __arm__
+#elif defined(__arm__)
# define systemd_NR_setns 375
-#elif defined(__x86_64__)
-# define systemd_NR_setns 308
#elif defined(__i386__)
# define systemd_NR_setns 346
+#elif defined(__ia64__)
+# define systemd_NR_setns systemd_SC_arch_bias(306)
+#elif defined(__m68k__)
+# define systemd_NR_setns 344
+#elif defined(_MIPS_SIM)
+# if _MIPS_SIM == _MIPS_SIM_ABI32
+# define systemd_NR_setns systemd_SC_arch_bias(344)
+# elif _MIPS_SIM == _MIPS_SIM_NABI32
+# define systemd_NR_setns systemd_SC_arch_bias(308)
+# elif _MIPS_SIM == _MIPS_SIM_ABI64
+# define systemd_NR_setns systemd_SC_arch_bias(303)
+# endif
#elif defined(__powerpc__)
# define systemd_NR_setns 350
-#elif defined __s390__ || defined __s390x__
+#elif defined(__s390__)
# define systemd_NR_setns 339
-#elif defined(__arc__)
-# define systemd_NR_setns 268
+#elif defined(__sparc__)
+# define systemd_NR_setns 337
+#elif defined(__x86_64__)
+# define systemd_NR_setns systemd_SC_arch_bias(308)
#else
-# warning "setns() syscall number unknown for your architecture"
+# warning "setns() syscall number is unknown for your architecture"
#endif
/* may be (invalid) negative number due to libseccomp, see PR 13319 */
@@ -276,32 +336,38 @@ static inline pid_t raw_getpid(void) {
/* ======================================================================= */
-#if defined __x86_64__
-# define systemd_NR_renameat2 316
-#elif defined __arm__
-# define systemd_NR_renameat2 382
-#elif defined __aarch64__
+#if defined(__aarch64__)
+# define systemd_NR_renameat2 276
+#elif defined(__alpha__)
+# define systemd_NR_renameat2 510
+#elif defined(__arc__) || defined(__tilegx__)
# define systemd_NR_renameat2 276
-#elif defined _MIPS_SIM
+#elif defined(__arm__)
+# define systemd_NR_renameat2 382
+#elif defined(__i386__)
+# define systemd_NR_renameat2 353
+#elif defined(__ia64__)
+# define systemd_NR_renameat2 systemd_SC_arch_bias(314)
+#elif defined(__m68k__)
+# define systemd_NR_renameat2 351
+#elif defined(_MIPS_SIM)
# if _MIPS_SIM == _MIPS_SIM_ABI32
-# define systemd_NR_renameat2 4351
-# endif
-# if _MIPS_SIM == _MIPS_SIM_NABI32
-# define systemd_NR_renameat2 6315
-# endif
-# if _MIPS_SIM == _MIPS_SIM_ABI64
-# define systemd_NR_renameat2 5311
+# define systemd_NR_renameat2 systemd_SC_arch_bias(351)
+# elif _MIPS_SIM == _MIPS_SIM_NABI32
+# define systemd_NR_renameat2 systemd_SC_arch_bias(315)
+# elif _MIPS_SIM == _MIPS_SIM_ABI64
+# define systemd_NR_renameat2 systemd_SC_arch_bias(311)
# endif
-#elif defined __i386__
-# define systemd_NR_renameat2 353
-#elif defined __powerpc64__
+#elif defined(__powerpc__)
# define systemd_NR_renameat2 357
-#elif defined __s390__ || defined __s390x__
+#elif defined(__s390__)
# define systemd_NR_renameat2 347
-#elif defined __arc__
-# define systemd_NR_renameat2 276
+#elif defined(__sparc__)
+# define systemd_NR_renameat2 345
+#elif defined(__x86_64__)
+# define systemd_NR_renameat2 systemd_SC_arch_bias(316)
#else
-# warning "renameat2() syscall number unknown for your architecture"
+# warning "renameat2() syscall number is unknown for your architecture"
#endif
/* may be (invalid) negative number due to libseccomp, see PR 13319 */
@@ -385,22 +451,38 @@ static inline key_serial_t missing_request_key(const char *type, const char *des
/* ======================================================================= */
-#if defined(__x86_64__)
-# define systemd_NR_copy_file_range 326
+#if defined(__aarch64__)
+# define systemd_NR_copy_file_range 285
+#elif defined(__alpha__)
+# define systemd_NR_copy_file_range 519
+#elif defined(__arc__) || defined(__tilegx__)
+# define systemd_NR_copy_file_range 285
+#elif defined(__arm__)
+# define systemd_NR_copy_file_range 391
#elif defined(__i386__)
# define systemd_NR_copy_file_range 377
-#elif defined __s390__
-# define systemd_NR_copy_file_range 375
-#elif defined __arm__
-# define systemd_NR_copy_file_range 391
-#elif defined __aarch64__
-# define systemd_NR_copy_file_range 285
-#elif defined __powerpc__
+#elif defined(__ia64__)
+# define systemd_NR_copy_file_range systemd_SC_arch_bias(323)
+#elif defined(__m68k__)
+# define systemd_NR_copy_file_range 376
+#elif defined(_MIPS_SIM)
+# if _MIPS_SIM == _MIPS_SIM_ABI32
+# define systemd_NR_copy_file_range systemd_SC_arch_bias(360)
+# elif _MIPS_SIM == _MIPS_SIM_NABI32
+# define systemd_NR_copy_file_range systemd_SC_arch_bias(324)
+# elif _MIPS_SIM == _MIPS_SIM_ABI64
+# define systemd_NR_copy_file_range systemd_SC_arch_bias(320)
+# endif
+#elif defined(__powerpc__)
# define systemd_NR_copy_file_range 379
-#elif defined __arc__
-# define systemd_NR_copy_file_range 285
+#elif defined(__s390__)
+# define systemd_NR_copy_file_range 375
+#elif defined(__sparc__)
+# define systemd_NR_copy_file_range 357
+#elif defined(__x86_64__)
+# define systemd_NR_copy_file_range systemd_SC_arch_bias(326)
#else
-# warning "copy_file_range() syscall number unknown for your architecture"
+# warning "copy_file_range() syscall number is unknown for your architecture"
#endif
/* may be (invalid) negative number due to libseccomp, see PR 13319 */
@@ -435,24 +517,38 @@ static inline ssize_t missing_copy_file_range(int fd_in, loff_t *off_in,
/* ======================================================================= */
-#if defined __i386__
-# define systemd_NR_bpf 357
-#elif defined __x86_64__
-# define systemd_NR_bpf 321
-#elif defined __aarch64__
+#if defined(__aarch64__)
+# define systemd_NR_bpf 280
+#elif defined(__alpha__)
+# define systemd_NR_bpf 515
+#elif defined(__arc__) || defined(__tilegx__)
# define systemd_NR_bpf 280
-#elif defined __arm__
+#elif defined(__arm__)
# define systemd_NR_bpf 386
+#elif defined(__i386__)
+# define systemd_NR_bpf 357
+#elif defined(__ia64__)
+# define systemd_NR_bpf systemd_SC_arch_bias(317)
+#elif defined(__m68k__)
+# define systemd_NR_bpf 354
+#elif defined(_MIPS_SIM)
+# if _MIPS_SIM == _MIPS_SIM_ABI32
+# define systemd_NR_bpf systemd_SC_arch_bias(355)
+# elif _MIPS_SIM == _MIPS_SIM_NABI32
+# define systemd_NR_bpf systemd_SC_arch_bias(319)
+# elif _MIPS_SIM == _MIPS_SIM_ABI64
+# define systemd_NR_bpf systemd_SC_arch_bias(315)
+# endif
#elif defined(__powerpc__)
# define systemd_NR_bpf 361
-#elif defined __sparc__
-# define systemd_NR_bpf 349
-#elif defined __s390__
+#elif defined(__s390__)
# define systemd_NR_bpf 351
-#elif defined __tilegx__
-# define systemd_NR_bpf 280
+#elif defined(__sparc__)
+# define systemd_NR_bpf 349
+#elif defined(__x86_64__)
+# define systemd_NR_bpf systemd_SC_arch_bias(321)
#else
-# warning "bpf() syscall number unknown for your architecture"
+# warning "bpf() syscall number is unknown for your architecture"
#endif
/* may be (invalid) negative number due to libseccomp, see PR 13319 */
@@ -487,30 +583,38 @@ static inline int missing_bpf(int cmd, union bpf_attr *attr, size_t size) {
/* ======================================================================= */
#ifndef __IGNORE_pkey_mprotect
-# if defined __i386__
-# define systemd_NR_pkey_mprotect 380
-# elif defined __x86_64__
-# define systemd_NR_pkey_mprotect 329
-# elif defined __aarch64__
+# if defined(__aarch64__)
# define systemd_NR_pkey_mprotect 288
-# elif defined __arm__
+# elif defined(__alpha__)
+# define systemd_NR_pkey_mprotect 524
+# elif defined(__arc__) || defined(__tilegx__)
+# define systemd_NR_pkey_mprotect 226
+# elif defined(__arm__)
# define systemd_NR_pkey_mprotect 394
-# elif defined __powerpc__
-# define systemd_NR_pkey_mprotect 386
-# elif defined __s390__
-# define systemd_NR_pkey_mprotect 384
-# elif defined _MIPS_SIM
+# elif defined(__i386__)
+# define systemd_NR_pkey_mprotect 380
+# elif defined(__ia64__)
+# define systemd_NR_pkey_mprotect systemd_SC_arch_bias(330)
+# elif defined(__m68k__)
+# define systemd_NR_pkey_mprotect 381
+# elif defined(_MIPS_SIM)
# if _MIPS_SIM == _MIPS_SIM_ABI32
-# define systemd_NR_pkey_mprotect 4363
-# endif
-# if _MIPS_SIM == _MIPS_SIM_NABI32
-# define systemd_NR_pkey_mprotect 6327
-# endif
-# if _MIPS_SIM == _MIPS_SIM_ABI64
-# define systemd_NR_pkey_mprotect 5323
+# define systemd_NR_pkey_mprotect systemd_SC_arch_bias(363)
+# elif _MIPS_SIM == _MIPS_SIM_NABI32
+# define systemd_NR_pkey_mprotect systemd_SC_arch_bias(327)
+# elif _MIPS_SIM == _MIPS_SIM_ABI64
+# define systemd_NR_pkey_mprotect systemd_SC_arch_bias(323)
# endif
+# elif defined(__powerpc__)
+# define systemd_NR_pkey_mprotect 386
+# elif defined(__s390__)
+# define systemd_NR_pkey_mprotect 384
+# elif defined(__sparc__)
+# define systemd_NR_pkey_mprotect 362
+# elif defined(__x86_64__)
+# define systemd_NR_pkey_mprotect systemd_SC_arch_bias(329)
# else
-# warning "pkey_mprotect() syscall number unknown for your architecture"
+# warning "pkey_mprotect() syscall number is unknown for your architecture"
# endif
/* may be (invalid) negative number due to libseccomp, see PR 13319 */
@@ -530,22 +634,38 @@ assert_cc(__NR_pkey_mprotect == systemd_NR_pkey_mprotect);
/* ======================================================================= */
-#if defined __aarch64__
+#if defined(__aarch64__)
# define systemd_NR_statx 291
-#elif defined __arm__
-# define systemd_NR_statx 397
-#elif defined __alpha__
+#elif defined(__alpha__)
# define systemd_NR_statx 522
-#elif defined __i386__ || defined __powerpc64__
+#elif defined(__arc__) || defined(__tilegx__)
+# define systemd_NR_statx 291
+#elif defined(__arm__)
+# define systemd_NR_statx 397
+#elif defined(__i386__)
# define systemd_NR_statx 383
-#elif defined __s390__ || defined __s390x__
+#elif defined(__ia64__)
+# define systemd_NR_statx systemd_SC_arch_bias(326)
+#elif defined(__m68k__)
# define systemd_NR_statx 379
-#elif defined __sparc__
+#elif defined(_MIPS_SIM)
+# if _MIPS_SIM == _MIPS_SIM_ABI32
+# define systemd_NR_statx systemd_SC_arch_bias(366)
+# elif _MIPS_SIM == _MIPS_SIM_NABI32
+# define systemd_NR_statx systemd_SC_arch_bias(330)
+# elif _MIPS_SIM == _MIPS_SIM_ABI64
+# define systemd_NR_statx systemd_SC_arch_bias(326)
+# endif
+#elif defined(__powerpc__)
+# define systemd_NR_statx 383
+#elif defined(__s390__)
+# define systemd_NR_statx 379
+#elif defined(__sparc__)
# define systemd_NR_statx 360
-#elif defined __x86_64__
-# define systemd_NR_statx 332
+#elif defined(__x86_64__)
+# define systemd_NR_statx systemd_SC_arch_bias(332)
#else
-# warning "statx() syscall number unknown for your architecture"
+# warning "statx() syscall number is unknown for your architecture"
#endif
/* may be (invalid) negative number due to libseccomp, see PR 13319 */
@@ -628,23 +748,7 @@ static inline long missing_get_mempolicy(int *mode, unsigned long *nodemask,
/* ======================================================================= */
/* should be always defined, see kernel 39036cd2727395c3369b1051005da74059a85317 */
-#if defined __alpha__
-# define systemd_NR_pidfd_send_signal 534
-#elif defined _MIPS_SIM
-# if _MIPS_SIM == _MIPS_SIM_ABI32 /* o32 */
-# define systemd_NR_pidfd_send_signal (424 + 4000)
-# endif
-# if _MIPS_SIM == _MIPS_SIM_NABI32 /* n32 */
-# define systemd_NR_pidfd_send_signal (424 + 6000)
-# endif
-# if _MIPS_SIM == _MIPS_SIM_ABI64 /* n64 */
-# define systemd_NR_pidfd_send_signal (424 + 5000)
-# endif
-#elif defined __ia64__
-# define systemd_NR_pidfd_send_signal (424 + 1024)
-#else
-# define systemd_NR_pidfd_send_signal 424
-#endif
+#define systemd_NR_pidfd_send_signal systemd_SC_arch_bias(424)
/* may be (invalid) negative number due to libseccomp, see PR 13319 */
#if defined __NR_pidfd_send_signal && __NR_pidfd_send_signal >= 0
@@ -660,7 +764,7 @@ assert_cc(__NR_pidfd_send_signal == systemd_NR_pidfd_send_signal);
#if !HAVE_PIDFD_SEND_SIGNAL
static inline int missing_pidfd_send_signal(int fd, int sig, siginfo_t *info, unsigned flags) {
-# ifdef __NR_pidfd_open
+# ifdef __NR_pidfd_send_signal
return syscall(__NR_pidfd_send_signal, fd, sig, info, flags);
# else
errno = ENOSYS;
@@ -672,23 +776,7 @@ static inline int missing_pidfd_send_signal(int fd, int sig, siginfo_t *info, un
#endif
/* should be always defined, see kernel 7615d9e1780e26e0178c93c55b73309a5dc093d7 */
-#if defined __alpha__
-# define systemd_NR_pidfd_open 544
-#elif defined _MIPS_SIM
-# if _MIPS_SIM == _MIPS_SIM_ABI32 /* o32 */
-# define systemd_NR_pidfd_open (434 + 4000)
-# endif
-# if _MIPS_SIM == _MIPS_SIM_NABI32 /* n32 */
-# define systemd_NR_pidfd_open (434 + 6000)
-# endif
-# if _MIPS_SIM == _MIPS_SIM_ABI64 /* n64 */
-# define systemd_NR_pidfd_open (434 + 5000)
-# endif
-#elif defined __ia64__
-# define systemd_NR_pidfd_open (434 + 1024)
-#else
-# define systemd_NR_pidfd_open 434
-#endif
+#define systemd_NR_pidfd_open systemd_SC_arch_bias(434)
/* may be (invalid) negative number due to libseccomp, see PR 13319 */
#if defined __NR_pidfd_open && __NR_pidfd_open >= 0
@@ -728,3 +816,68 @@ static inline int missing_rt_sigqueueinfo(pid_t tgid, int sig, siginfo_t *info)
# define rt_sigqueueinfo missing_rt_sigqueueinfo
#endif
+
+/* ======================================================================= */
+
+#if !HAVE_EXECVEAT
+static inline int missing_execveat(int dirfd, const char *pathname,
+ char *const argv[], char *const envp[],
+ int flags) {
+# if defined __NR_execveat && __NR_execveat >= 0
+ return syscall(__NR_execveat, dirfd, pathname, argv, envp, flags);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+
+# undef AT_EMPTY_PATH
+# define AT_EMPTY_PATH 0x1000
+# define execveat missing_execveat
+#endif
+
+/* ======================================================================= */
+
+#define systemd_NR_close_range systemd_SC_arch_bias(436)
+
+/* may be (invalid) negative number due to libseccomp, see PR 13319 */
+#if defined __NR_close_range && __NR_close_range >= 0
+# if defined systemd_NR_close_range
+assert_cc(__NR_close_range == systemd_NR_close_range);
+# endif
+#else
+# if defined __NR_close_range
+# undef __NR_close_range
+# endif
+# if defined systemd_NR_close_range
+# define __NR_close_range systemd_NR_close_range
+# endif
+#endif
+
+#if !HAVE_CLOSE_RANGE
+static inline int missing_close_range(int first_fd, int end_fd, unsigned flags) {
+# ifdef __NR_close_range
+ /* Kernel-side the syscall expects fds as unsigned integers (just like close() actually), while
+ * userspace exclusively uses signed integers for fds. We don't know just yet how glibc is going to
+ * wrap this syscall, but let's assume it's going to be similar to what they do for close(),
+ * i.e. make the same unsigned → signed type change from the raw kernel syscall compared to the
+ * userspace wrapper. There's only one caveat for this: unlike for close() there's the special
+ * UINT_MAX fd value for the 'end_fd' argument. Let's safely map that to -1 here. And let's refuse
+ * any other negative values. */
+ if ((first_fd < 0) || (end_fd < 0 && end_fd != -1)) {
+ errno = -EBADF;
+ return -1;
+ }
+
+ return syscall(__NR_close_range,
+ (unsigned) first_fd,
+ end_fd == -1 ? UINT_MAX : (unsigned) end_fd, /* Of course, the compiler should figure out that this is the identity mapping IRL */
+ flags);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+
+# define close_range missing_close_range
+#endif
diff --git a/shared/systemd/src/basic/missing_type.h b/shared/systemd/src/basic/missing_type.h
index bf8a6caa1b..f6233090a9 100644
--- a/shared/systemd/src/basic/missing_type.h
+++ b/shared/systemd/src/basic/missing_type.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <uchar.h>
diff --git a/shared/systemd/src/basic/parse-util.c b/shared/systemd/src/basic/parse-util.c
index 818c9054d6..5d4dafe3a5 100644
--- a/shared/systemd/src/basic/parse-util.c
+++ b/shared/systemd/src/basic/parse-util.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <errno.h>
#include <inttypes.h>
@@ -862,3 +862,45 @@ int parse_oom_score_adjust(const char *s, int *ret) {
*ret = v;
return 0;
}
+
+int store_loadavg_fixed_point(unsigned long i, unsigned long f, loadavg_t *ret) {
+ assert(ret);
+
+ if (i >= (~0UL << FSHIFT))
+ return -ERANGE;
+
+ i = i << FSHIFT;
+ f = DIV_ROUND_UP((f << FSHIFT), 100);
+
+ if (f >= FIXED_1)
+ return -ERANGE;
+
+ *ret = i | f;
+ return 0;
+}
+
+int parse_loadavg_fixed_point(const char *s, loadavg_t *ret) {
+ const char *d, *f_str, *i_str;
+ unsigned long i, f;
+ int r;
+
+ assert(s);
+ assert(ret);
+
+ d = strchr(s, '.');
+ if (!d)
+ return -EINVAL;
+
+ i_str = strndupa(s, d - s);
+ f_str = d + 1;
+
+ r = safe_atolu_full(i_str, 10, &i);
+ if (r < 0)
+ return r;
+
+ r = safe_atolu_full(f_str, 10, &f);
+ if (r < 0)
+ return r;
+
+ return store_loadavg_fixed_point(i, f, ret);
+}
diff --git a/shared/systemd/src/basic/parse-util.h b/shared/systemd/src/basic/parse-util.h
index 2cee65c49a..81478ed059 100644
--- a/shared/systemd/src/basic/parse-util.h
+++ b/shared/systemd/src/basic/parse-util.h
@@ -1,14 +1,17 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <inttypes.h>
#include <limits.h>
+#include <linux/loadavg.h>
#include <stddef.h>
#include <stdint.h>
#include <sys/types.h>
#include "macro.h"
+typedef unsigned long loadavg_t;
+
int parse_boolean(const char *v) _pure_;
int parse_dev(const char *s, dev_t *ret);
int parse_pid(const char *s, pid_t* ret_pid);
@@ -88,18 +91,18 @@ static inline int safe_atoux64(const char *s, uint64_t *ret) {
}
#if LONG_MAX == INT_MAX
-static inline int safe_atolu(const char *s, unsigned long *ret_u) {
+static inline int safe_atolu_full(const char *s, unsigned base, long unsigned *ret_u) {
assert_cc(sizeof(unsigned long) == sizeof(unsigned));
- return safe_atou(s, (unsigned*) ret_u);
+ return safe_atou_full(s, base, (unsigned*) ret_u);
}
static inline int safe_atoli(const char *s, long int *ret_u) {
assert_cc(sizeof(long int) == sizeof(int));
return safe_atoi(s, (int*) ret_u);
}
#else
-static inline int safe_atolu(const char *s, unsigned long *ret_u) {
+static inline int safe_atolu_full(const char *s, unsigned base, unsigned long *ret_u) {
assert_cc(sizeof(unsigned long) == sizeof(unsigned long long));
- return safe_atollu(s, (unsigned long long*) ret_u);
+ return safe_atollu_full(s, base, (unsigned long long*) ret_u);
}
static inline int safe_atoli(const char *s, long int *ret_u) {
assert_cc(sizeof(long int) == sizeof(long long int));
@@ -107,6 +110,10 @@ static inline int safe_atoli(const char *s, long int *ret_u) {
}
#endif
+static inline int safe_atolu(const char *s, unsigned long *ret_u) {
+ return safe_atolu_full(s, 0, ret_u);
+}
+
#if SIZE_MAX == UINT_MAX
static inline int safe_atozu(const char *s, size_t *ret_u) {
assert_cc(sizeof(size_t) == sizeof(unsigned));
@@ -137,3 +144,8 @@ int parse_ip_port_range(const char *s, uint16_t *low, uint16_t *high);
int parse_ip_prefix_length(const char *s, int *ret);
int parse_oom_score_adjust(const char *s, int *ret);
+
+/* Given a Linux load average (e.g. decimal number 34.89 where 34 is passed as i and 89 is passed as f), convert it
+ * to a loadavg_t. */
+int store_loadavg_fixed_point(unsigned long i, unsigned long f, loadavg_t *ret);
+int parse_loadavg_fixed_point(const char *s, loadavg_t *ret);
diff --git a/shared/systemd/src/basic/path-util.c b/shared/systemd/src/basic/path-util.c
index a36cf8332c..dae8b7341a 100644
--- a/shared/systemd/src/basic/path-util.c
+++ b/shared/systemd/src/basic/path-util.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <errno.h>
#include <limits.h>
@@ -550,7 +550,7 @@ char* path_join_internal(const char *first, ...) {
sz = strlen_ptr(first);
va_start(ap, first);
- while ((p = va_arg(ap, char*)) != (const char*) -1)
+ while ((p = va_arg(ap, char*)) != POINTER_MAX)
if (!isempty(p))
sz += 1 + strlen(p);
va_end(ap);
@@ -570,7 +570,7 @@ char* path_join_internal(const char *first, ...) {
}
va_start(ap, first);
- while ((p = va_arg(ap, char*)) != (const char*) -1) {
+ while ((p = va_arg(ap, char*)) != POINTER_MAX) {
if (isempty(p))
continue;
@@ -585,22 +585,53 @@ char* path_join_internal(const char *first, ...) {
return joined;
}
-int find_executable_full(const char *name, bool use_path_envvar, char **ret) {
+static int check_x_access(const char *path, int *ret_fd) {
+ if (ret_fd) {
+ _cleanup_close_ int fd = -1;
+ int r;
+
+ /* We need to use O_PATH because there may be executables for which we have only exec
+ * permissions, but not read (usually suid executables). */
+ fd = open(path, O_PATH|O_CLOEXEC);
+ if (fd < 0)
+ return -errno;
+
+ r = access_fd(fd, X_OK);
+ if (r < 0)
+ return r;
+
+ *ret_fd = TAKE_FD(fd);
+ } else {
+ /* Let's optimize things a bit by not opening the file if we don't need the fd. */
+ if (access(path, X_OK) < 0)
+ return -errno;
+ }
+
+ return 0;
+}
+
+int find_executable_full(const char *name, bool use_path_envvar, char **ret_filename, int *ret_fd) {
int last_error, r;
const char *p = NULL;
assert(name);
if (is_path(name)) {
- if (access(name, X_OK) < 0)
- return -errno;
+ _cleanup_close_ int fd = -1;
- if (ret) {
- r = path_make_absolute_cwd(name, ret);
+ r = check_x_access(name, ret_fd ? &fd : NULL);
+ if (r < 0)
+ return r;
+
+ if (ret_filename) {
+ r = path_make_absolute_cwd(name, ret_filename);
if (r < 0)
return r;
}
+ if (ret_fd)
+ *ret_fd = TAKE_FD(fd);
+
return 0;
}
@@ -613,8 +644,10 @@ int find_executable_full(const char *name, bool use_path_envvar, char **ret) {
last_error = -ENOENT;
+ /* Resolve a single-component name to a full path */
for (;;) {
_cleanup_free_ char *j = NULL, *element = NULL;
+ _cleanup_close_ int fd = -1;
r = extract_first_word(&p, &element, ":", EXTRACT_RELAX|EXTRACT_DONT_COALESCE_SEPARATORS);
if (r < 0)
@@ -629,7 +662,8 @@ int find_executable_full(const char *name, bool use_path_envvar, char **ret) {
if (!j)
return -ENOMEM;
- if (access(j, X_OK) >= 0) {
+ r = check_x_access(j, ret_fd ? &fd : NULL);
+ if (r >= 0) {
_cleanup_free_ char *with_dash;
with_dash = strjoin(j, "/");
@@ -643,8 +677,10 @@ int find_executable_full(const char *name, bool use_path_envvar, char **ret) {
/* We can't just `continue` inverting this case, since we need to update last_error. */
if (errno == ENOTDIR) {
/* Found it! */
- if (ret)
- *ret = path_simplify(TAKE_PTR(j), false);
+ if (ret_filename)
+ *ret_filename = path_simplify(TAKE_PTR(j), false);
+ if (ret_fd)
+ *ret_fd = TAKE_FD(fd);
return 0;
}
diff --git a/shared/systemd/src/basic/path-util.h b/shared/systemd/src/basic/path-util.h
index bd8c14903e..e7a26c9a84 100644
--- a/shared/systemd/src/basic/path-util.h
+++ b/shared/systemd/src/basic/path-util.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <alloca.h>
@@ -62,7 +62,7 @@ int path_compare(const char *a, const char *b) _pure_;
bool path_equal(const char *a, const char *b) _pure_;
bool path_equal_or_files_same(const char *a, const char *b, int flags);
char* path_join_internal(const char *first, ...);
-#define path_join(x, ...) path_join_internal(x, __VA_ARGS__, (const char*) -1)
+#define path_join(x, ...) path_join_internal(x, __VA_ARGS__, POINTER_MAX)
char* path_simplify(char *path, bool kill_dots);
@@ -88,9 +88,9 @@ int path_strv_make_absolute_cwd(char **l);
char** path_strv_resolve(char **l, const char *root);
char** path_strv_resolve_uniq(char **l, const char *root);
-int find_executable_full(const char *name, bool use_path_envvar, char **ret);
-static inline int find_executable(const char *name, char **ret) {
- return find_executable_full(name, true, ret);
+int find_executable_full(const char *name, bool use_path_envvar, char **ret_filename, int *ret_fd);
+static inline int find_executable(const char *name, char **ret_filename) {
+ return find_executable_full(name, true, ret_filename, NULL);
}
bool paths_check_timestamp(const char* const* paths, usec_t *paths_ts_usec, bool update);
diff --git a/shared/systemd/src/basic/prioq.c b/shared/systemd/src/basic/prioq.c
index 76b27fa0a8..559e5d124d 100644
--- a/shared/systemd/src/basic/prioq.c
+++ b/shared/systemd/src/basic/prioq.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Priority Queue
diff --git a/shared/systemd/src/basic/prioq.h b/shared/systemd/src/basic/prioq.h
index 1fb57bfa4c..951576c021 100644
--- a/shared/systemd/src/basic/prioq.h
+++ b/shared/systemd/src/basic/prioq.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <stdbool.h>
diff --git a/shared/systemd/src/basic/process-util.c b/shared/systemd/src/basic/process-util.c
index 80f13048c1..0851613fc9 100644
--- a/shared/systemd/src/basic/process-util.c
+++ b/shared/systemd/src/basic/process-util.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <ctype.h>
#include <errno.h>
diff --git a/shared/systemd/src/basic/process-util.h b/shared/systemd/src/basic/process-util.h
index 49bb74ac0f..6144f142c4 100644
--- a/shared/systemd/src/basic/process-util.h
+++ b/shared/systemd/src/basic/process-util.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <errno.h>
diff --git a/shared/systemd/src/basic/random-util.c b/shared/systemd/src/basic/random-util.c
index 2031262389..c831f06dac 100644
--- a/shared/systemd/src/basic/random-util.c
+++ b/shared/systemd/src/basic/random-util.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#if defined(__i386__) || defined(__x86_64__)
#include <cpuid.h>
@@ -452,10 +452,21 @@ size_t random_pool_size(void) {
}
int random_write_entropy(int fd, const void *seed, size_t size, bool credit) {
+ _cleanup_close_ int opened_fd = -1;
int r;
- assert(fd >= 0);
- assert(seed && size > 0);
+ assert(seed || size == 0);
+
+ if (size == 0)
+ return 0;
+
+ if (fd < 0) {
+ opened_fd = open("/dev/urandom", O_WRONLY|O_CLOEXEC|O_NOCTTY);
+ if (opened_fd < 0)
+ return -errno;
+
+ fd = opened_fd;
+ }
if (credit) {
_cleanup_free_ struct rand_pool_info *info = NULL;
@@ -481,5 +492,5 @@ int random_write_entropy(int fd, const void *seed, size_t size, bool credit) {
return r;
}
- return 0;
+ return 1;
}
diff --git a/shared/systemd/src/basic/random-util.h b/shared/systemd/src/basic/random-util.h
index 7824ffaceb..f661fc093a 100644
--- a/shared/systemd/src/basic/random-util.h
+++ b/shared/systemd/src/basic/random-util.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <stdbool.h>
diff --git a/shared/systemd/src/basic/ratelimit.c b/shared/systemd/src/basic/ratelimit.c
new file mode 100644
index 0000000000..bae2ec3ffc
--- /dev/null
+++ b/shared/systemd/src/basic/ratelimit.c
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <sys/time.h>
+
+#include "macro.h"
+#include "ratelimit.h"
+
+/* Modelled after Linux' lib/ratelimit.c by Dave Young
+ * <hidave.darkstar@gmail.com>, which is licensed GPLv2. */
+
+bool ratelimit_below(RateLimit *r) {
+ usec_t ts;
+
+ assert(r);
+
+ if (!ratelimit_configured(r))
+ return true;
+
+ ts = now(CLOCK_MONOTONIC);
+
+ if (r->begin <= 0 ||
+ ts - r->begin > r->interval) {
+ r->begin = ts;
+
+ /* Reset counter */
+ r->num = 0;
+ goto good;
+ }
+
+ if (r->num < r->burst)
+ goto good;
+
+ return false;
+
+good:
+ r->num++;
+ return true;
+}
diff --git a/shared/systemd/src/basic/ratelimit.h b/shared/systemd/src/basic/ratelimit.h
new file mode 100644
index 0000000000..ee1d17c0e7
--- /dev/null
+++ b/shared/systemd/src/basic/ratelimit.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include <stdbool.h>
+
+#include "time-util.h"
+#include "util.h"
+
+typedef struct RateLimit {
+ usec_t interval; /* Keep those two fields first so they can be initialized easily: */
+ unsigned burst; /* RateLimit rl = { INTERVAL, BURST }; */
+ unsigned num;
+ usec_t begin;
+} RateLimit;
+
+static inline void ratelimit_reset(RateLimit *rl) {
+ rl->num = rl->begin = 0;
+}
+
+static inline bool ratelimit_configured(RateLimit *rl) {
+ return rl->interval > 0 && rl->burst > 0;
+}
+
+bool ratelimit_below(RateLimit *r);
diff --git a/shared/systemd/src/basic/set.h b/shared/systemd/src/basic/set.h
index 7170eea84c..57ff713039 100644
--- a/shared/systemd/src/basic/set.h
+++ b/shared/systemd/src/basic/set.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include "extract-word.h"
@@ -128,10 +128,12 @@ int _set_ensure_consume(Set **s, const struct hash_ops *hash_ops, void *key HAS
int set_consume(Set *s, void *value);
-int _set_put_strdup(Set **s, const char *p HASHMAP_DEBUG_PARAMS);
-#define set_put_strdup(s, p) _set_put_strdup(s, p HASHMAP_DEBUG_SRC_ARGS)
-int _set_put_strdupv(Set **s, char **l HASHMAP_DEBUG_PARAMS);
-#define set_put_strdupv(s, l) _set_put_strdupv(s, l HASHMAP_DEBUG_SRC_ARGS)
+int _set_put_strdup_full(Set **s, const struct hash_ops *hash_ops, const char *p HASHMAP_DEBUG_PARAMS);
+#define set_put_strdup_full(s, hash_ops, p) _set_put_strdup_full(s, hash_ops, p HASHMAP_DEBUG_SRC_ARGS)
+#define set_put_strdup(s, p) set_put_strdup_full(s, &string_hash_ops_free, p)
+int _set_put_strdupv_full(Set **s, const struct hash_ops *hash_ops, char **l HASHMAP_DEBUG_PARAMS);
+#define set_put_strdupv_full(s, hash_ops, l) _set_put_strdupv_full(s, hash_ops, l HASHMAP_DEBUG_SRC_ARGS)
+#define set_put_strdupv(s, l) set_put_strdupv_full(s, &string_hash_ops_free, l)
int set_put_strsplit(Set *s, const char *v, const char *separators, ExtractFlags flags);
@@ -148,3 +150,5 @@ 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, bool wrap_with_separator, char **ret);
diff --git a/shared/systemd/src/basic/signal-util.c b/shared/systemd/src/basic/signal-util.c
index cb59f6ca0f..63b833b218 100644
--- a/shared/systemd/src/basic/signal-util.c
+++ b/shared/systemd/src/basic/signal-util.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <errno.h>
#include <stdarg.h>
@@ -49,16 +49,7 @@ static int sigaction_many_ap(const struct sigaction *sa, int sig, va_list ap) {
int r = 0;
/* negative signal ends the list. 0 signal is skipped. */
-
- if (sig < 0)
- return 0;
-
- if (sig > 0) {
- if (sigaction(sig, sa, NULL) < 0)
- r = -errno;
- }
-
- while ((sig = va_arg(ap, int)) >= 0) {
+ for (; sig >= 0; sig = va_arg(ap, int)) {
if (sig == 0)
continue;
diff --git a/shared/systemd/src/basic/signal-util.h b/shared/systemd/src/basic/signal-util.h
index 3909ee341d..bdd39d429d 100644
--- a/shared/systemd/src/basic/signal-util.h
+++ b/shared/systemd/src/basic/signal-util.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <signal.h>
diff --git a/shared/systemd/src/basic/siphash24.h b/shared/systemd/src/basic/siphash24.h
index fe43256882..90a6de00e4 100644
--- a/shared/systemd/src/basic/siphash24.h
+++ b/shared/systemd/src/basic/siphash24.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: CC0-1.0 */
+
#pragma once
#include <inttypes.h>
diff --git a/shared/systemd/src/basic/socket-util.c b/shared/systemd/src/basic/socket-util.c
index f2e1148e87..59039bea4f 100644
--- a/shared/systemd/src/basic/socket-util.c
+++ b/shared/systemd/src/basic/socket-util.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <arpa/inet.h>
#include <errno.h>
@@ -23,10 +23,7 @@
#include "format-util.h"
#include "io-util.h"
#include "log.h"
-#include "macro.h"
#include "memory-util.h"
-#include "missing_socket.h"
-#include "missing_network.h"
#include "parse-util.h"
#include "path-util.h"
#include "process-util.h"
@@ -320,7 +317,7 @@ bool socket_address_matches_fd(const SocketAddress *a, int fd) {
}
int sockaddr_port(const struct sockaddr *_sa, unsigned *ret_port) {
- union sockaddr_union *sa = (union sockaddr_union*) _sa;
+ const union sockaddr_union *sa = (const union sockaddr_union*) _sa;
/* Note, this returns the port as 'unsigned' rather than 'uint16_t', as AF_VSOCK knows larger ports */
@@ -345,6 +342,25 @@ int sockaddr_port(const struct sockaddr *_sa, unsigned *ret_port) {
}
}
+const union in_addr_union *sockaddr_in_addr(const struct sockaddr *_sa) {
+ const union sockaddr_union *sa = (const union sockaddr_union*) _sa;
+
+ if (!sa)
+ return NULL;
+
+ switch (sa->sa.sa_family) {
+
+ case AF_INET:
+ return (const union in_addr_union*) &sa->in.sin_addr;
+
+ case AF_INET6:
+ return (const union in_addr_union*) &sa->in6.sin6_addr;
+
+ default:
+ return NULL;
+ }
+}
+
int sockaddr_pretty(
const struct sockaddr *_sa,
socklen_t salen,
@@ -1240,71 +1256,8 @@ int socket_set_recvpktinfo(int fd, int af, bool b) {
case AF_NETLINK:
return setsockopt_int(fd, SOL_NETLINK, NETLINK_PKTINFO, b);
- default:
- return -EAFNOSUPPORT;
- }
-}
-
-int socket_set_recverr(int fd, int af, bool b) {
- int r;
-
- if (af == AF_UNSPEC) {
- r = socket_get_family(fd, &af);
- if (r < 0)
- return r;
- }
-
- switch (af) {
-
- case AF_INET:
- return setsockopt_int(fd, IPPROTO_IP, IP_RECVERR, b);
-
- case AF_INET6:
- return setsockopt_int(fd, IPPROTO_IPV6, IPV6_RECVERR, b);
-
- default:
- return -EAFNOSUPPORT;
- }
-}
-
-int socket_set_recvttl(int fd, int af, bool b) {
- int r;
-
- if (af == AF_UNSPEC) {
- r = socket_get_family(fd, &af);
- if (r < 0)
- return r;
- }
-
- switch (af) {
-
- case AF_INET:
- return setsockopt_int(fd, IPPROTO_IP, IP_RECVTTL, b);
-
- case AF_INET6:
- return setsockopt_int(fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, b);
-
- default:
- return -EAFNOSUPPORT;
- }
-}
-
-int socket_set_ttl(int fd, int af, int ttl) {
- int r;
-
- if (af == AF_UNSPEC) {
- r = socket_get_family(fd, &af);
- if (r < 0)
- return r;
- }
-
- switch (af) {
-
- case AF_INET:
- return setsockopt_int(fd, IPPROTO_IP, IP_TTL, ttl);
-
- case AF_INET6:
- return setsockopt_int(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, ttl);
+ case AF_PACKET:
+ return setsockopt_int(fd, SOL_PACKET, PACKET_AUXDATA, b);
default:
return -EAFNOSUPPORT;
@@ -1340,7 +1293,7 @@ int socket_set_unicast_if(int fd, int af, int ifi) {
}
}
-int socket_set_freebind(int fd, int af, bool b) {
+int socket_set_option(int fd, int af, int opt_ipv4, int opt_ipv6, int val) {
int r;
if (af == AF_UNSPEC) {
@@ -1352,18 +1305,18 @@ int socket_set_freebind(int fd, int af, bool b) {
switch (af) {
case AF_INET:
- return setsockopt_int(fd, IPPROTO_IP, IP_FREEBIND, b);
+ return setsockopt_int(fd, IPPROTO_IP, opt_ipv4, val);
case AF_INET6:
- return setsockopt_int(fd, IPPROTO_IPV6, IPV6_FREEBIND, b);
+ return setsockopt_int(fd, IPPROTO_IPV6, opt_ipv6, val);
default:
return -EAFNOSUPPORT;
}
}
-int socket_set_transparent(int fd, int af, bool b) {
- int r;
+int socket_get_mtu(int fd, int af, size_t *ret) {
+ int mtu, r;
if (af == AF_UNSPEC) {
r = socket_get_family(fd, &af);
@@ -1374,12 +1327,22 @@ int socket_set_transparent(int fd, int af, bool b) {
switch (af) {
case AF_INET:
- return setsockopt_int(fd, IPPROTO_IP, IP_TRANSPARENT, b);
+ r = getsockopt_int(fd, IPPROTO_IP, IP_MTU, &mtu);
+ break;
case AF_INET6:
- return setsockopt_int(fd, IPPROTO_IPV6, IPV6_TRANSPARENT, b);
+ r = getsockopt_int(fd, IPPROTO_IPV6, IPV6_MTU, &mtu);
+ break;
default:
return -EAFNOSUPPORT;
}
+
+ if (r < 0)
+ return r;
+ if (mtu <= 0)
+ return -EINVAL;
+
+ *ret = (size_t) mtu;
+ return 0;
}
diff --git a/shared/systemd/src/basic/socket-util.h b/shared/systemd/src/basic/socket-util.h
index c36f90f75f..240d209c14 100644
--- a/shared/systemd/src/basic/socket-util.h
+++ b/shared/systemd/src/basic/socket-util.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <inttypes.h>
@@ -15,6 +15,7 @@
#include <sys/un.h>
#include "macro.h"
+#include "missing_network.h"
#include "missing_socket.h"
#include "sparse-endian.h"
@@ -102,6 +103,7 @@ const char* socket_address_get_path(const SocketAddress *a);
bool socket_ipv6_is_supported(void);
int sockaddr_port(const struct sockaddr *_sa, unsigned *port);
+const union in_addr_union *sockaddr_in_addr(const struct sockaddr *sa);
int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret);
int getpeername_pretty(int fd, bool include_port, char **ret);
@@ -256,6 +258,19 @@ static inline int setsockopt_int(int fd, int level, int optname, int value) {
return 0;
}
+static inline int getsockopt_int(int fd, int level, int optname, int *ret) {
+ int v;
+ socklen_t sl = sizeof(v);
+
+ if (getsockopt(fd, level, optname, &v, &sl) < 0)
+ return -errno;
+ if (sl != sizeof(v))
+ return -EIO;
+
+ *ret = v;
+ return 0;
+}
+
int socket_bind_to_ifname(int fd, const char *ifname);
int socket_bind_to_ifindex(int fd, int ifindex);
@@ -263,9 +278,26 @@ ssize_t recvmsg_safe(int sockfd, struct msghdr *msg, int flags);
int socket_get_family(int fd, int *ret);
int socket_set_recvpktinfo(int fd, int af, bool b);
-int socket_set_recverr(int fd, int af, bool b);
-int socket_set_recvttl(int fd, int af, bool b);
-int socket_set_ttl(int fd, int af, int ttl);
int socket_set_unicast_if(int fd, int af, int ifi);
-int socket_set_freebind(int fd, int af, bool b);
-int socket_set_transparent(int fd, int af, bool b);
+
+int socket_set_option(int fd, int af, int opt_ipv4, int opt_ipv6, int val);
+static inline int socket_set_recverr(int fd, int af, bool b) {
+ return socket_set_option(fd, af, IP_RECVERR, IPV6_RECVERR, b);
+}
+static inline int socket_set_recvttl(int fd, int af, bool b) {
+ return socket_set_option(fd, af, IP_RECVTTL, IPV6_RECVHOPLIMIT, b);
+}
+static inline int socket_set_ttl(int fd, int af, int ttl) {
+ return socket_set_option(fd, af, IP_TTL, IPV6_UNICAST_HOPS, ttl);
+}
+static inline int socket_set_freebind(int fd, int af, bool b) {
+ return socket_set_option(fd, af, IP_FREEBIND, IPV6_FREEBIND, b);
+}
+static inline int socket_set_transparent(int fd, int af, bool b) {
+ return socket_set_option(fd, af, IP_TRANSPARENT, IPV6_TRANSPARENT, b);
+}
+static inline int socket_set_recvfragsize(int fd, int af, bool b) {
+ return socket_set_option(fd, af, IP_RECVFRAGSIZE, IPV6_RECVFRAGSIZE, b);
+}
+
+int socket_get_mtu(int fd, int af, size_t *ret);
diff --git a/shared/systemd/src/basic/sort-util.h b/shared/systemd/src/basic/sort-util.h
index a8dc3bb6ed..49586a4a24 100644
--- a/shared/systemd/src/basic/sort-util.h
+++ b/shared/systemd/src/basic/sort-util.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <stdlib.h>
@@ -68,3 +68,5 @@ static inline void qsort_r_safe(void *base, size_t nmemb, size_t size, __compar_
int (*_func_)(const typeof(p[0])*, const typeof(p[0])*, typeof(userdata)) = func; \
qsort_r_safe((p), (n), sizeof((p)[0]), (__compar_d_fn_t) _func_, userdata); \
})
+
+int cmp_int(const int *a, const int *b);
diff --git a/shared/systemd/src/basic/stat-util.c b/shared/systemd/src/basic/stat-util.c
index 574815bc43..41c92e69de 100644
--- a/shared/systemd/src/basic/stat-util.c
+++ b/shared/systemd/src/basic/stat-util.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <errno.h>
#include <fcntl.h>
@@ -408,7 +408,8 @@ bool stat_inode_unmodified(const struct stat *a, const struct stat *b) {
return a && b &&
(a->st_mode & S_IFMT) != 0 && /* We use the check for .st_mode if the structure was ever initialized */
((a->st_mode ^ b->st_mode) & S_IFMT) == 0 && /* same inode type */
- a->st_mtime == b->st_mtime &&
+ a->st_mtim.tv_sec == b->st_mtim.tv_sec &&
+ a->st_mtim.tv_nsec == b->st_mtim.tv_nsec &&
(!S_ISREG(a->st_mode) || a->st_size == b->st_size) && /* if regular file, compare file size */
a->st_dev == b->st_dev &&
a->st_ino == b->st_ino &&
diff --git a/shared/systemd/src/basic/stat-util.h b/shared/systemd/src/basic/stat-util.h
index 26ecd635f1..a566114f7c 100644
--- a/shared/systemd/src/basic/stat-util.h
+++ b/shared/systemd/src/basic/stat-util.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <fcntl.h>
diff --git a/shared/systemd/src/basic/stdio-util.h b/shared/systemd/src/basic/stdio-util.h
index c3b9448d4f..6dc1e72312 100644
--- a/shared/systemd/src/basic/stdio-util.h
+++ b/shared/systemd/src/basic/stdio-util.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <printf.h>
diff --git a/shared/systemd/src/basic/string-table.c b/shared/systemd/src/basic/string-table.c
index 0168cff886..116021df82 100644
--- a/shared/systemd/src/basic/string-table.c
+++ b/shared/systemd/src/basic/string-table.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "string-table.h"
#include "string-util.h"
diff --git a/shared/systemd/src/basic/string-table.h b/shared/systemd/src/basic/string-table.h
index 96924778f5..ae4ea145d3 100644
--- a/shared/systemd/src/basic/string-table.h
+++ b/shared/systemd/src/basic/string-table.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
@@ -28,13 +28,12 @@ ssize_t string_table_lookup(const char * const *table, size_t len, const char *k
#define _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(name,type,yes,scope) \
scope type name##_from_string(const char *s) { \
- int b; \
if (!s) \
return -1; \
- b = parse_boolean(s); \
+ int b = parse_boolean(s); \
if (b == 0) \
return (type) 0; \
- else if (b > 0) \
+ if (b > 0) \
return yes; \
return (type) string_table_lookup(name##_table, ELEMENTSOF(name##_table), s); \
}
@@ -79,11 +78,13 @@ ssize_t string_table_lookup(const char * const *table, size_t len, const char *k
_DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(name,type,yes,scope)
#define DEFINE_STRING_TABLE_LOOKUP(name,type) _DEFINE_STRING_TABLE_LOOKUP(name,type,)
+#define DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,)
#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP(name,type) _DEFINE_STRING_TABLE_LOOKUP(name,type,static)
#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,static)
#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,static)
#define DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes) _DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes,)
+#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes) _DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes,static)
/* For string conversions where numbers are also acceptable */
#define DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(name,type,max) \
diff --git a/shared/systemd/src/basic/string-util.c b/shared/systemd/src/basic/string-util.c
index ab725d0dab..7ab460faa5 100644
--- a/shared/systemd/src/basic/string-util.c
+++ b/shared/systemd/src/basic/string-util.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <errno.h>
#include <stdarg.h>
@@ -145,57 +145,32 @@ char *strnappend(const char *s, const char *suffix, size_t b) {
char *strjoin_real(const char *x, ...) {
va_list ap;
- size_t l;
+ size_t l = 1;
char *r, *p;
va_start(ap, x);
+ for (const char *t = x; t; t = va_arg(ap, const char *)) {
+ size_t n;
- if (x) {
- l = strlen(x);
-
- for (;;) {
- const char *t;
- size_t n;
-
- t = va_arg(ap, const char *);
- if (!t)
- break;
-
- n = strlen(t);
- if (n > ((size_t) -1) - l) {
- va_end(ap);
- return NULL;
- }
-
- l += n;
+ n = strlen(t);
+ if (n > SIZE_MAX - l) {
+ va_end(ap);
+ return NULL;
}
- } else
- l = 0;
-
+ l += n;
+ }
va_end(ap);
- r = new(char, l+1);
+ p = r = new(char, l);
if (!r)
return NULL;
- if (x) {
- p = stpcpy(r, x);
-
- va_start(ap, x);
-
- for (;;) {
- const char *t;
-
- t = va_arg(ap, const char *);
- if (!t)
- break;
-
- p = stpcpy(p, t);
- }
+ va_start(ap, x);
+ for (const char *t = x; t; t = va_arg(ap, const char *))
+ p = stpcpy(p, t);
+ va_end(ap);
- va_end(ap);
- } else
- r[0] = 0;
+ *p = 0;
return r;
}
diff --git a/shared/systemd/src/basic/string-util.h b/shared/systemd/src/basic/string-util.h
index cefbda3577..fdd3ce7363 100644
--- a/shared/systemd/src/basic/string-util.h
+++ b/shared/systemd/src/basic/string-util.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <stdbool.h>
@@ -33,6 +33,12 @@ static inline bool streq_ptr(const char *a, const char *b) {
return strcmp_ptr(a, b) == 0;
}
+static inline char* strstr_ptr(const char *haystack, const char *needle) {
+ if (!haystack || !needle)
+ return NULL;
+ return strstr(haystack, needle);
+}
+
static inline const char* strempty(const char *s) {
return s ?: "";
}
@@ -53,6 +59,10 @@ static inline const char* true_false(bool b) {
return b ? "true" : "false";
}
+static inline const char* plus_minus(bool b) {
+ return b ? "+" : "-";
+}
+
static inline const char* one_zero(bool b) {
return b ? "1" : "0";
}
diff --git a/shared/systemd/src/basic/strv.c b/shared/systemd/src/basic/strv.c
index b2b6de388a..492dfe4002 100644
--- a/shared/systemd/src/basic/strv.c
+++ b/shared/systemd/src/basic/strv.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <errno.h>
#include <fnmatch.h>
@@ -123,7 +123,6 @@ size_t strv_length(char * const *l) {
}
char **strv_new_ap(const char *x, va_list ap) {
- const char *s;
_cleanup_strv_free_ char **a = NULL;
size_t n = 0, i = 0;
va_list aq;
@@ -133,43 +132,28 @@ char **strv_new_ap(const char *x, va_list ap) {
* STRV_IFNOTNULL() macro to include possibly NULL strings in
* the string list. */
- if (x) {
- n = x == STRV_IGNORE ? 0 : 1;
-
- va_copy(aq, ap);
- while ((s = va_arg(aq, const char*))) {
- if (s == STRV_IGNORE)
- continue;
-
- n++;
- }
+ va_copy(aq, ap);
+ for (const char *s = x; s; s = va_arg(aq, const char*)) {
+ if (s == STRV_IGNORE)
+ continue;
- va_end(aq);
+ n++;
}
+ va_end(aq);
a = new(char*, n+1);
if (!a)
return NULL;
- if (x) {
- if (x != STRV_IGNORE) {
- a[i] = strdup(x);
- if (!a[i])
- return NULL;
- i++;
- }
-
- while ((s = va_arg(ap, const char*))) {
-
- if (s == STRV_IGNORE)
- continue;
+ for (const char *s = x; s; s = va_arg(ap, const char*)) {
+ if (s == STRV_IGNORE)
+ continue;
- a[i] = strdup(s);
- if (!a[i])
- return NULL;
+ a[i] = strdup(s);
+ if (!a[i])
+ return NULL;
- i++;
- }
+ i++;
}
a[i] = NULL;
@@ -537,6 +521,19 @@ int strv_consume_prepend(char ***l, char *value) {
return r;
}
+int strv_prepend(char ***l, const char *value) {
+ char *v;
+
+ if (!value)
+ return 0;
+
+ v = strdup(value);
+ if (!v)
+ return -ENOMEM;
+
+ return strv_consume_prepend(l, v);
+}
+
int strv_extend(char ***l, const char *value) {
char *v;
diff --git a/shared/systemd/src/basic/strv.h b/shared/systemd/src/basic/strv.h
index 919fabf75a..6b3e8e7f86 100644
--- a/shared/systemd/src/basic/strv.h
+++ b/shared/systemd/src/basic/strv.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <fnmatch.h>
@@ -34,6 +34,7 @@ size_t strv_length(char * const *l) _pure_;
int strv_extend_strv(char ***a, char * const *b, bool filter_duplicates);
int strv_extend_strv_concat(char ***a, char * const *b, const char *suffix);
+int strv_prepend(char ***l, const char *value);
int strv_extend(char ***l, const char *value);
int strv_extendf(char ***l, const char *format, ...) _printf_(2,0);
int strv_extend_front(char ***l, const char *value);
@@ -62,7 +63,7 @@ char **strv_new_internal(const char *x, ...) _sentinel_;
char **strv_new_ap(const char *x, va_list ap);
#define strv_new(...) strv_new_internal(__VA_ARGS__, NULL)
-#define STRV_IGNORE ((const char *) -1)
+#define STRV_IGNORE ((const char *) POINTER_MAX)
static inline const char* STRV_IFNOTNULL(const char *x) {
return x ? x : STRV_IGNORE;
diff --git a/shared/systemd/src/basic/strxcpyx.c b/shared/systemd/src/basic/strxcpyx.c
index ef6d3fa324..dbbf7d08d2 100644
--- a/shared/systemd/src/basic/strxcpyx.c
+++ b/shared/systemd/src/basic/strxcpyx.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Concatenates/copies strings. In any case, terminates in all cases
diff --git a/shared/systemd/src/basic/strxcpyx.h b/shared/systemd/src/basic/strxcpyx.h
index 9b66841246..cdef492db1 100644
--- a/shared/systemd/src/basic/strxcpyx.h
+++ b/shared/systemd/src/basic/strxcpyx.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <stddef.h>
diff --git a/shared/systemd/src/basic/time-util.c b/shared/systemd/src/basic/time-util.c
index 7fa3b48623..52c564a68d 100644
--- a/shared/systemd/src/basic/time-util.c
+++ b/shared/systemd/src/basic/time-util.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <ctype.h>
#include <errno.h>
@@ -1606,7 +1606,7 @@ TimestampStyle timestamp_style_from_string(const char *s) {
return t;
if (streq_ptr(s, "µs"))
return TIMESTAMP_US;
- if (streq_ptr(s, "µs+uts"))
+ if (streq_ptr(s, "µs+utc"))
return TIMESTAMP_US_UTC;
return t;
}
diff --git a/shared/systemd/src/basic/time-util.h b/shared/systemd/src/basic/time-util.h
index cecd5efa60..89ee8b4a96 100644
--- a/shared/systemd/src/basic/time-util.h
+++ b/shared/systemd/src/basic/time-util.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <inttypes.h>
@@ -63,10 +63,10 @@ typedef enum TimestampStyle {
/* We assume a maximum timezone length of 6. TZNAME_MAX is not defined on Linux, but glibc internally initializes this
* to 6. Let's rely on that. */
-#define FORMAT_TIMESTAMP_MAX (3+1+10+1+8+1+6+1+6+1)
-#define FORMAT_TIMESTAMP_WIDTH 28 /* when outputting, assume this width */
-#define FORMAT_TIMESTAMP_RELATIVE_MAX 256
-#define FORMAT_TIMESPAN_MAX 64
+#define FORMAT_TIMESTAMP_MAX (3U+1U+10U+1U+8U+1U+6U+1U+6U+1U)
+#define FORMAT_TIMESTAMP_WIDTH 28U /* when outputting, assume this width */
+#define FORMAT_TIMESTAMP_RELATIVE_MAX 256U
+#define FORMAT_TIMESPAN_MAX 64U
#define TIME_T_MAX (time_t)((UINTMAX_C(1) << ((sizeof(time_t) << 3) - 1)) - 1)
diff --git a/shared/systemd/src/basic/tmpfile-util.c b/shared/systemd/src/basic/tmpfile-util.c
index a49f7eee70..49c343773c 100644
--- a/shared/systemd/src/basic/tmpfile-util.c
+++ b/shared/systemd/src/basic/tmpfile-util.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <sys/mman.h>
diff --git a/shared/systemd/src/basic/tmpfile-util.h b/shared/systemd/src/basic/tmpfile-util.h
index 802c85d6d9..45255fc062 100644
--- a/shared/systemd/src/basic/tmpfile-util.h
+++ b/shared/systemd/src/basic/tmpfile-util.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <stdio.h>
diff --git a/shared/systemd/src/basic/umask-util.h b/shared/systemd/src/basic/umask-util.h
index cad745170e..bd7c2bdb8c 100644
--- a/shared/systemd/src/basic/umask-util.h
+++ b/shared/systemd/src/basic/umask-util.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <stdbool.h>
diff --git a/shared/systemd/src/basic/user-util.h b/shared/systemd/src/basic/user-util.h
index 13e2c99e6c..20ff415e2e 100644
--- a/shared/systemd/src/basic/user-util.h
+++ b/shared/systemd/src/basic/user-util.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <grp.h>
diff --git a/shared/systemd/src/basic/utf8.c b/shared/systemd/src/basic/utf8.c
index f0233397ef..59663c0350 100644
--- a/shared/systemd/src/basic/utf8.c
+++ b/shared/systemd/src/basic/utf8.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
/* Parts of this file are based on the GLIB utf8 validation functions. The
* original license text follows. */
diff --git a/shared/systemd/src/basic/utf8.h b/shared/systemd/src/basic/utf8.h
index f315ea0f1e..a6ea942c62 100644
--- a/shared/systemd/src/basic/utf8.h
+++ b/shared/systemd/src/basic/utf8.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <stdbool.h>
diff --git a/shared/systemd/src/basic/util.c b/shared/systemd/src/basic/util.c
index 2b3b3918a3..7c708eb3be 100644
--- a/shared/systemd/src/basic/util.c
+++ b/shared/systemd/src/basic/util.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <errno.h>
#include <fcntl.h>
@@ -165,7 +165,7 @@ int container_get_leader(const char *machine, pid_t *pid) {
return 0;
}
- if (!machine_name_is_valid(machine))
+ if (!hostname_is_valid(machine, 0))
return -EINVAL;
p = strjoina("/run/systemd/machines/", machine);
@@ -193,8 +193,8 @@ int container_get_leader(const char *machine, pid_t *pid) {
}
int version(void) {
- puts("systemd " STRINGIFY(PROJECT_VERSION) " (" GIT_VERSION ")\n"
- SYSTEMD_FEATURES);
+ printf("systemd " STRINGIFY(PROJECT_VERSION) " (" GIT_VERSION ")\n%s\n",
+ systemd_features);
return 0;
}
diff --git a/shared/systemd/src/basic/util.h b/shared/systemd/src/basic/util.h
index 6fc7480fcb..942d773ff1 100644
--- a/shared/systemd/src/basic/util.h
+++ b/shared/systemd/src/basic/util.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <stdint.h>