]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
terminal-util: Move various functions to ansi-color.c
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Wed, 7 May 2025 09:26:36 +0000 (11:26 +0200)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 9 May 2025 09:33:33 +0000 (11:33 +0200)
src/basic/ansi-color.c [new file with mode: 0644]
src/basic/ansi-color.h
src/basic/meson.build
src/basic/terminal-util.c
src/basic/terminal-util.h
src/network/networkctl-journal.c

diff --git a/src/basic/ansi-color.c b/src/basic/ansi-color.c
new file mode 100644 (file)
index 0000000..18e25f3
--- /dev/null
@@ -0,0 +1,98 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "ansi-color.h"
+#include "log.h"
+#include "process-util.h"
+#include "string-table.h"
+#include "strv.h"
+#include "terminal-util.h"
+
+static volatile int cached_color_mode = _COLOR_MODE_INVALID;
+static volatile int cached_underline_enabled = -1;
+
+bool underline_enabled(void) {
+
+        if (cached_underline_enabled < 0) {
+
+                /* The Linux console doesn't support underlining, turn it off, but only there. */
+
+                if (colors_enabled())
+                        cached_underline_enabled = !streq_ptr(getenv("TERM"), "linux");
+                else
+                        cached_underline_enabled = false;
+        }
+
+        return cached_underline_enabled;
+}
+
+void reset_ansi_feature_caches(void) {
+        cached_color_mode = _COLOR_MODE_INVALID;
+        cached_underline_enabled = -1;
+}
+
+ColorMode parse_systemd_colors(void) {
+        const char *e;
+
+        e = getenv("SYSTEMD_COLORS");
+        if (!e)
+                return _COLOR_MODE_INVALID;
+
+        ColorMode m = color_mode_from_string(e);
+        if (m < 0)
+                return log_debug_errno(m, "Failed to parse $SYSTEMD_COLORS value '%s', ignoring: %m", e);
+
+        return m;
+}
+
+static ColorMode get_color_mode_impl(void) {
+        /* Returns the mode used to choose output colors. The possible modes are COLOR_OFF for no colors,
+         * COLOR_16 for only the base 16 ANSI colors, COLOR_256 for more colors, and COLOR_24BIT for
+         * unrestricted color output. */
+
+        /* First, we check $SYSTEMD_COLORS, which is the explicit way to change the mode. */
+        ColorMode m = parse_systemd_colors();
+        if (m >= 0)
+                return m;
+
+        /* Next, check for the presence of $NO_COLOR; value is ignored. */
+        if (getenv("NO_COLOR"))
+                return COLOR_OFF;
+
+        /* If the above didn't work, we turn colors off unless we are on a TTY. And if we are on a TTY we
+         * turn it off if $TERM is set to "dumb". There's one special tweak though: if we are PID 1 then we
+         * do not check whether we are connected to a TTY, because we don't keep /dev/console open
+         * continuously due to fear of SAK, and hence things are a bit weird. */
+        if (getpid_cached() == 1 ? getenv_terminal_is_dumb() : terminal_is_dumb())
+                return COLOR_OFF;
+
+        /* We failed to figure out any reason to *disable* colors. Let's see how many colors we shall use. */
+        if (STRPTR_IN_SET(getenv("COLORTERM"),
+                          "truecolor",
+                          "24bit"))
+                return COLOR_24BIT;
+
+        /* Note that the Linux console can only display 16 colors. We still enable 256 color mode
+         * even for PID1 output though (which typically goes to the Linux console), since the Linux
+         * console is able to parse the 256 color sequences and automatically map them to the closest
+         * color in the 16 color palette (since kernel 3.16). Doing 256 colors is nice for people who
+         * invoke systemd in a container or via a serial link or such, and use a true 256 color
+         * terminal to do so. */
+        return COLOR_256;
+}
+
+ColorMode get_color_mode(void) {
+        if (cached_color_mode < 0)
+                cached_color_mode = get_color_mode_impl();
+
+        return cached_color_mode;
+}
+
+
+static const char* const color_mode_table[_COLOR_MODE_MAX] = {
+        [COLOR_OFF]   = "off",
+        [COLOR_16]    = "16",
+        [COLOR_256]   = "256",
+        [COLOR_24BIT] = "24bit",
+};
+
+DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(color_mode, ColorMode, COLOR_24BIT);
index 5f1418109c83b1aceafeaafa68039b00ca083225..f3e55e8165b2b08d59428feabbedfd7c5abf540e 100644 (file)
@@ -1,7 +1,34 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
-#include "terminal-util.h"
+#include <errno.h>
+
+#include "macro.h"
+
+/* Limits the use of ANSI colors to a subset. */
+typedef enum ColorMode {
+        COLOR_OFF,   /* No colors, monochrome output. */
+        COLOR_16,    /* Only the base 16 colors. */
+        COLOR_256,   /* Only 256 colors. */
+        COLOR_24BIT, /* For truecolor or 24bit color support, no restriction. */
+        _COLOR_MODE_MAX,
+        _COLOR_MODE_INVALID = -EINVAL,
+} ColorMode;
+
+const char* color_mode_to_string(ColorMode m) _const_;
+ColorMode color_mode_from_string(const char *s) _pure_;
+
+ColorMode get_color_mode(void);
+static inline bool colors_enabled(void) {
+        /* Returns true if colors are considered supported on our stdout. */
+        return get_color_mode() != COLOR_OFF;
+}
+
+ColorMode parse_systemd_colors(void);
+
+bool underline_enabled(void);
+
+void reset_ansi_feature_caches(void);
 
 /* Regular colors */
 #define ANSI_BLACK   "\x1B[0;30m" /* Some type of grey usually. */
index 7cc29bd0397c682b53e917130717f908baafb8a7..4588a9a6e88c32649b0f398927c3b20e1514a48c 100644 (file)
@@ -4,6 +4,7 @@ basic_sources = files(
         'MurmurHash2.c',
         'af-list.c',
         'alloc-util.c',
+        'ansi-color.c',
         'architecture.c',
         'argv-util.c',
         'arphrd-util.c',
index e59c8c2efe4e34b2d608e9ea93c89d6d719770ca..acd25389524ac34eb2122118e87a7046b3f45c00 100644 (file)
@@ -60,8 +60,6 @@ static volatile unsigned cached_lines = 0;
 
 static volatile int cached_on_tty = -1;
 static volatile int cached_on_dev_null = -1;
-static volatile int cached_color_mode = _COLOR_MODE_INVALID;
-static volatile int cached_underline_enabled = -1;
 
 bool isatty_safe(int fd) {
         assert(fd >= 0);
@@ -1433,10 +1431,10 @@ void reset_terminal_feature_caches(void) {
         cached_columns = 0;
         cached_lines = 0;
 
-        cached_color_mode = _COLOR_MODE_INVALID;
-        cached_underline_enabled = -1;
         cached_on_tty = -1;
         cached_on_dev_null = -1;
+
+        reset_ansi_feature_caches();
 }
 
 bool on_tty(void) {
@@ -1753,72 +1751,6 @@ bool terminal_is_dumb(void) {
         return getenv_terminal_is_dumb();
 }
 
-static const char* const color_mode_table[_COLOR_MODE_MAX] = {
-        [COLOR_OFF]   = "off",
-        [COLOR_16]    = "16",
-        [COLOR_256]   = "256",
-        [COLOR_24BIT] = "24bit",
-};
-
-DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(color_mode, ColorMode, COLOR_24BIT);
-
-static ColorMode parse_systemd_colors(void) {
-        const char *e;
-
-        e = getenv("SYSTEMD_COLORS");
-        if (!e)
-                return _COLOR_MODE_INVALID;
-
-        ColorMode m = color_mode_from_string(e);
-        if (m < 0)
-                return log_debug_errno(m, "Failed to parse $SYSTEMD_COLORS value '%s', ignoring: %m", e);
-
-        return m;
-}
-
-static ColorMode get_color_mode_impl(void) {
-        /* Returns the mode used to choose output colors. The possible modes are COLOR_OFF for no colors,
-         * COLOR_16 for only the base 16 ANSI colors, COLOR_256 for more colors, and COLOR_24BIT for
-         * unrestricted color output. */
-
-        /* First, we check $SYSTEMD_COLORS, which is the explicit way to change the mode. */
-        ColorMode m = parse_systemd_colors();
-        if (m >= 0)
-                return m;
-
-        /* Next, check for the presence of $NO_COLOR; value is ignored. */
-        if (getenv("NO_COLOR"))
-                return COLOR_OFF;
-
-        /* If the above didn't work, we turn colors off unless we are on a TTY. And if we are on a TTY we
-         * turn it off if $TERM is set to "dumb". There's one special tweak though: if we are PID 1 then we
-         * do not check whether we are connected to a TTY, because we don't keep /dev/console open
-         * continuously due to fear of SAK, and hence things are a bit weird. */
-        if (getpid_cached() == 1 ? getenv_terminal_is_dumb() : terminal_is_dumb())
-                return COLOR_OFF;
-
-        /* We failed to figure out any reason to *disable* colors. Let's see how many colors we shall use. */
-        if (STRPTR_IN_SET(getenv("COLORTERM"),
-                          "truecolor",
-                          "24bit"))
-                return COLOR_24BIT;
-
-        /* Note that the Linux console can only display 16 colors. We still enable 256 color mode
-         * even for PID1 output though (which typically goes to the Linux console), since the Linux
-         * console is able to parse the 256 color sequences and automatically map them to the closest
-         * color in the 16 color palette (since kernel 3.16). Doing 256 colors is nice for people who
-         * invoke systemd in a container or via a serial link or such, and use a true 256 color
-         * terminal to do so. */
-        return COLOR_256;
-}
-
-ColorMode get_color_mode(void) {
-        if (cached_color_mode < 0)
-                cached_color_mode = get_color_mode_impl();
-
-        return cached_color_mode;
-}
-
 bool dev_console_colors_enabled(void) {
         _cleanup_free_ char *s = NULL;
         ColorMode m;
@@ -1843,21 +1775,6 @@ bool dev_console_colors_enabled(void) {
         return !streq_ptr(s, "dumb");
 }
 
-bool underline_enabled(void) {
-
-        if (cached_underline_enabled < 0) {
-
-                /* The Linux console doesn't support underlining, turn it off, but only there. */
-
-                if (colors_enabled())
-                        cached_underline_enabled = !streq_ptr(getenv("TERM"), "linux");
-                else
-                        cached_underline_enabled = false;
-        }
-
-        return cached_underline_enabled;
-}
-
 int vt_restore(int fd) {
 
         static const struct vt_mode mode = {
index 0faf3c87611c1ea88b5b5b83e5fba9e83edf1ef7..3f6c3767704f5beb17f26e71dd9f6135462a8b19 100644 (file)
@@ -129,26 +129,6 @@ bool on_tty(void);
 bool getenv_terminal_is_dumb(void);
 bool terminal_is_dumb(void);
 
-/* Limits the use of ANSI colors to a subset. */
-typedef enum ColorMode {
-        COLOR_OFF,   /* No colors, monochrome output. */
-        COLOR_16,    /* Only the base 16 colors. */
-        COLOR_256,   /* Only 256 colors. */
-        COLOR_24BIT, /* For truecolor or 24bit color support, no restriction. */
-        _COLOR_MODE_MAX,
-        _COLOR_MODE_INVALID = -EINVAL,
-} ColorMode;
-
-const char* color_mode_to_string(ColorMode m) _const_;
-ColorMode color_mode_from_string(const char *s) _pure_;
-
-ColorMode get_color_mode(void);
-static inline bool colors_enabled(void) {
-        /* Returns true if colors are considered supported on our stdout. */
-        return get_color_mode() != COLOR_OFF;
-}
-
-bool underline_enabled(void);
 bool dev_console_colors_enabled(void);
 
 int get_ctty_devnr(pid_t pid, dev_t *ret);
index 58e67d9ebb798a6c44f3e2f74f4895a5dac6bc11..ca94410aee489768705b222a65d7ecb6e240e603 100644 (file)
@@ -1,5 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
+#include "ansi-color.h"
 #include "journal-internal.h"
 #include "log.h"
 #include "logs-show.h"