[systemd-commits] 4 commits - man/systemctl.xml src/systemctl.c TODO

Lennart Poettering lennart at kemper.freedesktop.org
Mon Jan 3 16:04:43 PST 2011


 TODO              |    2 -
 man/systemctl.xml |    7 ++++
 src/systemctl.c   |   93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 100 insertions(+), 2 deletions(-)

New commits:
commit ec14911e0d6b9473f4f1d6b43d7fcd67c48c2ffc
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Jan 4 01:04:20 2011 +0100

    systemctl: spawn pager only for commands that generates long output

diff --git a/src/systemctl.c b/src/systemctl.c
index 59ea749..0908b6a 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -113,6 +113,7 @@ 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;
@@ -421,6 +422,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 +770,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",
@@ -2477,6 +2482,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 +2868,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 +3232,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",
@@ -5370,8 +5382,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) {

commit 1888c9074ab1cb82c1719090561a31d7902df286
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Jan 4 00:58:28 2011 +0100

    systemctl: make the child the pager, leave systemctl as parent
    
    It's nicer if the child process gets reinitialized cleanly instead of
    the parent process.

diff --git a/src/systemctl.c b/src/systemctl.c
index 8a6277e..59ea749 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -110,6 +110,8 @@ static enum dot {
 
 static bool private_bus = false;
 
+static pid_t pager_pid = 0;
+
 static int daemon_reload(DBusConnection *bus, char **args, unsigned n);
 
 static bool on_tty(void) {
@@ -5283,10 +5285,12 @@ static int runlevel_main(void) {
 }
 
 static void pager_open(void) {
-        pid_t pid;
         int fd[2];
         const char *pager;
 
+        if (pager_pid > 0)
+                return;
+
         if (!on_tty() || arg_no_pager)
                 return;
 
@@ -5299,15 +5303,15 @@ static void pager_open(void) {
                 return;
         }
 
-        pid = fork();
-        if (pid < 0) {
+        pager_pid = fork();
+        if (pager_pid < 0) {
                 log_error("Failed to fork pager: %m");
                 close_pipe(fd);
                 return;
         }
 
-        /* The original process turns into the PAGER */
-        if (pid != 0) {
+        /* In the child start the pager */
+        if (pager_pid == 0) {
 
                 dup2(fd[0], STDIN_FILENO);
                 close_pipe(fd);
@@ -5315,6 +5319,8 @@ static void pager_open(void) {
                 if (!getenv("LESS"))
                         setenv("LESS", "FRSX", 0);
 
+                prctl(PR_SET_PDEATHSIG, SIGTERM);
+
                 if (pager) {
                         execlp(pager, pager, NULL);
                         execl("/bin/sh", "sh", "-c", pager, NULL);
@@ -5328,13 +5334,25 @@ static void pager_open(void) {
                 _exit(EXIT_FAILURE);
         }
 
-        /* Return in the child */
+        /* Return in the parent */
         if (dup2(fd[1], STDOUT_FILENO) < 0)
                 log_error("Failed to duplicate pager pipe: %m");
 
         close_pipe(fd);
 }
 
+static void pager_close(void) {
+        siginfo_t dummy;
+
+        if (pager_pid <= 0)
+                return;
+
+        /* Inform pager that we are done */
+        fclose(stdout);
+        wait_for_terminate(pager_pid, &dummy);
+        pager_pid = 0;
+}
+
 int main(int argc, char*argv[]) {
         int r, retval = EXIT_FAILURE;
         DBusConnection *bus = NULL;
@@ -5417,5 +5435,7 @@ finish:
 
         strv_free(arg_property);
 
+        pager_close();
+
         return retval;
 }

commit 611efaac7a76904ffc3d03592a8fe57da5f42c02
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Jan 4 00:47:40 2011 +0100

    systemctl: try harder to find a suitable pager

diff --git a/src/systemctl.c b/src/systemctl.c
index 585f1dc..8a6277e 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -4251,7 +4251,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                 ARG_SYSTEM,
                 ARG_GLOBAL,
                 ARG_NO_BLOCK,
-		ARG_NO_PAGER,
+                ARG_NO_PAGER,
                 ARG_NO_WALL,
                 ARG_ORDER,
                 ARG_REQUIRE,
@@ -4352,9 +4352,9 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                         arg_no_block = true;
                         break;
 
-		case ARG_NO_PAGER:
-			arg_no_pager = true;
-			break;
+                case ARG_NO_PAGER:
+                        arg_no_pager = true;
+                        break;
 
                 case ARG_NO_WALL:
                         arg_no_wall = true;
@@ -5283,45 +5283,56 @@ static int runlevel_main(void) {
 }
 
 static void pager_open(void) {
-	pid_t pid;
-	int fd[2];
-	const char *pager = getenv("PAGER");
-
-	if (!on_tty() || arg_no_pager)
-		return;
-	if (!pager)
-		pager = "less";
-	else if (!*pager || !strcmp(pager, "cat"))
-		return;
-
-	if (pipe(fd) < 0)
-		return;
-	pid = fork();
-	if (pid < 0) {
-		close(fd[0]);
-		close(fd[1]);
-		return;
-	}
-
-	/* Return in the child */
-	if (!pid) {
-		dup2(fd[1], 1);
-		close(fd[0]);
-		close(fd[1]);
-		return;
-	}
-
-	/* The original process turns into the PAGER */
-	dup2(fd[0], 0);
-	close(fd[0]);
-	close(fd[1]);
-
-	setenv("LESS", "FRSX", 0);
-	execlp(pager, pager, NULL);
-	execl("/bin/sh", "sh", "-c", pager, NULL);
-
-	log_error("unable to execute pager '%s'", pager);
-	_exit(EXIT_FAILURE);
+        pid_t pid;
+        int fd[2];
+        const char *pager;
+
+        if (!on_tty() || arg_no_pager)
+                return;
+
+        if ((pager = getenv("PAGER")))
+                if (!*pager || streq(pager, "cat"))
+                        return;
+
+        if (pipe(fd) < 0) {
+                log_error("Failed to create pager pipe: %m");
+                return;
+        }
+
+        pid = fork();
+        if (pid < 0) {
+                log_error("Failed to fork pager: %m");
+                close_pipe(fd);
+                return;
+        }
+
+        /* The original process turns into the PAGER */
+        if (pid != 0) {
+
+                dup2(fd[0], STDIN_FILENO);
+                close_pipe(fd);
+
+                if (!getenv("LESS"))
+                        setenv("LESS", "FRSX", 0);
+
+                if (pager) {
+                        execlp(pager, pager, NULL);
+                        execl("/bin/sh", "sh", "-c", pager, NULL);
+                } else {
+                        execlp("sensible-pager", "sensible-pager", NULL);
+                        execlp("less", "less", NULL);
+                        execlp("more", "more", NULL);
+                }
+
+                log_error("Unable to execute pager: %m");
+                _exit(EXIT_FAILURE);
+        }
+
+        /* Return in the child */
+        if (dup2(fd[1], STDOUT_FILENO) < 0)
+                log_error("Failed to duplicate pager pipe: %m");
+
+        close_pipe(fd);
 }
 
 int main(int argc, char*argv[]) {
@@ -5341,7 +5352,7 @@ int main(int argc, char*argv[]) {
                 goto finish;
         }
 
-	pager_open();
+        pager_open();
 
         /* /sbin/runlevel doesn't need to communicate via D-Bus, so
          * let's shortcut this */

commit 0736af98c6fae9c7d31e3dd17589421b7e883ef5
Author: Miklos Vajna <vmiklos at frugalware.org>
Date:   Sun Jan 2 00:25:57 2011 +0100

    systemctl: implement auto-pager a la git

diff --git a/TODO b/TODO
index e864634..69cff58 100644
--- a/TODO
+++ b/TODO
@@ -69,8 +69,6 @@
 
 * suspend, resume
 
-* systemctl auto-pager a la git
-
 * readahead: btrfs/LVM SSD detection
 
 * when processes remain in a service even though the start command failed enter active
diff --git a/man/systemctl.xml b/man/systemctl.xml
index 6b05e95..c21ed85 100644
--- a/man/systemctl.xml
+++ b/man/systemctl.xml
@@ -171,6 +171,13 @@
                                 enqueued.</para></listitem> </varlistentry>
 
                         <varlistentry>
+                                <term><option>--no-pager</option></term>
+
+				<listitem><para>Do not pipe output into a
+				pager.</para></listitem>
+			</varlistentry>
+
+                        <varlistentry>
                                 <term><option>--system</option></term>
 
                                 <listitem><para>Talk to the systemd
diff --git a/src/systemctl.c b/src/systemctl.c
index 4768fb2..585f1dc 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -65,6 +65,7 @@ static bool arg_user = false;
 static bool arg_global = false;
 static bool arg_immediate = false;
 static bool arg_no_block = false;
+static bool arg_no_pager = false;
 static bool arg_no_wtmp = false;
 static bool arg_no_sync = false;
 static bool arg_no_wall = false;
@@ -4110,6 +4111,7 @@ static int systemctl_help(void) {
                "                      pending\n"
                "  -q --quiet          Suppress output\n"
                "     --no-block       Do not wait until operation finished\n"
+               "     --no-pager       Do not pipe output into a pager.\n"
                "     --system         Connect to system manager\n"
                "     --user           Connect to user service manager\n"
                "     --order          When generating graph for dot, show only order\n"
@@ -4249,6 +4251,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                 ARG_SYSTEM,
                 ARG_GLOBAL,
                 ARG_NO_BLOCK,
+		ARG_NO_PAGER,
                 ARG_NO_WALL,
                 ARG_ORDER,
                 ARG_REQUIRE,
@@ -4272,6 +4275,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                 { "system",    no_argument,       NULL, ARG_SYSTEM    },
                 { "global",    no_argument,       NULL, ARG_GLOBAL    },
                 { "no-block",  no_argument,       NULL, ARG_NO_BLOCK  },
+                { "no-pager",  no_argument,       NULL, ARG_NO_PAGER  },
                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL   },
                 { "quiet",     no_argument,       NULL, 'q'           },
                 { "order",     no_argument,       NULL, ARG_ORDER     },
@@ -4348,6 +4352,10 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                         arg_no_block = true;
                         break;
 
+		case ARG_NO_PAGER:
+			arg_no_pager = true;
+			break;
+
                 case ARG_NO_WALL:
                         arg_no_wall = true;
                         break;
@@ -5274,6 +5282,48 @@ static int runlevel_main(void) {
         return 0;
 }
 
+static void pager_open(void) {
+	pid_t pid;
+	int fd[2];
+	const char *pager = getenv("PAGER");
+
+	if (!on_tty() || arg_no_pager)
+		return;
+	if (!pager)
+		pager = "less";
+	else if (!*pager || !strcmp(pager, "cat"))
+		return;
+
+	if (pipe(fd) < 0)
+		return;
+	pid = fork();
+	if (pid < 0) {
+		close(fd[0]);
+		close(fd[1]);
+		return;
+	}
+
+	/* Return in the child */
+	if (!pid) {
+		dup2(fd[1], 1);
+		close(fd[0]);
+		close(fd[1]);
+		return;
+	}
+
+	/* The original process turns into the PAGER */
+	dup2(fd[0], 0);
+	close(fd[0]);
+	close(fd[1]);
+
+	setenv("LESS", "FRSX", 0);
+	execlp(pager, pager, NULL);
+	execl("/bin/sh", "sh", "-c", pager, NULL);
+
+	log_error("unable to execute pager '%s'", pager);
+	_exit(EXIT_FAILURE);
+}
+
 int main(int argc, char*argv[]) {
         int r, retval = EXIT_FAILURE;
         DBusConnection *bus = NULL;
@@ -5291,6 +5341,8 @@ 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) {



More information about the systemd-commits mailing list