From 5cbdf86834fed3d4352a86b750ea169f64db8f3d Mon Sep 17 00:00:00 2001
From: "Taylor R. Campbell" <net/mumble/campbell>
Date: Sat, 21 Mar 2009 08:06:00 +0000
Subject: [PATCH] Periodically synchronize only the tty's x and y sizes. 
 Initialize the command strings only once; they are unlikely to change, and
 used in signal handlers.

---
 v7/src/microcode/uxtty.c | 167 +++++++++++++++++++++------------------
 1 file changed, 92 insertions(+), 75 deletions(-)

diff --git a/v7/src/microcode/uxtty.c b/v7/src/microcode/uxtty.c
index 875c3eab6..ed25c86d0 100644
--- a/v7/src/microcode/uxtty.c
+++ b/v7/src/microcode/uxtty.c
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Id: uxtty.c,v 1.18 2009/03/21 07:34:36 riastradh Exp $
+$Id: uxtty.c,v 1.19 2009/03/21 08:06:00 riastradh Exp $
 
 Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
     1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
@@ -49,8 +49,8 @@ static int tty_y_size;
 static const char * tty_command_beep;
 static const char * tty_command_clear;
 
-static bool tty_synchronized_p;
-static void UX_synchronize_tty (void);
+static bool tty_size_synchronized_p;
+static void UX_synchronize_tty_size (void);
 
 Tchannel
 OS_tty_input_channel (void)
@@ -67,28 +67,26 @@ OS_tty_output_channel (void)
 unsigned int
 OS_tty_x_size (void)
 {
-  UX_synchronize_tty ();
+  UX_synchronize_tty_size ();
   return (tty_x_size);
 }
 
 unsigned int
 OS_tty_y_size (void)
 {
-  UX_synchronize_tty ();
+  UX_synchronize_tty_size ();
   return (tty_y_size);
 }
 
 const char *
 OS_tty_command_beep (void)
 {
-  UX_synchronize_tty ();
   return (tty_command_beep);
 }
 
 const char *
 OS_tty_command_clear (void)
 {
-  UX_synchronize_tty ();
   return (tty_command_clear);
 }
 
@@ -125,84 +123,85 @@ tputs_write_char (char c)
 }
 
 static void
-UX_synchronize_tty (void)
+UX_tty_with_termcap (void (*procedure) (void))
 {
-  if (!tty_synchronized_p)
-    {
-      tty_x_size = (-1);
-      tty_y_size = (-1);
-      tty_command_beep = ALERT_STRING;
-      tty_command_clear = 0;
-      /* Figure out the size of the terminal.  First ask the operating
-	 system, if it has an appropriate system call.  Then try the
-	 environment variables COLUMNS and LINES.  Then try termcap.
-	 Finally, use the default.  */
+  tputs_output_scan = tputs_output;
+  {
+    char termcap_buffer [TERMCAP_BUFFER_SIZE];
+    const char *term;
+    if ((isatty (STDOUT_FILENO))
+	&& (!option_emacs_subprocess)
+	&& ((term = (getenv ("TERM"))) != 0)
+	&& ((tgetent (termcap_buffer, term)) > 0))
+      (*procedure) ();
+  }
+}
+
+static void
+UX_synchronize_tty_size_with_termcap (void)
+{
+  tty_x_size = (tgetnum ("co"));
+  tty_y_size = (tgetnum ("li"));
+}
+
+static void
+UX_synchronize_tty_size (void)
+{
+  if (tty_size_synchronized_p)
+    return;
+
+  tty_x_size = (-1);
+  tty_y_size = (-1);
+
+  /* Figure out the size of the terminal.  First ask the operating
+     system, if it has an appropriate system call.  Then try the
+     environment variables COLUMNS and LINES.  Then try termcap.
+     Finally, use the default.  */
 #ifdef TIOCGWINSZ
+  {
+    struct winsize size;
+    if ((UX_ioctl (STDOUT_FILENO, TIOCGWINSZ, (&size))) >= 0)
       {
-	struct winsize size;
-	if ((UX_ioctl (STDOUT_FILENO, TIOCGWINSZ, (&size))) >= 0)
-	  {
-	    tty_x_size = (size . ws_col);
-	    tty_y_size = (size . ws_row);
-	  }
+	tty_x_size = (size . ws_col);
+	tty_y_size = (size . ws_row);
       }
+  }
 #endif /* TIOCGWINSZ */
-      if ((tty_x_size <= 0) || (tty_y_size <= 0))
+
+  if ((tty_x_size <= 0) || (tty_y_size <= 0))
+    {
+      const char * columns = (UX_getenv ("COLUMNS"));
+      const char * lines = (UX_getenv ("LINES"));
+      if ((columns != 0) && (lines != 0))
 	{
-	  const char * columns = (UX_getenv ("COLUMNS"));
-	  const char * lines = (UX_getenv ("LINES"));
-	  if ((columns != 0) && (lines != 0))
+	  int x = (atoi (columns));
+	  int y = (atoi (lines));
+	  if ((x > 0) && (y > 0))
 	    {
-	      int x = (atoi (columns));
-	      int y = (atoi (lines));
-	      if ((x > 0) && (y > 0))
-		{
-		  tty_x_size = x;
-		  tty_y_size = y;
-		}
+	      tty_x_size = x;
+	      tty_y_size = y;
 	    }
 	}
-      tputs_output_scan = tputs_output;
-      {
-	static char tgetstr_buffer [TERMCAP_BUFFER_SIZE];
-	char termcap_buffer [TERMCAP_BUFFER_SIZE];
-	char * tbp = tgetstr_buffer;
-	const char * term;
-	if ((isatty (STDOUT_FILENO))
-	    && (!option_emacs_subprocess)
-	    && ((term = (getenv ("TERM"))) != 0)
-	    && ((tgetent (termcap_buffer, term)) > 0))
-	  {
-	    if ((tty_x_size <= 0) || (tty_y_size <= 0))
-	      {
-		tty_x_size = (tgetnum ("co"));
-		tty_y_size = (tgetnum ("li"));
-	      }
-	    tty_command_clear = (tgetstr ("cl", (&tbp)));
-	  }
-      }
-      if ((tty_x_size <= 0) || (tty_y_size <= 0))
-	{
-	  tty_x_size = DEFAULT_TTY_X_SIZE;
-	  tty_y_size = DEFAULT_TTY_Y_SIZE;
-	}
-      if (tty_command_clear == 0)
-	tty_command_clear = "\f";
-      else
-	{
-	  char * command = tputs_output_scan;
-	  tputs (tty_command_clear, tty_y_size, tputs_write_char);
-	  (*tputs_output_scan++) = '\0';
-	  tty_command_clear = command;
-	}
-      tty_synchronized_p = true;
     }
-}
 
-void
-UX_reinitialize_tty (void)
+  if ((tty_x_size <= 0) || (tty_y_size <= 0))
+    UX_tty_with_termcap (&UX_synchronize_tty_size_with_termcap);
+
+  if ((tty_x_size <= 0) || (tty_y_size <= 0))
+    {
+      tty_x_size = DEFAULT_TTY_X_SIZE;
+      tty_y_size = DEFAULT_TTY_Y_SIZE;
+    }
+
+  tty_size_synchronized_p = true;
+}
+
+static void
+UX_initialize_tty_with_termcap (void)
 {
-  tty_synchronized_p = false;
+  static char tgetstr_buffer [TERMCAP_BUFFER_SIZE];
+  char *tbp = tgetstr_buffer;
+  tty_command_clear = (tgetstr ("cl", (&tbp)));
 }
 
 void
@@ -212,6 +211,24 @@ UX_initialize_tty (void)
   (CHANNEL_INTERNAL (input_channel)) = 1;
   output_channel = (OS_open_fd (STDOUT_FILENO));
   (CHANNEL_INTERNAL (output_channel)) = 1;
-  tty_synchronized_p = false;
-  UX_synchronize_tty ();
+  tty_size_synchronized_p = false;
+  UX_synchronize_tty_size ();
+  tty_command_beep = ALERT_STRING;
+  tty_command_clear = 0;
+  UX_tty_with_termcap (&UX_initialize_tty_with_termcap);
+  if (tty_command_clear == 0)
+    tty_command_clear = "\f";
+  else
+    {
+      char * command = tputs_output_scan;
+      tputs (tty_command_clear, tty_y_size, tputs_write_char);
+      (*tputs_output_scan++) = '\0';
+      tty_command_clear = command;
+    }
+}
+
+void
+UX_reinitialize_tty (void)
+{
+  tty_size_synchronized_p = false;
 }
-- 
2.25.1