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);
(char*) "PATH=" DEFAULT_PATH_COMPAT,
NULL, /* container */
NULL, /* TERM */
+ NULL, /* COLORTERM */
+ NULL, /* NO_COLOR */
NULL, /* HOME */
NULL, /* USER */
NULL, /* LOGNAME */
/* 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)
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);
+ }
}
}
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);