From 0668f264f91f841740416042a37f50b38b59bfff Mon Sep 17 00:00:00 2001
From: Mats Erik Andersson <gnu@gisladisker.se>
Date: Fri, 3 Mar 2017 19:49:55 +0100
Subject: [PATCH 22/60] Test utility displays some termcaps.

---
 ChangeLog         |  13 +++++
 tests/Makefile.am |   2 +-
 tests/identify.c  | 126 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 140 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index fefaf4a7..2f11d205 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2017-03-03  Mats Erik Andersson  <gnu@gisladisker.se>
+
+	Test utility displays some termcaps.
+
+	* tests/Makefile.am (identify_LDADD): Set to contain
+	`$(top_builddir)/lib/libgnu.a' and `$(LIBUTIL)'.
+	* tests/identify.c: Include <string.h>.
+	[HAVE_TERMIOS_H]: Include <errno.h>, <termios.h>, <pty.h>.
+	[HAVE_TERMIOS_H && HAVE_FCNTL_H]: Include <fcntl.h>.
+	[HAVE_TCGETATTR] (test_flag): New macro.
+	[HAVE_TCGETATTR] (do_termcap): New function.
+	[HAVE_TCGETATTR] (main): Call do_termcap().
+
 2017-02-27  Mats Erik Andersson  <gnu@gisladisker.se>
 
 	telnetd: Portable option debugging.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index fbcf49e9..0750fe09 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -22,7 +22,7 @@ AM_CPPFLAGS = $(iu_INCLUDES)
 LDADD = $(iu_LIBRARIES)
 
 noinst_PROGRAMS = identify
-identify_LDADD =
+identify_LDADD = $(top_builddir)/lib/libgnu.a $(LIBUTIL)
 
 check_PROGRAMS = localhost readutmp waitdaemon
 
diff --git a/tests/identify.c b/tests/identify.c
index 39bf29d0..276b67e2 100644
--- a/tests/identify.c
+++ b/tests/identify.c
@@ -29,6 +29,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 
 #include <sys/param.h>
@@ -37,9 +38,128 @@
 #include <sys/socket.h>
 #include <sys/un.h>
 
+#ifdef HAVE_TERMIOS_H
+# include <errno.h>
+# if HAVE_FCNTL_H
+#  include <fcntl.h>
+# endif
+# include <termios.h>
+
+# include <pty.h>
+#endif /* HAVE_TERMIOS_H */
+
 #define tell_macro(a,b)	\
   printf ("%s: %s\n", (b) ? "Available macro" : "Not defined", (a));
 
+#ifdef HAVE_TCGETATTR
+# define test_flag(a, b, name)	\
+  if (tc.a & b) printf (" %s", name);
+
+void
+do_termcap(void)
+{
+  int pty, tty;
+  struct termios tc;
+
+  pty = openpty (&pty, &tty, NULL, NULL, NULL);
+  if (pty < 0)
+    {
+      fprintf (stderr, "openpt: errno = %d, %s\n",
+	       errno, strerror (errno));
+      return;
+    }
+
+  if (tcgetattr (tty, &tc) < 0)
+    {
+      fprintf (stderr, "tcgetattr; errno = %d, %s\n",
+	       errno, strerror (errno));
+      return;
+    }
+
+  printf ("_POSIX_VDISABLE = 0x%02x\n\n", _POSIX_VDISABLE);
+
+  /* Report the most interesting observations.  */
+  puts ("Default terminal settings (octal and hexadecimal):");
+  printf ("iflag = 0%06o = 0x%04x,  oflag = 0%06o = 0x%04x\n",
+	  tc.c_iflag, tc.c_iflag, tc.c_oflag, tc.c_oflag);
+  printf ("cflag = 0%06o = 0x%04x,  lflag = 0%06o = 0x%04x\n",
+	  tc.c_cflag, tc.c_cflag, tc.c_lflag, tc.c_lflag);
+
+  puts ("\nThe most relevant properties being set:");
+
+  printf ("iflag:");
+  test_flag (c_iflag, IXOFF, "IXOFF");
+  test_flag (c_iflag, IXON, "IXON");
+  test_flag (c_iflag, IXANY, "IXANY");
+  test_flag (c_iflag, BRKINT, "BRKINT");
+  test_flag (c_iflag, ISTRIP, "ISTRIP");
+  test_flag (c_iflag, IGNCR, "IGNCR");
+  test_flag (c_iflag, INLCR, "INLCR");
+  test_flag (c_iflag, ICRNL, "ICRNL");
+  puts ("");
+
+  printf ("oflag:");
+  test_flag (c_oflag, OPOST, "OPOST");
+  test_flag (c_oflag, OCRNL, "OCRNL");
+  test_flag (c_oflag, ONLCR, "ONLCR");
+  test_flag (c_oflag, ONLRET, "ONLRET");
+
+# ifdef TABDLY
+  printf (" TAB");
+  switch (tc.c_oflag & TABDLY)
+    {
+    case TAB3:
+      putchar ('3');
+      break;
+#  ifdef TAB2
+    case TAB2:
+      putchar ('2');
+      break;
+#  endif /* TAB2 */
+#  ifdef TAB1
+    case TAB1:
+      putchar ('1');
+      break;
+#  endif /* TAB1 */
+    case TAB0:
+      putchar ('0');
+      break;
+    }
+# elif defined OXTABS /* !TABDLY */
+  test_flag (c_oflag, OXTABS, "OXTABS");
+# endif /* OXTABS */
+
+  puts ("");
+
+  printf ("cflag:");
+  switch (tc.c_cflag & CSIZE)
+    {
+    case CS8:
+      printf (" CS8");
+      break;
+    case CS7:
+      printf (" CS7");
+    }
+  puts ("");
+
+  printf ("lflag:");
+  test_flag (c_lflag, ICANON, "ICANON");
+  test_flag (c_lflag, ISIG, "TRAPSIG");
+  test_flag (c_lflag, IEXTEN, "IEXTEN");
+  test_flag (c_lflag, ECHO, "ECHO");
+  test_flag (c_lflag, ECHOE, "ECHOE");
+  test_flag (c_lflag, ECHOK, "ECHOK");
+  test_flag (c_lflag, ECHOKE, "ECHOKE");
+  test_flag (c_lflag, ECHONL, "ECHONL");
+  test_flag (c_lflag, ECHOCTL, "ECHOCTL");
+  puts ("");
+
+  return;
+}
+# undef test_flag
+#endif /* HAVE_TCGETATTR */
+
+
 int
 main (void)
 {
@@ -113,5 +233,11 @@ main (void)
 
   printf ("Size of 'struct sockaddr_un.sun_path': %zu\n",
 	  sizeof (su.sun_path));
+
+#if HAVE_TCGETATTR
+  puts("");
+  do_termcap ();
+#endif
+
   return 0;
 }
-- 
2.26.0.292.g33ef6b2f38

