changeset 82995:039bd6989d29

Portability fixes (now it compiles & runs fine on Solaris). lib-src/emacsclient.c: Removed tty proxy kludge. Emacs should just use the same terminal as emacsclient. (ec_get_tty, ec_set_tty, master, pty_name, old_tty, tty, old_tty_valid) (tty_erase_char, quit_char, flow_control, meta_key, _sobuf, init_tty) (window_change, reset_tty, init_pty, copy_from_to) (pty_conversation): Removed. (window_change_signal): Just forward the signal to Emacs, don't do anything else. (init_signals): Don't set handlers for SIGHUP & SIGINT. (strprefix): New function. (main): Don't touch the terminal, simply tell its name to Emacs. lisp/server.el (server-frames): Changed name and semantics to server-ttys. (server-tty-live-p): New function. (server-sentinel): Delete the whole tty, not just the frame. (server-handle-delete-frame): Removed. (server-handle-delete-tty): New function. Close the client connection if the tty is deleted. (server-start): Clean up server-ttys, not server-frames. Set up delete-tty-after-functions. (server-process-filter): Set up server-ttys, not server-frames. Updated protocol for sending our pid to emacsclient. (server-buffer-done): Don't delete the client process directly, delete the tty instead, and rely on the delete-tty hook to close the connection. Otherwise the terminal could be left in a bad state. src/cm.c (cmputc): Don't abort on write errors. src/indent.c: #include <stdio.h>, for termchar.h. src/window.c: Ditto. src/xfaces.c: Ditto. src/sysdep.c (init_sigio, reset_sigio, request_sigio)[!SIGIO] (unrequest_sigio)[!SIGIO]: If SIGIO is not supported, don't do anything. (For Solaris.) (init_sys_modes): Moved tty_set_terminal_modes call back to here, disable window system check. (reset_sys_modes): Reset the terminal even if X is running. src/term.c (Vdelete_tty_after_functions): New variable. (syms_of_term): Initialize it. (Fdelete_tty): Updated docs. (delete_tty): Run delete-tty-after-functions. (term_init): Removed tty_set_terminal_modes call. git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-35
author Karoly Lorentey <lorentey@elte.hu>
date Sat, 03 Jan 2004 08:31:14 +0000
parents 44ffe551079c
children c16b10dde3f2
files README.multi-tty lib-src/emacsclient.c lisp/server.el src/Makefile.in src/cm.c src/dispnew.c src/indent.c src/sysdep.c src/syssignal.h src/term.c src/window.c src/xfaces.c
diffstat 12 files changed, 180 insertions(+), 641 deletions(-) [+]
line wrap: on
line diff
--- a/README.multi-tty	Fri Jan 02 13:03:12 2004 +0000
+++ b/README.multi-tty	Sat Jan 03 08:31:14 2004 +0000
@@ -130,7 +130,9 @@
 ** Something with (maybe) multi-keyboard support broke function keys
    and arrows on ttys during X+tty combo sessions.  Debug this.
 
-** Fix faces on tty frames during X-tty combo sessions.
+** Fix faces on tty frames during X-tty combo sessions.  There is an
+   init_frame_faces call in init_sys_modes, see if there is a problem
+   with it.
 
 ** During an X-tty combo session, a (message "Hello") from a tty frame
    goes to the X frame.  Fix this.
@@ -186,7 +188,8 @@
 	select(9, [0 3 5 6], NULL, NULL, {0, 0}) = 2 (in [5 6], left {0, 0})
 	gettimeofday({1072842297, 748245}, NULL) = 0
 
-   I have not been able to reproduce this.
+   I have seen something similar with a single X frame, but have not
+   been able to reproduce it for debugging.
 
 ** Define a output_initial value for output_method for the initial
    frame that is dumped with Emacs.  Checking for this frame (e.g. in
@@ -196,6 +199,12 @@
    about face problems.  This can even lock up Emacs (if the recursive
    frame sets single_kboard).
 
+** Clean up the source of emacsclient.  It is a mess.
+
+** C-x 5 2, C-x 5 o, C-x 5 0 on an emacsclient frame unexpectedly
+   exits emacsclient.  This is a result of trying to be clever with
+   delete-frame-functions.
+
 DIARY OF CHANGES
 ----------------
 
--- a/lib-src/emacsclient.c	Fri Jan 02 13:03:12 2004 +0000
+++ b/lib-src/emacsclient.c	Sat Jan 03 08:31:14 2004 +0000
@@ -41,54 +41,10 @@
 # include <pwd.h>
 #endif /* not VMS */
 
-
-/****************************************/
-
+#include <signal.h>
 #include <errno.h>
-#include <signal.h>
-
-#ifndef INCLUDED_FCNTL
-#define INCLUDED_FCNTL
-#include <fcntl.h>
-#endif
-
-#ifdef HAVE_TERMIOS
-#ifndef NO_TERMIO
-#include <termio.h>
-#endif
-#include <termios.h>
-#endif /* not HAVE_TERMIOS */
-
-#ifdef __GNU_LIBRARY__
-#include <sys/ioctl.h>
-#include <termios.h>
-#endif
-
-#if (defined (POSIX) || defined (NEED_UNISTD_H)) && defined (HAVE_UNISTD_H)
-#include <unistd.h>
-#endif
-
 
 
-/* Try to establish the correct character to disable terminal functions
-   in a system-independent manner.  Note that USG (at least) define
-   _POSIX_VDISABLE as 0!  */
-
-#ifdef _POSIX_VDISABLE
-#define CDISABLE _POSIX_VDISABLE
-#else /* not _POSIX_VDISABLE */
-#ifdef CDEL
-#undef CDISABLE
-#define CDISABLE CDEL
-#else /* not CDEL */
-#define CDISABLE 255
-#endif /* not CDEL */
-#endif /* not _POSIX_VDISABLE */
-
-
-
-/****************************************/
-
 char *getenv (), *getwd ();
 char *getcwd ();
 
@@ -314,532 +270,37 @@
     }
 }
 
-
-#ifdef HAVE_TERMIOS
-
-/* Adapted from emacs_get_tty() in sysdep.c. */
-int
-ec_get_tty (int fd, struct termios *settings)
-{
-  bzero (settings, sizeof (struct termios));
-  if (tcgetattr (fd, settings) < 0)
-    return -1;
-  return 0;
-}
-
-/* Adapted from emacs_set_tty() in sysdep.c. */
-int
-ec_set_tty (int fd, struct termios *settings, int flushp)
-{
-  /* Set the primary parameters - baud rate, character size, etcetera.  */
-
-  int i;
-  /* We have those nifty POSIX tcmumbleattr functions.
-     William J. Smith <wjs@wiis.wang.com> writes:
-     "POSIX 1003.1 defines tcsetattr to return success if it was
-     able to perform any of the requested actions, even if some
-     of the requested actions could not be performed.
-     We must read settings back to ensure tty setup properly.
-     AIX requires this to keep tty from hanging occasionally."  */
-  /* This make sure that we don't loop indefinitely in here.  */
-  for (i = 0 ; i < 10 ; i++)
-    if (tcsetattr (fd, flushp ? TCSAFLUSH : TCSADRAIN, settings) < 0)
-      {
-	if (errno == EINTR)
-	  continue;
-	else
-	  return -1;
-      }
-    else
-      {
-	struct termios new;
-        
-	bzero (&new, sizeof (new));
-	/* Get the current settings, and see if they're what we asked for.  */
-	tcgetattr (fd, &new);
-	/* We cannot use memcmp on the whole structure here because under
-	 * aix386 the termios structure has some reserved field that may
-	 * not be filled in.
-	 */
-	if (   new.c_iflag == settings->c_iflag
-	    && new.c_oflag == settings->c_oflag
-	    && new.c_cflag == settings->c_cflag
-	    && new.c_lflag == settings->c_lflag
-	    && memcmp (new.c_cc, settings->c_cc, NCCS) == 0)
-	  break;
-	else
-	  continue;
-      }
-  return 0;
-}
-
-int master;
-char *pty_name;
-
-struct termios old_tty;
-struct termios tty;
-int old_tty_valid;
-
-int tty_erase_char;
-int quit_char = 'g' & 037;
-int flow_control = 0;
-int meta_key = 0;
-char _sobuf[BUFSIZ];
 int emacs_pid;
 
-/* Adapted from init_sys_modes() in sysdep.c. */
-int
-init_tty ()
-{
-  if (! isatty (0))
-    {
-      fprintf (stderr, "%s: Input is not a terminal", "init_tty");
-      return 0;
-    }
-  
-  ec_get_tty (0, &old_tty);
-  old_tty_valid = 1;
-  tty = old_tty;
-  
-  tty_erase_char = old_tty.c_cc[VERASE];
-  
-  tty.c_iflag |= (IGNBRK);	/* Ignore break condition */
-  tty.c_iflag &= ~ICRNL;	/* Disable map of CR to NL on input */
-#ifdef INLCR
-  tty.c_iflag &= ~INLCR;	/* Disable map of NL to CR on input */
-#endif
-#ifdef ISTRIP
-  tty.c_iflag &= ~ISTRIP;	/* don't strip 8th bit on input */
-#endif
-  tty.c_lflag &= ~ECHO;         /* Disable echo */
-  tty.c_lflag &= ~ICANON;	/* Disable erase/kill processing */
-#ifdef IEXTEN
-  tty.c_lflag &= ~IEXTEN;	/* Disable other editing characters.  */
-#endif
-  tty.c_lflag |= ISIG;          /* Enable signals */
-  if (flow_control)
-    {
-      tty.c_iflag |= IXON;	/* Enable start/stop output control */
-#ifdef IXANY
-      tty.c_iflag &= ~IXANY;
-#endif /* IXANY */
-    }
-  else
-    tty.c_iflag &= ~IXON;	/* Disable start/stop output control */
-  tty.c_oflag &= ~ONLCR;	/* Disable map of NL to CR-NL
-                                   on output */
-  tty.c_oflag &= ~TAB3;         /* Disable tab expansion */
-#ifdef CS8
-  if (meta_key)
-    {
-      tty.c_cflag |= CS8;	/* allow 8th bit on input */
-      tty.c_cflag &= ~PARENB;   /* Don't check parity */
-    }
-#endif
-  tty.c_cc[VINTR] = quit_char;	/* C-g (usually) gives SIGINT */
-  /* Set up C-g for both SIGQUIT and SIGINT.
-     We don't know which we will get, but we handle both alike
-     so which one it really gives us does not matter.  */
-  tty.c_cc[VQUIT] = quit_char;
-  tty.c_cc[VMIN] = 1;      /* Input should wait for at least 1 char */
-  tty.c_cc[VTIME] = 0;          /* no matter how long that takes.  */
-#ifdef VSWTCH
-  tty.c_cc[VSWTCH] = CDISABLE;	/* Turn off shell layering use of C-z */
-#endif
-
-#ifdef VSUSP
-  tty.c_cc[VSUSP] = CDISABLE;	/* Turn off mips handling of C-z.  */
-#endif /* VSUSP */
-#ifdef V_DSUSP
-  tty.c_cc[V_DSUSP] = CDISABLE; /* Turn off mips handling of C-y.  */
-#endif /* V_DSUSP */
-#ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP.  */
-  tty.c_cc[VDSUSP] = CDISABLE;
-#endif /* VDSUSP */
-#ifdef VLNEXT
-  tty.c_cc[VLNEXT] = CDISABLE;
-#endif /* VLNEXT */
-#ifdef VREPRINT
-  tty.c_cc[VREPRINT] = CDISABLE;
-#endif /* VREPRINT */
-#ifdef VWERASE
-  tty.c_cc[VWERASE] = CDISABLE;
-#endif /* VWERASE */
-#ifdef VDISCARD
-  tty.c_cc[VDISCARD] = CDISABLE;
-#endif /* VDISCARD */
-
-  if (flow_control)
-    {
-#ifdef VSTART
-      tty.c_cc[VSTART] = '\021';
-#endif /* VSTART */
-#ifdef VSTOP
-      tty.c_cc[VSTOP] = '\023';
-#endif /* VSTOP */
-    }
-  else
-    {
-#ifdef VSTART
-      tty.c_cc[VSTART] = CDISABLE;
-#endif /* VSTART */
-#ifdef VSTOP
-      tty.c_cc[VSTOP] = CDISABLE;
-#endif /* VSTOP */
-    }
-  
-#ifdef SET_LINE_DISCIPLINE
-  /* Need to explicitly request TERMIODISC line discipline or
-     Ultrix's termios does not work correctly.  */
-  tty.c_line = SET_LINE_DISCIPLINE;
-#endif
-  
-#ifdef AIX
-#ifndef IBMR2AIX
-  /* AIX enhanced edit loses NULs, so disable it.  */
-  tty.c_line = 0;
-  tty.c_iflag &= ~ASCEDIT;
+#ifdef nec_ews_svr4
+extern char *_sobuf ;
 #else
-  tty.c_cc[VSTRT] = 255;
-  tty.c_cc[VSTOP] = 255;
-  tty.c_cc[VSUSP] = 255;
-  tty.c_cc[VDSUSP] = 255;
-#endif /* IBMR2AIX */
-  if (flow_control)
-    {
-#ifdef VSTART
-      tty.c_cc[VSTART] = '\021';
-#endif /* VSTART */
-#ifdef VSTOP
-      tty.c_cc[VSTOP] = '\023';
-#endif /* VSTOP */
-    }
-  /* Also, PTY overloads NUL and BREAK.
-     don't ignore break, but don't signal either, so it looks like NUL.
-     This really serves a purpose only if running in an XTERM window
-     or via TELNET or the like, but does no harm elsewhere.  */
-  tty.c_iflag &= ~IGNBRK;
-  tty.c_iflag &= ~BRKINT;
-#endif /* AIX */
-  
-  ec_set_tty (0, &tty, 0);
-
-      /* This code added to insure that, if flow-control is not to be used,
-	 we have an unlocked terminal at the start. */
-
-#ifdef TCXONC
-  if (!flow_control) ioctl (0, TCXONC, 1);
-#endif
-#ifndef APOLLO
-#ifdef TIOCSTART
-  if (!flow_control) ioctl (0, TIOCSTART, 0);
+#if defined (USG) || defined (DGUX)
+unsigned char _sobuf[BUFSIZ+8];
+#else
+char _sobuf[BUFSIZ];
 #endif
 #endif
 
-#if defined (HAVE_TERMIOS) || defined (HPUX9)
-#ifdef TCOON
-  if (!flow_control) tcflow (0, TCOON);
-#endif
-#endif
-  
-#ifdef _IOFBF
-  /* This symbol is defined on recent USG systems.
-     Someone says without this call USG won't really buffer the file
-     even with a call to setbuf. */
-  setvbuf (stdout, (char *) _sobuf, _IOFBF, sizeof _sobuf);
-#else
-  setbuf (stdout, (char *) _sobuf);
-#endif
-
-  return 1;
-}
-
-void
-window_change ()
-{
-  int width = 0, height = 0;
-
-#ifdef TIOCGWINSZ
-  {
-    /* BSD-style.  */
-    struct winsize size;
-    
-    if (ioctl (0, TIOCGWINSZ, &size) == -1)
-      width = height = 0;
-    else
-      {
-        width = size.ws_col;
-        height = size.ws_row;
-      }
-  }
-#else
-#ifdef TIOCGSIZE
-  {
-    /* SunOS - style.  */
-    struct ttysize size;
-    
-    if (ioctl (0, TIOCGSIZE, &size) == -1)
-      width = height = 0;
-    else
-      {
-        width = size.ts_cols;
-        height = size.ts_lines;
-      }
-  }
-#endif /* not SunOS-style */
-#endif /* not BSD-style */
-
-#ifdef TIOCSWINSZ
-  {
-    /* BSD-style.  */
-    struct winsize size;
-    size.ws_row = height;
-    size.ws_col = width;
-    
-    ioctl (master, TIOCSWINSZ, &size);
-  }
-#else
-#ifdef TIOCSSIZE
-  {
-    /* SunOS - style.  */
-    struct ttysize size;
-    size.ts_lines = height;
-    size.ts_cols = width;
-    
-    ioctl (master, TIOCGSIZE, &size);
-  }
-#endif /* not SunOS-style */
-#endif /* not BSD-style */
-
-  if (emacs_pid && width && height)
-    kill (emacs_pid, SIGWINCH);
-}
-
-int in_conversation = 0;
-int quit_conversation = 0;
-
-SIGTYPE
-hang_up_signal (int signalnum)
-{
-  int old_errno = errno;
-  
-  if (! in_conversation)
-    return;
-
-  quit_conversation = 1;
-  
-  errno = old_errno;
-}
-
 SIGTYPE
 window_change_signal (int signalnum)
 {
   int old_errno = errno;
 
-  if (! in_conversation)
-    goto end;
+  if (emacs_pid)
+    kill (emacs_pid, SIGWINCH);
 
-  window_change();
-
- end:
   signal (SIGWINCH, window_change_signal);
   errno = old_errno;
 }
 
-SIGTYPE
-interrupt_signal (int signalnum)
-{
-  int old_errno = errno;
-  
-  /* Forward it to Emacs. */
-  if (emacs_pid)
-    kill (emacs_pid, SIGINT);
-
-  errno = old_errno;
-}
-
-int
-init_signals ()
+void
+init_signals (void)
 {
   /* Set up signal handlers. */
   signal (SIGWINCH, window_change_signal);
-  signal (SIGHUP, hang_up_signal);
-  signal (SIGINT, interrupt_signal);
-  return 1;
 }
 
-
-
-/* Adapted from reset_sys_modes in sysdep.c. */
-int
-reset_tty ()
-{
-  fflush (stdout);
-#ifdef BSD_SYSTEM
-#ifndef BSD4_1
-  /* Avoid possible loss of output when changing terminal modes.  */
-  fsync (fileno (stdout));
-#endif
-#endif
-
-#ifdef F_SETFL
-#ifdef O_NDELAY
-  fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~O_NDELAY);
-#endif
-#endif /* F_SETFL */
-
-  if (old_tty_valid)
-    while (ec_set_tty (0, &old_tty, 0) < 0 && errno == EINTR)
-      ;
-
-  return 1;
-}
-
-
-int
-init_pty ()
-{
-  master = getpt ();
-  if (master < 0)
-    return 0;
-
-  if (grantpt (master) < 0 || unlockpt (master) < 0)
-    goto close_master;
-  pty_name = strdup (ptsname (master));
-  if (! pty_name)
-    goto close_master;
-
-  /* Propagate window size. */
-  window_change ();
-  
-  return 1;
-  
- close_master:
-  close (master);
-  return 0;
-}
-
-int
-copy_from_to (int in, int out, int sigio)
-{
-  static char buf[BUFSIZ];
-  int nread = read (in, &buf, BUFSIZ);
-  if (nread == 0)
-    return 1;                   /* EOF */
-  else if (nread < 0 && errno != EAGAIN)
-    return 0;
-  else if (nread > 0)
-    {
-      int r = 0;
-      int written = 0;
-
-      do {
-        r = write (out, &buf, nread);
-      } while ((r < 0 && errno == EINTR)
-               || (r > 0 && (written += r) && written != nread));
-      
-      if (r < 0)
-        return 0;
-
-      if (sigio && emacs_pid)
-        kill (emacs_pid, SIGIO);
-    }
-  return 1;
-}
-
-int
-pty_conversation (FILE *in)
-{
-  char *str;
-  char string[BUFSIZ];              
-  fd_set set, rset;
-  int res;
-
-  FD_ZERO (&set);
-  FD_SET (master, &set);
-  FD_SET (1, &set);
-  FD_SET (fileno (in), &set);
-
-  in_conversation = 1;
-  
-  while (! quit_conversation) {
-    rset = set;
-    res = select (FD_SETSIZE, &rset, NULL, NULL, NULL);
-    if (res < 0 && errno != EINTR)
-      {
-          reset_tty ();
-          fprintf (stderr, "%s: ", progname);
-          perror ("select");
-          return 0;             /* Error */
-      }
-    else if (res > 0)
-      {
-        if (FD_ISSET (master, &rset))
-          {
-            /* Copy Emacs output to stdout. */
-            if (! copy_from_to (master, 0, 0))
-              {
-                FD_CLR (master, &set);
-              }
-          }
-        if (FD_ISSET (1, &rset))
-          {
-            /* Forward user input to Emacs. */
-            if (! copy_from_to (1, master, 1))
-              {
-                FD_CLR (master, &set);
-              }
-          }
-        if (FD_ISSET (fileno (in), &rset))
-          {
-            do {
-              res = read (fileno (in), string, BUFSIZ-1);
-            } while (res < 0 && errno == EINTR);
-            if (res < 0)
-              {
-                reset_tty ();
-                fprintf (stderr, "%s: ", progname);
-                perror ("read");
-                return 0;
-              }
-            if (!res)
-              {
-                return 1;
-              }
-            
-            string[res] = 0;
-            if (string[res-1] == '\n')
-              string[res-1] = 0;
-            
-            if (! emacs_pid)
-              {
-                /* Get the pid of the Emacs process.
-                   XXX Is there some nifty libc/kernel feature for doing this?
-                */
-                if (! string[0])
-                  {
-                    reset_tty ();
-                    fprintf (stderr, "%s: could not get Emacs process id\n"
-                             "Maybe this Emacs does not support multiple terminals.\n", progname);
-                    return 0;
-                  }
-                emacs_pid = strtol (string, NULL, 10);
-              }
-            
-            if (! emacs_pid)    /* emacs_pid should be set above */
-              {
-                reset_tty ();
-                fprintf (stderr, "%s: %s\n", progname, string);
-                return 0;
-              }
-          }
-      }
-  }
-  return 1;
-}
-
-#endif /* HAVE_TERMIOS */
-
 
 #if !defined (HAVE_SOCKETS) || defined (NO_SOCKETS_IN_FILE_SYSTEM)
 
@@ -886,6 +347,23 @@
   return 0;
 }
 
+/* Returns 1 if PREFIX is a prefix of STRING. */
+static int
+strprefix (char *prefix, char *string)
+{
+  int i;
+  if (! prefix)
+    return 1;
+
+  if (!string)
+    return 0;
+  
+  for (i = 0; prefix[i]; i++)
+    if (!string[i] || string[i] != prefix[i])
+      return 0;
+  return 1;
+}
+
 int
 main (argc, argv)
      int argc;
@@ -1086,31 +564,14 @@
 
   if (frame)
     {
-      if (! init_signals ())
-        {
-          fprintf (stderr, "%s: ", argv[0]);
-          perror ("fdopen");
-          fail ();
-        }
-        
-      if (! init_tty ())
-        {
-          reset_tty ();
-          fprintf (stderr, "%s: ", argv[0]);
-          perror ("fdopen");
-          fail ();
-        }
+      char *tty_name = ttyname (fileno (stdin));
+      if (! tty_name)
+        fail ();
       
-      if (! init_pty ())
-        {
-          reset_tty ();
-          fprintf (stderr, "%s: ", argv[0]);
-          perror ("fdopen");
-          fail ();
-        }
+      init_signals ();
       
       fprintf (out, "-tty ");
-      quote_file_name (pty_name, out);
+      quote_file_name (tty_name, out);
       fprintf (out, " ");
       quote_file_name (getenv("TERM"), out);
       fprintf (out, " ");
@@ -1160,22 +621,10 @@
   /* Maybe wait for an answer.   */
   if (nowait)
     {
-      reset_tty ();
       return 0;
     }
 
-  if (frame)
-    {
-      if (! pty_conversation (out))
-        {
-          reset_tty ();
-          fail ();
-        }
-      reset_tty ();
-      return 0;
-    }
-  
-  if (!eval)
+  if (!eval && !frame)
     {
       printf ("Waiting for Emacs...");
       needlf = 2;
@@ -1185,17 +634,26 @@
   /* Now, wait for an answer and print any messages.  */
   while ((str = fgets (string, BUFSIZ, in)))
     {
-      if (needlf == 2)
-	printf ("\n");
-      printf ("%s", str);
-      needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
+      if (frame)
+        {
+          if (strprefix ("emacs-pid ", str))
+            {
+              emacs_pid = strtol (string + strlen ("emacs-pid"), NULL, 10);
+            }
+        }
+      else
+        {
+          if (needlf == 2)
+            printf ("\n");
+          printf ("%s", str);
+          needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
+        }
     }
 
   if (needlf)
     printf ("\n");
   fflush (stdout);
 
-  reset_tty ();
   return 0;
 }
 
--- a/lisp/server.el	Fri Jan 02 13:03:12 2004 +0000
+++ b/lisp/server.el	Sat Jan 03 08:31:14 2004 +0000
@@ -106,10 +106,11 @@
 that can be given to the server process to identify a client.
 When a buffer is marked as \"done\", it is removed from this list.")
 
-(defvar server-frames nil
-  "List of current server frames.
-Each element is (CLIENTID FRAME) where CLIENTID is a string
+(defvar server-ttys nil
+  "List of current terminal devices used by the server.
+Each element is (CLIENTID TTY) where CLIENTID is a string
 that can be given to the server process to identify a client.
+TTY is the name of the tty device.
 When all the buffers of the client are marked as \"done\", 
 the frame is deleted.")
 
@@ -180,6 +181,14 @@
 		string)
 	(or (bolp) (newline)))))
 
+(defun server-tty-live-p (tty)
+  "Return non-nil if the tty device named TTY has a live frame."
+  (let (result)
+    (dolist (frame (frame-list) result)
+      (when (and (eq (frame-live-p frame) t)
+		 (equal (frame-tty-name frame) tty))
+	(setq result t)))))
+
 (defun server-sentinel (proc msg)
   (let ((client (assq proc server-clients)))
     ;; Remove PROC from the list of clients.
@@ -195,22 +204,21 @@
 			      (not server-existing-buffer))
 			 (server-temp-file-p)))
 	    (kill-buffer (current-buffer)))))
-      (let ((frame (assq (car client) server-frames)))
-	(when frame
-	  (setq server-frames (delq frame server-frames))
-	  (when (frame-live-p (cadr frame)) (delete-frame (cadr frame) 'force))))))
+      (let ((tty (assq (car client) server-ttys)))
+	(when tty
+	  (setq server-ttys (delq tty server-ttys))
+	  (when (server-tty-live-p (cadr tty))
+	    (delete-tty (cadr tty)))))))
   (server-log (format "Status changed to %s" (process-status proc)) proc))
 
-(defun server-handle-delete-frame (frame)
-  (dolist (entry server-frames)
+(defun server-handle-delete-tty (tty)
+  (dolist (entry server-ttys)
     (let ((proc (nth 0 entry))
-	  (f (nth 1 entry)))
-      (when (eq f frame)
+	  (term (nth 1 entry)))
+      (when (equal term tty)
 	(let ((client (assq proc server-clients)))
-	  (if (and (cdr client) (not (yes-or-no-p "Frame has pending buffers; close anyway? ")))
-	      (error "Frame deletion cancelled")
-	    (setq server-frames (delq entry server-frames))
-	    (delete-process (car client))))))))
+	  (setq server-ttys (delq entry server-ttys))
+	  (delete-process (car client)))))))
 
 (defun server-select-display (display)
   ;; If the current frame is on `display' we're all set.
@@ -280,15 +288,15 @@
     (let ((buffer (nth 1 (car server-clients))))
       (server-buffer-done buffer)))
   ;; Delete any remaining opened frames of the previous server.
-  (while server-frames
-    (let ((frame (cadar server-frames)))
-      (setq server-frames (cdr server-frames))
-      (when (frame-live-p frame) (delete-frame frame 'force))))
+  (while server-ttys
+    (let ((tty (cadar server-ttys)))
+      (setq server-ttys (cdr server-ttys))
+      (when (server-tty-live-p tty) (delete-tty tty))))
   (unless leave-dead
     (if server-process
 	(server-log (message "Restarting server")))
     (letf (((default-file-modes) ?\700))
-      (add-to-list 'delete-frame-functions 'server-handle-delete-frame)
+      (add-to-list 'delete-tty-after-functions 'server-handle-delete-tty)
       (setq server-process
 	    (make-network-process
 	     :name "server" :family 'local :server t :noquery t
@@ -354,9 +362,9 @@
 	      (setq request (substring request (match-end 0)))
 	      (condition-case err
 		  (let ((frame (make-frame-on-tty tty type)))
-		    (setq server-frames (cons (list (car client) frame) server-frames))
+		    (setq server-ttys (cons (list (car client) (frame-tty-name frame)) server-ttys))
 		    (sit-for 0)
-		    (process-send-string proc (concat (number-to-string (emacs-pid)) "\n"))
+		    (process-send-string proc (concat "emacs-pid " (number-to-string (emacs-pid)) "\n"))
 		    (select-frame frame)
 		    (setq newframe t))
 		(error (ignore-errors (process-send-string proc (concat (nth 1 err) "\n")))
@@ -488,9 +496,15 @@
 	;; If client now has no pending buffers,
 	;; tell it that it is done, and forget it entirely.
 	(unless (cdr client)
-	  (delete-process (car client))
-	  (server-log "Close" (car client))
-	  (setq server-clients (delq client server-clients))))
+	  (let ((tty (assq (car client) server-ttys)))
+	    (if tty
+		;; Be careful, if we delete the process before the
+		;; tty, then the terminal modes will not be restored
+		;; correctly.
+		(delete-tty (cadr tty))
+	      (delete-process (car client))
+	      (server-log "Close" (car client))
+	      (setq server-clients (delq client server-clients))))))
       (setq old-clients (cdr old-clients)))
     (if (and (bufferp buffer) (buffer-name buffer))
 	;; We may or may not kill this buffer;
--- a/src/Makefile.in	Fri Jan 02 13:03:12 2004 +0000
+++ b/src/Makefile.in	Sat Jan 03 08:31:14 2004 +0000
@@ -1142,7 +1142,7 @@
    msdos.h composite.h fontset.h blockinput.h atimer.h systime.h keymap.h
 xfaces.o: xfaces.c dispextern.h frame.h xterm.h buffer.h blockinput.h \
    window.h charset.h msdos.h dosfns.h composite.h atimer.h systime.h \
-   systty.h termchar.h $(config_h)
+   termchar.h $(config_h)
 xfns.o: xfns.c buffer.h frame.h window.h keyboard.h xterm.h dispextern.h \
    $(srcdir)/../lwlib/lwlib.h blockinput.h atimer.h systime.h epaths.h \
    charset.h gtkutil.h systty.h termchar.h $(config_h)
--- a/src/cm.c	Fri Jan 02 13:03:12 2004 +0000
+++ b/src/cm.c	Sat Jan 03 08:31:14 2004 +0000
@@ -70,8 +70,7 @@
 {
   if (TTY_TERMSCRIPT (current_tty))
     putc (c & 0177, TTY_TERMSCRIPT (current_tty));
-  if (putc (c & 0177, TTY_OUTPUT (current_tty)) == EOF)
-      abort ();                 /* XXX For testing only! */
+  putc (c & 0177, TTY_OUTPUT (current_tty));
   return c;
 }
 
--- a/src/dispnew.c	Fri Jan 02 13:03:12 2004 +0000
+++ b/src/dispnew.c	Sat Jan 03 08:31:14 2004 +0000
@@ -5925,7 +5925,7 @@
   int old_errno = errno;
 
   struct tty_display_info *tty;
-  
+
   /* The frame size change obviously applies to a single
      termcap-controlled terminal, but we can't decide which.
      Therefore, we resize the frames corresponding to each tty.
@@ -5934,22 +5934,18 @@
 
     if (! tty->term_initted)
       continue;
-    
+
     get_tty_size (fileno (TTY_INPUT (tty)), &width, &height);
     
     {
       Lisp_Object tail, frame;
       
       FOR_EACH_FRAME (tail, frame)
-        {
-          if (FRAME_TERMCAP_P (XFRAME (frame)) && FRAME_TTY (XFRAME (frame)) == tty)
-            {
-              /* Record the new sizes, but don't reallocate the data structures
-                 now.  Let that be done later outside of the signal handler.  */
-              change_frame_size (XFRAME (frame), height, width, 0, 1, 0);
-              break;
-            }
-        }
+        if (FRAME_TERMCAP_P (XFRAME (frame)) && FRAME_TTY (XFRAME (frame)) == tty)
+          /* Record the new sizes, but don't reallocate the data
+             structures now.  Let that be done later outside of the
+             signal handler.  */
+          change_frame_size (XFRAME (frame), height, width, 0, 1, 0);
     }
   }
   
--- a/src/indent.c	Fri Jan 02 13:03:12 2004 +0000
+++ b/src/indent.c	Sat Jan 03 08:31:14 2004 +0000
@@ -20,6 +20,8 @@
 Boston, MA 02111-1307, USA.  */
 
 #include <config.h>
+#include <stdio.h>
+
 #include "lisp.h"
 #include "buffer.h"
 #include "charset.h"
--- a/src/sysdep.c	Fri Jan 02 13:03:12 2004 +0000
+++ b/src/sysdep.c	Sat Jan 03 08:31:14 2004 +0000
@@ -913,6 +913,29 @@
     }
 }
 
+#ifndef SIGIO
+/* If SIGIO is broken, don't do anything. */
+void
+init_sigio (int fd)
+{
+}
+
+void
+reset_sigio (int fd)
+{
+}
+
+void
+request_sigio (void)
+{
+}
+
+void
+unrequest_sigio (void)
+{
+}
+
+#else
 #ifdef F_SETFL
 
 int old_fcntl_flags[MAXDESC];
@@ -932,10 +955,13 @@
 reset_sigio (fd)
      int fd;
 {
+#ifdef FASYNC
   fcntl (fd, F_SETFL, old_fcntl_flags[fd]);
+#endif
 }
 
 #ifdef FASYNC		/* F_SETFL does not imply existence of FASYNC */
+/* XXX Uhm, this FASYNC is not used anymore here. */
 
 void
 request_sigio ()
@@ -1053,6 +1079,7 @@
 #endif /* STRIDE */
 #endif /* FASYNC */
 #endif /* F_SETFL */
+#endif /* SIGIO */
 
 /* Saving and restoring the process group of Emacs's terminal.  */
 
@@ -1368,6 +1395,7 @@
 #ifdef HAVE_WINDOW_SYSTEM
   /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
      needs the initialization code below.  */
+  /* XXX This need to be revised for X+tty session support. */
   if (tty_out->input != stdin || (!read_socket_hook && EQ (Vwindow_system, Qnil)))
 #endif
     {
@@ -1641,6 +1669,8 @@
 #else
   setbuf (TTY_OUTPUT (tty_out), (char *) _sobuf);
 #endif
+
+#if 0                /* We always need this with multi-tty support. */
 #ifdef HAVE_WINDOW_SYSTEM
   /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
      needs the initialization code below.  */
@@ -1652,6 +1682,8 @@
 #endif
       )
 #endif
+#endif
+    tty_set_terminal_modes (tty_out);
 
   if (!tty_out->term_initted)
     {
@@ -1750,7 +1782,6 @@
   *widthp = 0;
   *heightp = 0;
 #endif
-
 #endif /* not VMS */
 #endif /* not SunOS-style */
 #endif /* not BSD-style */
@@ -1815,6 +1846,7 @@
     }
   if (!tty_out->term_initted)
     return;
+#if 0                           /* We always need to do this with multi-tty support. */
 #ifdef HAVE_WINDOW_SYSTEM
   /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
      needs the clean-up code below.  */
@@ -1828,7 +1860,8 @@
           ))
     return;
 #endif
-
+#endif
+  
   cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
   tty_clear_end_of_line (tty_out, FrameCols (tty_out));
   cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
--- a/src/syssignal.h	Fri Jan 02 13:03:12 2004 +0000
+++ b/src/syssignal.h	Sat Jan 03 08:31:14 2004 +0000
@@ -25,6 +25,7 @@
    indicate that SIGIO doesn't work by #undef-ing SIGIO.  If this file
    #includes <signal.h>, then that will re-#define SIGIO and confuse
    things.  */
+/* XXX This is not correct anymore, there is a BROKEN_SIGIO macro. */
 
 #define SIGMASKTYPE sigset_t
 
--- a/src/term.c	Fri Jan 02 13:03:12 2004 +0000
+++ b/src/term.c	Sat Jan 03 08:31:14 2004 +0000
@@ -100,6 +100,9 @@
 
 Lisp_Object Vring_bell_function;
 
+/* Functions to call after a tty was deleted. */
+Lisp_Object Vdelete_tty_after_functions;
+
 /* Terminal characteristics that higher levels want to look at. */
 
 struct tty_display_info *tty_list;
@@ -2751,8 +2754,6 @@
   /* Init system terminal modes (RAW or CBREAK, etc.).  */
   init_sys_modes (tty);
 
-  tty_set_terminal_modes (tty);
-
   return tty;
 #endif /* not WINDOWSNT */
 }
@@ -2772,7 +2773,11 @@
 
 
 DEFUN ("delete-tty", Fdelete_tty, Sdelete_tty, 0, 1, 0,
-       doc: /* Delete all frames on the terminal named TTY, and close the device. */)
+       doc: /* Delete all frames on the terminal named TTY, and close the device.
+If omitted, TTY defaults to the controlling terminal.
+
+This function runs `delete-tty-after-functions' after closing the
+tty.  The functions are run with one arg, the frame to be deleted.  */)
   (tty)
      Lisp_Object tty;
 {
@@ -2802,7 +2807,8 @@
 delete_tty (struct tty_display_info *tty)
 {
   Lisp_Object tail, frame;
-
+  char *tty_name;
+  
   if (deleting_tty)
     /* We get a recursive call when we delete the last frame on this
        tty. */
@@ -2838,8 +2844,7 @@
 
   reset_sys_modes (tty);
 
-  if (tty->name)
-    xfree (tty->name);
+  tty_name = tty->name;
   if (tty->type)
     xfree (tty->type);
 
@@ -2873,6 +2878,21 @@
   bzero (tty, sizeof (struct tty_display_info));
   xfree (tty);
   deleting_tty = 0;
+
+  /* Run `delete-tty-after-functions'.  */
+  if (!NILP (Vrun_hooks))
+    {
+      Lisp_Object args[2];
+      args[0] = intern ("delete-tty-after-functions");
+      if (tty_name)
+        {
+          args[1] = build_string (tty_name);
+          xfree (tty_name);
+        }
+      else
+        args[1] = Qnil;
+      Frun_hook_with_args (2, args);
+    }
 }
 
 
@@ -2911,6 +2931,12 @@
 The function should accept no arguments.  */);
   Vring_bell_function = Qnil;
 
+  DEFVAR_LISP ("delete-tty-after-functions", &Vdelete_tty_after_functions,
+    doc: /* Functions to be run after deleting a tty.
+The functions are run with one argument, the name of the tty to be deleted.
+See `delete-tty'.  */);
+  Vdelete_tty_after_functions = Qnil;
+
   Qframe_tty_name = intern ("frame-tty-name");
   staticpro (&Qframe_tty_name);
 
--- a/src/window.c	Fri Jan 02 13:03:12 2004 +0000
+++ b/src/window.c	Sat Jan 03 08:31:14 2004 +0000
@@ -21,6 +21,8 @@
 Boston, MA 02111-1307, USA.  */
 
 #include <config.h>
+#include <stdio.h>
+
 #include "lisp.h"
 #include "buffer.h"
 #include "keyboard.h"
--- a/src/xfaces.c	Fri Jan 02 13:03:12 2004 +0000
+++ b/src/xfaces.c	Sat Jan 03 08:31:14 2004 +0000
@@ -194,6 +194,7 @@
 #include <config.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <stdio.h>              /* This needs to be before termchar.h */
 
 #include "lisp.h"
 #include "charset.h"
@@ -241,7 +242,6 @@
 #include "blockinput.h"
 #include "window.h"
 #include "intervals.h"
-#include "systty.h" /* For emacs_tty in termchar.h */
 #include "termchar.h"
 
 #ifdef HAVE_X_WINDOWS
@@ -263,7 +263,6 @@
 
 #endif /* HAVE_X_WINDOWS */
 
-#include <stdio.h>
 #include <ctype.h>
 
 #define abs(X)		((X) < 0 ? -(X) : (X))