aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaroly Lorentey2004-01-03 08:31:14 +0000
committerKaroly Lorentey2004-01-03 08:31:14 +0000
commit4d553a13abdadb4bb469bc0b59c003d48066dce5 (patch)
tree0b84a435d41801417190e60bf89ffa0305c8c4ac
parentb28c910d1f41815fa4744756852d5f2377d28636 (diff)
downloademacs-4d553a13abdadb4bb469bc0b59c003d48066dce5.tar.gz
emacs-4d553a13abdadb4bb469bc0b59c003d48066dce5.zip
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
-rw-r--r--README.multi-tty13
-rw-r--r--lib-src/emacsclient.c638
-rw-r--r--lisp/server.el64
-rw-r--r--src/Makefile.in2
-rw-r--r--src/cm.c3
-rw-r--r--src/dispnew.c18
-rw-r--r--src/indent.c2
-rw-r--r--src/sysdep.c37
-rw-r--r--src/syssignal.h1
-rw-r--r--src/term.c38
-rw-r--r--src/window.c2
-rw-r--r--src/xfaces.c3
12 files changed, 180 insertions, 641 deletions
diff --git a/README.multi-tty b/README.multi-tty
index f395d3acbdc..585bec050c2 100644
--- a/README.multi-tty
+++ b/README.multi-tty
@@ -130,7 +130,9 @@ THINGS TO DO
130** Something with (maybe) multi-keyboard support broke function keys 130** Something with (maybe) multi-keyboard support broke function keys
131 and arrows on ttys during X+tty combo sessions. Debug this. 131 and arrows on ttys during X+tty combo sessions. Debug this.
132 132
133** Fix faces on tty frames during X-tty combo sessions. 133** Fix faces on tty frames during X-tty combo sessions. There is an
134 init_frame_faces call in init_sys_modes, see if there is a problem
135 with it.
134 136
135** During an X-tty combo session, a (message "Hello") from a tty frame 137** During an X-tty combo session, a (message "Hello") from a tty frame
136 goes to the X frame. Fix this. 138 goes to the X frame. Fix this.
@@ -186,7 +188,8 @@ THINGS TO DO
186 select(9, [0 3 5 6], NULL, NULL, {0, 0}) = 2 (in [5 6], left {0, 0}) 188 select(9, [0 3 5 6], NULL, NULL, {0, 0}) = 2 (in [5 6], left {0, 0})
187 gettimeofday({1072842297, 748245}, NULL) = 0 189 gettimeofday({1072842297, 748245}, NULL) = 0
188 190
189 I have not been able to reproduce this. 191 I have seen something similar with a single X frame, but have not
192 been able to reproduce it for debugging.
190 193
191** Define a output_initial value for output_method for the initial 194** Define a output_initial value for output_method for the initial
192 frame that is dumped with Emacs. Checking for this frame (e.g. in 195 frame that is dumped with Emacs. Checking for this frame (e.g. in
@@ -196,6 +199,12 @@ THINGS TO DO
196 about face problems. This can even lock up Emacs (if the recursive 199 about face problems. This can even lock up Emacs (if the recursive
197 frame sets single_kboard). 200 frame sets single_kboard).
198 201
202** Clean up the source of emacsclient. It is a mess.
203
204** C-x 5 2, C-x 5 o, C-x 5 0 on an emacsclient frame unexpectedly
205 exits emacsclient. This is a result of trying to be clever with
206 delete-frame-functions.
207
199DIARY OF CHANGES 208DIARY OF CHANGES
200---------------- 209----------------
201 210
diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c
index 741f5da2f1e..563a8ba9db0 100644
--- a/lib-src/emacsclient.c
+++ b/lib-src/emacsclient.c
@@ -41,54 +41,10 @@ Boston, MA 02111-1307, USA. */
41# include <pwd.h> 41# include <pwd.h>
42#endif /* not VMS */ 42#endif /* not VMS */
43 43
44
45/****************************************/
46
47#include <errno.h>
48#include <signal.h> 44#include <signal.h>
49 45#include <errno.h>
50#ifndef INCLUDED_FCNTL
51#define INCLUDED_FCNTL
52#include <fcntl.h>
53#endif
54
55#ifdef HAVE_TERMIOS
56#ifndef NO_TERMIO
57#include <termio.h>
58#endif
59#include <termios.h>
60#endif /* not HAVE_TERMIOS */
61
62#ifdef __GNU_LIBRARY__
63#include <sys/ioctl.h>
64#include <termios.h>
65#endif
66
67#if (defined (POSIX) || defined (NEED_UNISTD_H)) && defined (HAVE_UNISTD_H)
68#include <unistd.h>
69#endif
70
71 46
72 47
73/* Try to establish the correct character to disable terminal functions
74 in a system-independent manner. Note that USG (at least) define
75 _POSIX_VDISABLE as 0! */
76
77#ifdef _POSIX_VDISABLE
78#define CDISABLE _POSIX_VDISABLE
79#else /* not _POSIX_VDISABLE */
80#ifdef CDEL
81#undef CDISABLE
82#define CDISABLE CDEL
83#else /* not CDEL */
84#define CDISABLE 255
85#endif /* not CDEL */
86#endif /* not _POSIX_VDISABLE */
87
88
89
90/****************************************/
91
92char *getenv (), *getwd (); 48char *getenv (), *getwd ();
93char *getcwd (); 49char *getcwd ();
94 50
@@ -314,532 +270,37 @@ fail (void)
314 } 270 }
315} 271}
316 272
317
318#ifdef HAVE_TERMIOS
319
320/* Adapted from emacs_get_tty() in sysdep.c. */
321int
322ec_get_tty (int fd, struct termios *settings)
323{
324 bzero (settings, sizeof (struct termios));
325 if (tcgetattr (fd, settings) < 0)
326 return -1;
327 return 0;
328}
329
330/* Adapted from emacs_set_tty() in sysdep.c. */
331int
332ec_set_tty (int fd, struct termios *settings, int flushp)
333{
334 /* Set the primary parameters - baud rate, character size, etcetera. */
335
336 int i;
337 /* We have those nifty POSIX tcmumbleattr functions.
338 William J. Smith <wjs@wiis.wang.com> writes:
339 "POSIX 1003.1 defines tcsetattr to return success if it was
340 able to perform any of the requested actions, even if some
341 of the requested actions could not be performed.
342 We must read settings back to ensure tty setup properly.
343 AIX requires this to keep tty from hanging occasionally." */
344 /* This make sure that we don't loop indefinitely in here. */
345 for (i = 0 ; i < 10 ; i++)
346 if (tcsetattr (fd, flushp ? TCSAFLUSH : TCSADRAIN, settings) < 0)
347 {
348 if (errno == EINTR)
349 continue;
350 else
351 return -1;
352 }
353 else
354 {
355 struct termios new;
356
357 bzero (&new, sizeof (new));
358 /* Get the current settings, and see if they're what we asked for. */
359 tcgetattr (fd, &new);
360 /* We cannot use memcmp on the whole structure here because under
361 * aix386 the termios structure has some reserved field that may
362 * not be filled in.
363 */
364 if ( new.c_iflag == settings->c_iflag
365 && new.c_oflag == settings->c_oflag
366 && new.c_cflag == settings->c_cflag
367 && new.c_lflag == settings->c_lflag
368 && memcmp (new.c_cc, settings->c_cc, NCCS) == 0)
369 break;
370 else
371 continue;
372 }
373 return 0;
374}
375
376int master;
377char *pty_name;
378
379struct termios old_tty;
380struct termios tty;
381int old_tty_valid;
382
383int tty_erase_char;
384int quit_char = 'g' & 037;
385int flow_control = 0;
386int meta_key = 0;
387char _sobuf[BUFSIZ];
388int emacs_pid; 273int emacs_pid;
389 274
390/* Adapted from init_sys_modes() in sysdep.c. */ 275#ifdef nec_ews_svr4
391int 276extern char *_sobuf ;
392init_tty ()
393{
394 if (! isatty (0))
395 {
396 fprintf (stderr, "%s: Input is not a terminal", "init_tty");
397 return 0;
398 }
399
400 ec_get_tty (0, &old_tty);
401 old_tty_valid = 1;
402 tty = old_tty;
403
404 tty_erase_char = old_tty.c_cc[VERASE];
405
406 tty.c_iflag |= (IGNBRK); /* Ignore break condition */
407 tty.c_iflag &= ~ICRNL; /* Disable map of CR to NL on input */
408#ifdef INLCR
409 tty.c_iflag &= ~INLCR; /* Disable map of NL to CR on input */
410#endif
411#ifdef ISTRIP
412 tty.c_iflag &= ~ISTRIP; /* don't strip 8th bit on input */
413#endif
414 tty.c_lflag &= ~ECHO; /* Disable echo */
415 tty.c_lflag &= ~ICANON; /* Disable erase/kill processing */
416#ifdef IEXTEN
417 tty.c_lflag &= ~IEXTEN; /* Disable other editing characters. */
418#endif
419 tty.c_lflag |= ISIG; /* Enable signals */
420 if (flow_control)
421 {
422 tty.c_iflag |= IXON; /* Enable start/stop output control */
423#ifdef IXANY
424 tty.c_iflag &= ~IXANY;
425#endif /* IXANY */
426 }
427 else
428 tty.c_iflag &= ~IXON; /* Disable start/stop output control */
429 tty.c_oflag &= ~ONLCR; /* Disable map of NL to CR-NL
430 on output */
431 tty.c_oflag &= ~TAB3; /* Disable tab expansion */
432#ifdef CS8
433 if (meta_key)
434 {
435 tty.c_cflag |= CS8; /* allow 8th bit on input */
436 tty.c_cflag &= ~PARENB; /* Don't check parity */
437 }
438#endif
439 tty.c_cc[VINTR] = quit_char; /* C-g (usually) gives SIGINT */
440 /* Set up C-g for both SIGQUIT and SIGINT.
441 We don't know which we will get, but we handle both alike
442 so which one it really gives us does not matter. */
443 tty.c_cc[VQUIT] = quit_char;
444 tty.c_cc[VMIN] = 1; /* Input should wait for at least 1 char */
445 tty.c_cc[VTIME] = 0; /* no matter how long that takes. */
446#ifdef VSWTCH
447 tty.c_cc[VSWTCH] = CDISABLE; /* Turn off shell layering use of C-z */
448#endif
449
450#ifdef VSUSP
451 tty.c_cc[VSUSP] = CDISABLE; /* Turn off mips handling of C-z. */
452#endif /* VSUSP */
453#ifdef V_DSUSP
454 tty.c_cc[V_DSUSP] = CDISABLE; /* Turn off mips handling of C-y. */
455#endif /* V_DSUSP */
456#ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
457 tty.c_cc[VDSUSP] = CDISABLE;
458#endif /* VDSUSP */
459#ifdef VLNEXT
460 tty.c_cc[VLNEXT] = CDISABLE;
461#endif /* VLNEXT */
462#ifdef VREPRINT
463 tty.c_cc[VREPRINT] = CDISABLE;
464#endif /* VREPRINT */
465#ifdef VWERASE
466 tty.c_cc[VWERASE] = CDISABLE;
467#endif /* VWERASE */
468#ifdef VDISCARD
469 tty.c_cc[VDISCARD] = CDISABLE;
470#endif /* VDISCARD */
471
472 if (flow_control)
473 {
474#ifdef VSTART
475 tty.c_cc[VSTART] = '\021';
476#endif /* VSTART */
477#ifdef VSTOP
478 tty.c_cc[VSTOP] = '\023';
479#endif /* VSTOP */
480 }
481 else
482 {
483#ifdef VSTART
484 tty.c_cc[VSTART] = CDISABLE;
485#endif /* VSTART */
486#ifdef VSTOP
487 tty.c_cc[VSTOP] = CDISABLE;
488#endif /* VSTOP */
489 }
490
491#ifdef SET_LINE_DISCIPLINE
492 /* Need to explicitly request TERMIODISC line discipline or
493 Ultrix's termios does not work correctly. */
494 tty.c_line = SET_LINE_DISCIPLINE;
495#endif
496
497#ifdef AIX
498#ifndef IBMR2AIX
499 /* AIX enhanced edit loses NULs, so disable it. */
500 tty.c_line = 0;
501 tty.c_iflag &= ~ASCEDIT;
502#else 277#else
503 tty.c_cc[VSTRT] = 255; 278#if defined (USG) || defined (DGUX)
504 tty.c_cc[VSTOP] = 255; 279unsigned char _sobuf[BUFSIZ+8];
505 tty.c_cc[VSUSP] = 255;
506 tty.c_cc[VDSUSP] = 255;
507#endif /* IBMR2AIX */
508 if (flow_control)
509 {
510#ifdef VSTART
511 tty.c_cc[VSTART] = '\021';
512#endif /* VSTART */
513#ifdef VSTOP
514 tty.c_cc[VSTOP] = '\023';
515#endif /* VSTOP */
516 }
517 /* Also, PTY overloads NUL and BREAK.
518 don't ignore break, but don't signal either, so it looks like NUL.
519 This really serves a purpose only if running in an XTERM window
520 or via TELNET or the like, but does no harm elsewhere. */
521 tty.c_iflag &= ~IGNBRK;
522 tty.c_iflag &= ~BRKINT;
523#endif /* AIX */
524
525 ec_set_tty (0, &tty, 0);
526
527 /* This code added to insure that, if flow-control is not to be used,
528 we have an unlocked terminal at the start. */
529
530#ifdef TCXONC
531 if (!flow_control) ioctl (0, TCXONC, 1);
532#endif
533#ifndef APOLLO
534#ifdef TIOCSTART
535 if (!flow_control) ioctl (0, TIOCSTART, 0);
536#endif
537#endif
538
539#if defined (HAVE_TERMIOS) || defined (HPUX9)
540#ifdef TCOON
541 if (!flow_control) tcflow (0, TCOON);
542#endif
543#endif
544
545#ifdef _IOFBF
546 /* This symbol is defined on recent USG systems.
547 Someone says without this call USG won't really buffer the file
548 even with a call to setbuf. */
549 setvbuf (stdout, (char *) _sobuf, _IOFBF, sizeof _sobuf);
550#else 280#else
551 setbuf (stdout, (char *) _sobuf); 281char _sobuf[BUFSIZ];
282#endif
552#endif 283#endif
553
554 return 1;
555}
556
557void
558window_change ()
559{
560 int width = 0, height = 0;
561
562#ifdef TIOCGWINSZ
563 {
564 /* BSD-style. */
565 struct winsize size;
566
567 if (ioctl (0, TIOCGWINSZ, &size) == -1)
568 width = height = 0;
569 else
570 {
571 width = size.ws_col;
572 height = size.ws_row;
573 }
574 }
575#else
576#ifdef TIOCGSIZE
577 {
578 /* SunOS - style. */
579 struct ttysize size;
580
581 if (ioctl (0, TIOCGSIZE, &size) == -1)
582 width = height = 0;
583 else
584 {
585 width = size.ts_cols;
586 height = size.ts_lines;
587 }
588 }
589#endif /* not SunOS-style */
590#endif /* not BSD-style */
591
592#ifdef TIOCSWINSZ
593 {
594 /* BSD-style. */
595 struct winsize size;
596 size.ws_row = height;
597 size.ws_col = width;
598
599 ioctl (master, TIOCSWINSZ, &size);
600 }
601#else
602#ifdef TIOCSSIZE
603 {
604 /* SunOS - style. */
605 struct ttysize size;
606 size.ts_lines = height;
607 size.ts_cols = width;
608
609 ioctl (master, TIOCGSIZE, &size);
610 }
611#endif /* not SunOS-style */
612#endif /* not BSD-style */
613
614 if (emacs_pid && width && height)
615 kill (emacs_pid, SIGWINCH);
616}
617
618int in_conversation = 0;
619int quit_conversation = 0;
620
621SIGTYPE
622hang_up_signal (int signalnum)
623{
624 int old_errno = errno;
625
626 if (! in_conversation)
627 return;
628
629 quit_conversation = 1;
630
631 errno = old_errno;
632}
633 284
634SIGTYPE 285SIGTYPE
635window_change_signal (int signalnum) 286window_change_signal (int signalnum)
636{ 287{
637 int old_errno = errno; 288 int old_errno = errno;
638 289
639 if (! in_conversation)
640 goto end;
641
642 window_change();
643
644 end:
645 signal (SIGWINCH, window_change_signal);
646 errno = old_errno;
647}
648
649SIGTYPE
650interrupt_signal (int signalnum)
651{
652 int old_errno = errno;
653
654 /* Forward it to Emacs. */
655 if (emacs_pid) 290 if (emacs_pid)
656 kill (emacs_pid, SIGINT); 291 kill (emacs_pid, SIGWINCH);
657 292
293 signal (SIGWINCH, window_change_signal);
658 errno = old_errno; 294 errno = old_errno;
659} 295}
660 296
661int 297void
662init_signals () 298init_signals (void)
663{ 299{
664 /* Set up signal handlers. */ 300 /* Set up signal handlers. */
665 signal (SIGWINCH, window_change_signal); 301 signal (SIGWINCH, window_change_signal);
666 signal (SIGHUP, hang_up_signal);
667 signal (SIGINT, interrupt_signal);
668 return 1;
669}
670
671
672
673/* Adapted from reset_sys_modes in sysdep.c. */
674int
675reset_tty ()
676{
677 fflush (stdout);
678#ifdef BSD_SYSTEM
679#ifndef BSD4_1
680 /* Avoid possible loss of output when changing terminal modes. */
681 fsync (fileno (stdout));
682#endif
683#endif
684
685#ifdef F_SETFL
686#ifdef O_NDELAY
687 fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~O_NDELAY);
688#endif
689#endif /* F_SETFL */
690
691 if (old_tty_valid)
692 while (ec_set_tty (0, &old_tty, 0) < 0 && errno == EINTR)
693 ;
694
695 return 1;
696}
697
698
699int
700init_pty ()
701{
702 master = getpt ();
703 if (master < 0)
704 return 0;
705
706 if (grantpt (master) < 0 || unlockpt (master) < 0)
707 goto close_master;
708 pty_name = strdup (ptsname (master));
709 if (! pty_name)
710 goto close_master;
711
712 /* Propagate window size. */
713 window_change ();
714
715 return 1;
716
717 close_master:
718 close (master);
719 return 0;
720}
721
722int
723copy_from_to (int in, int out, int sigio)
724{
725 static char buf[BUFSIZ];
726 int nread = read (in, &buf, BUFSIZ);
727 if (nread == 0)
728 return 1; /* EOF */
729 else if (nread < 0 && errno != EAGAIN)
730 return 0;
731 else if (nread > 0)
732 {
733 int r = 0;
734 int written = 0;
735
736 do {
737 r = write (out, &buf, nread);
738 } while ((r < 0 && errno == EINTR)
739 || (r > 0 && (written += r) && written != nread));
740
741 if (r < 0)
742 return 0;
743
744 if (sigio && emacs_pid)
745 kill (emacs_pid, SIGIO);
746 }
747 return 1;
748}
749
750int
751pty_conversation (FILE *in)
752{
753 char *str;
754 char string[BUFSIZ];
755 fd_set set, rset;
756 int res;
757
758 FD_ZERO (&set);
759 FD_SET (master, &set);
760 FD_SET (1, &set);
761 FD_SET (fileno (in), &set);
762
763 in_conversation = 1;
764
765 while (! quit_conversation) {
766 rset = set;
767 res = select (FD_SETSIZE, &rset, NULL, NULL, NULL);
768 if (res < 0 && errno != EINTR)
769 {
770 reset_tty ();
771 fprintf (stderr, "%s: ", progname);
772 perror ("select");
773 return 0; /* Error */
774 }
775 else if (res > 0)
776 {
777 if (FD_ISSET (master, &rset))
778 {
779 /* Copy Emacs output to stdout. */
780 if (! copy_from_to (master, 0, 0))
781 {
782 FD_CLR (master, &set);
783 }
784 }
785 if (FD_ISSET (1, &rset))
786 {
787 /* Forward user input to Emacs. */
788 if (! copy_from_to (1, master, 1))
789 {
790 FD_CLR (master, &set);
791 }
792 }
793 if (FD_ISSET (fileno (in), &rset))
794 {
795 do {
796 res = read (fileno (in), string, BUFSIZ-1);
797 } while (res < 0 && errno == EINTR);
798 if (res < 0)
799 {
800 reset_tty ();
801 fprintf (stderr, "%s: ", progname);
802 perror ("read");
803 return 0;
804 }
805 if (!res)
806 {
807 return 1;
808 }
809
810 string[res] = 0;
811 if (string[res-1] == '\n')
812 string[res-1] = 0;
813
814 if (! emacs_pid)
815 {
816 /* Get the pid of the Emacs process.
817 XXX Is there some nifty libc/kernel feature for doing this?
818 */
819 if (! string[0])
820 {
821 reset_tty ();
822 fprintf (stderr, "%s: could not get Emacs process id\n"
823 "Maybe this Emacs does not support multiple terminals.\n", progname);
824 return 0;
825 }
826 emacs_pid = strtol (string, NULL, 10);
827 }
828
829 if (! emacs_pid) /* emacs_pid should be set above */
830 {
831 reset_tty ();
832 fprintf (stderr, "%s: %s\n", progname, string);
833 return 0;
834 }
835 }
836 }
837 }
838 return 1;
839} 302}
840 303
841#endif /* HAVE_TERMIOS */
842
843 304
844#if !defined (HAVE_SOCKETS) || defined (NO_SOCKETS_IN_FILE_SYSTEM) 305#if !defined (HAVE_SOCKETS) || defined (NO_SOCKETS_IN_FILE_SYSTEM)
845 306
@@ -886,6 +347,23 @@ socket_status (socket_name)
886 return 0; 347 return 0;
887} 348}
888 349
350/* Returns 1 if PREFIX is a prefix of STRING. */
351static int
352strprefix (char *prefix, char *string)
353{
354 int i;
355 if (! prefix)
356 return 1;
357
358 if (!string)
359 return 0;
360
361 for (i = 0; prefix[i]; i++)
362 if (!string[i] || string[i] != prefix[i])
363 return 0;
364 return 1;
365}
366
889int 367int
890main (argc, argv) 368main (argc, argv)
891 int argc; 369 int argc;
@@ -1086,31 +564,14 @@ To start the server in Emacs, type \"M-x server-start\".\n",
1086 564
1087 if (frame) 565 if (frame)
1088 { 566 {
1089 if (! init_signals ()) 567 char *tty_name = ttyname (fileno (stdin));
1090 { 568 if (! tty_name)
1091 fprintf (stderr, "%s: ", argv[0]); 569 fail ();
1092 perror ("fdopen");
1093 fail ();
1094 }
1095
1096 if (! init_tty ())
1097 {
1098 reset_tty ();
1099 fprintf (stderr, "%s: ", argv[0]);
1100 perror ("fdopen");
1101 fail ();
1102 }
1103 570
1104 if (! init_pty ()) 571 init_signals ();
1105 {
1106 reset_tty ();
1107 fprintf (stderr, "%s: ", argv[0]);
1108 perror ("fdopen");
1109 fail ();
1110 }
1111 572
1112 fprintf (out, "-tty "); 573 fprintf (out, "-tty ");
1113 quote_file_name (pty_name, out); 574 quote_file_name (tty_name, out);
1114 fprintf (out, " "); 575 fprintf (out, " ");
1115 quote_file_name (getenv("TERM"), out); 576 quote_file_name (getenv("TERM"), out);
1116 fprintf (out, " "); 577 fprintf (out, " ");
@@ -1160,22 +621,10 @@ To start the server in Emacs, type \"M-x server-start\".\n",
1160 /* Maybe wait for an answer. */ 621 /* Maybe wait for an answer. */
1161 if (nowait) 622 if (nowait)
1162 { 623 {
1163 reset_tty ();
1164 return 0; 624 return 0;
1165 } 625 }
1166 626
1167 if (frame) 627 if (!eval && !frame)
1168 {
1169 if (! pty_conversation (out))
1170 {
1171 reset_tty ();
1172 fail ();
1173 }
1174 reset_tty ();
1175 return 0;
1176 }
1177
1178 if (!eval)
1179 { 628 {
1180 printf ("Waiting for Emacs..."); 629 printf ("Waiting for Emacs...");
1181 needlf = 2; 630 needlf = 2;
@@ -1185,17 +634,26 @@ To start the server in Emacs, type \"M-x server-start\".\n",
1185 /* Now, wait for an answer and print any messages. */ 634 /* Now, wait for an answer and print any messages. */
1186 while ((str = fgets (string, BUFSIZ, in))) 635 while ((str = fgets (string, BUFSIZ, in)))
1187 { 636 {
1188 if (needlf == 2) 637 if (frame)
1189 printf ("\n"); 638 {
1190 printf ("%s", str); 639 if (strprefix ("emacs-pid ", str))
1191 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n'; 640 {
641 emacs_pid = strtol (string + strlen ("emacs-pid"), NULL, 10);
642 }
643 }
644 else
645 {
646 if (needlf == 2)
647 printf ("\n");
648 printf ("%s", str);
649 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
650 }
1192 } 651 }
1193 652
1194 if (needlf) 653 if (needlf)
1195 printf ("\n"); 654 printf ("\n");
1196 fflush (stdout); 655 fflush (stdout);
1197 656
1198 reset_tty ();
1199 return 0; 657 return 0;
1200} 658}
1201 659
diff --git a/lisp/server.el b/lisp/server.el
index ef9aa47b6bd..7b42d0fe2a9 100644
--- a/lisp/server.el
+++ b/lisp/server.el
@@ -106,10 +106,11 @@ Each element is (CLIENTID BUFFERS...) where CLIENTID is a string
106that can be given to the server process to identify a client. 106that can be given to the server process to identify a client.
107When a buffer is marked as \"done\", it is removed from this list.") 107When a buffer is marked as \"done\", it is removed from this list.")
108 108
109(defvar server-frames nil 109(defvar server-ttys nil
110 "List of current server frames. 110 "List of current terminal devices used by the server.
111Each element is (CLIENTID FRAME) where CLIENTID is a string 111Each element is (CLIENTID TTY) where CLIENTID is a string
112that can be given to the server process to identify a client. 112that can be given to the server process to identify a client.
113TTY is the name of the tty device.
113When all the buffers of the client are marked as \"done\", 114When all the buffers of the client are marked as \"done\",
114the frame is deleted.") 115the frame is deleted.")
115 116
@@ -180,6 +181,14 @@ are done with it in the server.")
180 string) 181 string)
181 (or (bolp) (newline))))) 182 (or (bolp) (newline)))))
182 183
184(defun server-tty-live-p (tty)
185 "Return non-nil if the tty device named TTY has a live frame."
186 (let (result)
187 (dolist (frame (frame-list) result)
188 (when (and (eq (frame-live-p frame) t)
189 (equal (frame-tty-name frame) tty))
190 (setq result t)))))
191
183(defun server-sentinel (proc msg) 192(defun server-sentinel (proc msg)
184 (let ((client (assq proc server-clients))) 193 (let ((client (assq proc server-clients)))
185 ;; Remove PROC from the list of clients. 194 ;; Remove PROC from the list of clients.
@@ -195,22 +204,21 @@ are done with it in the server.")
195 (not server-existing-buffer)) 204 (not server-existing-buffer))
196 (server-temp-file-p))) 205 (server-temp-file-p)))
197 (kill-buffer (current-buffer))))) 206 (kill-buffer (current-buffer)))))
198 (let ((frame (assq (car client) server-frames))) 207 (let ((tty (assq (car client) server-ttys)))
199 (when frame 208 (when tty
200 (setq server-frames (delq frame server-frames)) 209 (setq server-ttys (delq tty server-ttys))
201 (when (frame-live-p (cadr frame)) (delete-frame (cadr frame) 'force)))))) 210 (when (server-tty-live-p (cadr tty))
211 (delete-tty (cadr tty)))))))
202 (server-log (format "Status changed to %s" (process-status proc)) proc)) 212 (server-log (format "Status changed to %s" (process-status proc)) proc))
203 213
204(defun server-handle-delete-frame (frame) 214(defun server-handle-delete-tty (tty)
205 (dolist (entry server-frames) 215 (dolist (entry server-ttys)
206 (let ((proc (nth 0 entry)) 216 (let ((proc (nth 0 entry))
207 (f (nth 1 entry))) 217 (term (nth 1 entry)))
208 (when (eq f frame) 218 (when (equal term tty)
209 (let ((client (assq proc server-clients))) 219 (let ((client (assq proc server-clients)))
210 (if (and (cdr client) (not (yes-or-no-p "Frame has pending buffers; close anyway? "))) 220 (setq server-ttys (delq entry server-ttys))
211 (error "Frame deletion cancelled") 221 (delete-process (car client)))))))
212 (setq server-frames (delq entry server-frames))
213 (delete-process (car client))))))))
214 222
215(defun server-select-display (display) 223(defun server-select-display (display)
216 ;; If the current frame is on `display' we're all set. 224 ;; If the current frame is on `display' we're all set.
@@ -280,15 +288,15 @@ Prefix arg means just kill any existing server communications subprocess."
280 (let ((buffer (nth 1 (car server-clients)))) 288 (let ((buffer (nth 1 (car server-clients))))
281 (server-buffer-done buffer))) 289 (server-buffer-done buffer)))
282 ;; Delete any remaining opened frames of the previous server. 290 ;; Delete any remaining opened frames of the previous server.
283 (while server-frames 291 (while server-ttys
284 (let ((frame (cadar server-frames))) 292 (let ((tty (cadar server-ttys)))
285 (setq server-frames (cdr server-frames)) 293 (setq server-ttys (cdr server-ttys))
286 (when (frame-live-p frame) (delete-frame frame 'force)))) 294 (when (server-tty-live-p tty) (delete-tty tty))))
287 (unless leave-dead 295 (unless leave-dead
288 (if server-process 296 (if server-process
289 (server-log (message "Restarting server"))) 297 (server-log (message "Restarting server")))
290 (letf (((default-file-modes) ?\700)) 298 (letf (((default-file-modes) ?\700))
291 (add-to-list 'delete-frame-functions 'server-handle-delete-frame) 299 (add-to-list 'delete-tty-after-functions 'server-handle-delete-tty)
292 (setq server-process 300 (setq server-process
293 (make-network-process 301 (make-network-process
294 :name "server" :family 'local :server t :noquery t 302 :name "server" :family 'local :server t :noquery t
@@ -354,9 +362,9 @@ PROC is the server process. Format of STRING is \"PATH PATH PATH... \\n\"."
354 (setq request (substring request (match-end 0))) 362 (setq request (substring request (match-end 0)))
355 (condition-case err 363 (condition-case err
356 (let ((frame (make-frame-on-tty tty type))) 364 (let ((frame (make-frame-on-tty tty type)))
357 (setq server-frames (cons (list (car client) frame) server-frames)) 365 (setq server-ttys (cons (list (car client) (frame-tty-name frame)) server-ttys))
358 (sit-for 0) 366 (sit-for 0)
359 (process-send-string proc (concat (number-to-string (emacs-pid)) "\n")) 367 (process-send-string proc (concat "emacs-pid " (number-to-string (emacs-pid)) "\n"))
360 (select-frame frame) 368 (select-frame frame)
361 (setq newframe t)) 369 (setq newframe t))
362 (error (ignore-errors (process-send-string proc (concat (nth 1 err) "\n"))) 370 (error (ignore-errors (process-send-string proc (concat (nth 1 err) "\n")))
@@ -488,9 +496,15 @@ FOR-KILLING if non-nil indicates that we are called from `kill-buffer'."
488 ;; If client now has no pending buffers, 496 ;; If client now has no pending buffers,
489 ;; tell it that it is done, and forget it entirely. 497 ;; tell it that it is done, and forget it entirely.
490 (unless (cdr client) 498 (unless (cdr client)
491 (delete-process (car client)) 499 (let ((tty (assq (car client) server-ttys)))
492 (server-log "Close" (car client)) 500 (if tty
493 (setq server-clients (delq client server-clients)))) 501 ;; Be careful, if we delete the process before the
502 ;; tty, then the terminal modes will not be restored
503 ;; correctly.
504 (delete-tty (cadr tty))
505 (delete-process (car client))
506 (server-log "Close" (car client))
507 (setq server-clients (delq client server-clients))))))
494 (setq old-clients (cdr old-clients))) 508 (setq old-clients (cdr old-clients)))
495 (if (and (bufferp buffer) (buffer-name buffer)) 509 (if (and (bufferp buffer) (buffer-name buffer))
496 ;; We may or may not kill this buffer; 510 ;; We may or may not kill this buffer;
diff --git a/src/Makefile.in b/src/Makefile.in
index 1f0e18d9e55..32215899a4a 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1142,7 +1142,7 @@ xdisp.o: xdisp.c macros.h commands.h process.h indent.h buffer.h dispextern.h co
1142 msdos.h composite.h fontset.h blockinput.h atimer.h systime.h keymap.h 1142 msdos.h composite.h fontset.h blockinput.h atimer.h systime.h keymap.h
1143xfaces.o: xfaces.c dispextern.h frame.h xterm.h buffer.h blockinput.h \ 1143xfaces.o: xfaces.c dispextern.h frame.h xterm.h buffer.h blockinput.h \
1144 window.h charset.h msdos.h dosfns.h composite.h atimer.h systime.h \ 1144 window.h charset.h msdos.h dosfns.h composite.h atimer.h systime.h \
1145 systty.h termchar.h $(config_h) 1145 termchar.h $(config_h)
1146xfns.o: xfns.c buffer.h frame.h window.h keyboard.h xterm.h dispextern.h \ 1146xfns.o: xfns.c buffer.h frame.h window.h keyboard.h xterm.h dispextern.h \
1147 $(srcdir)/../lwlib/lwlib.h blockinput.h atimer.h systime.h epaths.h \ 1147 $(srcdir)/../lwlib/lwlib.h blockinput.h atimer.h systime.h epaths.h \
1148 charset.h gtkutil.h systty.h termchar.h $(config_h) 1148 charset.h gtkutil.h systty.h termchar.h $(config_h)
diff --git a/src/cm.c b/src/cm.c
index 74f119d9b68..1f165e90f4a 100644
--- a/src/cm.c
+++ b/src/cm.c
@@ -70,8 +70,7 @@ cmputc (c)
70{ 70{
71 if (TTY_TERMSCRIPT (current_tty)) 71 if (TTY_TERMSCRIPT (current_tty))
72 putc (c & 0177, TTY_TERMSCRIPT (current_tty)); 72 putc (c & 0177, TTY_TERMSCRIPT (current_tty));
73 if (putc (c & 0177, TTY_OUTPUT (current_tty)) == EOF) 73 putc (c & 0177, TTY_OUTPUT (current_tty));
74 abort (); /* XXX For testing only! */
75 return c; 74 return c;
76} 75}
77 76
diff --git a/src/dispnew.c b/src/dispnew.c
index 87ac292a1b0..be6e6330e31 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -5925,7 +5925,7 @@ window_change_signal (signalnum) /* If we don't have an argument, */
5925 int old_errno = errno; 5925 int old_errno = errno;
5926 5926
5927 struct tty_display_info *tty; 5927 struct tty_display_info *tty;
5928 5928
5929 /* The frame size change obviously applies to a single 5929 /* The frame size change obviously applies to a single
5930 termcap-controlled terminal, but we can't decide which. 5930 termcap-controlled terminal, but we can't decide which.
5931 Therefore, we resize the frames corresponding to each tty. 5931 Therefore, we resize the frames corresponding to each tty.
@@ -5934,22 +5934,18 @@ window_change_signal (signalnum) /* If we don't have an argument, */
5934 5934
5935 if (! tty->term_initted) 5935 if (! tty->term_initted)
5936 continue; 5936 continue;
5937 5937
5938 get_tty_size (fileno (TTY_INPUT (tty)), &width, &height); 5938 get_tty_size (fileno (TTY_INPUT (tty)), &width, &height);
5939 5939
5940 { 5940 {
5941 Lisp_Object tail, frame; 5941 Lisp_Object tail, frame;
5942 5942
5943 FOR_EACH_FRAME (tail, frame) 5943 FOR_EACH_FRAME (tail, frame)
5944 { 5944 if (FRAME_TERMCAP_P (XFRAME (frame)) && FRAME_TTY (XFRAME (frame)) == tty)
5945 if (FRAME_TERMCAP_P (XFRAME (frame)) && FRAME_TTY (XFRAME (frame)) == tty) 5945 /* Record the new sizes, but don't reallocate the data
5946 { 5946 structures now. Let that be done later outside of the
5947 /* Record the new sizes, but don't reallocate the data structures 5947 signal handler. */
5948 now. Let that be done later outside of the signal handler. */ 5948 change_frame_size (XFRAME (frame), height, width, 0, 1, 0);
5949 change_frame_size (XFRAME (frame), height, width, 0, 1, 0);
5950 break;
5951 }
5952 }
5953 } 5949 }
5954 } 5950 }
5955 5951
diff --git a/src/indent.c b/src/indent.c
index bc32aa1f407..0eca2f3410e 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -20,6 +20,8 @@ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */ 20Boston, MA 02111-1307, USA. */
21 21
22#include <config.h> 22#include <config.h>
23#include <stdio.h>
24
23#include "lisp.h" 25#include "lisp.h"
24#include "buffer.h" 26#include "buffer.h"
25#include "charset.h" 27#include "charset.h"
diff --git a/src/sysdep.c b/src/sysdep.c
index 502671ba0f6..a84a6d5c1fb 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -913,6 +913,29 @@ restore_signal_handlers (saved_handlers)
913 } 913 }
914} 914}
915 915
916#ifndef SIGIO
917/* If SIGIO is broken, don't do anything. */
918void
919init_sigio (int fd)
920{
921}
922
923void
924reset_sigio (int fd)
925{
926}
927
928void
929request_sigio (void)
930{
931}
932
933void
934unrequest_sigio (void)
935{
936}
937
938#else
916#ifdef F_SETFL 939#ifdef F_SETFL
917 940
918int old_fcntl_flags[MAXDESC]; 941int old_fcntl_flags[MAXDESC];
@@ -932,10 +955,13 @@ void
932reset_sigio (fd) 955reset_sigio (fd)
933 int fd; 956 int fd;
934{ 957{
958#ifdef FASYNC
935 fcntl (fd, F_SETFL, old_fcntl_flags[fd]); 959 fcntl (fd, F_SETFL, old_fcntl_flags[fd]);
960#endif
936} 961}
937 962
938#ifdef FASYNC /* F_SETFL does not imply existence of FASYNC */ 963#ifdef FASYNC /* F_SETFL does not imply existence of FASYNC */
964/* XXX Uhm, this FASYNC is not used anymore here. */
939 965
940void 966void
941request_sigio () 967request_sigio ()
@@ -1053,6 +1079,7 @@ unrequest_sigio ()
1053#endif /* STRIDE */ 1079#endif /* STRIDE */
1054#endif /* FASYNC */ 1080#endif /* FASYNC */
1055#endif /* F_SETFL */ 1081#endif /* F_SETFL */
1082#endif /* SIGIO */
1056 1083
1057/* Saving and restoring the process group of Emacs's terminal. */ 1084/* Saving and restoring the process group of Emacs's terminal. */
1058 1085
@@ -1368,6 +1395,7 @@ nil means don't delete them until `list-processes' is run. */);
1368#ifdef HAVE_WINDOW_SYSTEM 1395#ifdef HAVE_WINDOW_SYSTEM
1369 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore 1396 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
1370 needs the initialization code below. */ 1397 needs the initialization code below. */
1398 /* XXX This need to be revised for X+tty session support. */
1371 if (tty_out->input != stdin || (!read_socket_hook && EQ (Vwindow_system, Qnil))) 1399 if (tty_out->input != stdin || (!read_socket_hook && EQ (Vwindow_system, Qnil)))
1372#endif 1400#endif
1373 { 1401 {
@@ -1641,6 +1669,8 @@ nil means don't delete them until `list-processes' is run. */);
1641#else 1669#else
1642 setbuf (TTY_OUTPUT (tty_out), (char *) _sobuf); 1670 setbuf (TTY_OUTPUT (tty_out), (char *) _sobuf);
1643#endif 1671#endif
1672
1673#if 0 /* We always need this with multi-tty support. */
1644#ifdef HAVE_WINDOW_SYSTEM 1674#ifdef HAVE_WINDOW_SYSTEM
1645 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore 1675 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
1646 needs the initialization code below. */ 1676 needs the initialization code below. */
@@ -1652,6 +1682,8 @@ nil means don't delete them until `list-processes' is run. */);
1652#endif 1682#endif
1653 ) 1683 )
1654#endif 1684#endif
1685#endif
1686 tty_set_terminal_modes (tty_out);
1655 1687
1656 if (!tty_out->term_initted) 1688 if (!tty_out->term_initted)
1657 { 1689 {
@@ -1750,7 +1782,6 @@ get_tty_size (int fd, int *widthp, int *heightp)
1750 *widthp = 0; 1782 *widthp = 0;
1751 *heightp = 0; 1783 *heightp = 0;
1752#endif 1784#endif
1753
1754#endif /* not VMS */ 1785#endif /* not VMS */
1755#endif /* not SunOS-style */ 1786#endif /* not SunOS-style */
1756#endif /* not BSD-style */ 1787#endif /* not BSD-style */
@@ -1815,6 +1846,7 @@ reset_sys_modes (tty_out)
1815 } 1846 }
1816 if (!tty_out->term_initted) 1847 if (!tty_out->term_initted)
1817 return; 1848 return;
1849#if 0 /* We always need to do this with multi-tty support. */
1818#ifdef HAVE_WINDOW_SYSTEM 1850#ifdef HAVE_WINDOW_SYSTEM
1819 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore 1851 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
1820 needs the clean-up code below. */ 1852 needs the clean-up code below. */
@@ -1828,7 +1860,8 @@ reset_sys_modes (tty_out)
1828 )) 1860 ))
1829 return; 1861 return;
1830#endif 1862#endif
1831 1863#endif
1864
1832 cmgoto (tty_out, FrameRows (tty_out) - 1, 0); 1865 cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
1833 tty_clear_end_of_line (tty_out, FrameCols (tty_out)); 1866 tty_clear_end_of_line (tty_out, FrameCols (tty_out));
1834 cmgoto (tty_out, FrameRows (tty_out) - 1, 0); 1867 cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
diff --git a/src/syssignal.h b/src/syssignal.h
index 2b536758e27..7c3690903df 100644
--- a/src/syssignal.h
+++ b/src/syssignal.h
@@ -25,6 +25,7 @@ Boston, MA 02111-1307, USA. */
25 indicate that SIGIO doesn't work by #undef-ing SIGIO. If this file 25 indicate that SIGIO doesn't work by #undef-ing SIGIO. If this file
26 #includes <signal.h>, then that will re-#define SIGIO and confuse 26 #includes <signal.h>, then that will re-#define SIGIO and confuse
27 things. */ 27 things. */
28/* XXX This is not correct anymore, there is a BROKEN_SIGIO macro. */
28 29
29#define SIGMASKTYPE sigset_t 30#define SIGMASKTYPE sigset_t
30 31
diff --git a/src/term.c b/src/term.c
index 24dbc614c6f..96fa9baddac 100644
--- a/src/term.c
+++ b/src/term.c
@@ -100,6 +100,9 @@ static void delete_tty_1 P_ ((struct tty_display_info *));
100 100
101Lisp_Object Vring_bell_function; 101Lisp_Object Vring_bell_function;
102 102
103/* Functions to call after a tty was deleted. */
104Lisp_Object Vdelete_tty_after_functions;
105
103/* Terminal characteristics that higher levels want to look at. */ 106/* Terminal characteristics that higher levels want to look at. */
104 107
105struct tty_display_info *tty_list; 108struct tty_display_info *tty_list;
@@ -2751,8 +2754,6 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2751 /* Init system terminal modes (RAW or CBREAK, etc.). */ 2754 /* Init system terminal modes (RAW or CBREAK, etc.). */
2752 init_sys_modes (tty); 2755 init_sys_modes (tty);
2753 2756
2754 tty_set_terminal_modes (tty);
2755
2756 return tty; 2757 return tty;
2757#endif /* not WINDOWSNT */ 2758#endif /* not WINDOWSNT */
2758} 2759}
@@ -2772,7 +2773,11 @@ fatal (str, arg1, arg2)
2772 2773
2773 2774
2774DEFUN ("delete-tty", Fdelete_tty, Sdelete_tty, 0, 1, 0, 2775DEFUN ("delete-tty", Fdelete_tty, Sdelete_tty, 0, 1, 0,
2775 doc: /* Delete all frames on the terminal named TTY, and close the device. */) 2776 doc: /* Delete all frames on the terminal named TTY, and close the device.
2777If omitted, TTY defaults to the controlling terminal.
2778
2779This function runs `delete-tty-after-functions' after closing the
2780tty. The functions are run with one arg, the frame to be deleted. */)
2776 (tty) 2781 (tty)
2777 Lisp_Object tty; 2782 Lisp_Object tty;
2778{ 2783{
@@ -2802,7 +2807,8 @@ void
2802delete_tty (struct tty_display_info *tty) 2807delete_tty (struct tty_display_info *tty)
2803{ 2808{
2804 Lisp_Object tail, frame; 2809 Lisp_Object tail, frame;
2805 2810 char *tty_name;
2811
2806 if (deleting_tty) 2812 if (deleting_tty)
2807 /* We get a recursive call when we delete the last frame on this 2813 /* We get a recursive call when we delete the last frame on this
2808 tty. */ 2814 tty. */
@@ -2838,8 +2844,7 @@ delete_tty (struct tty_display_info *tty)
2838 2844
2839 reset_sys_modes (tty); 2845 reset_sys_modes (tty);
2840 2846
2841 if (tty->name) 2847 tty_name = tty->name;
2842 xfree (tty->name);
2843 if (tty->type) 2848 if (tty->type)
2844 xfree (tty->type); 2849 xfree (tty->type);
2845 2850
@@ -2873,6 +2878,21 @@ delete_tty (struct tty_display_info *tty)
2873 bzero (tty, sizeof (struct tty_display_info)); 2878 bzero (tty, sizeof (struct tty_display_info));
2874 xfree (tty); 2879 xfree (tty);
2875 deleting_tty = 0; 2880 deleting_tty = 0;
2881
2882 /* Run `delete-tty-after-functions'. */
2883 if (!NILP (Vrun_hooks))
2884 {
2885 Lisp_Object args[2];
2886 args[0] = intern ("delete-tty-after-functions");
2887 if (tty_name)
2888 {
2889 args[1] = build_string (tty_name);
2890 xfree (tty_name);
2891 }
2892 else
2893 args[1] = Qnil;
2894 Frun_hook_with_args (2, args);
2895 }
2876} 2896}
2877 2897
2878 2898
@@ -2911,6 +2931,12 @@ This variable can be used by terminal emulator packages. */);
2911The function should accept no arguments. */); 2931The function should accept no arguments. */);
2912 Vring_bell_function = Qnil; 2932 Vring_bell_function = Qnil;
2913 2933
2934 DEFVAR_LISP ("delete-tty-after-functions", &Vdelete_tty_after_functions,
2935 doc: /* Functions to be run after deleting a tty.
2936The functions are run with one argument, the name of the tty to be deleted.
2937See `delete-tty'. */);
2938 Vdelete_tty_after_functions = Qnil;
2939
2914 Qframe_tty_name = intern ("frame-tty-name"); 2940 Qframe_tty_name = intern ("frame-tty-name");
2915 staticpro (&Qframe_tty_name); 2941 staticpro (&Qframe_tty_name);
2916 2942
diff --git a/src/window.c b/src/window.c
index 48e517a68f7..854fb712a2d 100644
--- a/src/window.c
+++ b/src/window.c
@@ -21,6 +21,8 @@ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21Boston, MA 02111-1307, USA. */ 21Boston, MA 02111-1307, USA. */
22 22
23#include <config.h> 23#include <config.h>
24#include <stdio.h>
25
24#include "lisp.h" 26#include "lisp.h"
25#include "buffer.h" 27#include "buffer.h"
26#include "keyboard.h" 28#include "keyboard.h"
diff --git a/src/xfaces.c b/src/xfaces.c
index 7b3637b1a6a..9f51f118f3e 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -194,6 +194,7 @@ Boston, MA 02111-1307, USA. */
194#include <config.h> 194#include <config.h>
195#include <sys/types.h> 195#include <sys/types.h>
196#include <sys/stat.h> 196#include <sys/stat.h>
197#include <stdio.h> /* This needs to be before termchar.h */
197 198
198#include "lisp.h" 199#include "lisp.h"
199#include "charset.h" 200#include "charset.h"
@@ -241,7 +242,6 @@ Boston, MA 02111-1307, USA. */
241#include "blockinput.h" 242#include "blockinput.h"
242#include "window.h" 243#include "window.h"
243#include "intervals.h" 244#include "intervals.h"
244#include "systty.h" /* For emacs_tty in termchar.h */
245#include "termchar.h" 245#include "termchar.h"
246 246
247#ifdef HAVE_X_WINDOWS 247#ifdef HAVE_X_WINDOWS
@@ -263,7 +263,6 @@ Boston, MA 02111-1307, USA. */
263 263
264#endif /* HAVE_X_WINDOWS */ 264#endif /* HAVE_X_WINDOWS */
265 265
266#include <stdio.h>
267#include <ctype.h> 266#include <ctype.h>
268 267
269#define abs(X) ((X) < 0 ? -(X) : (X)) 268#define abs(X) ((X) < 0 ? -(X) : (X))