]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
pid1: show fancy name field at boot, if specified
authorLennart Poettering <lennart@poettering.net>
Mon, 12 Jan 2026 12:44:54 +0000 (13:44 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 21 Jan 2026 20:32:49 +0000 (21:32 +0100)
src/core/main.c

index 2676cd4c6b93c33dc1aa9f2438e549e977eafcf5..0e5e201f2dd757ff944631634b5222eee9b05965 100644 (file)
 #include "umask-util.h"
 #include "unit-name.h"
 #include "user-util.h"
+#include "utf8.h"
 #include "version.h"
 #include "virt.h"
 #include "watchdog.h"
@@ -1389,37 +1390,76 @@ static int enforce_syscall_archs(Set *archs) {
 }
 
 static int os_release_status(void) {
-        _cleanup_free_ char *pretty_name = NULL, *name = NULL, *version = NULL,
-                            *ansi_color = NULL, *support_end = NULL;
+        _cleanup_free_ char *pretty_name = NULL, *fancy_name = NULL,
+                *name = NULL, *version = NULL, *ansi_color = NULL, *support_end = NULL, *codename = NULL;
         int r;
 
         r = parse_os_release(NULL,
-                             "PRETTY_NAME", &pretty_name,
-                             "NAME",        &name,
-                             "VERSION",     &version,
-                             "ANSI_COLOR",  &ansi_color,
-                             "SUPPORT_END", &support_end);
+                             "PRETTY_NAME",      &pretty_name,
+                             "FANCY_NAME",       &fancy_name,
+                             "NAME",             &name,
+                             "VERSION",          &version,
+                             "VERSION_CODENAME", &codename,
+                             "ANSI_COLOR",       &ansi_color,
+                             "SUPPORT_END",      &support_end);
         if (r < 0)
                 return log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,
                                       "Failed to read os-release file, ignoring: %m");
 
         const char *label = os_release_pretty_name(pretty_name, name);
-        const char *color = empty_to_null(ansi_color) ?: "1";
 
         if (show_status_on(arg_show_status)) {
+                const char *color = empty_to_null(ansi_color) ?: "1";
+
+                /* The fancy name may contain emoji characters and ANSI sequences. Don't use it if our locale
+                 * doesn't allow that, or ANSI sequences are off, or if it is empty. */
+
+                if (!isempty(fancy_name)) {
+                        _cleanup_free_ char *unescaped = NULL;
+
+                        /* Undo one level of C-style unescaping for this one */
+                        ssize_t l = cunescape(fancy_name, /* flags= */ 0, &unescaped);
+                        if (l < 0) {
+                                log_debug_errno(l, "Failed to unescape FANCY_NAME=, ignoring: %m");
+                                fancy_name = mfree(fancy_name);
+                        } else {
+                                free_and_replace(fancy_name, unescaped);
+
+                                /* FANCY_NAME= does not contain version/codename info (unlike PRETTY_NAME=),
+                                 * but in this context it makes sense to show them if defined, hence append
+                                 * them here. */
+                                if (version && !strextend(&fancy_name, " ", version))
+                                        return log_oom();
+
+                                if (codename && !strextend(&fancy_name, " (", codename, ")"))
+                                        return log_oom();
+                        }
+                }
+
+                if (isempty(fancy_name) ||
+                    (!emoji_enabled() && !ascii_is_valid(fancy_name)) ||
+                    !log_get_show_color())
+                        fancy_name = mfree(fancy_name);
+
+                if (!fancy_name && log_get_show_color()) {
+                        fancy_name = strjoin("\x1B[", color, "m", label);
+                        if (!fancy_name)
+                                return log_oom();
+                }
+
                 if (in_initrd()) {
                         if (log_get_show_color())
                                 status_printf(NULL, 0,
-                                              ANSI_HIGHLIGHT "Booting initrd of " ANSI_NORMAL "\x1B[%sm%s" ANSI_NORMAL ANSI_HIGHLIGHT "." ANSI_NORMAL,
-                                              color, label);
+                                              ANSI_HIGHLIGHT "Booting initrd of " ANSI_NORMAL "%s" ANSI_NORMAL ANSI_HIGHLIGHT "." ANSI_NORMAL,
+                                              fancy_name);
                         else
                                 status_printf(NULL, 0,
                                               "Booting initrd of %s...", label);
                 } else {
                         if (log_get_show_color())
                                 status_printf(NULL, 0,
-                                              "\n" ANSI_HIGHLIGHT "Welcome to " ANSI_NORMAL "\x1B[%sm%s" ANSI_NORMAL ANSI_HIGHLIGHT "!" ANSI_NORMAL "\n",
-                                              color, label);
+                                              "\n" ANSI_HIGHLIGHT "Welcome to " ANSI_NORMAL "%s" ANSI_NORMAL ANSI_HIGHLIGHT "!" ANSI_NORMAL "\n",
+                                              fancy_name);
                         else
                                 status_printf(NULL, 0,
                                               "\nWelcome to %s!\n",