X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fsystemctl.c;h=fb3430048cd7f7aef5e9234832774513731f543a;hb=867b3b7d6b88ba4d07ec7c830576d4ac2f7dd226;hp=59ea7490e767dfa879e3673a7875a9d4b2654e77;hpb=1888c9074ab1cb82c1719090561a31d7902df286;p=elogind.git diff --git a/src/systemctl.c b/src/systemctl.c index 59ea7490e..fb3430048 100644 --- a/src/systemctl.c +++ b/src/systemctl.c @@ -113,10 +113,17 @@ static bool private_bus = false; static pid_t pager_pid = 0; static int daemon_reload(DBusConnection *bus, char **args, unsigned n); +static void pager_open(void); static bool on_tty(void) { static int t = -1; + /* Note that this is invoked relatively early, before we start + * the pager. That means the value we return reflects whether + * we originally were started on a tty, not if we currently + * are. But this is intended, since we want color, and so on + * when run in our own pager. */ + if (_unlikely_(t < 0)) t = isatty(STDOUT_FILENO) > 0; @@ -421,6 +428,8 @@ static int list_units(DBusConnection *bus, char **args, unsigned n) { assert(bus); + pager_open(); + if (!(m = dbus_message_new_method_call( "org.freedesktop.systemd1", "/org/freedesktop/systemd1", @@ -767,6 +776,8 @@ static int list_jobs(DBusConnection *bus, char **args, unsigned n) { assert(bus); + pager_open(); + if (!(m = dbus_message_new_method_call( "org.freedesktop.systemd1", "/org/freedesktop/systemd1", @@ -1604,6 +1615,8 @@ finish: } typedef struct ExecStatusInfo { + char *name; + char *path; char **argv; @@ -1621,6 +1634,7 @@ typedef struct ExecStatusInfo { static void exec_status_info_free(ExecStatusInfo *i) { assert(i); + free(i->name); free(i->path); strv_free(i->argv); free(i); @@ -1833,15 +1847,31 @@ static void print_status_info(UnitStatusInfo *i) { LIST_FOREACH(exec, p, i->exec) { char *t; + bool good; /* Only show exited processes here */ if (p->code == 0) continue; t = strv_join(p->argv, " "); - printf("\t Process: %u (%s, code=%s, ", p->pid, strna(t), sigchld_code_to_string(p->code)); + printf("\t Process: %u %s=%s ", p->pid, p->name, strna(t)); free(t); +#ifdef HAVE_SYSV_COMPAT + if (i->is_sysv) + good = is_clean_exit_lsb(p->code, p->status); + else +#endif + good = is_clean_exit(p->code, p->status); + + if (!good) { + on = ansi_highlight(true); + off = ansi_highlight(false); + } else + on = off = ""; + + printf("%s(code=%s, ", on, sigchld_code_to_string(p->code)); + if (p->code == CLD_EXITED) { const char *c; @@ -1856,7 +1886,10 @@ static void print_status_info(UnitStatusInfo *i) { } else printf("signal=%s", signal_to_string(p->status)); - printf(")\n"); + + printf(")%s\n", off); + + on = off = NULL; if (i->main_pid == p->pid && i->start_timestamp == p->start_timestamp && @@ -2072,6 +2105,11 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn if (!(info = new0(ExecStatusInfo, 1))) return -ENOMEM; + if (!(info->name = strdup(name))) { + free(info); + return -ENOMEM; + } + if ((r = exec_status_info_deserialize(&sub, info)) < 0) { free(info); return r; @@ -2477,6 +2515,9 @@ static int show(DBusConnection *bus, char **args, unsigned n) { show_properties = !streq(args[0], "status"); + if (show_properties) + pager_open(); + if (show_properties && n <= 1) { /* If not argument is specified inspect the manager * itself */ @@ -2860,6 +2901,8 @@ static int dump(DBusConnection *bus, char **args, unsigned n) { dbus_error_init(&error); + pager_open(); + if (!(m = dbus_message_new_method_call( "org.freedesktop.systemd1", "/org/freedesktop/systemd1", @@ -3222,6 +3265,8 @@ static int show_enviroment(DBusConnection *bus, char **args, unsigned n) { dbus_error_init(&error); + pager_open(); + if (!(m = dbus_message_new_method_call( "org.freedesktop.systemd1", "/org/freedesktop/systemd1", @@ -5298,6 +5343,10 @@ static void pager_open(void) { if (!*pager || streq(pager, "cat")) return; + /* Determine and cache number of columns before we spawn the + * pager so that we get the value from the actual tty */ + columns(); + if (pipe(fd) < 0) { log_error("Failed to create pager pipe: %m"); return; @@ -5316,8 +5365,7 @@ static void pager_open(void) { dup2(fd[0], STDIN_FILENO); close_pipe(fd); - if (!getenv("LESS")) - setenv("LESS", "FRSX", 0); + setenv("LESS", "FRSX", 0); prctl(PR_SET_PDEATHSIG, SIGTERM); @@ -5325,7 +5373,14 @@ static void pager_open(void) { execlp(pager, pager, NULL); execl("/bin/sh", "sh", "-c", pager, NULL); } else { - execlp("sensible-pager", "sensible-pager", NULL); + /* Debian's alternatives command for pagers is + * called 'pager'. Note that we do not call + * sensible-pagers here, since that is just a + * shell script that implements a logic that + * is similar to this one anyway, but is + * Debian-specific. */ + execlp("pager", "pager", NULL); + execlp("less", "less", NULL); execlp("more", "more", NULL); } @@ -5370,8 +5425,6 @@ int main(int argc, char*argv[]) { goto finish; } - pager_open(); - /* /sbin/runlevel doesn't need to communicate via D-Bus, so * let's shortcut this */ if (arg_action == ACTION_RUNLEVEL) {