static char **arg_states = NULL;
static char **arg_properties = NULL;
static bool arg_all = false;
+static bool original_stdout_is_tty;
static enum dependency {
DEPENDENCY_FORWARD,
DEPENDENCY_REVERSE,
}
}
- if (!arg_full) {
+ if (!arg_full && original_stdout_is_tty) {
unsigned basic_len;
id_len = MIN(max_id_len, 25u);
basic_len = 5 + id_len + 5 + active_len + sub_len;
on_active, active_len, u->active_state,
sub_len, u->sub_state, off_active,
job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
- if (!arg_full && arg_no_pager)
+ if (desc_len > 0)
printf("%.*s\n", desc_len, u->description);
else
printf("%s\n", u->description);
} else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
uint32_t id;
const char *path, *result, *unit;
+ char *r;
if (dbus_message_get_args(message, &error,
DBUS_TYPE_UINT32, &id,
DBUS_TYPE_STRING, &result,
DBUS_TYPE_INVALID)) {
- free(set_remove(d->set, (char*) path));
+ r = set_remove(d->set, (char*) path);
+ if (!r)
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+ free(r);
if (!isempty(result))
d->result = strdup(result);
/* Compatibility with older systemd versions <
* 183 during upgrades. This should be dropped
* one day. */
- free(set_remove(d->set, (char*) path));
+ r = set_remove(d->set, (char*) path);
+ if (!r)
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+ free(r);
if (*result)
d->result = strdup(result);
}
return 0;
+ } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "BlockIODeviceWeight")) {
+ DBusMessageIter sub, sub2;
+
+ dbus_message_iter_recurse(iter, &sub);
+ while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) {
+ const char *path;
+ uint64_t weight;
+
+ dbus_message_iter_recurse(&sub, &sub2);
+
+ if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, true) >= 0 &&
+ bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &weight, false) >= 0)
+ printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
+
+ dbus_message_iter_next(&sub);
+ }
+ return 0;
+
} else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
DBusMessageIter sub, sub2;
!dbus_message_iter_append_basic(&sub, DBUS_TYPE_BOOLEAN, &b))
return log_oom();
- } else if (streq(field, "MemoryLimit") || streq(field, "MemorySoftLimit")) {
+ } else if (streq(field, "MemoryLimit")) {
off_t bytes;
uint64_t u;
rwm = "";
}
+ if (!path_startswith(path, "/dev")) {
+ log_error("%s is not a device file in /dev.", path);
+ return -EINVAL;
+ }
+
if (!dbus_message_iter_open_container(&sub2, DBUS_TYPE_STRUCT, NULL, &sub3) ||
!dbus_message_iter_append_basic(&sub3, DBUS_TYPE_STRING, &path) ||
!dbus_message_iter_append_basic(&sub3, DBUS_TYPE_STRING, &rwm) ||
if (!dbus_message_iter_close_container(&sub, &sub2))
return log_oom();
+ } else if (streq(field, "BlockIOReadBandwidth") || streq(field, "BlockIOWriteBandwidth")) {
+ DBusMessageIter sub2;
+
+ if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "a(st)", &sub) ||
+ !dbus_message_iter_open_container(&sub, DBUS_TYPE_ARRAY, "(st)", &sub2))
+ return log_oom();
+
+ if (!isempty(eq)) {
+ const char *path, *bandwidth;
+ DBusMessageIter sub3;
+ uint64_t u;
+ off_t bytes;
+ char *e;
+
+ e = strchr(eq, ' ');
+ if (e) {
+ path = strndupa(eq, e - eq);
+ bandwidth = e+1;
+ } else {
+ log_error("Failed to parse %s value %s.", field, eq);
+ return -EINVAL;
+ }
+
+ if (!path_startswith(path, "/dev")) {
+ log_error("%s is not a device file in /dev.", path);
+ return -EINVAL;
+ }
+
+ r = parse_bytes(bandwidth, &bytes);
+ if (r < 0) {
+ log_error("Failed to parse byte value %s.", bandwidth);
+ return -EINVAL;
+ }
+
+ u = (uint64_t) bytes;
+
+ if (!dbus_message_iter_open_container(&sub2, DBUS_TYPE_STRUCT, NULL, &sub3) ||
+ !dbus_message_iter_append_basic(&sub3, DBUS_TYPE_STRING, &path) ||
+ !dbus_message_iter_append_basic(&sub3, DBUS_TYPE_UINT64, &u) ||
+ !dbus_message_iter_close_container(&sub2, &sub3))
+ return log_oom();
+ }
+
+ if (!dbus_message_iter_close_container(&sub, &sub2))
+ return log_oom();
+
+ } else if (streq(field, "BlockIODeviceWeight")) {
+ DBusMessageIter sub2;
+
+ if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "a(st)", &sub) ||
+ !dbus_message_iter_open_container(&sub, DBUS_TYPE_ARRAY, "(st)", &sub2))
+ return log_oom();
+
+ if (!isempty(eq)) {
+ const char *path, *weight;
+ DBusMessageIter sub3;
+ uint64_t u;
+ char *e;
+
+ e = strchr(eq, ' ');
+ if (e) {
+ path = strndupa(eq, e - eq);
+ weight = e+1;
+ } else {
+ log_error("Failed to parse %s value %s.", field, eq);
+ return -EINVAL;
+ }
+
+ if (!path_startswith(path, "/dev")) {
+ log_error("%s is not a device file in /dev.", path);
+ return -EINVAL;
+ }
+
+ r = safe_atou64(weight, &u);
+ if (r < 0) {
+ log_error("Failed to parse %s value %s.", field, weight);
+ return -EINVAL;
+ }
+ if (!dbus_message_iter_open_container(&sub2, DBUS_TYPE_STRUCT, NULL, &sub3) ||
+ !dbus_message_iter_append_basic(&sub3, DBUS_TYPE_STRING, &path) ||
+ !dbus_message_iter_append_basic(&sub3, DBUS_TYPE_UINT64, &u) ||
+ !dbus_message_iter_close_container(&sub2, &sub3))
+ return log_oom();
+ }
+
+ if (!dbus_message_iter_close_container(&sub, &sub2))
+ return log_oom();
+
} else {
log_error("Unknown assignment %s.", assignment);
return -EINVAL;
static int set_property(DBusConnection *bus, char **args) {
- _cleanup_free_ DBusMessage *m = NULL, *reply = NULL;
+ _cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL;
+ _cleanup_free_ char *n = NULL;
DBusMessageIter iter, sub;
dbus_bool_t runtime;
DBusError error;
runtime = arg_runtime;
- if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &args[1]) ||
+ n = unit_name_mangle(args[1]);
+ if (!n)
+ return log_oom();
+
+ if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &n) ||
!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &runtime) ||
!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(sv)", &sub))
return log_oom();
log_parse_environment();
log_open();
+ /* Explicitly not on_tty() to avoid setting cached value.
+ * This becomes relevant for piping output which might be
+ * ellipsized. */
+ original_stdout_is_tty = isatty(STDOUT_FILENO);
+
r = parse_argv(argc, argv);
if (r < 0)
goto finish;