]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
run: tweak logic how we set $TERM for activated services
authorLennart Poettering <lennart@poettering.net>
Fri, 31 Jan 2025 14:06:34 +0000 (15:06 +0100)
committerLennart Poettering <lennart@poettering.net>
Thu, 27 Feb 2025 14:13:15 +0000 (15:13 +0100)
There are two cases when we invoke a service on a TTY:

1. We ourselves are connected to a TTY and would intend to enable PTY
   forwarding.
2. We are allocating a TTY but are not ourselves connected to a TTY and
   just want to input/output to pipe or other non-TTY fd.

Let's propagate $TERM only as-is in the first case. In the 2nd case,
let's explicitly set $TERM to "dumb", so that invoked progams do not
issue needless ansi sequences, since we are not propagating them to a
terminal either.

This should be a much safer result, for cases where people include
invocations of systemd-nspawn with full TTY allocation in a shell
pipeline or so.

(of course, the user can always explicitly override this)

src/run/run.c

index b2d74f608896fb27b6352b0755c109cd83e93760..816fd8dd9a4cfc8ce63be09ed7bc3cb717ead82c 100644 (file)
@@ -1233,7 +1233,7 @@ static int transient_kill_set_properties(sd_bus_message *m) {
 }
 
 static int transient_service_set_properties(sd_bus_message *m, const char *pty_path, int pty_fd) {
-        bool send_term = false;
+        int send_term = false; /* tri-state */
         int r;
 
         /* We disable environment expansion on the server side via ExecStartEx=:.
@@ -1312,14 +1312,22 @@ static int transient_service_set_properties(sd_bus_message *m, const char *pty_p
                 if (r < 0)
                         return bus_log_create_error(r);
 
-                send_term = isatty_safe(STDIN_FILENO) || isatty_safe(STDOUT_FILENO) || isatty_safe(STDERR_FILENO);
+                send_term = -1;
         }
 
-        if (send_term) {
+        if (send_term != 0) {
                 const char *e;
 
-                e = getenv("TERM");
-                if (e) {
+                /* Propagate $TERM only if we are actually connected to a TTY  */
+                if (isatty_safe(STDIN_FILENO) || isatty_safe(STDOUT_FILENO) || isatty_safe(STDERR_FILENO)) {
+                        e = getenv("TERM");
+                        send_term = true;
+                } 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";
+
+                if (send_term > 0) {
                         _cleanup_free_ char *n = NULL;
 
                         n = strjoin("TERM=", e);