]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
shared/pager: print the name of the pager we'll try next in debug message 23575/head
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 31 May 2022 08:59:12 +0000 (10:59 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 1 Jun 2022 07:27:35 +0000 (09:27 +0200)
I had a strange failure where the pager was hanging on invocation (gdm crashed
and the kernel got into a strange state where it was hanging on some tasks).
Based on the logs from 'SYSTEMCTL_LOG_LEVEL=debug journalctl', I couldn't even
tell which pager binary we're executing. So let's shorten the function a bit and
provide a bit more detail.

src/shared/pager.c

index 1a93deb628488ad7caa9f4fa6f6eb4600d91d59b..dc717cd1fe8e23c0caa0c9740b3ed40b4d5c614a 100644 (file)
@@ -219,31 +219,30 @@ void pager_open(PagerFlags flags) {
                 /* 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. */
-                FOREACH_STRING(exe, "pager", "less", "more") {
-                        /* Only less implements secure mode right now. */
-                        if (use_secure_mode && !streq(exe, "less"))
+                static const char* pagers[] = { "pager", "less", "more", "(built-in)" };
+
+                for (unsigned i = 0; i < ELEMENTSOF(pagers); i++) {
+                        /* Only less (and our trivial fallback) implement secure mode right now. */
+                        if (use_secure_mode && !STR_IN_SET(pagers[i], "less", "(built-in)"))
                                 continue;
 
-                        r = loop_write(exe_name_pipe[1], exe, strlen(exe) + 1, false);
-                        if (r  < 0) {
+                        r = loop_write(exe_name_pipe[1], pagers[i], strlen(pagers[i]) + 1, false);
+                        if (r < 0) {
                                 log_error_errno(r, "Failed to write pager name to socket: %m");
                                 _exit(EXIT_FAILURE);
                         }
-                        execlp(exe, exe, NULL);
-                        log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno,
-                                       "Failed to execute '%s', using next fallback pager: %m", exe);
-                }
 
-                /* Our builtin is also very secure. */
-                r = loop_write(exe_name_pipe[1], "(built-in)", strlen("(built-in)") + 1, false);
-                if (r < 0) {
-                        log_error_errno(r, "Failed to write pager name to socket: %m");
-                        _exit(EXIT_FAILURE);
+                        if (i < ELEMENTSOF(pagers) - 1) {
+                                execlp(pagers[i], pagers[i], NULL);
+                                log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno,
+                                               "Failed to execute '%s', will try '%s' next: %m", pagers[i], pagers[i+1]);
+                        } else {
+                                /* Close pipe to signal the parent to start sending data */
+                                safe_close_pair(exe_name_pipe);
+                                pager_fallback();
+                                assert_not_reached();
+                        }
                 }
-                /* Close pipe to signal the parent to start sending data */
-                safe_close_pair(exe_name_pipe);
-                pager_fallback();
-                /* not reached */
         }
 
         /* Return in the parent */