summaryrefslogtreecommitdiff
path: root/src/libsystemd
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsystemd')
-rw-r--r--src/libsystemd/libsystemd.sym2
-rw-r--r--src/libsystemd/sd-bus/bus-container.c11
-rw-r--r--src/libsystemd/sd-bus/busctl.c23
-rw-r--r--src/libsystemd/sd-bus/sd-bus.c165
-rw-r--r--src/libsystemd/sd-bus/test-bus-marshal.c31
-rw-r--r--src/libsystemd/sd-daemon/sd-daemon.c16
-rw-r--r--src/libsystemd/sd-device/device-enumerator.c6
-rw-r--r--src/libsystemd/sd-device/device-private.c8
-rw-r--r--src/libsystemd/sd-device/sd-device.c19
-rw-r--r--src/libsystemd/sd-event/sd-event.c30
-rw-r--r--src/libsystemd/sd-hwdb/hwdb-internal.h1
11 files changed, 232 insertions, 80 deletions
diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym
index 518cbbb7ed..843a1e9880 100644
--- a/src/libsystemd/libsystemd.sym
+++ b/src/libsystemd/libsystemd.sym
@@ -477,4 +477,6 @@ global:
LIBSYSTEMD_227 {
global:
sd_bus_default_flush_close;
+ sd_bus_path_decode_many;
+ sd_bus_path_encode_many;
} LIBSYSTEMD_226;
diff --git a/src/libsystemd/sd-bus/bus-container.c b/src/libsystemd/sd-bus/bus-container.c
index 5c607f49b1..435ec92d6f 100644
--- a/src/libsystemd/sd-bus/bus-container.c
+++ b/src/libsystemd/sd-bus/bus-container.c
@@ -217,15 +217,8 @@ int bus_container_connect_kernel(sd_bus *b) {
_exit(EXIT_FAILURE);
}
- cmsg = CMSG_FIRSTHDR(&mh);
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_RIGHTS;
- cmsg->cmsg_len = CMSG_LEN(sizeof(int));
- memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
-
- mh.msg_controllen = cmsg->cmsg_len;
-
- if (sendmsg(pair[1], &mh, MSG_NOSIGNAL) < 0)
+ r = send_one_fd(pair[1], fd, 0);
+ if (r < 0)
_exit(EXIT_FAILURE);
_exit(EXIT_SUCCESS);
diff --git a/src/libsystemd/sd-bus/busctl.c b/src/libsystemd/sd-bus/busctl.c
index 5d07d5809c..ab8816942c 100644
--- a/src/libsystemd/sd-bus/busctl.c
+++ b/src/libsystemd/sd-bus/busctl.c
@@ -21,22 +21,21 @@
#include <getopt.h>
-#include "strv.h"
-#include "util.h"
-#include "log.h"
-#include "build.h"
-#include "pager.h"
-#include "path-util.h"
-#include "set.h"
-
#include "sd-bus.h"
-#include "bus-internal.h"
-#include "bus-util.h"
+
#include "bus-dump.h"
+#include "bus-internal.h"
#include "bus-signature.h"
#include "bus-type.h"
+#include "bus-util.h"
#include "busctl-introspect.h"
+#include "log.h"
+#include "pager.h"
+#include "path-util.h"
+#include "set.h"
+#include "strv.h"
#include "terminal-util.h"
+#include "util.h"
static bool arg_no_pager = false;
static bool arg_legend = true;
@@ -1786,9 +1785,7 @@ static int parse_argv(int argc, char *argv[]) {
return help();
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case ARG_NO_PAGER:
arg_no_pager = true;
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
index 53d1c6f61d..a23f7257fa 100644
--- a/src/libsystemd/sd-bus/sd-bus.c
+++ b/src/libsystemd/sd-bus/sd-bus.c
@@ -3454,6 +3454,171 @@ _public_ int sd_bus_path_decode(const char *path, const char *prefix, char **ext
return 1;
}
+_public_ int sd_bus_path_encode_many(char **out, const char *path_template, ...) {
+ _cleanup_strv_free_ char **labels = NULL;
+ char *path, *path_pos, **label_pos;
+ const char *sep, *template_pos;
+ size_t path_length;
+ va_list list;
+ int r;
+
+ assert_return(out, -EINVAL);
+ assert_return(path_template, -EINVAL);
+
+ path_length = strlen(path_template);
+
+ va_start(list, path_template);
+ for (sep = strchr(path_template, '%'); sep; sep = strchr(sep + 1, '%')) {
+ const char *arg;
+ char *label;
+
+ arg = va_arg(list, const char *);
+ if (!arg) {
+ va_end(list);
+ return -EINVAL;
+ }
+
+ label = bus_label_escape(arg);
+ if (!label) {
+ va_end(list);
+ return -ENOMEM;
+ }
+
+ r = strv_consume(&labels, label);
+ if (r < 0) {
+ va_end(list);
+ return r;
+ }
+
+ /* add label length, but account for the format character */
+ path_length += strlen(label) - 1;
+ }
+ va_end(list);
+
+ path = malloc(path_length + 1);
+ if (!path)
+ return -ENOMEM;
+
+ path_pos = path;
+ label_pos = labels;
+
+ for (template_pos = path_template; *template_pos; ) {
+ sep = strchrnul(template_pos, '%');
+ path_pos = mempcpy(path_pos, template_pos, sep - template_pos);
+ if (!*sep)
+ break;
+
+ path_pos = stpcpy(path_pos, *label_pos++);
+ template_pos = sep + 1;
+ }
+
+ *path_pos = 0;
+ *out = path;
+ return 0;
+}
+
+_public_ int sd_bus_path_decode_many(const char *path, const char *path_template, ...) {
+ _cleanup_strv_free_ char **labels = NULL;
+ const char *template_pos, *path_pos;
+ char **label_pos;
+ va_list list;
+ int r;
+
+ /*
+ * This decodes an object-path based on a template argument. The
+ * template consists of a verbatim path, optionally including special
+ * directives:
+ *
+ * - Each occurrence of '%' in the template matches an arbitrary
+ * substring of a label in the given path. At most one such
+ * directive is allowed per label. For each such directive, the
+ * caller must provide an output parameter (char **) via va_arg. If
+ * NULL is passed, the given label is verified, but not returned.
+ * For each matched label, the *decoded* label is stored in the
+ * passed output argument, and the caller is responsible to free
+ * it. Note that the output arguments are only modified if the
+ * actualy path matched the template. Otherwise, they're left
+ * untouched.
+ *
+ * This function returns <0 on error, 0 if the path does not match the
+ * template, 1 if it matched.
+ */
+
+ assert_return(path, -EINVAL);
+ assert_return(path_template, -EINVAL);
+
+ path_pos = path;
+
+ for (template_pos = path_template; *template_pos; ) {
+ const char *sep;
+ size_t length;
+ char *label;
+
+ /* verify everything until the next '%' matches verbatim */
+ sep = strchrnul(template_pos, '%');
+ length = sep - template_pos;
+ if (strncmp(path_pos, template_pos, length))
+ return 0;
+
+ path_pos += length;
+ template_pos += length;
+
+ if (!*template_pos)
+ break;
+
+ /* We found the next '%' character. Everything up until here
+ * matched. We now skip ahead to the end of this label and make
+ * sure it matches the tail of the label in the path. Then we
+ * decode the string in-between and save it for later use. */
+
+ ++template_pos; /* skip over '%' */
+
+ sep = strchrnul(template_pos, '/');
+ length = sep - template_pos; /* length of suffix to match verbatim */
+
+ /* verify the suffixes match */
+ sep = strchrnul(path_pos, '/');
+ if (sep - path_pos < (ssize_t)length ||
+ strncmp(sep - length, template_pos, length))
+ return 0;
+
+ template_pos += length; /* skip over matched label */
+ length = sep - path_pos - length; /* length of sub-label to decode */
+
+ /* store unescaped label for later use */
+ label = bus_label_unescape_n(path_pos, length);
+ if (!label)
+ return -ENOMEM;
+
+ r = strv_consume(&labels, label);
+ if (r < 0)
+ return r;
+
+ path_pos = sep; /* skip decoded label and suffix */
+ }
+
+ /* end of template must match end of path */
+ if (*path_pos)
+ return 0;
+
+ /* copy the labels over to the caller */
+ va_start(list, path_template);
+ for (label_pos = labels; label_pos && *label_pos; ++label_pos) {
+ char **arg;
+
+ arg = va_arg(list, char **);
+ if (arg)
+ *arg = *label_pos;
+ else
+ free(*label_pos);
+ }
+ va_end(list);
+
+ free(labels);
+ labels = NULL;
+ return 1;
+}
+
_public_ int sd_bus_try_close(sd_bus *bus) {
int r;
diff --git a/src/libsystemd/sd-bus/test-bus-marshal.c b/src/libsystemd/sd-bus/test-bus-marshal.c
index b203707f27..ff6bba5988 100644
--- a/src/libsystemd/sd-bus/test-bus-marshal.c
+++ b/src/libsystemd/sd-bus/test-bus-marshal.c
@@ -66,6 +66,36 @@ static void test_bus_path_encode(void) {
assert_se(sd_bus_path_decode(e, "/foo/bar", &f) > 0 && streq(f, "foo.bar"));
}
+static void test_bus_path_encode_many(void) {
+ _cleanup_free_ char *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL, *f = NULL;
+
+ assert_se(sd_bus_path_decode_many("/foo/bar", "/prefix/%", NULL) == 0);
+ assert_se(sd_bus_path_decode_many("/prefix/bar", "/prefix/%bar", NULL) == 1);
+ assert_se(sd_bus_path_decode_many("/foo/bar", "/prefix/%/suffix", NULL) == 0);
+ assert_se(sd_bus_path_decode_many("/prefix/foobar/suffix", "/prefix/%/suffix", &a) == 1 && streq_ptr(a, "foobar"));
+ assert_se(sd_bus_path_decode_many("/prefix/one_foo_two/mid/three_bar_four/suffix", "/prefix/one_%_two/mid/three_%_four/suffix", &b, &c) == 1 && streq_ptr(b, "foo") && streq_ptr(c, "bar"));
+ assert_se(sd_bus_path_decode_many("/prefix/one_foo_two/mid/three_bar_four/suffix", "/prefix/one_%_two/mid/three_%_four/suffix", NULL, &d) == 1 && streq_ptr(d, "bar"));
+
+ assert_se(sd_bus_path_decode_many("/foo/bar", "/foo/bar/%", NULL) == 0);
+ assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/bar%", NULL) == 0);
+ assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%/bar", NULL) == 0);
+ assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%bar", NULL) == 0);
+ assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/bar/suffix") == 1);
+ assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%%/suffix", NULL, NULL) == 0); /* multiple '%' are treated verbatim */
+ assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%/suffi", NULL) == 0);
+ assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%/suffix", &e) == 1 && streq_ptr(e, "bar"));
+ assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%/%", NULL, NULL) == 1);
+ assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%/%/%", NULL, NULL, NULL) == 1);
+ assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "%/%/%", NULL, NULL, NULL) == 0);
+ assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%/%", NULL, NULL) == 0);
+ assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%/%/", NULL, NULL) == 0);
+ assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%/", NULL) == 0);
+ assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%", NULL) == 0);
+ assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "%", NULL) == 0);
+
+ assert_se(sd_bus_path_encode_many(&f, "/prefix/one_%_two/mid/three_%_four/suffix", "foo", "bar") >= 0 && streq_ptr(f, "/prefix/one_foo_two/mid/three_bar_four/suffix"));
+}
+
static void test_bus_label_escape_one(const char *a, const char *b) {
_cleanup_free_ char *t = NULL, *x = NULL, *y = NULL;
@@ -393,6 +423,7 @@ int main(int argc, char *argv[]) {
test_bus_label_escape();
test_bus_path_encode();
test_bus_path_encode_unique();
+ test_bus_path_encode_many();
return 0;
}
diff --git a/src/libsystemd/sd-daemon/sd-daemon.c b/src/libsystemd/sd-daemon/sd-daemon.c
index 9ec73406c6..5fb0b73d02 100644
--- a/src/libsystemd/sd-daemon/sd-daemon.c
+++ b/src/libsystemd/sd-daemon/sd-daemon.c
@@ -310,10 +310,15 @@ _public_ int sd_is_socket_unix(int fd, int type, int listening, const char *path
_public_ int sd_is_mq(int fd, const char *path) {
struct mq_attr attr;
- assert_return(fd >= 0, -EBADF);
+ /* Check that the fd is valid */
+ assert_return(fcntl(fd, F_GETFD) >= 0, -errno);
- if (mq_getattr(fd, &attr) < 0)
+ if (mq_getattr(fd, &attr) < 0) {
+ if (errno == EBADF)
+ /* A non-mq fd (or an invalid one, but we ruled that out above) */
+ return 0;
return -errno;
+ }
if (path) {
char fpath[PATH_MAX];
@@ -498,16 +503,11 @@ _public_ int sd_notifyf(int unset_environment, const char *format, ...) {
}
_public_ int sd_booted(void) {
- struct stat st;
-
/* We test whether the runtime unit file directory has been
* created. This takes place in mount-setup.c, so is
* guaranteed to happen very early during boot. */
- if (lstat("/run/systemd/system/", &st) < 0)
- return 0;
-
- return !!S_ISDIR(st.st_mode);
+ return laccess("/run/systemd/system/", F_OK) >= 0;
}
_public_ int sd_watchdog_enabled(int unset_environment, uint64_t *usec) {
diff --git a/src/libsystemd/sd-device/device-enumerator.c b/src/libsystemd/sd-device/device-enumerator.c
index 5eb37e16cb..45a4d12eb7 100644
--- a/src/libsystemd/sd-device/device-enumerator.c
+++ b/src/libsystemd/sd-device/device-enumerator.c
@@ -812,10 +812,8 @@ static int enumerator_scan_devices_all(sd_device_enumerator *enumerator) {
if (access("/sys/subsystem", F_OK) >= 0) {
/* we have /subsystem/, forget all the old stuff */
r = enumerator_scan_dir(enumerator, "subsystem", "devices", NULL);
- if (r < 0) {
- log_debug("device-enumerator: failed to scan /sys/subsystem: %s", strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_debug_errno(r, "device-enumerator: failed to scan /sys/subsystem: %m");
} else {
int k;
diff --git a/src/libsystemd/sd-device/device-private.c b/src/libsystemd/sd-device/device-private.c
index 0ec9667744..b5215cb9b5 100644
--- a/src/libsystemd/sd-device/device-private.c
+++ b/src/libsystemd/sd-device/device-private.c
@@ -200,10 +200,8 @@ static int device_read_db(sd_device *device) {
if (r < 0) {
if (r == -ENOENT)
return 0;
- else {
- log_debug("sd-device: failed to read db '%s': %s", path, strerror(-r));
- return r;
- }
+ else
+ return log_debug_errno(r, "sd-device: failed to read db '%s': %m", path);
}
/* devices with a database entry are initialized */
@@ -247,7 +245,7 @@ static int device_read_db(sd_device *device) {
db[i] = '\0';
r = handle_db_line(device, key, value);
if (r < 0)
- log_debug("sd-device: failed to handle db entry '%c:%s': %s", key, value, strerror(-r));
+ log_debug_errno(r, "sd-device: failed to handle db entry '%c:%s': %m", key, value);
state = PRE_KEY;
}
diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c
index 7cea5a0746..c528a157c1 100644
--- a/src/libsystemd/sd-device/sd-device.c
+++ b/src/libsystemd/sd-device/sd-device.c
@@ -169,11 +169,10 @@ int device_set_syspath(sd_device *device, const char *_syspath, bool verify) {
/* the device does not exist (any more?) */
return -ENODEV;
- log_debug("sd-device: could not canonicalize '%s': %m", _syspath);
- return -errno;
+ return log_debug_errno(errno, "sd-device: could not canonicalize '%s': %m", _syspath);
}
} else if (r < 0) {
- log_debug("sd-device: could not get target of '%s': %s", _syspath, strerror(-r));
+ log_debug_errno(r, "sd-device: could not get target of '%s': %m", _syspath);
return r;
}
@@ -516,7 +515,7 @@ int device_read_uevent_file(sd_device *device) {
/* some devices may not have uevent files, see set_syspath() */
return 0;
else if (r < 0) {
- log_debug("sd-device: failed to read uevent file '%s': %s", path, strerror(-r));
+ log_debug_errno(r, "sd-device: failed to read uevent file '%s': %m", path);
return r;
}
@@ -555,7 +554,7 @@ int device_read_uevent_file(sd_device *device) {
r = handle_uevent_line(device, key, value, &major, &minor);
if (r < 0)
- log_debug("sd-device: failed to handle uevent entry '%s=%s': %s", key, value, strerror(-r));
+ log_debug_errno(r, "sd-device: failed to handle uevent entry '%s=%s': %m", key, value);
state = PRE_KEY;
}
@@ -569,7 +568,7 @@ int device_read_uevent_file(sd_device *device) {
if (major) {
r = device_set_devnum(device, major, minor);
if (r < 0)
- log_debug("sd-device: could not set 'MAJOR=%s' or 'MINOR=%s' from '%s': %s", major, minor, path, strerror(-r));
+ log_debug_errno(r, "sd-device: could not set 'MAJOR=%s' or 'MINOR=%s' from '%s': %m", major, minor, path);
}
return 0;
@@ -1271,10 +1270,8 @@ int device_read_db_aux(sd_device *device, bool force) {
if (r < 0) {
if (r == -ENOENT)
return 0;
- else {
- log_debug("sd-device: failed to read db '%s': %s", path, strerror(-r));
- return r;
- }
+ else
+ return log_debug_errno(r, "sd-device: failed to read db '%s': %m", path);
}
/* devices with a database entry are initialized */
@@ -1318,7 +1315,7 @@ int device_read_db_aux(sd_device *device, bool force) {
db[i] = '\0';
r = handle_db_line(device, key, value);
if (r < 0)
- log_debug("sd-device: failed to handle db entry '%c:%s': %s", key, value, strerror(-r));
+ log_debug_errno(r, "sd-device: failed to handle db entry '%c:%s': %m", key, value);
state = PRE_KEY;
}
diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c
index 48a5219275..1a82c4c940 100644
--- a/src/libsystemd/sd-event/sd-event.c
+++ b/src/libsystemd/sd-event/sd-event.c
@@ -242,12 +242,6 @@ static int pending_prioq_compare(const void *a, const void *b) {
if (x->pending_iteration > y->pending_iteration)
return 1;
- /* Stability for the rest */
- if (x < y)
- return -1;
- if (x > y)
- return 1;
-
return 0;
}
@@ -277,12 +271,6 @@ static int prepare_prioq_compare(const void *a, const void *b) {
if (x->priority > y->priority)
return 1;
- /* Stability for the rest */
- if (x < y)
- return -1;
- if (x > y)
- return 1;
-
return 0;
}
@@ -310,12 +298,6 @@ static int earliest_time_prioq_compare(const void *a, const void *b) {
if (x->time.next > y->time.next)
return 1;
- /* Stability for the rest */
- if (x < y)
- return -1;
- if (x > y)
- return 1;
-
return 0;
}
@@ -343,12 +325,6 @@ static int latest_time_prioq_compare(const void *a, const void *b) {
if (x->time.next + x->time.accuracy > y->time.next + y->time.accuracy)
return 1;
- /* Stability for the rest */
- if (x < y)
- return -1;
- if (x > y)
- return 1;
-
return 0;
}
@@ -370,12 +346,6 @@ static int exit_prioq_compare(const void *a, const void *b) {
if (x->priority > y->priority)
return 1;
- /* Stability for the rest */
- if (x < y)
- return -1;
- if (x > y)
- return 1;
-
return 0;
}
diff --git a/src/libsystemd/sd-hwdb/hwdb-internal.h b/src/libsystemd/sd-hwdb/hwdb-internal.h
index fedccdec72..13fddfc8ad 100644
--- a/src/libsystemd/sd-hwdb/hwdb-internal.h
+++ b/src/libsystemd/sd-hwdb/hwdb-internal.h
@@ -19,6 +19,7 @@
#pragma once
#include "sparse-endian.h"
+#include "util.h"
#define HWDB_SIG { 'K', 'S', 'L', 'P', 'H', 'H', 'R', 'H' }