]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
terminal-util: Don't assume terminal is dumb if connected to /dev/null
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Thu, 16 Mar 2023 10:21:28 +0000 (11:21 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Thu, 16 Mar 2023 10:21:28 +0000 (11:21 +0100)
If we're connected to /dev/null, we're likely going to be writing
colors to something that's not stdout/stderr, so let's fall back to
checking TERM if that's the case.

src/basic/terminal-util.c

index 5cf2055dc6e6be764a09012a86d2b5d57b95e9fc..d3aa5c27e2b788d9e0c2a0353ea51fa54c37eb24 100644 (file)
@@ -49,6 +49,7 @@ static volatile unsigned cached_columns = 0;
 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_INVALID;
 static volatile int cached_underline_enabled = -1;
 
@@ -894,6 +895,7 @@ void reset_terminal_feature_caches(void) {
         cached_color_mode = _COLOR_INVALID;
         cached_underline_enabled = -1;
         cached_on_tty = -1;
+        cached_on_dev_null = -1;
 }
 
 bool on_tty(void) {
@@ -1224,6 +1226,20 @@ int open_terminal_in_namespace(pid_t pid, const char *name, int mode) {
         return receive_one_fd(pair[0], 0);
 }
 
+static bool on_dev_null(void) {
+        struct stat dst, ost, est;
+
+        if (cached_on_dev_null >= 0)
+                return cached_on_dev_null;
+
+        if (stat("/dev/null", &dst) < 0 || fstat(STDOUT_FILENO, &ost) < 0 || fstat(STDERR_FILENO, &est) < 0)
+                cached_on_dev_null = false;
+        else
+                cached_on_dev_null = stat_inode_same(&dst, &ost) && stat_inode_same(&dst, &est);
+
+        return cached_on_dev_null;
+}
+
 static bool getenv_terminal_is_dumb(void) {
         const char *e;
 
@@ -1235,7 +1251,7 @@ static bool getenv_terminal_is_dumb(void) {
 }
 
 bool terminal_is_dumb(void) {
-        if (!on_tty())
+        if (!on_tty() && !on_dev_null())
                 return true;
 
         return getenv_terminal_is_dumb();