]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
nspawn,run,machinectl,socket-activate: propagate $COLORTERM + $NO_COLOR 36770/head
authorLennart Poettering <lennart@poettering.net>
Mon, 17 Mar 2025 08:52:52 +0000 (09:52 +0100)
committerLennart Poettering <lennart@poettering.net>
Mon, 17 Mar 2025 09:17:54 +0000 (10:17 +0100)
When we pass information about our calling terminal on to some service
or command we invoke, propagate $COLORTERM + $NO_COLOR in addition to
$TERM, in order to always consider the triplet of the three env vars the
real deal.

src/machine/machinectl.c
src/nspawn/nspawn.c
src/run/run.c
src/socket-activate/socket-activate.c

index b7b7130fdb31d16b79236c8bbade46277cfd31fc..366446c3062937e22a69eeeae9b5d6f539e078a5 100644 (file)
@@ -1362,15 +1362,17 @@ static int shell_machine(int argc, char *argv[], void *userdata) {
                 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
                                        "Shell only supported on local machines.");
 
-        /* Pass $TERM to shell session, if not explicitly specified. */
-        if (!strv_find_prefix(arg_setenv, "TERM=")) {
-                const char *t;
+        /* Pass $TERM & Co. to shell session, if not explicitly specified. */
+        FOREACH_STRING(v, "TERM=", "COLORTERM=", "NO_COLOR=") {
+                if (strv_find_prefix(arg_setenv, v))
+                        continue;
 
-                t = strv_find_prefix(environ, "TERM=");
-                if (t) {
-                        if (strv_extend(&arg_setenv, t) < 0)
-                                return log_oom();
-                }
+                const char *t = strv_find_prefix(environ, v);
+                if (!t)
+                        continue;
+
+                if (strv_extend(&arg_setenv, t) < 0)
+                        return log_oom();
         }
 
         (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
index f19014016f85cfe2898c1c949dda593ba7a4938b..e3c5d6b732700c6cb08c6a193619843a2d01fd11 100644 (file)
@@ -3337,6 +3337,8 @@ static int inner_child(
                 (char*) "PATH=" DEFAULT_PATH_COMPAT,
                 NULL, /* container */
                 NULL, /* TERM */
+                NULL, /* COLORTERM */
+                NULL, /* NO_COLOR */
                 NULL, /* HOME */
                 NULL, /* USER */
                 NULL, /* LOGNAME */
@@ -3588,9 +3590,17 @@ static int inner_child(
         /* LXC sets container=lxc, so follow the scheme here */
         envp[n_env++] = strjoina("container=", arg_container_service_name);
 
-        /* Propagate $TERM unless we are invoked in pipe mode and stdin/stdout/stderr don't refer to a TTY */
-        const char *term = (arg_console_mode != CONSOLE_PIPE || on_tty()) ? strv_find_prefix(environ, "TERM=") : NULL;
-        envp[n_env++] = (char*) (term ?: "TERM=dumb");
+        /* Propagate $TERM & Co. unless we are invoked in pipe mode and stdin/stdout/stderr don't refer to a TTY */
+        if (arg_console_mode != CONSOLE_PIPE || on_tty()) {
+                FOREACH_STRING(v, "TERM=", "COLORTERM=", "NO_COLOR=") {
+                        char *t = strv_find_prefix(environ, v);
+                        if (!t)
+                                continue;
+
+                        envp[n_env++] = t;
+                }
+        } else
+                envp[n_env++] = (char*) "TERM=dumb";
 
         if (home || !uid_is_valid(arg_uid) || arg_uid == 0)
                 if (asprintf(envp + n_env++, "HOME=%s", home ?: "/root") < 0)
index 523993cffdbf5b56624565cc05e907e2efc87b96..b9a4ecd2e4f042a66a0efa52aafffda116d3612f 100644 (file)
@@ -1334,29 +1334,48 @@ static int transient_service_set_properties(sd_bus_message *m, const char *pty_p
                 send_term = false;
 
         if (send_term != 0) {
-                const char *e;
+                const char *e, *colorterm = NULL, *no_color = NULL;
 
-                /* Propagate $TERM only if we are actually connected to a TTY */
+                /* Propagate $TERM + $COLORTERM + $NO_COLOR if we are actually connected to a TTY */
                 if (isatty_safe(STDIN_FILENO) || isatty_safe(STDOUT_FILENO) || isatty_safe(STDERR_FILENO)) {
-                        e = getenv("TERM");
+                        e = strv_find_prefix(environ, "TERM=");
                         send_term = !!e;
+
+                        if (send_term) {
+                                /* If we send $TERM along, then also propagate $COLORTERM + $NO_COLOR right with it */
+                                colorterm = strv_find_prefix(environ, "COLORTERM=");
+                                no_color = strv_find_prefix(environ, "NO_COLOR=");
+                        }
                 } else
                         /* If we are not connected to any TTY ourselves, then send TERM=dumb, but only if we
                          * really need to (because we actually allocated a TTY for the service) */
-                        e = "dumb";
+                        e = "TERM=dumb";
 
                 if (send_term > 0) {
-                        _cleanup_free_ char *n = NULL;
-
-                        n = strjoin("TERM=", e);
-                        if (!n)
-                                return log_oom();
-
-                        r = sd_bus_message_append(m,
-                                                  "(sv)",
-                                                  "Environment", "as", 1, n);
+                        r = sd_bus_message_append(
+                                        m,
+                                        "(sv)",
+                                        "Environment", "as", 1, e);
                         if (r < 0)
                                 return bus_log_create_error(r);
+
+                        if (colorterm) {
+                                r = sd_bus_message_append(
+                                                m,
+                                                "(sv)",
+                                                "Environment", "as", 1, colorterm);
+                                if (r < 0)
+                                        return bus_log_create_error(r);
+                        }
+
+                        if (no_color) {
+                                r = sd_bus_message_append(
+                                                m,
+                                                "(sv)",
+                                                "Environment", "as", 1, no_color);
+                                if (r < 0)
+                                        return bus_log_create_error(r);
+                        }
                 }
         }
 
index 134ed3f0de29153806e82171f32d5145ad32ac90..ac663d03238620033eef215c2b6ff9d231b14dc8 100644 (file)
@@ -132,7 +132,7 @@ static int exec_process(const char *name, char **argv, int start_fd, size_t n_fd
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                        "--inetd only supported for single file descriptors.");
 
-        FOREACH_STRING(var, "TERM", "PATH", "USER", "HOME") {
+        FOREACH_STRING(var, "TERM", "COLORTERM", "NO_COLOR", "PATH", "USER", "HOME") {
                 const char *n;
 
                 n = strv_find_prefix(environ, var);