summaryrefslogtreecommitdiff
path: root/src/basic
diff options
context:
space:
mode:
Diffstat (limited to 'src/basic')
-rw-r--r--src/basic/MurmurHash2.c2
-rw-r--r--src/basic/architecture.c176
-rw-r--r--src/basic/architecture.h195
-rw-r--r--src/basic/btrfs-util.h4
-rw-r--r--src/basic/c-rbtree.c5
-rw-r--r--src/basic/calendarspec.c22
-rw-r--r--src/basic/cgroup-util.c49
-rw-r--r--src/basic/cgroup-util.h2
-rw-r--r--src/basic/clock-util.c11
-rw-r--r--src/basic/clock-util.h2
-rw-r--r--src/basic/copy.c63
-rw-r--r--src/basic/ether-addr-util.c12
-rw-r--r--src/basic/ether-addr-util.h10
-rw-r--r--src/basic/extract-word.c14
-rw-r--r--src/basic/fileio.c16
-rw-r--r--src/basic/formats-util.h2
-rw-r--r--src/basic/gunicode.h4
-rw-r--r--src/basic/hashmap.c14
-rw-r--r--src/basic/hexdecoct.c10
-rw-r--r--src/basic/hostname-util.c36
-rw-r--r--src/basic/hostname-util.h1
-rw-r--r--src/basic/io-util.c2
-rw-r--r--src/basic/io-util.h2
-rw-r--r--src/basic/list.h14
-rw-r--r--src/basic/locale-util.c2
-rw-r--r--src/basic/log.h3
-rw-r--r--src/basic/login-util.h4
-rw-r--r--src/basic/macro.h15
-rw-r--r--src/basic/missing.h230
-rw-r--r--src/basic/missing_syscall.h310
-rw-r--r--src/basic/mount-util.c4
-rw-r--r--src/basic/parse-util.c2
-rw-r--r--src/basic/process-util.c77
-rw-r--r--src/basic/selinux-util.c34
-rw-r--r--src/basic/selinux-util.h2
-rw-r--r--src/basic/set.h3
-rw-r--r--src/basic/sigbus.h4
-rw-r--r--src/basic/signal-util.h8
-rw-r--r--src/basic/socket-label.c34
-rw-r--r--src/basic/socket-util.c2
-rw-r--r--src/basic/stdio-util.h2
-rw-r--r--src/basic/strbuf.c6
-rw-r--r--src/basic/string-util.c2
-rw-r--r--src/basic/time-util.c54
-rw-r--r--src/basic/utf8.c2
-rw-r--r--src/basic/utf8.h1
-rw-r--r--src/basic/util.h1
-rw-r--r--src/basic/virt.c74
-rw-r--r--src/basic/xattr-util.c2
49 files changed, 1089 insertions, 457 deletions
diff --git a/src/basic/MurmurHash2.c b/src/basic/MurmurHash2.c
index 2f4149dbe9..9020793930 100644
--- a/src/basic/MurmurHash2.c
+++ b/src/basic/MurmurHash2.c
@@ -50,7 +50,7 @@ uint32_t MurmurHash2 ( const void * key, int len, uint32_t seed )
const unsigned char * data = (const unsigned char *)key;
- while(len >= 4)
+ while (len >= 4)
{
uint32_t k = *(uint32_t*)data;
diff --git a/src/basic/architecture.c b/src/basic/architecture.c
new file mode 100644
index 0000000000..a9ecfc1cd6
--- /dev/null
+++ b/src/basic/architecture.c
@@ -0,0 +1,176 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2014 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/utsname.h>
+
+#include "architecture.h"
+#include "macro.h"
+#include "string-table.h"
+#include "string-util.h"
+
+int uname_architecture(void) {
+
+ /* Return a sanitized enum identifying the architecture we are
+ * running on. This is based on uname(), and the user may
+ * hence control what this returns by using
+ * personality(). This puts the user in control on systems
+ * that can run binaries of multiple architectures.
+ *
+ * We do not translate the string returned by uname()
+ * 1:1. Instead we try to clean it up and break down the
+ * confusion on x86 and arm in particular.
+ *
+ * We do not try to distinguish CPUs not CPU features, but
+ * actual architectures, i.e. that have genuinely different
+ * code. */
+
+ static const struct {
+ const char *machine;
+ int arch;
+ } arch_map[] = {
+#if defined(__x86_64__) || defined(__i386__)
+ { "x86_64", ARCHITECTURE_X86_64 },
+ { "i686", ARCHITECTURE_X86 },
+ { "i586", ARCHITECTURE_X86 },
+ { "i486", ARCHITECTURE_X86 },
+ { "i386", ARCHITECTURE_X86 },
+#elif defined(__powerpc__) || defined(__powerpc64__)
+ { "ppc64", ARCHITECTURE_PPC64 },
+ { "ppc64le", ARCHITECTURE_PPC64_LE },
+ { "ppc", ARCHITECTURE_PPC },
+ { "ppcle", ARCHITECTURE_PPC_LE },
+#elif defined(__ia64__)
+ { "ia64", ARCHITECTURE_IA64 },
+#elif defined(__hppa__) || defined(__hppa64__)
+ { "parisc64", ARCHITECTURE_PARISC64 },
+ { "parisc", ARCHITECTURE_PARISC },
+#elif defined(__s390__) || defined(__s390x__)
+ { "s390x", ARCHITECTURE_S390X },
+ { "s390", ARCHITECTURE_S390 },
+#elif defined(__sparc__) || defined(__sparc64__)
+ { "sparc64", ARCHITECTURE_SPARC64 },
+ { "sparc", ARCHITECTURE_SPARC },
+#elif defined(__mips__) || defined(__mips64__)
+ { "mips64", ARCHITECTURE_MIPS64 },
+ { "mips", ARCHITECTURE_MIPS },
+#elif defined(__alpha__)
+ { "alpha" , ARCHITECTURE_ALPHA },
+#elif defined(__arm__) || defined(__aarch64__)
+ { "aarch64", ARCHITECTURE_ARM64 },
+ { "aarch64_be", ARCHITECTURE_ARM64_BE },
+ { "armv4l", ARCHITECTURE_ARM },
+ { "armv4b", ARCHITECTURE_ARM_BE },
+ { "armv4tl", ARCHITECTURE_ARM },
+ { "armv4tb", ARCHITECTURE_ARM_BE },
+ { "armv5tl", ARCHITECTURE_ARM },
+ { "armv5tb", ARCHITECTURE_ARM_BE },
+ { "armv5tel", ARCHITECTURE_ARM },
+ { "armv5teb" , ARCHITECTURE_ARM_BE },
+ { "armv5tejl", ARCHITECTURE_ARM },
+ { "armv5tejb", ARCHITECTURE_ARM_BE },
+ { "armv6l", ARCHITECTURE_ARM },
+ { "armv6b", ARCHITECTURE_ARM_BE },
+ { "armv7l", ARCHITECTURE_ARM },
+ { "armv7b", ARCHITECTURE_ARM_BE },
+ { "armv7ml", ARCHITECTURE_ARM },
+ { "armv7mb", ARCHITECTURE_ARM_BE },
+ { "armv4l", ARCHITECTURE_ARM },
+ { "armv4b", ARCHITECTURE_ARM_BE },
+ { "armv4tl", ARCHITECTURE_ARM },
+ { "armv4tb", ARCHITECTURE_ARM_BE },
+ { "armv5tl", ARCHITECTURE_ARM },
+ { "armv5tb", ARCHITECTURE_ARM_BE },
+ { "armv5tel", ARCHITECTURE_ARM },
+ { "armv5teb", ARCHITECTURE_ARM_BE },
+ { "armv5tejl", ARCHITECTURE_ARM },
+ { "armv5tejb", ARCHITECTURE_ARM_BE },
+ { "armv6l", ARCHITECTURE_ARM },
+ { "armv6b", ARCHITECTURE_ARM_BE },
+ { "armv7l", ARCHITECTURE_ARM },
+ { "armv7b", ARCHITECTURE_ARM_BE },
+ { "armv7ml", ARCHITECTURE_ARM },
+ { "armv7mb", ARCHITECTURE_ARM_BE },
+ { "armv8l", ARCHITECTURE_ARM },
+ { "armv8b", ARCHITECTURE_ARM_BE },
+#elif defined(__sh__) || defined(__sh64__)
+ { "sh5", ARCHITECTURE_SH64 },
+ { "sh2", ARCHITECTURE_SH },
+ { "sh2a", ARCHITECTURE_SH },
+ { "sh3", ARCHITECTURE_SH },
+ { "sh4", ARCHITECTURE_SH },
+ { "sh4a", ARCHITECTURE_SH },
+#elif defined(__m68k__)
+ { "m68k", ARCHITECTURE_M68K },
+#elif defined(__tilegx__)
+ { "tilegx", ARCHITECTURE_TILEGX },
+#elif defined(__cris__)
+ { "crisv32", ARCHITECTURE_CRIS },
+#else
+#error "Please register your architecture here!"
+#endif
+ };
+
+ static int cached = _ARCHITECTURE_INVALID;
+ struct utsname u;
+ unsigned i;
+
+ if (cached != _ARCHITECTURE_INVALID)
+ return cached;
+
+ assert_se(uname(&u) >= 0);
+
+ for (i = 0; i < ELEMENTSOF(arch_map); i++)
+ if (streq(arch_map[i].machine, u.machine))
+ return cached = arch_map[i].arch;
+
+ assert_not_reached("Couldn't identify architecture. You need to patch systemd.");
+ return _ARCHITECTURE_INVALID;
+}
+
+static const char *const architecture_table[_ARCHITECTURE_MAX] = {
+ [ARCHITECTURE_X86] = "x86",
+ [ARCHITECTURE_X86_64] = "x86-64",
+ [ARCHITECTURE_PPC] = "ppc",
+ [ARCHITECTURE_PPC_LE] = "ppc-le",
+ [ARCHITECTURE_PPC64] = "ppc64",
+ [ARCHITECTURE_PPC64_LE] = "ppc64-le",
+ [ARCHITECTURE_IA64] = "ia64",
+ [ARCHITECTURE_PARISC] = "parisc",
+ [ARCHITECTURE_PARISC64] = "parisc64",
+ [ARCHITECTURE_S390] = "s390",
+ [ARCHITECTURE_S390X] = "s390x",
+ [ARCHITECTURE_SPARC] = "sparc",
+ [ARCHITECTURE_SPARC64] = "sparc64",
+ [ARCHITECTURE_MIPS] = "mips",
+ [ARCHITECTURE_MIPS_LE] = "mips-le",
+ [ARCHITECTURE_MIPS64] = "mips64",
+ [ARCHITECTURE_MIPS64_LE] = "mips64-le",
+ [ARCHITECTURE_ALPHA] = "alpha",
+ [ARCHITECTURE_ARM] = "arm",
+ [ARCHITECTURE_ARM_BE] = "arm-be",
+ [ARCHITECTURE_ARM64] = "arm64",
+ [ARCHITECTURE_ARM64_BE] = "arm64-be",
+ [ARCHITECTURE_SH] = "sh",
+ [ARCHITECTURE_SH64] = "sh64",
+ [ARCHITECTURE_M68K] = "m68k",
+ [ARCHITECTURE_TILEGX] = "tilegx",
+ [ARCHITECTURE_CRIS] = "cris",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(architecture, int);
diff --git a/src/basic/architecture.h b/src/basic/architecture.h
new file mode 100644
index 0000000000..c22cbc8279
--- /dev/null
+++ b/src/basic/architecture.h
@@ -0,0 +1,195 @@
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2014 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <endian.h>
+
+#include "macro.h"
+#include "util.h"
+
+/* A cleaned up architecture definition. We don't want to get lost in
+ * processor features, models, generations or even ABIs. Hence we
+ * focus on general family, and distinguish word width and
+ * endianness. */
+
+enum {
+ ARCHITECTURE_X86 = 0,
+ ARCHITECTURE_X86_64,
+ ARCHITECTURE_PPC,
+ ARCHITECTURE_PPC_LE,
+ ARCHITECTURE_PPC64,
+ ARCHITECTURE_PPC64_LE,
+ ARCHITECTURE_IA64,
+ ARCHITECTURE_PARISC,
+ ARCHITECTURE_PARISC64,
+ ARCHITECTURE_S390,
+ ARCHITECTURE_S390X,
+ ARCHITECTURE_SPARC,
+ ARCHITECTURE_SPARC64,
+ ARCHITECTURE_MIPS,
+ ARCHITECTURE_MIPS_LE,
+ ARCHITECTURE_MIPS64,
+ ARCHITECTURE_MIPS64_LE,
+ ARCHITECTURE_ALPHA,
+ ARCHITECTURE_ARM,
+ ARCHITECTURE_ARM_BE,
+ ARCHITECTURE_ARM64,
+ ARCHITECTURE_ARM64_BE,
+ ARCHITECTURE_SH,
+ ARCHITECTURE_SH64,
+ ARCHITECTURE_M68K,
+ ARCHITECTURE_TILEGX,
+ ARCHITECTURE_CRIS,
+ _ARCHITECTURE_MAX,
+ _ARCHITECTURE_INVALID = -1
+};
+
+int uname_architecture(void);
+
+/*
+ * LIB_ARCH_TUPLE should resolve to the local library path
+ * architecture tuple systemd is built for, according to the Debian
+ * tuple list:
+ *
+ * https://wiki.debian.org/Multiarch/Tuples
+ *
+ * This is used in library search paths that should understand
+ * Debian's paths on all distributions.
+ */
+
+#if defined(__x86_64__)
+# define native_architecture() ARCHITECTURE_X86_64
+# define LIB_ARCH_TUPLE "x86_64-linux-gnu"
+# define SECONDARY_ARCHITECTURE ARCHITECTURE_X86
+#elif defined(__i386__)
+# define native_architecture() ARCHITECTURE_X86
+# define LIB_ARCH_TUPLE "i386-linux-gnu"
+#elif defined(__powerpc64__)
+# if __BYTE_ORDER == __BIG_ENDIAN
+# define native_architecture() ARCHITECTURE_PPC64
+# define LIB_ARCH_TUPLE "ppc64-linux-gnu"
+# define SECONDARY_ARCHITECTURE ARCHITECTURE_PPC
+# else
+# define native_architecture() ARCHITECTURE_PPC64_LE
+# define LIB_ARCH_TUPLE "powerpc64le-linux-gnu"
+# define SECONDARY_ARCHITECTURE ARCHITECTURE_PPC_LE
+# endif
+#elif defined(__powerpc__)
+# if __BYTE_ORDER == __BIG_ENDIAN
+# define native_architecture() ARCHITECTURE_PPC
+# define LIB_ARCH_TUPLE "powerpc-linux-gnu"
+# else
+# define native_architecture() ARCHITECTURE_PPC_LE
+# error "Missing LIB_ARCH_TUPLE for PPCLE"
+# endif
+#elif defined(__ia64__)
+# define native_architecture() ARCHITECTURE_IA64
+# define LIB_ARCH_TUPLE "ia64-linux-gnu"
+#elif defined(__hppa64__)
+# define native_architecture() ARCHITECTURE_PARISC64
+# error "Missing LIB_ARCH_TUPLE for HPPA64"
+#elif defined(__hppa__)
+# define native_architecture() ARCHITECTURE_PARISC
+# define LIB_ARCH_TUPLE "hppa‑linux‑gnu"
+#elif defined(__s390x__)
+# define native_architecture() ARCHITECTURE_S390X
+# define LIB_ARCH_TUPLE "s390x-linux-gnu"
+# define SECONDARY_ARCHITECTURE ARCHITECTURE_S390
+#elif defined(__s390__)
+# define native_architecture() ARCHITECTURE_S390
+# define LIB_ARCH_TUPLE "s390-linux-gnu"
+#elif defined(__sparc64__)
+# define native_architecture() ARCHITECTURE_SPARC64
+# define LIB_ARCH_TUPLE "sparc64-linux-gnu"
+#elif defined(__sparc__)
+# define native_architecture() ARCHITECTURE_SPARC
+# define LIB_ARCH_TUPLE "sparc-linux-gnu"
+#elif defined(__mips64__)
+# if __BYTE_ORDER == __BIG_ENDIAN
+# define native_architecture() ARCHITECTURE_MIPS64
+# error "Missing LIB_ARCH_TUPLE for MIPS64"
+# else
+# define native_architecture() ARCHITECTURE_MIPS64_LE
+# error "Missing LIB_ARCH_TUPLE for MIPS64_LE"
+# endif
+#elif defined(__mips__)
+# if __BYTE_ORDER == __BIG_ENDIAN
+# define native_architecture() ARCHITECTURE_MIPS
+# define LIB_ARCH_TUPLE "mips-linux-gnu"
+# else
+# define native_architecture() ARCHITECTURE_MIPS_LE
+# define LIB_ARCH_TUPLE "mipsel-linux-gnu"
+# endif
+#elif defined(__alpha__)
+# define native_architecture() ARCHITECTURE_ALPHA
+# define LIB_ARCH_TUPLE "alpha-linux-gnu"
+#elif defined(__aarch64__)
+# if __BYTE_ORDER == __BIG_ENDIAN
+# define native_architecture() ARCHITECTURE_ARM64_BE
+# define LIB_ARCH_TUPLE "aarch64_be-linux-gnu"
+# else
+# define native_architecture() ARCHITECTURE_ARM64
+# define LIB_ARCH_TUPLE "aarch64-linux-gnu"
+# endif
+#elif defined(__arm__)
+# if __BYTE_ORDER == __BIG_ENDIAN
+# define native_architecture() ARCHITECTURE_ARM_BE
+# if defined(__ARM_EABI__)
+# if defined(__ARM_PCS_VFP)
+# define LIB_ARCH_TUPLE "armeb-linux-gnueabihf"
+# else
+# define LIB_ARCH_TUPLE "armeb-linux-gnueabi"
+# endif
+# else
+# define LIB_ARCH_TUPLE "armeb-linux-gnu"
+# endif
+# else
+# define native_architecture() ARCHITECTURE_ARM
+# if defined(__ARM_EABI__)
+# if defined(__ARM_PCS_VFP)
+# define LIB_ARCH_TUPLE "arm-linux-gnueabihf"
+# else
+# define LIB_ARCH_TUPLE "arm-linux-gnueabi"
+# endif
+# else
+# define LIB_ARCH_TUPLE "arm-linux-gnu"
+# endif
+# endif
+#elif defined(__sh64__)
+# define native_architecture() ARCHITECTURE_SH64
+# error "Missing LIB_ARCH_TUPLE for SH64"
+#elif defined(__sh__)
+# define native_architecture() ARCHITECTURE_SH
+# define LIB_ARCH_TUPLE "sh4-linux-gnu"
+#elif defined(__m68k__)
+# define native_architecture() ARCHITECTURE_M68K
+# define LIB_ARCH_TUPLE "m68k-linux-gnu"
+#elif defined(__tilegx__)
+# define native_architecture() ARCHITECTURE_TILEGX
+# error "Missing LIB_ARCH_TUPLE for TILEGX"
+#elif defined(__cris__)
+# define native_architecture() ARCHITECTURE_CRIS
+# error "Missing LIB_ARCH_TUPLE for CRIS"
+#else
+# error "Please register your architecture here!"
+#endif
+
+const char *architecture_to_string(int a) _const_;
+int architecture_from_string(const char *s) _pure_;
diff --git a/src/basic/btrfs-util.h b/src/basic/btrfs-util.h
index 37802c2565..1d852d502c 100644
--- a/src/basic/btrfs-util.h
+++ b/src/basic/btrfs-util.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -17,8 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
#include <stdbool.h>
#include <stdint.h>
#include <sys/types.h>
diff --git a/src/basic/c-rbtree.c b/src/basic/c-rbtree.c
index 914d7e5229..cf5a7242df 100644
--- a/src/basic/c-rbtree.c
+++ b/src/basic/c-rbtree.c
@@ -195,11 +195,6 @@ static inline void c_rbnode_set_parent_and_color(CRBNode *n, CRBNode *p, unsigne
n->__parent_and_color = (CRBNode*)((unsigned long)p | c);
}
-/* same as c_rbnode_set_parent_and_color(), but keeps the current parent */
-static inline void c_rbnode_set_color(CRBNode *n, unsigned long c) {
- c_rbnode_set_parent_and_color(n, c_rbnode_parent(n), c);
-}
-
/* same as c_rbnode_set_parent_and_color(), but keeps the current color */
static inline void c_rbnode_set_parent(CRBNode *n, CRBNode *p) {
c_rbnode_set_parent_and_color(n, p, c_rbnode_color(n));
diff --git a/src/basic/calendarspec.c b/src/basic/calendarspec.c
index 775879076d..6e0bab9b94 100644
--- a/src/basic/calendarspec.c
+++ b/src/basic/calendarspec.c
@@ -114,7 +114,7 @@ static void sort_chain(CalendarComponent **c) {
static void fix_year(CalendarComponent *c) {
/* Turns 12 → 2012, 89 → 1989 */
- while(c) {
+ while (c) {
CalendarComponent *n = c->next;
if (c->value >= 0 && c->value < 70)
@@ -978,7 +978,7 @@ static int find_next(const CalendarSpec *spec, struct tm *tm, usec_t *usec) {
for (;;) {
/* Normalize the current date */
- mktime_or_timegm(&c, spec->utc);
+ (void) mktime_or_timegm(&c, spec->utc);
c.tm_isdst = -1;
c.tm_year += 1900;
@@ -990,8 +990,10 @@ static int find_next(const CalendarSpec *spec, struct tm *tm, usec_t *usec) {
c.tm_mday = 1;
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
}
- if (r < 0 || tm_out_of_bounds(&c, spec->utc))
+ if (r < 0)
return r;
+ if (tm_out_of_bounds(&c, spec->utc))
+ return -ENOENT;
c.tm_mon += 1;
r = find_matching_component(spec->month, &c.tm_mon);
@@ -1002,7 +1004,7 @@ static int find_next(const CalendarSpec *spec, struct tm *tm, usec_t *usec) {
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
}
if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
- c.tm_year ++;
+ c.tm_year++;
c.tm_mon = 0;
c.tm_mday = 1;
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
@@ -1013,7 +1015,7 @@ static int find_next(const CalendarSpec *spec, struct tm *tm, usec_t *usec) {
if (r > 0)
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
- c.tm_mon ++;
+ c.tm_mon++;
c.tm_mday = 1;
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
continue;
@@ -1027,18 +1029,18 @@ static int find_next(const CalendarSpec *spec, struct tm *tm, usec_t *usec) {
r = find_matching_component(spec->hour, &c.tm_hour);
if (r > 0)
- c.tm_min = c.tm_sec = 0;
+ c.tm_min = c.tm_sec = tm_usec = 0;
if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
- c.tm_mday ++;
+ c.tm_mday++;
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
continue;
}
r = find_matching_component(spec->minute, &c.tm_min);
if (r > 0)
- c.tm_sec = 0;
+ c.tm_sec = tm_usec = 0;
if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
- c.tm_hour ++;
+ c.tm_hour++;
c.tm_min = c.tm_sec = tm_usec = 0;
continue;
}
@@ -1049,7 +1051,7 @@ static int find_next(const CalendarSpec *spec, struct tm *tm, usec_t *usec) {
c.tm_sec /= USEC_PER_SEC;
if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
- c.tm_min ++;
+ c.tm_min++;
c.tm_sec = tm_usec = 0;
continue;
}
diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c
index 6ef00d51df..5043180747 100644
--- a/src/basic/cgroup-util.c
+++ b/src/basic/cgroup-util.c
@@ -101,6 +101,39 @@ int cg_read_pid(FILE *f, pid_t *_pid) {
return 1;
}
+int cg_read_event(const char *controller, const char *path, const char *event,
+ char **val)
+{
+ _cleanup_free_ char *events = NULL, *content = NULL;
+ char *p, *line;
+ int r;
+
+ r = cg_get_path(controller, path, "cgroup.events", &events);
+ if (r < 0)
+ return r;
+
+ r = read_full_file(events, &content, NULL);
+ if (r < 0)
+ return r;
+
+ p = content;
+ while ((line = strsep(&p, "\n"))) {
+ char *key;
+
+ key = strsep(&line, " ");
+ if (!key || !line)
+ return -EINVAL;
+
+ if (strcmp(key, event))
+ continue;
+
+ *val = strdup(line);
+ return 0;
+ }
+
+ return -ENOENT;
+}
+
int cg_enumerate_subgroups(const char *controller, const char *path, DIR **_d) {
_cleanup_free_ char *fs = NULL;
int r;
@@ -1007,18 +1040,12 @@ int cg_is_empty_recursive(const char *controller, const char *path) {
return unified;
if (unified > 0) {
- _cleanup_free_ char *populated = NULL, *t = NULL;
+ _cleanup_free_ char *t = NULL;
/* On the unified hierarchy we can check empty state
- * via the "cgroup.populated" attribute. */
+ * via the "populated" attribute of "cgroup.events". */
- r = cg_get_path(controller, path, "cgroup.populated", &populated);
- if (r < 0)
- return r;
-
- r = read_one_line_file(populated, &t);
- if (r == -ENOENT)
- return 1;
+ r = cg_read_event(controller, path, "populated", &t);
if (r < 0)
return r;
@@ -1248,7 +1275,7 @@ int cg_pid_get_path_shifted(pid_t pid, const char *root, char **cgroup) {
return 0;
}
-int cg_path_decode_unit(const char *cgroup, char **unit){
+int cg_path_decode_unit(const char *cgroup, char **unit) {
char *c, *s;
size_t n;
@@ -2129,7 +2156,7 @@ int cg_unified(void) {
if (statfs("/sys/fs/cgroup/", &fs) < 0)
return -errno;
- if (F_TYPE_EQUAL(fs.f_type, CGROUP_SUPER_MAGIC))
+ if (F_TYPE_EQUAL(fs.f_type, CGROUP2_SUPER_MAGIC))
unified_cache = true;
else if (F_TYPE_EQUAL(fs.f_type, TMPFS_MAGIC))
unified_cache = false;
diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h
index ad1edd9cdb..4254e51e5d 100644
--- a/src/basic/cgroup-util.h
+++ b/src/basic/cgroup-util.h
@@ -96,6 +96,8 @@ static inline bool CGROUP_BLKIO_WEIGHT_IS_OK(uint64_t x) {
int cg_enumerate_processes(const char *controller, const char *path, FILE **_f);
int cg_read_pid(FILE *f, pid_t *_pid);
+int cg_read_event(const char *controller, const char *path, const char *event,
+ char **val);
int cg_enumerate_subgroups(const char *controller, const char *path, DIR **_d);
int cg_read_subgroup(DIR *d, char **fn);
diff --git a/src/basic/clock-util.c b/src/basic/clock-util.c
index 507e757ff0..7fe8d35ea5 100644
--- a/src/basic/clock-util.c
+++ b/src/basic/clock-util.c
@@ -69,9 +69,12 @@ int clock_set_hwclock(const struct tm *tm) {
return 0;
}
-int clock_is_localtime(void) {
+int clock_is_localtime(const char* adjtime_path) {
_cleanup_fclose_ FILE *f;
+ if (adjtime_path == NULL)
+ adjtime_path = "/etc/adjtime";
+
/*
* The third line of adjtime is "UTC" or "LOCAL" or nothing.
* # /etc/adjtime
@@ -79,7 +82,7 @@ int clock_is_localtime(void) {
* 0
* UTC
*/
- f = fopen("/etc/adjtime", "re");
+ f = fopen(adjtime_path, "re");
if (f) {
char line[LINE_MAX];
bool b;
@@ -88,7 +91,8 @@ int clock_is_localtime(void) {
fgets(line, sizeof(line), f) &&
fgets(line, sizeof(line), f);
if (!b)
- return -EIO;
+ /* less than three lines -> default to UTC */
+ return 0;
truncate_nl(line);
return streq(line, "LOCAL");
@@ -96,6 +100,7 @@ int clock_is_localtime(void) {
} else if (errno != ENOENT)
return -errno;
+ /* adjtime not present -> default to UTC */
return 0;
}
diff --git a/src/basic/clock-util.h b/src/basic/clock-util.h
index f471f2abcf..8830cd2f38 100644
--- a/src/basic/clock-util.h
+++ b/src/basic/clock-util.h
@@ -21,7 +21,7 @@
#include <time.h>
-int clock_is_localtime(void);
+int clock_is_localtime(const char* adjtime_path);
int clock_set_timezone(int *min);
int clock_reset_timewarp(void);
int clock_get_hwclock(struct tm *tm);
diff --git a/src/basic/copy.c b/src/basic/copy.c
index 519b412941..41dc8ca79a 100644
--- a/src/basic/copy.c
+++ b/src/basic/copy.c
@@ -40,17 +40,38 @@
#include "fs-util.h"
#include "io-util.h"
#include "macro.h"
+#include "missing.h"
#include "string-util.h"
#include "strv.h"
#include "time-util.h"
#include "umask-util.h"
#include "xattr-util.h"
-#define COPY_BUFFER_SIZE (16*1024)
+#define COPY_BUFFER_SIZE (16*1024u)
+
+static ssize_t try_copy_file_range(int fd_in, loff_t *off_in,
+ int fd_out, loff_t *off_out,
+ size_t len,
+ unsigned int flags) {
+ static int have = -1;
+ ssize_t r;
+
+ if (have == false)
+ return -ENOSYS;
+
+ r = copy_file_range(fd_in, off_in, fd_out, off_out, len, flags);
+ if (_unlikely_(have < 0))
+ have = r >= 0 || errno != ENOSYS;
+ if (r >= 0)
+ return r;
+ else
+ return -errno;
+}
int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink) {
- bool try_sendfile = true, try_splice = true;
+ bool try_cfr = true, try_sendfile = true, try_splice = true;
int r;
+ size_t m = SSIZE_MAX; /* that the maximum that sendfile and c_f_r accept */
assert(fdf >= 0);
assert(fdt >= 0);
@@ -67,11 +88,9 @@ int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink) {
}
for (;;) {
- size_t m = COPY_BUFFER_SIZE;
ssize_t n;
if (max_bytes != (uint64_t) -1) {
-
if (max_bytes <= 0)
return 1; /* return > 0 if we hit the max_bytes limit */
@@ -79,44 +98,59 @@ int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink) {
m = (size_t) max_bytes;
}
+ /* First try copy_file_range(), unless we already tried */
+ if (try_cfr) {
+ n = try_copy_file_range(fdf, NULL, fdt, NULL, m, 0u);
+ if (n < 0) {
+ if (!IN_SET(n, -EINVAL, -ENOSYS, -EXDEV))
+ return n;
+
+ try_cfr = false;
+ /* use fallback below */
+ } else if (n == 0) /* EOF */
+ break;
+ else
+ /* Success! */
+ goto next;
+ }
+
/* First try sendfile(), unless we already tried */
if (try_sendfile) {
-
n = sendfile(fdt, fdf, NULL, m);
if (n < 0) {
- if (errno != EINVAL && errno != ENOSYS)
+ if (!IN_SET(errno, EINVAL, ENOSYS))
return -errno;
try_sendfile = false;
/* use fallback below */
} else if (n == 0) /* EOF */
break;
- else if (n > 0)
+ else
/* Success! */
goto next;
}
- /* The try splice, unless we already tried */
+ /* Then try splice, unless we already tried */
if (try_splice) {
n = splice(fdf, NULL, fdt, NULL, m, 0);
if (n < 0) {
- if (errno != EINVAL && errno != ENOSYS)
+ if (!IN_SET(errno, EINVAL, ENOSYS))
return -errno;
try_splice = false;
/* use fallback below */
} else if (n == 0) /* EOF */
break;
- else if (n > 0)
+ else
/* Success! */
goto next;
}
/* As a fallback just copy bits by hand */
{
- uint8_t buf[m];
+ uint8_t buf[MIN(m, COPY_BUFFER_SIZE)];
- n = read(fdf, buf, m);
+ n = read(fdf, buf, sizeof buf);
if (n < 0)
return -errno;
if (n == 0) /* EOF */
@@ -132,6 +166,11 @@ int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink) {
assert(max_bytes >= (uint64_t) n);
max_bytes -= n;
}
+ /* sendfile accepts at most SSIZE_MAX-offset bytes to copy,
+ * so reduce our maximum by the amount we already copied,
+ * but don't go below our copy buffer size, unless we are
+ * close the the limit of bytes we are allowed to copy. */
+ m = MAX(MIN(COPY_BUFFER_SIZE, max_bytes), m - n);
}
return 0; /* return 0 if we hit EOF earlier than the size limit */
diff --git a/src/basic/ether-addr-util.c b/src/basic/ether-addr-util.c
index ded6d31f4b..a4d8d656da 100644
--- a/src/basic/ether-addr-util.c
+++ b/src/basic/ether-addr-util.c
@@ -42,3 +42,15 @@ char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR
return buffer;
}
+
+bool ether_addr_equal(const struct ether_addr *a, const struct ether_addr *b) {
+ assert(a);
+ assert(b);
+
+ return a->ether_addr_octet[0] == b->ether_addr_octet[0] &&
+ a->ether_addr_octet[1] == b->ether_addr_octet[1] &&
+ a->ether_addr_octet[2] == b->ether_addr_octet[2] &&
+ a->ether_addr_octet[3] == b->ether_addr_octet[3] &&
+ a->ether_addr_octet[4] == b->ether_addr_octet[4] &&
+ a->ether_addr_octet[5] == b->ether_addr_octet[5];
+}
diff --git a/src/basic/ether-addr-util.h b/src/basic/ether-addr-util.h
index 4487149efd..074363793e 100644
--- a/src/basic/ether-addr-util.h
+++ b/src/basic/ether-addr-util.h
@@ -20,10 +20,18 @@
***/
#include <net/ethernet.h>
+#include <stdbool.h>
#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]
#define ETHER_ADDR_TO_STRING_MAX (3*6)
-
char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]);
+
+bool ether_addr_equal(const struct ether_addr *a, const struct ether_addr *b);
+
+#define ETHER_ADDR_NULL ((const struct ether_addr){})
+
+static inline bool ether_addr_is_null(const struct ether_addr *addr) {
+ return ether_addr_equal(addr, &ETHER_ADDR_NULL);
+}
diff --git a/src/basic/extract-word.c b/src/basic/extract-word.c
index ee35d2a0ec..d6c1228463 100644
--- a/src/basic/extract-word.c
+++ b/src/basic/extract-word.c
@@ -63,12 +63,12 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
if (!GREEDY_REALLOC(s, allocated, sz+1))
return -ENOMEM;
- for (;; (*p) ++, c = **p) {
+ for (;; (*p)++, c = **p) {
if (c == 0)
goto finish_force_terminate;
else if (strchr(separators, c)) {
if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
- (*p) ++;
+ (*p)++;
goto finish_force_next;
}
} else {
@@ -81,7 +81,7 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
}
}
- for (;; (*p) ++, c = **p) {
+ for (;; (*p)++, c = **p) {
if (backslash) {
if (!GREEDY_REALLOC(s, allocated, sz+7))
return -ENOMEM;
@@ -129,7 +129,7 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
backslash = false;
} else if (quote) { /* inside either single or double quotes */
- for (;; (*p) ++, c = **p) {
+ for (;; (*p)++, c = **p) {
if (c == 0) {
if (flags & EXTRACT_RELAX)
goto finish_force_terminate;
@@ -149,7 +149,7 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
}
} else {
- for (;; (*p) ++, c = **p) {
+ for (;; (*p)++, c = **p) {
if (c == 0)
goto finish_force_terminate;
else if ((c == '\'' || c == '"') && (flags & EXTRACT_QUOTES)) {
@@ -160,11 +160,11 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
break;
} else if (strchr(separators, c)) {
if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
- (*p) ++;
+ (*p)++;
goto finish_force_next;
}
/* Skip additional coalesced separators. */
- for (;; (*p) ++, c = **p) {
+ for (;; (*p)++, c = **p) {
if (c == 0)
goto finish_force_terminate;
if (!strchr(separators, c))
diff --git a/src/basic/fileio.c b/src/basic/fileio.c
index e43ca6d29e..69590941e5 100644
--- a/src/basic/fileio.c
+++ b/src/basic/fileio.c
@@ -352,7 +352,7 @@ static int parse_env_file_internal(
case KEY:
if (strchr(newline, c)) {
state = PRE_KEY;
- line ++;
+ line++;
n_key = 0;
} else if (c == '=') {
state = PRE_VALUE;
@@ -376,7 +376,7 @@ static int parse_env_file_internal(
case PRE_VALUE:
if (strchr(newline, c)) {
state = PRE_KEY;
- line ++;
+ line++;
key[n_key] = 0;
if (value)
@@ -416,7 +416,7 @@ static int parse_env_file_internal(
case VALUE:
if (strchr(newline, c)) {
state = PRE_KEY;
- line ++;
+ line++;
key[n_key] = 0;
@@ -535,7 +535,7 @@ static int parse_env_file_internal(
state = COMMENT_ESCAPE;
else if (strchr(newline, c)) {
state = PRE_KEY;
- line ++;
+ line++;
}
break;
@@ -588,7 +588,7 @@ static int parse_env_file_push(
va_list aq, *ap = userdata;
if (!utf8_is_valid(key)) {
- _cleanup_free_ char *p;
+ _cleanup_free_ char *p = NULL;
p = utf8_escape_invalid(key);
log_error("%s:%u: invalid UTF-8 in key '%s', ignoring.", strna(filename), line, p);
@@ -596,7 +596,7 @@ static int parse_env_file_push(
}
if (value && !utf8_is_valid(value)) {
- _cleanup_free_ char *p;
+ _cleanup_free_ char *p = NULL;
p = utf8_escape_invalid(value);
log_error("%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.", strna(filename), line, key, p);
@@ -908,7 +908,7 @@ int get_proc_field(const char *filename, const char *pattern, const char *termin
/* Back off one char if there's nothing but whitespace
and zeros */
if (!*t || isspace(*t))
- t --;
+ t--;
}
len = strcspn(t, terminator);
@@ -1069,7 +1069,7 @@ int fflush_and_check(FILE *f) {
/* This is much like like mkostemp() but is subject to umask(). */
int mkostemp_safe(char *pattern, int flags) {
- _cleanup_umask_ mode_t u;
+ _cleanup_umask_ mode_t u = 0;
int fd;
assert(pattern);
diff --git a/src/basic/formats-util.h b/src/basic/formats-util.h
index ce516b117d..9b4e8e98fa 100644
--- a/src/basic/formats-util.h
+++ b/src/basic/formats-util.h
@@ -49,7 +49,7 @@
#if SIZEOF_TIME_T == 8
# define PRI_TIME PRIi64
#elif SIZEOF_TIME_T == 4
-# define PRI_TIME PRIu32
+# define PRI_TIME "li"
#else
# error Unknown time_t size
#endif
diff --git a/src/basic/gunicode.h b/src/basic/gunicode.h
index b03aa43160..5975bc8fc9 100644
--- a/src/basic/gunicode.h
+++ b/src/basic/gunicode.h
@@ -1,11 +1,11 @@
+#pragma once
+
/* gunicode.h - Unicode manipulation functions
*
* Copyright (C) 1999, 2000 Tom Tromey
* Copyright 2000, 2005 Red Hat, Inc.
*/
-#pragma once
-
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
diff --git a/src/basic/hashmap.c b/src/basic/hashmap.c
index 6f1a049d47..85b8d812b3 100644
--- a/src/basic/hashmap.c
+++ b/src/basic/hashmap.c
@@ -176,7 +176,7 @@ enum HashmapType {
};
struct _packed_ indirect_storage {
- char *storage; /* where buckets and DIBs are stored */
+ void *storage; /* where buckets and DIBs are stored */
uint8_t hash_key[HASH_KEY_SIZE]; /* hash key; changes during resize */
unsigned n_entries; /* number of stored entries */
@@ -193,7 +193,7 @@ struct direct_storage {
/* This gives us 39 bytes on 64bit, or 35 bytes on 32bit.
* That's room for 4 set_entries + 4 DIB bytes + 3 unused bytes on 64bit,
* or 7 set_entries + 7 DIB bytes + 0 unused bytes on 32bit. */
- char storage[sizeof(struct indirect_storage)];
+ uint8_t storage[sizeof(struct indirect_storage)];
};
#define DIRECT_BUCKETS(entry_t) \
@@ -302,7 +302,7 @@ static void n_entries_dec(HashmapBase *h) {
h->n_direct_entries--;
}
-static char *storage_ptr(HashmapBase *h) {
+static void *storage_ptr(HashmapBase *h) {
return h->has_indirect ? h->indirect.storage
: h->direct.storage;
}
@@ -347,7 +347,7 @@ static void get_hash_key(uint8_t hash_key[HASH_KEY_SIZE], bool reuse_is_ok) {
static struct hashmap_base_entry *bucket_at(HashmapBase *h, unsigned idx) {
return (struct hashmap_base_entry*)
- (storage_ptr(h) + idx * hashmap_type_info[h->type].entry_size);
+ ((uint8_t*) storage_ptr(h) + idx * hashmap_type_info[h->type].entry_size);
}
static struct plain_hashmap_entry *plain_bucket_at(Hashmap *h, unsigned idx) {
@@ -381,7 +381,7 @@ static struct hashmap_base_entry *bucket_at_virtual(HashmapBase *h, struct swap_
static dib_raw_t *dib_raw_ptr(HashmapBase *h) {
return (dib_raw_t*)
- (storage_ptr(h) + hashmap_type_info[h->type].entry_size * n_buckets(h));
+ ((uint8_t*) storage_ptr(h) + hashmap_type_info[h->type].entry_size * n_buckets(h));
}
static unsigned bucket_distance(HashmapBase *h, unsigned idx, unsigned from) {
@@ -1028,7 +1028,7 @@ static int hashmap_base_put_boldly(HashmapBase *h, unsigned idx,
*/
static int resize_buckets(HashmapBase *h, unsigned entries_add) {
struct swap_entries swap;
- char *new_storage;
+ void *new_storage;
dib_raw_t *old_dibs, *new_dibs;
const struct hashmap_type_info *hi;
unsigned idx, optimal_idx;
@@ -1095,7 +1095,7 @@ static int resize_buckets(HashmapBase *h, unsigned entries_add) {
h->indirect.n_buckets = (1U << new_shift) /
(hi->entry_size + sizeof(dib_raw_t));
- old_dibs = (dib_raw_t*)(new_storage + hi->entry_size * old_n_buckets);
+ old_dibs = (dib_raw_t*)((uint8_t*) new_storage + hi->entry_size * old_n_buckets);
new_dibs = dib_raw_ptr(h);
/*
diff --git a/src/basic/hexdecoct.c b/src/basic/hexdecoct.c
index d7ad8d41f2..c5bda6c4d6 100644
--- a/src/basic/hexdecoct.c
+++ b/src/basic/hexdecoct.c
@@ -276,8 +276,8 @@ int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *_l
if (padding) {
/* strip the padding */
while (l > 0 && p[l - 1] == '=' && pad < 7) {
- pad ++;
- l --;
+ pad++;
+ l--;
}
}
@@ -505,7 +505,7 @@ int unbase64char(char c) {
if (c == '+')
return offset;
- offset ++;
+ offset++;
if (c == '/')
return offset;
@@ -621,9 +621,9 @@ int unbase64mem(const char *p, size_t l, void **mem, size_t *_len) {
/* strip the padding */
if (l > 0 && p[l - 1] == '=')
- l --;
+ l--;
if (l > 0 && p[l - 1] == '=')
- l --;
+ l--;
/* a group of four input bytes needs three output bytes, in case of
padding we need to add two or three extra bytes */
diff --git a/src/basic/hostname-util.c b/src/basic/hostname-util.c
index 4fe6a725aa..13c3bb6446 100644
--- a/src/basic/hostname-util.c
+++ b/src/basic/hostname-util.c
@@ -17,7 +17,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <bits/local_lim.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
@@ -49,6 +48,10 @@ bool hostname_is_set(void) {
char* gethostname_malloc(void) {
struct utsname u;
+ /* This call tries to return something useful, either the actual hostname
+ * or it makes something up. The only reason it might fail is OOM.
+ * It might even return "localhost" if that's set. */
+
assert_se(uname(&u) >= 0);
if (isempty(u.nodename) || streq(u.nodename, "(none)"))
@@ -57,6 +60,31 @@ char* gethostname_malloc(void) {
return strdup(u.nodename);
}
+int gethostname_strict(char **ret) {
+ struct utsname u;
+ char *k;
+
+ /* This call will rather fail than make up a name. It will not return "localhost" either. */
+
+ assert_se(uname(&u) >= 0);
+
+ if (isempty(u.nodename))
+ return -ENXIO;
+
+ if (streq(u.nodename, "(none)"))
+ return -ENXIO;
+
+ if (is_localhost(u.nodename))
+ return -ENXIO;
+
+ k = strdup(u.nodename);
+ if (!k)
+ return -ENOMEM;
+
+ *ret = k;
+ return 0;
+}
+
static bool hostname_valid_char(char c) {
return
(c >= 'a' && c <= 'z') ||
@@ -96,7 +124,7 @@ bool hostname_is_valid(const char *s, bool allow_trailing_dot) {
return false;
dot = true;
- n_dots ++;
+ n_dots++;
} else {
if (!hostname_valid_char(*p))
return false;
@@ -122,6 +150,8 @@ char* hostname_cleanup(char *s) {
assert(s);
+ strshorten(s, HOST_NAME_MAX);
+
for (p = s, d = s, dot = true; *p; p++) {
if (*p == '.') {
if (dot)
@@ -141,8 +171,6 @@ char* hostname_cleanup(char *s) {
else
*d = 0;
- strshorten(s, HOST_NAME_MAX);
-
return s;
}
diff --git a/src/basic/hostname-util.h b/src/basic/hostname-util.h
index d062eddea1..7af4e6c7ec 100644
--- a/src/basic/hostname-util.h
+++ b/src/basic/hostname-util.h
@@ -26,6 +26,7 @@
bool hostname_is_set(void);
char* gethostname_malloc(void);
+int gethostname_strict(char **ret);
bool hostname_is_valid(const char *s, bool allow_trailing_dot) _pure_;
char* hostname_cleanup(char *s);
diff --git a/src/basic/io-util.c b/src/basic/io-util.c
index 3ec8d61236..0037a37f2a 100644
--- a/src/basic/io-util.c
+++ b/src/basic/io-util.c
@@ -249,7 +249,7 @@ ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length) {
} else if (n > 0)
q += n;
else
- q ++;
+ q++;
}
if (q > w) {
diff --git a/src/basic/io-util.h b/src/basic/io-util.h
index 142c940d92..4684ed3bfc 100644
--- a/src/basic/io-util.h
+++ b/src/basic/io-util.h
@@ -46,7 +46,7 @@ ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length);
char *_s = (char *)(s); \
_i->iov_base = _s; \
_i->iov_len = strlen(_s); \
- } while(false)
+ } while (false)
static inline size_t IOVEC_TOTAL_SIZE(const struct iovec *i, unsigned n) {
unsigned j;
diff --git a/src/basic/list.h b/src/basic/list.h
index c68185f587..5962aa4211 100644
--- a/src/basic/list.h
+++ b/src/basic/list.h
@@ -32,7 +32,7 @@
#define LIST_HEAD_INIT(head) \
do { \
(head) = NULL; } \
- while(false)
+ while (false)
/* Initialize a list item */
#define LIST_INIT(name,item) \
@@ -40,7 +40,7 @@
typeof(*(item)) *_item = (item); \
assert(_item); \
_item->name##_prev = _item->name##_next = NULL; \
- } while(false)
+ } while (false)
/* Prepend an item to the list */
#define LIST_PREPEND(name,head,item) \
@@ -51,7 +51,7 @@
_item->name##_next->name##_prev = _item; \
_item->name##_prev = NULL; \
*_head = _item; \
- } while(false)
+ } while (false)
/* Append an item to the list */
#define LIST_APPEND(name,head,item) \
@@ -59,7 +59,7 @@
typeof(*(head)) *_tail; \
LIST_FIND_TAIL(name,head,_tail); \
LIST_INSERT_AFTER(name,head,_tail,item); \
- } while(false)
+ } while (false)
/* Remove an item from the list */
#define LIST_REMOVE(name,head,item) \
@@ -75,7 +75,7 @@
*_head = _item->name##_next; \
} \
_item->name##_next = _item->name##_prev = NULL; \
- } while(false)
+ } while (false)
/* Find the head of the list */
#define LIST_FIND_HEAD(name,item,head) \
@@ -119,7 +119,7 @@
_b->name##_prev = _a; \
_a->name##_next = _b; \
} \
- } while(false)
+ } while (false)
/* Insert an item before another one (a = where, b = what) */
#define LIST_INSERT_BEFORE(name,head,a,b) \
@@ -145,7 +145,7 @@
_b->name##_next = _a; \
_a->name##_prev = _b; \
} \
- } while(false)
+ } while (false)
#define LIST_JUST_US(name,item) \
(!(item)->name##_prev && !(item)->name##_next) \
diff --git a/src/basic/locale-util.c b/src/basic/locale-util.c
index cda6b2895d..eaad25e65b 100644
--- a/src/basic/locale-util.c
+++ b/src/basic/locale-util.c
@@ -153,6 +153,8 @@ static int add_locales_from_libdir (Set *locales) {
FOREACH_DIRENT(entry, dir, return -errno) {
char *z;
+ dirent_ensure_type(dir, entry);
+
if (entry->d_type != DT_DIR)
continue;
diff --git a/src/basic/log.h b/src/basic/log.h
index 60ddead74c..b6356228d9 100644
--- a/src/basic/log.h
+++ b/src/basic/log.h
@@ -193,7 +193,7 @@ void log_assert_failed_return(
#ifdef LOG_TRACE
# define log_trace(...) log_debug(__VA_ARGS__)
#else
-# define log_trace(...) do {} while(0)
+# define log_trace(...) do {} while (0)
#endif
/* Structured logging */
@@ -246,5 +246,4 @@ int log_syntax_internal(
log_syntax_internal(unit, _level, config_file, config_line, 0, __FILE__, __LINE__, __func__, \
"String is not UTF-8 clean, ignoring assignment: %s", strna(_p)); \
} \
- -EINVAL; \
})
diff --git a/src/basic/login-util.h b/src/basic/login-util.h
index 89a337d7c1..b01ee25c88 100644
--- a/src/basic/login-util.h
+++ b/src/basic/login-util.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -17,8 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
#include <stdbool.h>
#include <unistd.h>
diff --git a/src/basic/macro.h b/src/basic/macro.h
index 2695d0edb7..e41aa4260f 100644
--- a/src/basic/macro.h
+++ b/src/basic/macro.h
@@ -23,10 +23,15 @@
#include <inttypes.h>
#include <stdbool.h>
#include <sys/param.h>
+#include <sys/sysmacros.h>
#include <sys/types.h>
#define _printf_(a,b) __attribute__ ((format (printf, a, b)))
-#define _alloc_(...) __attribute__ ((alloc_size(__VA_ARGS__)))
+#ifdef __clang__
+# define _alloc_(...)
+#else
+# define _alloc_(...) __attribute__ ((alloc_size(__VA_ARGS__)))
+#endif
#define _sentinel_ __attribute__ ((sentinel))
#define _unused_ __attribute__ ((unused))
#define _destructor_ __attribute__ ((destructor))
@@ -224,7 +229,7 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) {
/* We override the glibc assert() here. */
#undef assert
#ifdef NDEBUG
-#define assert(expr) do {} while(false)
+#define assert(expr) do {} while (false)
#else
#define assert(expr) assert_message_se(expr, #expr)
#endif
@@ -361,6 +366,12 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) {
_found; \
})
+#define SWAP_TWO(x, y) do { \
+ typeof(x) _t = (x); \
+ (x) = (y); \
+ (y) = (_t); \
+ } while (false)
+
/* Define C11 thread_local attribute even on older gcc compiler
* version */
#ifndef thread_local
diff --git a/src/basic/missing.h b/src/basic/missing.h
index f3d32362bd..66cd5921ad 100644
--- a/src/basic/missing.h
+++ b/src/basic/missing.h
@@ -31,6 +31,7 @@
#include <linux/neighbour.h>
#include <linux/oom.h>
#include <linux/rtnetlink.h>
+#include <net/ethernet.h>
#include <stdlib.h>
#include <sys/resource.h>
#include <sys/syscall.h>
@@ -134,84 +135,6 @@
#define SOL_SCTP 132
#endif
-#if !HAVE_DECL_PIVOT_ROOT
-static inline int pivot_root(const char *new_root, const char *put_old) {
- return syscall(SYS_pivot_root, new_root, put_old);
-}
-#endif
-
-#ifndef __NR_memfd_create
-# if defined __x86_64__
-# define __NR_memfd_create 319
-# elif defined __arm__
-# define __NR_memfd_create 385
-# elif defined __aarch64__
-# define __NR_memfd_create 279
-# elif defined __s390__
-# define __NR_memfd_create 350
-# elif defined _MIPS_SIM
-# if _MIPS_SIM == _MIPS_SIM_ABI32
-# define __NR_memfd_create 4354
-# endif
-# if _MIPS_SIM == _MIPS_SIM_NABI32
-# define __NR_memfd_create 6318
-# endif
-# if _MIPS_SIM == _MIPS_SIM_ABI64
-# define __NR_memfd_create 5314
-# endif
-# elif defined __i386__
-# define __NR_memfd_create 356
-# else
-# warning "__NR_memfd_create unknown for your architecture"
-# define __NR_memfd_create 0xffffffff
-# endif
-#endif
-
-#if !HAVE_DECL_MEMFD_CREATE
-static inline int memfd_create(const char *name, unsigned int flags) {
- return syscall(__NR_memfd_create, name, flags);
-}
-#endif
-
-#ifndef __NR_getrandom
-# if defined __x86_64__
-# define __NR_getrandom 318
-# elif defined(__i386__)
-# define __NR_getrandom 355
-# elif defined(__arm__)
-# define __NR_getrandom 384
-# elif defined(__aarch64__)
-# define __NR_getrandom 278
-# elif defined(__ia64__)
-# define __NR_getrandom 1339
-# elif defined(__m68k__)
-# define __NR_getrandom 352
-# elif defined(__s390x__)
-# define __NR_getrandom 349
-# elif defined(__powerpc__)
-# define __NR_getrandom 359
-# elif defined _MIPS_SIM
-# if _MIPS_SIM == _MIPS_SIM_ABI32
-# define __NR_getrandom 4353
-# endif
-# if _MIPS_SIM == _MIPS_SIM_NABI32
-# define __NR_getrandom 6317
-# endif
-# if _MIPS_SIM == _MIPS_SIM_ABI64
-# define __NR_getrandom 5313
-# endif
-# else
-# warning "__NR_getrandom unknown for your architecture"
-# define __NR_getrandom 0xffffffff
-# endif
-#endif
-
-#if !HAVE_DECL_GETRANDOM
-static inline int getrandom(void *buffer, size_t count, unsigned flags) {
- return syscall(__NR_getrandom, buffer, count, flags);
-}
-#endif
-
#ifndef GRND_NONBLOCK
#define GRND_NONBLOCK 0x0001
#endif
@@ -514,6 +437,10 @@ struct btrfs_ioctl_quota_ctl_args {
#define CGROUP_SUPER_MAGIC 0x27e0eb
#endif
+#ifndef CGROUP2_SUPER_MAGIC
+#define CGROUP2_SUPER_MAGIC 0x63677270
+#endif
+
#ifndef TMPFS_MAGIC
#define TMPFS_MAGIC 0x01021994
#endif
@@ -526,12 +453,6 @@ struct btrfs_ioctl_quota_ctl_args {
#define MS_PRIVATE (1 << 18)
#endif
-#if !HAVE_DECL_GETTID
-static inline pid_t gettid(void) {
- return (pid_t) syscall(SYS_gettid);
-}
-#endif
-
#ifndef SCM_SECURITY
#define SCM_SECURITY 0x03
#endif
@@ -560,32 +481,6 @@ static inline pid_t gettid(void) {
#define MAX_HANDLE_SZ 128
#endif
-#ifndef __NR_name_to_handle_at
-# if defined(__x86_64__)
-# define __NR_name_to_handle_at 303
-# elif defined(__i386__)
-# define __NR_name_to_handle_at 341
-# elif defined(__arm__)
-# define __NR_name_to_handle_at 370
-# elif defined(__powerpc__)
-# define __NR_name_to_handle_at 345
-# else
-# error "__NR_name_to_handle_at is not defined"
-# endif
-#endif
-
-#if !HAVE_DECL_NAME_TO_HANDLE_AT
-struct file_handle {
- unsigned int handle_bytes;
- int handle_type;
- unsigned char f_handle[0];
-};
-
-static inline int name_to_handle_at(int fd, const char *name, struct file_handle *handle, int *mnt_id, int flags) {
- return syscall(__NR_name_to_handle_at, fd, name, handle, mnt_id, flags);
-}
-#endif
-
#ifndef HAVE_SECURE_GETENV
# ifdef HAVE___SECURE_GETENV
# define secure_getenv __secure_getenv
@@ -634,22 +529,6 @@ static inline int name_to_handle_at(int fd, const char *name, struct file_handle
#endif
-#ifndef __NR_setns
-# if defined(__x86_64__)
-# define __NR_setns 308
-# elif defined(__i386__)
-# define __NR_setns 346
-# else
-# error "__NR_setns is not defined"
-# endif
-#endif
-
-#if !HAVE_DECL_SETNS
-static inline int setns(int fd, int nstype) {
- return syscall(__NR_setns, fd, nstype);
-}
-#endif
-
#if !HAVE_DECL_LO_FLAGS_PARTSCAN
#define LO_FLAGS_PARTSCAN 8
#endif
@@ -883,13 +762,16 @@ static inline int setns(int fd, int nstype) {
#define IFLA_BRPORT_FAST_LEAVE 7
#define IFLA_BRPORT_LEARNING 8
#define IFLA_BRPORT_UNICAST_FLOOD 9
-#define IFLA_BRPORT_PROXYARP 10
#define IFLA_BRPORT_LEARNING_SYNC 11
#define __IFLA_BRPORT_MAX 12
#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
#endif
+#if !HAVE_DECL_IFLA_BRPORT_PROXYARP
+#define IFLA_BRPORT_PROXYARP 10
+#endif
+
#if !HAVE_DECL_NDA_IFINDEX
#define NDA_UNSPEC 0
#define NDA_DST 1
@@ -1014,69 +896,10 @@ static inline int setns(int fd, int nstype) {
#define CAP_AUDIT_READ 37
#endif
-static inline int raw_clone(unsigned long flags, void *child_stack) {
-#if defined(__s390__) || defined(__CRIS__)
- /* On s390 and cris the order of the first and second arguments
- * of the raw clone() system call is reversed. */
- return (int) syscall(__NR_clone, child_stack, flags);
-#else
- return (int) syscall(__NR_clone, flags, child_stack);
-#endif
-}
-
-static inline pid_t raw_getpid(void) {
-#if defined(__alpha__)
- return (pid_t) syscall(__NR_getxpid);
-#else
- return (pid_t) syscall(__NR_getpid);
-#endif
-}
-
-#if !HAVE_DECL_RENAMEAT2
-
-#ifndef __NR_renameat2
-# if defined __x86_64__
-# define __NR_renameat2 316
-# elif defined __arm__
-# define __NR_renameat2 382
-# elif defined _MIPS_SIM
-# if _MIPS_SIM == _MIPS_SIM_ABI32
-# define __NR_renameat2 4351
-# endif
-# if _MIPS_SIM == _MIPS_SIM_NABI32
-# define __NR_renameat2 6315
-# endif
-# if _MIPS_SIM == _MIPS_SIM_ABI64
-# define __NR_renameat2 5311
-# endif
-# elif defined __i386__
-# define __NR_renameat2 353
-# else
-# warning "__NR_renameat2 unknown for your architecture"
-# define __NR_renameat2 0xffffffff
-# endif
-#endif
-
-static inline int renameat2(int oldfd, const char *oldname, int newfd, const char *newname, unsigned flags) {
- return syscall(__NR_renameat2, oldfd, oldname, newfd, newname, flags);
-}
-#endif
-
#ifndef RENAME_NOREPLACE
#define RENAME_NOREPLACE (1 << 0)
#endif
-#if !HAVE_DECL_KCMP
-static inline int kcmp(pid_t pid1, pid_t pid2, int type, unsigned long idx1, unsigned long idx2) {
-#if defined(__NR_kcmp)
- return syscall(__NR_kcmp, pid1, pid2, type, idx1, idx2);
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-#endif
-
#ifndef KCMP_FILE
#define KCMP_FILE 0
#endif
@@ -1093,35 +916,6 @@ static inline int kcmp(pid_t pid1, pid_t pid2, int type, unsigned long idx1, uns
typedef int32_t key_serial_t;
#endif
-#if !HAVE_DECL_KEYCTL
-static inline long keyctl(int cmd, unsigned long arg2, unsigned long arg3, unsigned long arg4,unsigned long arg5) {
-#if defined(__NR_keyctl)
- return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5);
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-
-static inline key_serial_t add_key(const char *type, const char *description, const void *payload, size_t plen, key_serial_t ringid) {
-#if defined (__NR_add_key)
- return syscall(__NR_add_key, type, description, payload, plen, ringid);
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-
-static inline key_serial_t request_key(const char *type, const char *description, const char * callout_info, key_serial_t destringid) {
-#if defined (__NR_request_key)
- return syscall(__NR_request_key, type, description, callout_info, destringid);
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-#endif
-
#ifndef KEYCTL_READ
#define KEYCTL_READ 11
#endif
@@ -1168,4 +962,10 @@ static inline key_serial_t request_key(const char *type, const char *description
#define char16_t uint16_t
#endif
+#ifndef ETHERTYPE_LLDP
+#define ETHERTYPE_LLDP 0x88cc
#endif
+
+#endif
+
+#include "missing_syscall.h"
diff --git a/src/basic/missing_syscall.h b/src/basic/missing_syscall.h
new file mode 100644
index 0000000000..d502d3b9ca
--- /dev/null
+++ b/src/basic/missing_syscall.h
@@ -0,0 +1,310 @@
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+ Copyright 2016 Zbigniew Jędrzejewski-Szmek
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+/* Missing glibc definitions to access certain kernel APIs */
+
+#if !HAVE_DECL_PIVOT_ROOT
+static inline int pivot_root(const char *new_root, const char *put_old) {
+ return syscall(SYS_pivot_root, new_root, put_old);
+}
+#endif
+
+/* ======================================================================= */
+
+#if !HAVE_DECL_MEMFD_CREATE
+# ifndef __NR_memfd_create
+# if defined __x86_64__
+# define __NR_memfd_create 319
+# elif defined __arm__
+# define __NR_memfd_create 385
+# elif defined __aarch64__
+# define __NR_memfd_create 279
+# elif defined __s390__
+# define __NR_memfd_create 350
+# elif defined _MIPS_SIM
+# if _MIPS_SIM == _MIPS_SIM_ABI32
+# define __NR_memfd_create 4354
+# endif
+# if _MIPS_SIM == _MIPS_SIM_NABI32
+# define __NR_memfd_create 6318
+# endif
+# if _MIPS_SIM == _MIPS_SIM_ABI64
+# define __NR_memfd_create 5314
+# endif
+# elif defined __i386__
+# define __NR_memfd_create 356
+# else
+# warning "__NR_memfd_create unknown for your architecture"
+# endif
+# endif
+
+static inline int memfd_create(const char *name, unsigned int flags) {
+# ifdef __NR_memfd_create
+ return syscall(__NR_memfd_create, name, flags);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+#endif
+
+/* ======================================================================= */
+
+#if !HAVE_DECL_GETRANDOM
+# ifndef __NR_getrandom
+# if defined __x86_64__
+# define __NR_getrandom 318
+# elif defined(__i386__)
+# define __NR_getrandom 355
+# elif defined(__arm__)
+# define __NR_getrandom 384
+# elif defined(__aarch64__)
+# define __NR_getrandom 278
+# elif defined(__ia64__)
+# define __NR_getrandom 1339
+# elif defined(__m68k__)
+# define __NR_getrandom 352
+# elif defined(__s390x__)
+# define __NR_getrandom 349
+# elif defined(__powerpc__)
+# define __NR_getrandom 359
+# elif defined _MIPS_SIM
+# if _MIPS_SIM == _MIPS_SIM_ABI32
+# define __NR_getrandom 4353
+# endif
+# if _MIPS_SIM == _MIPS_SIM_NABI32
+# define __NR_getrandom 6317
+# endif
+# if _MIPS_SIM == _MIPS_SIM_ABI64
+# define __NR_getrandom 5313
+# endif
+# else
+# warning "__NR_getrandom unknown for your architecture"
+# endif
+# endif
+
+static inline int getrandom(void *buffer, size_t count, unsigned flags) {
+# ifdef __NR_getrandom
+ return syscall(__NR_getrandom, buffer, count, flags);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+#endif
+
+/* ======================================================================= */
+
+#if !HAVE_DECL_GETTID
+static inline pid_t gettid(void) {
+ return (pid_t) syscall(SYS_gettid);
+}
+#endif
+
+/* ======================================================================= */
+
+#if !HAVE_DECL_NAME_TO_HANDLE_AT
+# ifndef __NR_name_to_handle_at
+# if defined(__x86_64__)
+# define __NR_name_to_handle_at 303
+# elif defined(__i386__)
+# define __NR_name_to_handle_at 341
+# elif defined(__arm__)
+# define __NR_name_to_handle_at 370
+# elif defined(__powerpc__)
+# define __NR_name_to_handle_at 345
+# else
+# error "__NR_name_to_handle_at is not defined"
+# endif
+# endif
+
+struct file_handle {
+ unsigned int handle_bytes;
+ int handle_type;
+ unsigned char f_handle[0];
+};
+
+static inline int name_to_handle_at(int fd, const char *name, struct file_handle *handle, int *mnt_id, int flags) {
+# ifdef __NR_name_to_handle_at
+ return syscall(__NR_name_to_handle_at, fd, name, handle, mnt_id, flags);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+#endif
+
+/* ======================================================================= */
+
+#if !HAVE_DECL_SETNS
+# ifndef __NR_setns
+# if defined(__x86_64__)
+# define __NR_setns 308
+# elif defined(__i386__)
+# define __NR_setns 346
+# else
+# error "__NR_setns is not defined"
+# endif
+# endif
+
+static inline int setns(int fd, int nstype) {
+# ifdef __NR_setns
+ return syscall(__NR_setns, fd, nstype);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+#endif
+
+/* ======================================================================= */
+
+static inline int raw_clone(unsigned long flags, void *child_stack) {
+#if defined(__s390__) || defined(__CRIS__)
+ /* On s390 and cris the order of the first and second arguments
+ * of the raw clone() system call is reversed. */
+ return (int) syscall(__NR_clone, child_stack, flags);
+#else
+ return (int) syscall(__NR_clone, flags, child_stack);
+#endif
+}
+
+/* ======================================================================= */
+
+static inline pid_t raw_getpid(void) {
+#if defined(__alpha__)
+ return (pid_t) syscall(__NR_getxpid);
+#else
+ return (pid_t) syscall(__NR_getpid);
+#endif
+}
+
+/* ======================================================================= */
+
+#if !HAVE_DECL_RENAMEAT2
+# ifndef __NR_renameat2
+# if defined __x86_64__
+# define __NR_renameat2 316
+# elif defined __arm__
+# define __NR_renameat2 382
+# elif defined _MIPS_SIM
+# if _MIPS_SIM == _MIPS_SIM_ABI32
+# define __NR_renameat2 4351
+# endif
+# if _MIPS_SIM == _MIPS_SIM_NABI32
+# define __NR_renameat2 6315
+# endif
+# if _MIPS_SIM == _MIPS_SIM_ABI64
+# define __NR_renameat2 5311
+# endif
+# elif defined __i386__
+# define __NR_renameat2 353
+# else
+# warning "__NR_renameat2 unknown for your architecture"
+# endif
+# endif
+
+static inline int renameat2(int oldfd, const char *oldname, int newfd, const char *newname, unsigned flags) {
+# ifdef __NR_renameat2
+ return syscall(__NR_renameat2, oldfd, oldname, newfd, newname, flags);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+#endif
+
+/* ======================================================================= */
+
+#if !HAVE_DECL_KCMP
+static inline int kcmp(pid_t pid1, pid_t pid2, int type, unsigned long idx1, unsigned long idx2) {
+# ifdef __NR_kcmp
+ return syscall(__NR_kcmp, pid1, pid2, type, idx1, idx2);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+#endif
+
+/* ======================================================================= */
+
+#if !HAVE_DECL_KEYCTL
+static inline long keyctl(int cmd, unsigned long arg2, unsigned long arg3, unsigned long arg4,unsigned long arg5) {
+# ifdef __NR_keyctl
+ return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+
+static inline key_serial_t add_key(const char *type, const char *description, const void *payload, size_t plen, key_serial_t ringid) {
+# ifdef __NR_add_key
+ return syscall(__NR_add_key, type, description, payload, plen, ringid);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+
+static inline key_serial_t request_key(const char *type, const char *description, const char * callout_info, key_serial_t destringid) {
+# ifdef __NR_request_key
+ return syscall(__NR_request_key, type, description, callout_info, destringid);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+#endif
+
+/* ======================================================================= */
+
+#if !HAVE_DECL_COPY_FILE_RANGE
+# ifndef __NR_copy_file_range
+# if defined(__x86_64__)
+# define __NR_copy_file_range 326
+# elif defined(__i386__)
+# define __NR_copy_file_range 377
+# elif defined __s390__
+# define __NR_copy_file_range 375
+# elif defined __arm__
+# define __NR_copy_file_range 391
+# elif defined __aarch64__
+# define __NR_copy_file_range 285
+# else
+# warning "__NR_copy_file_range not defined for your architecture"
+# endif
+# endif
+
+static inline ssize_t copy_file_range(int fd_in, loff_t *off_in,
+ int fd_out, loff_t *off_out,
+ size_t len,
+ unsigned int flags) {
+# ifdef __NR_copy_file_range
+ return syscall(__NR_copy_file_range, fd_in, off_in, fd_out, off_out, len, flags);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+#endif
diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c
index 33f2ee96d8..5faa2eba05 100644
--- a/src/basic/mount-util.c
+++ b/src/basic/mount-util.c
@@ -47,7 +47,7 @@ static int fd_fdinfo_mnt_id(int fd, const char *filename, int flags, int *mnt_id
if ((flags & AT_EMPTY_PATH) && isempty(filename))
xsprintf(path, "/proc/self/fdinfo/%i", fd);
else {
- subfd = openat(fd, filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_PATH);
+ subfd = openat(fd, filename, O_CLOEXEC|O_PATH);
if (subfd < 0)
return -errno;
@@ -230,7 +230,7 @@ int path_is_mount_point(const char *t, int flags) {
if (!parent)
return -ENOMEM;
- fd = openat(AT_FDCWD, parent, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_PATH);
+ fd = openat(AT_FDCWD, parent, O_DIRECTORY|O_CLOEXEC|O_PATH);
if (fd < 0)
return -errno;
diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c
index a3cb81b040..6c11b605a9 100644
--- a/src/basic/parse-util.c
+++ b/src/basic/parse-util.c
@@ -505,7 +505,7 @@ int parse_fractional_part_u(const char **p, size_t digits, unsigned *res) {
s = *p;
/* accept any number of digits, strtoull is limted to 19 */
- for(i=0; i < digits; i++,s++) {
+ for (i=0; i < digits; i++,s++) {
if (*s < '0' || *s > '9') {
if (i == 0)
return -EINVAL;
diff --git a/src/basic/process-util.c b/src/basic/process-util.c
index 189ef9ab60..ae3f6109ad 100644
--- a/src/basic/process-util.c
+++ b/src/basic/process-util.c
@@ -38,6 +38,7 @@
#endif
#include "alloc-util.h"
+#include "architecture.h"
#include "escape.h"
#include "fd-util.h"
#include "fileio.h"
@@ -205,7 +206,7 @@ void rename_process(const char name[8]) {
* "systemd"). If you pass a longer string it will be
* truncated */
- prctl(PR_SET_NAME, name);
+ (void) prctl(PR_SET_NAME, name);
if (program_invocation_name)
strncpy(program_invocation_name, name, strlen(program_invocation_name));
@@ -674,75 +675,43 @@ bool oom_score_adjust_is_valid(int oa) {
}
unsigned long personality_from_string(const char *p) {
+ int architecture;
- /* Parse a personality specifier. We introduce our own
- * identifiers that indicate specific ABIs, rather than just
- * hints regarding the register size, since we want to keep
- * things open for multiple locally supported ABIs for the
- * same register size. We try to reuse the ABI identifiers
- * used by libseccomp. */
+ if (!p)
+ return PERSONALITY_INVALID;
-#if defined(__x86_64__)
+ /* Parse a personality specifier. We use our own identifiers that indicate specific ABIs, rather than just
+ * hints regarding the register size, since we want to keep things open for multiple locally supported ABIs for
+ * the same register size. */
- if (streq(p, "x86"))
- return PER_LINUX32;
+ architecture = architecture_from_string(p);
+ if (architecture < 0)
+ return PERSONALITY_INVALID;
- if (streq(p, "x86-64"))
+ if (architecture == native_architecture())
return PER_LINUX;
-
-#elif defined(__i386__)
-
- if (streq(p, "x86"))
- return PER_LINUX;
-
-#elif defined(__s390x__)
-
- if (streq(p, "s390"))
+#ifdef SECONDARY_ARCHITECTURE
+ if (architecture == SECONDARY_ARCHITECTURE)
return PER_LINUX32;
-
- if (streq(p, "s390x"))
- return PER_LINUX;
-
-#elif defined(__s390__)
-
- if (streq(p, "s390"))
- return PER_LINUX;
#endif
return PERSONALITY_INVALID;
}
const char* personality_to_string(unsigned long p) {
-
-#if defined(__x86_64__)
-
- if (p == PER_LINUX32)
- return "x86";
-
- if (p == PER_LINUX)
- return "x86-64";
-
-#elif defined(__i386__)
-
- if (p == PER_LINUX)
- return "x86";
-
-#elif defined(__s390x__)
+ int architecture = _ARCHITECTURE_INVALID;
if (p == PER_LINUX)
- return "s390x";
-
- if (p == PER_LINUX32)
- return "s390";
-
-#elif defined(__s390__)
-
- if (p == PER_LINUX)
- return "s390";
-
+ architecture = native_architecture();
+#ifdef SECONDARY_ARCHITECTURE
+ else if (p == PER_LINUX32)
+ architecture = SECONDARY_ARCHITECTURE;
#endif
- return NULL;
+ if (architecture < 0)
+ return NULL;
+
+ return architecture_to_string(architecture);
}
void valgrind_summary_hack(void) {
diff --git a/src/basic/selinux-util.c b/src/basic/selinux-util.c
index 6c63b9d652..10c2f39369 100644
--- a/src/basic/selinux-util.c
+++ b/src/basic/selinux-util.c
@@ -80,31 +80,23 @@ void mac_selinux_retest(void) {
#endif
}
-int mac_selinux_init(const char *prefix) {
+int mac_selinux_init(void) {
int r = 0;
#ifdef HAVE_SELINUX
usec_t before_timestamp, after_timestamp;
struct mallinfo before_mallinfo, after_mallinfo;
- if (!mac_selinux_use())
+ if (label_hnd)
return 0;
- if (label_hnd)
+ if (!mac_selinux_use())
return 0;
before_mallinfo = mallinfo();
before_timestamp = now(CLOCK_MONOTONIC);
- if (prefix) {
- struct selinux_opt options[] = {
- { .type = SELABEL_OPT_SUBSET, .value = prefix },
- };
-
- label_hnd = selabel_open(SELABEL_CTX_FILE, options, ELEMENTSOF(options));
- } else
- label_hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0);
-
+ label_hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0);
if (!label_hnd) {
log_enforcing("Failed to initialize SELinux context: %m");
r = security_getenforce() == 1 ? -errno : 0;
@@ -160,7 +152,7 @@ int mac_selinux_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
return 0;
if (r >= 0) {
- r = lsetfilecon(path, fcon);
+ r = lsetfilecon_raw(path, fcon);
/* If the FS doesn't support labels, then exit without warning */
if (r < 0 && errno == EOPNOTSUPP)
@@ -225,7 +217,7 @@ int mac_selinux_get_create_label_from_exe(const char *exe, char **label) {
return -errno;
sclass = string_to_security_class("process");
- r = security_compute_create(mycon, fcon, sclass, (security_context_t *) label);
+ r = security_compute_create_raw(mycon, fcon, sclass, (security_context_t *) label);
if (r < 0)
return -errno;
#endif
@@ -270,7 +262,7 @@ int mac_selinux_get_child_mls_label(int socket_fd, const char *exe, const char *
if (r < 0)
return -errno;
- r = getpeercon(socket_fd, &peercon);
+ r = getpeercon_raw(socket_fd, &peercon);
if (r < 0)
return -errno;
@@ -304,7 +296,7 @@ int mac_selinux_get_child_mls_label(int socket_fd, const char *exe, const char *
return -ENOMEM;
sclass = string_to_security_class("process");
- r = security_compute_create(mycon, fcon, sclass, (security_context_t *) label);
+ r = security_compute_create_raw(mycon, fcon, sclass, (security_context_t *) label);
if (r < 0)
return -errno;
#endif
@@ -358,7 +350,7 @@ int mac_selinux_create_file_prepare(const char *path, mode_t mode) {
log_enforcing("Failed to determine SELinux security context for %s: %m", path);
} else {
- if (setfscreatecon(filecon) >= 0)
+ if (setfscreatecon_raw(filecon) >= 0)
return 0; /* Success! */
log_enforcing("Failed to set SELinux security context %s for %s: %m", filecon, path);
@@ -379,7 +371,7 @@ void mac_selinux_create_file_clear(void) {
if (!mac_selinux_use())
return;
- setfscreatecon(NULL);
+ setfscreatecon_raw(NULL);
#endif
}
@@ -410,7 +402,7 @@ void mac_selinux_create_socket_clear(void) {
if (!mac_selinux_use())
return;
- setsockcreatecon(NULL);
+ setsockcreatecon_raw(NULL);
#endif
}
@@ -469,7 +461,7 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
return -errno;
} else {
- if (setfscreatecon(fcon) < 0) {
+ if (setfscreatecon_raw(fcon) < 0) {
log_enforcing("Failed to set SELinux security context %s for %s: %m", fcon, path);
if (security_getenforce() > 0)
return -errno;
@@ -480,7 +472,7 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
r = bind(fd, addr, addrlen) < 0 ? -errno : 0;
if (context_changed)
- setfscreatecon(NULL);
+ setfscreatecon_raw(NULL);
return r;
diff --git a/src/basic/selinux-util.h b/src/basic/selinux-util.h
index 27e8edb41b..ce6bc8e44c 100644
--- a/src/basic/selinux-util.h
+++ b/src/basic/selinux-util.h
@@ -29,7 +29,7 @@ bool mac_selinux_use(void);
bool mac_selinux_have(void);
void mac_selinux_retest(void);
-int mac_selinux_init(const char *prefix);
+int mac_selinux_init(void);
void mac_selinux_finish(void);
int mac_selinux_fix(const char *path, bool ignore_enoent, bool ignore_erofs);
diff --git a/src/basic/set.h b/src/basic/set.h
index 2bff5062da..e0d9dd001c 100644
--- a/src/basic/set.h
+++ b/src/basic/set.h
@@ -126,6 +126,9 @@ int set_put_strdupv(Set *s, char **l);
#define SET_FOREACH(e, s, i) \
for ((i) = ITERATOR_FIRST; set_iterate((s), &(i), (void**)&(e)); )
+#define SET_FOREACH_MOVE(e, d, s) \
+ for (; ({ e = set_first(s); assert_se(!e || set_move_one(d, s, e) >= 0); e; }); )
+
DEFINE_TRIVIAL_CLEANUP_FUNC(Set*, set_free);
DEFINE_TRIVIAL_CLEANUP_FUNC(Set*, set_free_free);
diff --git a/src/basic/sigbus.h b/src/basic/sigbus.h
index cce9eb201b..980243d9ce 100644
--- a/src/basic/sigbus.h
+++ b/src/basic/sigbus.h
@@ -1,3 +1,5 @@
+#pragma once
+
/***
This file is part of systemd.
@@ -17,8 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
void sigbus_install(void);
void sigbus_reset(void);
diff --git a/src/basic/signal-util.h b/src/basic/signal-util.h
index 72b10e8712..a7322ff26a 100644
--- a/src/basic/signal-util.h
+++ b/src/basic/signal-util.h
@@ -44,9 +44,9 @@ static inline void block_signals_reset(sigset_t *ss) {
assert_se(sigprocmask(SIG_SETMASK, ss, NULL) >= 0);
}
-#define BLOCK_SIGNALS(...) \
- _cleanup_(block_signals_reset) sigset_t _saved_sigset = ({ \
- sigset_t t; \
+#define BLOCK_SIGNALS(...) \
+ _cleanup_(block_signals_reset) _unused_ sigset_t _saved_sigset = ({ \
+ sigset_t t; \
assert_se(sigprocmask_many(SIG_BLOCK, &t, __VA_ARGS__, -1) >= 0); \
- t; \
+ t; \
})
diff --git a/src/basic/socket-label.c b/src/basic/socket-label.c
index 35e9573aa4..6d1dc83874 100644
--- a/src/basic/socket-label.c
+++ b/src/basic/socket-label.c
@@ -23,7 +23,6 @@
#include <stddef.h>
#include <string.h>
#include <sys/socket.h>
-#include <sys/stat.h>
#include <sys/un.h>
#include <unistd.h>
@@ -35,6 +34,7 @@
#include "mkdir.h"
#include "selinux-util.h"
#include "socket-util.h"
+#include "umask-util.h"
int socket_address_listen(
const SocketAddress *a,
@@ -112,28 +112,24 @@ int socket_address_listen(
return -errno;
if (socket_address_family(a) == AF_UNIX && a->sockaddr.un.sun_path[0] != 0) {
- mode_t old_mask;
-
/* Create parents */
- mkdir_parents_label(a->sockaddr.un.sun_path, directory_mode);
+ (void) mkdir_parents_label(a->sockaddr.un.sun_path, directory_mode);
/* Enforce the right access mode for the socket */
- old_mask = umask(~ socket_mode);
-
- r = mac_selinux_bind(fd, &a->sockaddr.sa, a->size);
-
- if (r < 0 && errno == EADDRINUSE) {
- /* Unlink and try again */
- unlink(a->sockaddr.un.sun_path);
- r = bind(fd, &a->sockaddr.sa, a->size);
+ RUN_WITH_UMASK(~socket_mode) {
+ r = mac_selinux_bind(fd, &a->sockaddr.sa, a->size);
+ if (r == -EADDRINUSE) {
+ /* Unlink and try again */
+ unlink(a->sockaddr.un.sun_path);
+ if (bind(fd, &a->sockaddr.sa, a->size) < 0)
+ return -errno;
+ } else if (r < 0)
+ return r;
}
-
- umask(old_mask);
- } else
- r = bind(fd, &a->sockaddr.sa, a->size);
-
- if (r < 0)
- return -errno;
+ } else {
+ if (bind(fd, &a->sockaddr.sa, a->size) < 0)
+ return -errno;
+ }
if (socket_address_can_accept(a))
if (listen(fd, backlog) < 0)
diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c
index 58512686e3..0f38f9a0f3 100644
--- a/src/basic/socket-util.c
+++ b/src/basic/socket-util.c
@@ -942,7 +942,7 @@ ssize_t next_datagram_size_fd(int fd) {
int k;
/* This is a bit like FIONREAD/SIOCINQ, however a bit more powerful. The difference being: recv(MSG_PEEK) will
- * actually cause the next datagram in the queue to be validated regarding checksums, which FIONREAD dosn't
+ * actually cause the next datagram in the queue to be validated regarding checksums, which FIONREAD doesn't
* do. This difference is actually of major importance as we need to be sure that the size returned here
* actually matches what we will read with recvmsg() next, as otherwise we might end up allocating a buffer of
* the wrong size. */
diff --git a/src/basic/stdio-util.h b/src/basic/stdio-util.h
index 0a675571ff..bd1144b4c9 100644
--- a/src/basic/stdio-util.h
+++ b/src/basic/stdio-util.h
@@ -73,4 +73,4 @@ do { \
assert_not_reached("Unknown format string argument."); \
} \
} \
-} while(false)
+} while (false)
diff --git a/src/basic/strbuf.c b/src/basic/strbuf.c
index 77220c0251..797f00cf71 100644
--- a/src/basic/strbuf.c
+++ b/src/basic/strbuf.c
@@ -121,7 +121,7 @@ static void bubbleinsert(struct strbuf_node *node,
sizeof(struct strbuf_child_entry) * (node->children_count - left));
node->children[left] = new;
- node->children_count ++;
+ node->children_count++;
}
/* add string, return the index/offset into the buffer */
@@ -156,6 +156,10 @@ ssize_t strbuf_add_string(struct strbuf *str, const char *s, size_t len) {
return off;
}
+ /* bsearch is not allowed on a NULL sequence */
+ if (node->children_count == 0)
+ break;
+
/* lookup child node */
c = s[len - 1 - depth];
search.c = c;
diff --git a/src/basic/string-util.c b/src/basic/string-util.c
index 0bde55f9d5..293a15f9c0 100644
--- a/src/basic/string-util.c
+++ b/src/basic/string-util.c
@@ -477,7 +477,7 @@ char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigne
}
if (k > x) /* last character was wide and went over quota */
- x ++;
+ x++;
for (j = s + old_length; k < new_length && j > i; ) {
char32_t c;
diff --git a/src/basic/time-util.c b/src/basic/time-util.c
index 0b4f5ab5b9..7ca764abeb 100644
--- a/src/basic/time-util.c
+++ b/src/basic/time-util.c
@@ -139,8 +139,7 @@ dual_timestamp* dual_timestamp_from_boottime_or_monotonic(dual_timestamp *ts, us
usec_t timespec_load(const struct timespec *ts) {
assert(ts);
- if (ts->tv_sec == (time_t) -1 &&
- ts->tv_nsec == (long) -1)
+ if (ts->tv_sec == (time_t) -1 && ts->tv_nsec == (long) -1)
return USEC_INFINITY;
if ((usec_t) ts->tv_sec > (UINT64_MAX - (ts->tv_nsec / NSEC_PER_USEC)) / USEC_PER_SEC)
@@ -154,13 +153,13 @@ usec_t timespec_load(const struct timespec *ts) {
static nsec_t timespec_load_nsec(const struct timespec *ts) {
assert(ts);
- if (ts->tv_sec == (time_t) -1 &&
- ts->tv_nsec == (long) -1)
+ if (ts->tv_sec == (time_t) -1 && ts->tv_nsec == (long) -1)
return NSEC_INFINITY;
- return
- (nsec_t) ts->tv_sec * NSEC_PER_SEC +
- (nsec_t) ts->tv_nsec;
+ if ((nsec_t) ts->tv_sec >= (UINT64_MAX - ts->tv_nsec) / NSEC_PER_SEC)
+ return NSEC_INFINITY;
+
+ return (nsec_t) ts->tv_sec * NSEC_PER_SEC + (nsec_t) ts->tv_nsec;
}
struct timespec *timespec_store(struct timespec *ts, usec_t u) {
@@ -577,12 +576,12 @@ int parse_timestamp(const char *t, usec_t *usec) {
goto from_tm;
} else if (streq(t, "yesterday")) {
- tm.tm_mday --;
+ tm.tm_mday--;
tm.tm_sec = tm.tm_min = tm.tm_hour = 0;
goto from_tm;
} else if (streq(t, "tomorrow")) {
- tm.tm_mday ++;
+ tm.tm_mday++;
tm.tm_sec = tm.tm_min = tm.tm_hour = 0;
goto from_tm;
}
@@ -705,8 +704,7 @@ finish:
return 0;
}
-int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
-
+static char* extract_multiplier(char *p, usec_t *multiplier) {
static const struct {
const char *suffix;
usec_t usec;
@@ -740,7 +738,22 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
{ "usec", 1ULL },
{ "us", 1ULL },
};
+ unsigned i;
+
+ for (i = 0; i < ELEMENTSOF(table); i++) {
+ char *e;
+
+ e = startswith(p, table[i].suffix);
+ if (e) {
+ *multiplier = table[i].usec;
+ return e;
+ }
+ }
+
+ return p;
+}
+int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
const char *p, *s;
usec_t r = 0;
bool something = false;
@@ -765,8 +778,8 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
for (;;) {
long long l, z = 0;
char *e;
- unsigned i, n = 0;
- usec_t multiplier, k;
+ unsigned n = 0;
+ usec_t multiplier = default_unit, k;
p += strspn(p, WHITESPACE);
@@ -779,10 +792,8 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
errno = 0;
l = strtoll(p, &e, 10);
-
if (errno > 0)
return -errno;
-
if (l < 0)
return -ERANGE;
@@ -806,18 +817,7 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
return -EINVAL;
e += strspn(e, WHITESPACE);
-
- for (i = 0; i < ELEMENTSOF(table); i++)
- if (startswith(e, table[i].suffix)) {
- multiplier = table[i].usec;
- p = e + strlen(table[i].suffix);
- break;
- }
-
- if (i >= ELEMENTSOF(table)) {
- multiplier = default_unit;
- p = e;
- }
+ p = extract_multiplier(e, &multiplier);
something = true;
diff --git a/src/basic/utf8.c b/src/basic/utf8.c
index 629db123cd..6eae2b983d 100644
--- a/src/basic/utf8.c
+++ b/src/basic/utf8.c
@@ -241,7 +241,7 @@ char *utf8_escape_non_printable(const char *str) {
*(s++) = hexchar((int) *str);
str += 1;
- len --;
+ len--;
}
}
} else {
diff --git a/src/basic/utf8.h b/src/basic/utf8.h
index 12c272d66e..f9b9c9468b 100644
--- a/src/basic/utf8.h
+++ b/src/basic/utf8.h
@@ -28,6 +28,7 @@
#include "missing.h"
#define UTF8_REPLACEMENT_CHARACTER "\xef\xbf\xbd"
+#define UTF8_BYTE_ORDER_MARK "\xef\xbb\xbf"
bool unichar_is_valid(char32_t c);
diff --git a/src/basic/util.h b/src/basic/util.h
index e095254b57..286db05159 100644
--- a/src/basic/util.h
+++ b/src/basic/util.h
@@ -36,6 +36,7 @@
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/statfs.h>
+#include <sys/sysmacros.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
diff --git a/src/basic/virt.c b/src/basic/virt.c
index 19b6318e3d..e6c5a095a0 100644
--- a/src/basic/virt.c
+++ b/src/basic/virt.c
@@ -98,6 +98,8 @@ static int detect_vm_cpuid(void) {
: "0" (eax)
);
+ log_debug("Virtualization found, CPUID=%s", sig.text);
+
for (j = 0; j < ELEMENTSOF(cpuid_vendor_table); j ++)
if (streq(sig.text, cpuid_vendor_table[j].cpuid))
return cpuid_vendor_table[j].id;
@@ -105,6 +107,7 @@ static int detect_vm_cpuid(void) {
return VIRTUALIZATION_VM_OTHER;
}
#endif
+ log_debug("No virtualization found in CPUID");
return VIRTUALIZATION_NONE;
}
@@ -121,19 +124,25 @@ static int detect_vm_device_tree(void) {
dir = opendir("/proc/device-tree");
if (!dir) {
- if (errno == ENOENT)
+ if (errno == ENOENT) {
+ log_debug_errno(errno, "/proc/device-tree: %m");
return VIRTUALIZATION_NONE;
+ }
return -errno;
}
FOREACH_DIRENT(dent, dir, return -errno)
- if (strstr(dent->d_name, "fw-cfg"))
+ if (strstr(dent->d_name, "fw-cfg")) {
+ log_debug("Virtualization QEMU: \"fw-cfg\" present in /proc/device-tree/%s", dent->d_name);
return VIRTUALIZATION_QEMU;
+ }
+ log_debug("No virtualization found in /proc/device-tree/*");
return VIRTUALIZATION_NONE;
} else if (r < 0)
return r;
+ log_debug("Virtualization %s found in /proc/device-tree/hypervisor/compatible", hvtype);
if (streq(hvtype, "linux,kvm"))
return VIRTUALIZATION_KVM;
else if (strstr(hvtype, "xen"))
@@ -141,6 +150,7 @@ static int detect_vm_device_tree(void) {
else
return VIRTUALIZATION_VM_OTHER;
#else
+ log_debug("This platform does not support /proc/device-tree");
return VIRTUALIZATION_NONE;
#endif
}
@@ -184,30 +194,58 @@ static int detect_vm_dmi(void) {
return r;
}
+
+
for (j = 0; j < ELEMENTSOF(dmi_vendor_table); j++)
- if (startswith(s, dmi_vendor_table[j].vendor))
+ if (startswith(s, dmi_vendor_table[j].vendor)) {
+ log_debug("Virtualization %s found in DMI (%s)", s, dmi_vendors[i]);
return dmi_vendor_table[j].id;
+ }
}
#endif
+ log_debug("No virtualization found in DMI");
+
return VIRTUALIZATION_NONE;
}
static int detect_vm_xen(void) {
+ /* Check for Dom0 will be executed later in detect_vm_xen_dom0
+ Thats why we dont check the content of /proc/xen/capabilities here. */
+ if (access("/proc/xen/capabilities", F_OK) < 0) {
+ log_debug("Virtualization XEN not found, /proc/xen/capabilities does not exist");
+ return VIRTUALIZATION_NONE;
+ }
+
+ log_debug("Virtualization XEN found (/proc/xen/capabilities exists)");
+ return VIRTUALIZATION_XEN;
+
+}
+
+static bool detect_vm_xen_dom0(void) {
_cleanup_free_ char *domcap = NULL;
char *cap, *i;
int r;
r = read_one_line_file("/proc/xen/capabilities", &domcap);
- if (r == -ENOENT)
- return VIRTUALIZATION_NONE;
+ if (r == -ENOENT) {
+ log_debug("Virtualization XEN not found, /proc/xen/capabilities does not exist");
+ return false;
+ }
+ if (r < 0)
+ return r;
i = domcap;
while ((cap = strsep(&i, ",")))
if (streq(cap, "control_d"))
break;
+ if (!cap) {
+ log_debug("Virtualization XEN DomU found (/proc/xen/capabilites)");
+ return false;
+ }
- return cap ? VIRTUALIZATION_NONE : VIRTUALIZATION_XEN;
+ log_debug("Virtualization XEN Dom0 ignored (/proc/xen/capabilities)");
+ return true;
}
static int detect_vm_hypervisor(void) {
@@ -220,6 +258,8 @@ static int detect_vm_hypervisor(void) {
if (r < 0)
return r;
+ log_debug("Virtualization %s found in /sys/hypervisor/type", hvtype);
+
if (streq(hvtype, "xen"))
return VIRTUALIZATION_XEN;
else
@@ -234,9 +274,13 @@ static int detect_vm_uml(void) {
r = read_full_file("/proc/cpuinfo", &cpuinfo_contents, NULL);
if (r < 0)
return r;
- if (strstr(cpuinfo_contents, "\nvendor_id\t: User Mode Linux\n"))
+
+ if (strstr(cpuinfo_contents, "\nvendor_id\t: User Mode Linux\n")) {
+ log_debug("UML virtualization found in /proc/cpuinfo");
return VIRTUALIZATION_UML;
+ }
+ log_debug("No virtualization found in /proc/cpuinfo (%s)", cpuinfo_contents);
return VIRTUALIZATION_NONE;
}
@@ -252,11 +296,13 @@ static int detect_vm_zvm(void) {
if (r < 0)
return r;
+ log_debug("Virtualization %s found in /proc/sysinfo", t);
if (streq(t, "z/VM"))
return VIRTUALIZATION_ZVM;
else
return VIRTUALIZATION_KVM;
#else
+ log_debug("This platform does not support /proc/sysinfo");
return VIRTUALIZATION_NONE;
#endif
}
@@ -324,7 +370,14 @@ int detect_vm(void) {
return r;
finish:
+ /* x86 xen Dom0 is detected as XEN in hypervisor and maybe others.
+ * In order to detect the Dom0 as not virtualization we need to
+ * double-check it */
+ if (r == VIRTUALIZATION_XEN && detect_vm_xen_dom0())
+ r = VIRTUALIZATION_NONE;
+
cached_found = r;
+ log_debug("Found VM virtualization %s", virtualization_to_string(r));
return r;
}
@@ -412,6 +465,7 @@ int detect_container(void) {
r = VIRTUALIZATION_CONTAINER_OTHER;
finish:
+ log_debug("Found container virtualization %s", virtualization_to_string(r));
cached_found = r;
return r;
}
@@ -420,10 +474,10 @@ int detect_virtualization(void) {
int r;
r = detect_container();
- if (r != 0)
- return r;
+ if (r == 0)
+ r = detect_vm();
- return detect_vm();
+ return r;
}
int running_in_chroot(void) {
diff --git a/src/basic/xattr-util.c b/src/basic/xattr-util.c
index 8d7f14f382..8256899eda 100644
--- a/src/basic/xattr-util.c
+++ b/src/basic/xattr-util.c
@@ -110,7 +110,7 @@ ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute,
/* The kernel doesn't have a fgetxattrat() command, hence let's emulate one */
- fd = openat(dirfd, filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_PATH|(flags & AT_SYMLINK_NOFOLLOW ? O_NOFOLLOW : 0));
+ fd = openat(dirfd, filename, O_CLOEXEC|O_PATH|(flags & AT_SYMLINK_NOFOLLOW ? O_NOFOLLOW : 0));
if (fd < 0)
return -errno;