billiob pushed a commit to branch master.

http://git.enlightenment.org/apps/terminology.git/commit/?id=6b8da827224f0efe27fd15ac069a98f77a5b7b27

commit 6b8da827224f0efe27fd15ac069a98f77a5b7b27
Author: Boris Faure <[email protected]>
Date:   Sun Apr 5 15:50:12 2020 +0200

    tycommon: ensure common tools are running in terminology
    
    This is done by reading the tertiary device attributes and expecting
    terminology's value.
---
 src/bin/tycommon.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++----
 src/bin/tycommon.h |   4 +-
 2 files changed, 107 insertions(+), 10 deletions(-)

diff --git a/src/bin/tycommon.c b/src/bin/tycommon.c
index 1877637..7503eea 100644
--- a/src/bin/tycommon.c
+++ b/src/bin/tycommon.c
@@ -1,20 +1,117 @@
 #include "private.h"
 #include <errno.h>
+#include <fcntl.h>
 #include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/select.h>
+#include <sys/types.h>
+#include <termios.h>
 #include <unistd.h>
 #include "tycommon.h"
 
-
+/* returns 0 if running in terminology, something else otherwise */
 int
-is_running_in_terminology(void)
+expect_running_in_terminology(void)
 {
-   if (!getenv("TERMINOLOGY")) return 0;
-   // Terminology's escape codes do not got through tmux
-   if (getenv("TMUX")) return 0;
-   // Terminology's escape codes do not got through screen
-   if (getenv("STY")) return 0;
+   char buf[32];
+   ssize_t len = 0;
+   const char *expected = "\033P!|7E7E5459\033\\";
+   const char *pos = expected;
+   fd_set readset;
+   struct timeval tv;
+   struct termios ttystate, ttysave;
+   int res = -1;
+
+   /* get current terminal state */
+   if (tcgetattr(STDIN_FILENO, &ttystate))
+     {
+        perror("tcgetattr");
+        return -1;
+     }
+   ttysave = ttystate;
+
+   /* turn off canonical (buffered) mode and echo */
+   ttystate.c_lflag &= ~(ICANON | ECHO);
+   /* minimum of number input read: 1 byte. */
+   ttystate.c_cc[VMIN] = 1;
+   ttystate.c_cc[VTIME] = 0;
+
+   /* set new terminal attributes */
+   if (tcsetattr(STDIN_FILENO, TCSANOW, &ttystate))
+     {
+        perror("tcsetattr");
+        return -1;
+     }
+
+   /* Query device attributes 3 */
+   buf[0] = '\033';
+   buf[1] = '[';
+   buf[2] = '=';
+   buf[3] = 'c';
+   len = ty_write(STDOUT_FILENO, buf, 4);
+   if (len != 4)
+     {
+        perror("write");
+        res = -1;
+        goto end;
+     }
+
+   while (pos != (expected + strlen(expected)))
+     {
+        /* wait up to 1 second */
+        tv.tv_sec = 1;
+        tv.tv_usec = 0;
+
+        FD_ZERO(&readset);
+        FD_SET(STDIN_FILENO, &readset);
+
+        errno = 0;
+        if (select(1, &readset, NULL, NULL, &tv) < 0)
+          {
+             perror("select");
+             res = -1;
+             goto end;
+          }
+
+        if (FD_ISSET(STDIN_FILENO, &readset))
+          {
+             len = read(STDIN_FILENO, buf, 1);
+             if (len != 1)
+               {
+                  perror("read");
+                  res = -1;
+                  goto end;
+               }
+
+             if (buf[0] == *pos)
+               pos++;
+             else if (pos == expected)
+               continue;
+             else
+               {
+                  res = -1;
+                  goto end;
+               }
+          }
+        else
+          {
+             res = -1;
+             goto end;
+          }
+     }
+   res = 0;
+
+end:
+
+   /* restore attributes */
+   if (tcsetattr(STDIN_FILENO, TCSANOW, &ttysave))
+     {
+        perror("tcsetattr");
+        return -1;
+     }
 
-   return 1;
+   return res;
 }
 
 ssize_t
diff --git a/src/bin/tycommon.h b/src/bin/tycommon.h
index d5bf90e..7688b3a 100644
--- a/src/bin/tycommon.h
+++ b/src/bin/tycommon.h
@@ -1,13 +1,13 @@
 #ifndef _TY_COMMON_H__
 #define _TY_COMMON_H__ 1
 
-int is_running_in_terminology(void);
+int expect_running_in_terminology(void);
 ssize_t ty_write(int fd, const void *buf, size_t count);
 
 #define ON_NOT_RUNNING_IN_TERMINOLOGY_EXIT_1()                             \
   do                                                                       \
     {                                                                      \
-       if (!is_running_in_terminology())                                   \
+       if (expect_running_in_terminology() != 0)                           \
          {                                                                 \
             fprintf(stderr, "not directly running in terminology\n");      \
             exit(1);                                                       \

-- 


Reply via email to