static int enable_wait_for_jobs(DBusConnection *bus) {
DBusError error;
- DBusMessage *m = NULL, *reply = NULL;
- int r;
assert(bus);
dbus_error_init(&error);
-
dbus_bus_add_match(bus,
"type='signal',"
"sender='org.freedesktop.systemd1',"
if (dbus_error_is_set(&error)) {
log_error("Failed to add match: %s", error.message);
- r = -EIO;
- goto finish;
- }
-
- if (!(m = dbus_message_new_method_call(
- "org.freedesktop.systemd1",
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
- "Subscribe"))) {
- log_error("Could not allocate message.");
- r = -ENOMEM;
- goto finish;
- }
-
- if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
- log_error("Failed to issue method call: %s", error.message);
- r = -EIO;
- goto finish;
+ dbus_error_free(&error);
+ return -EIO;
}
- r = 0;
-
-finish:
/* This is slightly dirty, since we don't undo the match registrations. */
-
- if (m)
- dbus_message_unref(m);
-
- if (reply)
- dbus_message_unref(reply);
-
- dbus_error_free(&error);
-
- return r;
+ return 0;
}
static int wait_for_jobs(DBusConnection *bus, Set *s) {
/* Yes, heuristics! But we can change this check
* should it turn out to not be sufficient */
- if (strstr(name, "Timestamp") || strstr(name, "Elapse")) {
+ if (strstr(name, "Timestamp")) {
char timestamp[FORMAT_TIMESTAMP_MAX], *t;
if ((t = format_timestamp(timestamp, sizeof(timestamp), u)) || arg_all)
printf("%s=%s\n", name, strempty(t));
+ } else if (strstr(name, "USec")) {
+ char timespan[FORMAT_TIMESPAN_MAX];
+
+ printf("%s=%s\n", name, format_timespan(timespan, sizeof(timespan), u));
} else
printf("%s=%llu\n", name, (unsigned long long) u);
}
return 0;
+ } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_BYTE) {
+ DBusMessageIter sub;
+
+ dbus_message_iter_recurse(iter, &sub);
+ if (arg_all ||
+ dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+ printf("%s=", name);
+
+ while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+ uint8_t u;
+
+ assert(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_BYTE);
+ dbus_message_iter_get_basic(&sub, &u);
+ printf("%02x", u);
+
+ dbus_message_iter_next(&sub);
+ }
+
+ puts("");
+ }
+
+ return 0;
} else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Paths")) {
DBusMessageIter sub, sub2;
if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &base, true) >= 0 &&
bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &value, true) >= 0 &&
- bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &next_elapse, false) >= 0)
- printf("%s=%llu\n", base, (unsigned long long) value);
+ bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &next_elapse, false) >= 0) {
+ char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
+
+ printf("%s={ value=%s ; next_elapse=%s }\n",
+ base,
+ format_timespan(timespan1, sizeof(timespan1), value),
+ format_timespan(timespan2, sizeof(timespan2), next_elapse));
+ }
+
+ dbus_message_iter_next(&sub);
+ }
+
+ return 0;
+ } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && startswith(name, "Exec")) {
+
+ DBusMessageIter sub, sub2, sub3;
+
+ dbus_message_iter_recurse(iter, &sub);
+
+ while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) {
+ const char *path;
+ uint64_t start_time, exit_time;
+ uint32_t pid;
+ int32_t code, status;
+
+ dbus_message_iter_recurse(&sub, &sub2);
+
+ if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, true) < 0)
+ continue;
+
+ if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_ARRAY ||
+ dbus_message_iter_get_element_type(&sub2) != DBUS_TYPE_STRING)
+ continue;
+
+ printf("%s={ path=%s ; argv[]=", name, path);
+
+ dbus_message_iter_recurse(&sub2, &sub3);
+
+ while (dbus_message_iter_get_arg_type(&sub3) != DBUS_TYPE_INVALID) {
+ const char *s;
+
+ assert(dbus_message_iter_get_arg_type(&sub3) == DBUS_TYPE_STRING);
+ dbus_message_iter_get_basic(&sub3, &s);
+ printf("%s ", s);
+ dbus_message_iter_next(&sub3);
+ }
+
+ if (dbus_message_iter_next(&sub2) &&
+ bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &start_time, true) >= 0 &&
+ bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &exit_time, true) >= 0 &&
+ bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &pid, true) >= 0 &&
+ bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_INT32, &code, true) >= 0 &&
+ bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_INT32, &status, false) >= 0) {
+
+ char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
+
+ printf("; start=%s ; stop=%s ; pid=%u ; code=%s ; status=%i/%s",
+ strna(format_timestamp(timestamp1, sizeof(timestamp1), start_time)),
+ strna(format_timestamp(timestamp2, sizeof(timestamp2), exit_time)),
+ (unsigned) pid,
+ sigchld_code_to_string(code),
+ status,
+ strna(code == CLD_EXITED ? NULL : strsignal(status)));
+ }
+
+ printf(" }\n");
dbus_message_iter_next(&sub);
}
"Send control commands to the systemd manager.\n\n"
" -h --help Show this help\n"
" -t --type=TYPE List only units of a particular type\n"
- " -p --property=NAME Show only property by this name\n"
+ " -p --property=NAME Show only properties by this name\n"
" -a --all Show all units/properties, including dead/empty ones\n"
" --replace When installing a new job, replace existing conflicting ones\n"
" --system Connect to system bus\n"
" reload [NAME...] Reload one or more units\n"
" isolate [NAME] Start one unit and stop all others\n"
" check [NAME...] Check whether any of the passed units are active\n"
- " show [NAME...|JOB...] Show information about one or more units\n"
+ " show [NAME...|JOB...] Show information about one or more units/jobs/manager\n"
" load [NAME...] Load one or more units\n"
" list-jobs List jobs\n"
" cancel [JOB...] Cancel one or more jobs\n"