# HG changeset patch # User Karoly Lorentey # Date 1072682186 0 # Node ID d4e6a050c9b1447783682cf38a5d1227c3e327c3 # Parent db645482d6bcc39a7db9e49e0036300177fa957c Bugfix festival. lib-src/emacsclient.c (main_argc, main_argv): New variables. (main): Initialize them. (fail): Use them. (window_change, copy_from_to): Don't kill if emacs_pid is zero. (pty_conversation): Watch the command socket, too. Read emacs_pid here. Emacs and emacsclient could deadlock if Emacs tried to do a reset_sys_modes before sending its pid. lisp/server.el: Automatically delete the client frame when done editing. (server-frames): New variable. (server-process-filter, server-sentinel, server-buffer-done): Use it. (server-process-filter): Do a redisplay before evaluating other parameters. (Prevents "emacsclient -h -e '(delete-frame)'" from messing up the system. src/dispextern.h: Update prototypes. src/dispnew.c (window_change_signal): Do nothing if !term_initted. (init_display): Set the frame size from the tty data after term_init. src/emacs.c (main): Make sure things that init_sys_modes needs are initialized before init_display (which calls init_sys_modes now). (sort_args): Use xfree, not free. (shut_down_emacs) [!EMACS_HAVE_TTY_PGRP]: Use reset_all_sys_modes instead of reset_sys_modes. src/frame.c (make_terminal_frame): Sigh. Move terminal initialization back to the middle of frame setup. Handle errors by making sure that the delete_tty() called from term_init() will see and delete this frame. (Fdelete_frame): Kill the frame before calling delete_tty(). Fix condition for tty deletion. src/keyboard.c (Fset_input_mode): Use reset_sys_modes on the current terminal only. src/lisp.h: Remove duplicate prototypes. src/msdos.c (croak): use reset_all_sys_modes(). src/sysdeps.c (init_baud_rate): Added tty parameter, use it instead of CURTTY. (child_setup_tty): Reset sigio on stdin, not CURTTY(). (reset_sigio): Added fd parameter, put explicit fcntl there. (request_sigio, unrequest_sigio)[FASYNC]: Simply block/unblock the SIGIO signal, don't touch the file params. There are multiple ttys now, and we can't disable the SIGIO from emacsclient. (get_tty_size)[VMS]: Use tty_out instead of CURTTY(). (reset_sys_modes): Don't call cursor_to, clear_end_of_line; call cmgoto and tty_clear_end_of_line instead. The frame may already be dead. Updated reset_sigio call. src/term.c (clear_and_of_line): Separate tty-dependent stuff to tty_clear_end_of_line() for reset_sys_modes. (tty_clear_end_of_line): New function. (term_init): Added frame parameter, don't use selected_frame. Set the frame's output_data.tty value (in case there is an error later). Set the frame size in Wcm, not in the frame. Only free the termcap buffer if there is a termcap-related error. Call init_sys_modes last, not first. (deleting_tty): New variable. (delete_tty): Use it for handling recursive calls. Free deleted tty, except its Wcm (there is still a dangling reference somewhere). git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-19 diff -r db645482d6bc -r d4e6a050c9b1 README.multi-tty --- a/README.multi-tty Sun Dec 28 22:28:52 2003 +0000 +++ b/README.multi-tty Mon Dec 29 07:16:26 2003 +0000 @@ -67,11 +67,7 @@ specify a terminal device (`tty' parameter) and a terminal type (`tty-type' parameter) to `make-terminal-frame'. `tty' must be a terminal device created by the updated emacsclient, or there will - be problems with terminal input and window resizes. (The kernel - notifies processes about pending input or terminal resizes only on - the controlling terminal, so we need emacsclient to sit on the real - terminal device, create SIGIO signals upon terminal input, and - forward SIGWINCH signals to us.) + be problems with terminal input and window resizes. You can test for the presence of multiple terminal support by testing for the `multi-tty' feature. @@ -160,6 +156,9 @@ terminal. Note that this means that multi-tty does not work with raw ttys!) + (Update: This is bullshit. There is a read_input_waiting function, + extend that somehow.) + -- Make make-terminal-frame look up the `tty' and `tty-type' frame parameters from the currently selected terminal before the global default. @@ -191,6 +190,13 @@ (Done.) +-- Restore tty screen after closing the terminal. + + (Done, we do the same as Emacs 21.2 for all terminals.) + +-- 'TERM=dumb src/emacs' does not restore the terminal state. + + (Done.) THINGS TO DO ------------ @@ -216,35 +222,38 @@ ** Export delete_tty to the Lisp environment, for emacsclient. -** Restore tty screen after closing the terminal. - -** 'TERM=dumb src/emacs' does not restore the terminal state. - ** C-g should work on secondary terminals. ** Make parts of struct tty_output accessible from Lisp. The device name and the type is sufficient. ** Find out why does Emacs abort when it wants to close its - controlling tty. + controlling tty. Hint: chan_process[] array. Hey, maybe + noninterrupt-IO would work, too? ** Implement support for starting an interactive Emacs session without an initial frame. (The user would connect to it and open frames later, with emacsclient.) Not necessarily a good idea. -** Support raw secondary terminals. (This one is tricky, SIGIO works - only on the controlling terminal. The emacsclient solution works - nicely, so this is not that important anyway.) +** Support raw secondary terminals. (Note that SIGIO works only on + the controlling terminal.) Hint: extend read_input_waiting() for + multiple ttys and hopefully this will be fixed. ** What does interrupt_input do? I tried to disable it for raw secondary tty support, but it does not seem to do anything useful. +** Issue with SIGIO: it needs to be disabled during redisplay. See if + fcntl() kernel behaviour could be emulated by emacsclient. + ** Move optimalization parameters (costs) from union output_data to a backend-neutral per-device structure. ** Find out the best way to support suspending Emacs with multiple ttys. +** Deal with SIGHUP in Emacs and in emacsclient. (After this, the + server-frames may be removed from server.el.) + ** Do tty output through term_hooks, like all other display backends. ** Fix X support. diff -r db645482d6bc -r d4e6a050c9b1 lib-src/emacsclient.c --- a/lib-src/emacsclient.c Sun Dec 28 22:28:52 2003 +0000 +++ b/lib-src/emacsclient.c Mon Dec 29 07:16:26 2003 +0000 @@ -102,6 +102,12 @@ /* Name used to invoke this program. */ char *progname; +/* The first argument to main. */ +int main_argc; + +/* The second argument to main. */ +char **main_argv; + /* Nonzero means don't wait for a response from Emacs. --no-wait. */ int nowait = 0; @@ -294,14 +300,12 @@ defined-- exit with an errorcode. */ void -fail (argc, argv) - int argc; - char **argv; +fail () { if (alternate_editor) { int i = optind - 1; - execvp (alternate_editor, argv + i); + execvp (alternate_editor, main_argv + i); return; } else @@ -603,7 +607,7 @@ #endif /* not SunOS-style */ #endif /* not BSD-style */ - if (width != 0 && height != 0) + if (emacs_pid && width && height) kill (emacs_pid, SIGWINCH); } @@ -721,7 +725,7 @@ if (r < 0) return 0; /* Error */ - if (sigio) + if (emacs_pid && sigio) { kill (emacs_pid, SIGIO); } @@ -730,8 +734,10 @@ } int -pty_conversation () +pty_conversation (FILE *in) { + char *str; + char string[BUFSIZ]; fd_set set; in_conversation = 1; @@ -742,6 +748,7 @@ FD_ZERO (&set); FD_SET (master, &set); FD_SET (1, &set); + FD_SET (fileno (in), &set); res = select (FD_SETSIZE, &set, NULL, NULL, NULL); if (res < 0) { @@ -762,6 +769,24 @@ if (! copy_from_to (1, master, 1)) return 1; } + if (FD_ISSET (fileno (in), &set)) + { + if (! emacs_pid) + { + /* Get the pid of the Emacs process. + XXX Is there is some nifty libc/kernel feature for doing this? + */ + str = fgets (string, BUFSIZ, in); + if (! str) + { + reset_tty (); + fprintf (stderr, "%s: %s\n", progname, str); + fail (); + } + + emacs_pid = atoi (str); + } + } } } return 1; @@ -828,6 +853,8 @@ char *cwd, *str; char string[BUFSIZ]; + main_argc = argc; + main_argv = argv; progname = argv[0]; /* Process options. */ @@ -1087,19 +1114,7 @@ if (here) { - /* First of all, get the pid of the Emacs process. - XXX Is there is some nifty libc/kernel feature for doing this? - */ - str = fgets (string, BUFSIZ, in); - emacs_pid = atoi (str); - if (emacs_pid == 0) - { - reset_tty (); - fprintf (stderr, "%s: %s\n", argv[0], str); - fail (argc, argv); - } - - if (! pty_conversation ()) + if (! pty_conversation (out)) { reset_tty (); fprintf (stderr, "%s: ", argv[0]); diff -r db645482d6bc -r d4e6a050c9b1 lisp/server.el --- a/lisp/server.el Sun Dec 28 22:28:52 2003 +0000 +++ b/lisp/server.el Mon Dec 29 07:16:26 2003 +0000 @@ -106,6 +106,13 @@ 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 +that can be given to the server process to identify a client. +When all the buffers of the client are marked as \"done\", +the frame is deleted.") + (defvar server-buffer-clients nil "List of client ids for clients requesting editing of current buffer.") (make-variable-buffer-local 'server-buffer-clients) @@ -178,6 +185,7 @@ ;; Remove PROC from the list of clients. (when client (setq server-clients (delq client server-clients)) + (setq server-frames (delq client server-frames)) (dolist (buf (cdr client)) (with-current-buffer buf ;; Remove PROC from the clients of each buffer. @@ -326,6 +334,8 @@ (setq request (substring request (match-end 0))) (condition-case err (let ((frame (make-terminal-frame `((tty . ,pty) (tty-type . ,type))))) + (setq server-frames (cons (list (car client) frame) server-frames)) + (sit-for 0) (process-send-string proc (concat (number-to-string (emacs-pid)) "\n")) (select-frame frame)) (error (process-send-string proc (nth 1 err)) @@ -368,6 +378,9 @@ (if (null (cdr client)) ;; This client is empty; get rid of it immediately. (progn + (let ((frame (cadr (assq (car client) server-frames)))) + ;; Close the client's frame. + (when frame (delete-frame frame))) (delete-process proc) (server-log "Close empty client" proc)) ;; We visited some buffer for this client. @@ -454,6 +467,9 @@ ;; If client now has no pending buffers, ;; tell it that it is done, and forget it entirely. (unless (cdr client) + (let ((frame (cadr (assq (car client) server-frames)))) + ;; Close the client's frame. + (when frame (delete-frame frame))) (delete-process (car client)) (server-log "Close" (car client)) (setq server-clients (delq client server-clients)))) diff -r db645482d6bc -r d4e6a050c9b1 src/Makefile.in --- a/src/Makefile.in Sun Dec 28 22:28:52 2003 +0000 +++ b/src/Makefile.in Mon Dec 29 07:16:26 2003 +0000 @@ -1119,7 +1119,7 @@ composite.h $(config_h) sysdep.o: sysdep.c syssignal.h systty.h systime.h syswait.h blockinput.h \ process.h dispextern.h termhooks.h termchar.h termopts.h \ - frame.h atimer.h window.h msdos.h dosfns.h keyboard.h $(config_h) + frame.h atimer.h window.h msdos.h dosfns.h keyboard.h cm.h $(config_h) term.o: term.c systty.h termchar.h termhooks.h termopts.h $(config_h) cm.h frame.h \ disptab.h dispextern.h keyboard.h charset.h coding.h ccl.h msdos.h termcap.o: termcap.c $(config_h) diff -r db645482d6bc -r d4e6a050c9b1 src/dispextern.h --- a/src/dispextern.h Sun Dec 28 22:28:52 2003 +0000 +++ b/src/dispextern.h Mon Dec 29 07:16:26 2003 +0000 @@ -2566,7 +2566,7 @@ void request_sigio P_ ((void)); void unrequest_sigio P_ ((void)); int tabs_safe_p P_ ((struct tty_output *)); -void init_baud_rate P_ ((void)); +void init_baud_rate P_ ((struct tty_output *)); void init_sigio P_ ((int)); /* Defined in xfaces.c */ @@ -2743,6 +2743,7 @@ extern void clear_frame P_ ((void)); extern void clear_end_of_line P_ ((int)); extern void clear_end_of_line_raw P_ ((int)); +extern void tty_clear_end_of_line P_ ((struct tty_output *, int)); extern void delete_glyphs P_ ((int)); extern void ins_del_lines P_ ((int, int)); extern int string_cost P_ ((char *)); @@ -2750,7 +2751,7 @@ extern void calculate_costs P_ ((struct frame *)); extern void set_tty_color_mode P_ ((struct frame *, Lisp_Object)); extern void tty_setup_colors P_ ((struct tty_output *, int)); -extern struct tty_output *term_init P_ ((char *, char *)); +extern struct tty_output *term_init P_ ((Lisp_Object, char *, char *)); extern struct tty_output *term_dummy_init P_ ((void)); extern void fatal P_ ((/* char *, ... */)); void cursor_to P_ ((int, int)); diff -r db645482d6bc -r d4e6a050c9b1 src/dispnew.c --- a/src/dispnew.c Sun Dec 28 22:28:52 2003 +0000 +++ b/src/dispnew.c Mon Dec 29 07:16:26 2003 +0000 @@ -5921,11 +5921,12 @@ /* 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. - - XXX In fact we only get the signal for the initial terminal. */ for (tty = tty_list; tty; tty = tty->next) { + if (! tty->term_initted) + continue; + get_tty_size (tty, &width, &height); { @@ -6623,8 +6624,13 @@ } #endif /* VMS */ - term_init (0, terminal_type); - + { + struct tty_output *tty; + + tty = term_init (selected_frame, 0, terminal_type); + change_frame_size (XFRAME (selected_frame), FrameRows (tty), FrameCols (tty), 0, 0, 0); + } + { struct frame *sf = SELECTED_FRAME (); int width = FRAME_TOTAL_COLS (sf); diff -r db645482d6bc -r d4e6a050c9b1 src/emacs.c --- a/src/emacs.c Sun Dec 28 22:28:52 2003 +0000 +++ b/src/emacs.c Mon Dec 29 07:16:26 2003 +0000 @@ -1561,6 +1561,13 @@ #endif /* end #ifdef HAVE_NTGUI */ } +#ifndef MAC_OS8 + /* Called before init_window_once for Mac OS Classic. */ + init_keyboard (); /* This too must precede init_sys_modes. */ +#endif +#ifdef VMS + init_vmsproc (); /* And this too. */ +#endif /* VMS */ if (!noninteractive) { #ifdef VMS @@ -1568,14 +1575,6 @@ #endif /* VMS */ init_display (); /* Determine terminal type. Calls init_sys_modes. */ } -#ifndef MAC_OS8 - /* Called before init_window_once for Mac OS Classic. */ - init_keyboard (); /* This too must precede init_sys_modes. */ -#endif -#ifdef VMS - init_vmsproc (); /* And this too. */ -#endif /* VMS */ - /* init_sys_modes (); */ /* Init system terminal modes (RAW or CBREAK, etc.). */ #if defined (HAVE_X_WINDOWS) || defined (WINDOWSNT) init_xfns (); #endif /* HAVE_X_WINDOWS */ @@ -1910,9 +1909,9 @@ bcopy (new, argv, sizeof (char *) * argc); - free (options); - free (new); - free (priority); + xfree (options); + xfree (new); + xfree (priority); } DEFUN ("kill-emacs", Fkill_emacs, Skill_emacs, 0, 1, "P", @@ -1999,7 +1998,7 @@ } #else fflush (stdout); - reset_sys_modes (); + reset_all_sys_modes (); #endif stuff_buffered_input (stuff); diff -r db645482d6bc -r d4e6a050c9b1 src/frame.c --- a/src/frame.c Sun Dec 28 22:28:52 2003 +0000 +++ b/src/frame.c Mon Dec 29 07:16:26 2003 +0000 @@ -485,13 +485,6 @@ register struct frame *f; Lisp_Object frame; char name[20]; - struct tty_output *tty; - - /* init_term may throw an error, so create the tty first. */ - if (initialized) - tty = term_init (tty_name, tty_type); - else - tty = term_dummy_init (); #ifdef MULTI_KBOARD if (!initial_kboard) @@ -550,9 +543,23 @@ #ifdef MAC_OS8 make_mac_terminal_frame (f); #else - f->output_method = output_termcap; - f->output_data.tty = tty; - f->output_data.tty->top_frame = frame; + { + struct tty_output *tty; + f->output_method = output_termcap; + + if (initialized) + { + /* Note that term_init may signal an error, but then it is its + responsibility to make sure this frame is deleted. */ + f->output_data.tty = term_init (frame, tty_name, tty_type); + } + else + { + /* init_display() will reinitialize the terminal with correct values after dump. */ + f->output_data.tty = term_dummy_init (); + } + } + #ifdef CANNOT_DUMP FRAME_FOREGROUND_PIXEL(f) = FACE_TTY_DEFAULT_FG_COLOR; FRAME_BACKGROUND_PIXEL(f) = FACE_TTY_DEFAULT_BG_COLOR; @@ -1383,25 +1390,33 @@ if (FRAME_TERMCAP_P (f)) { - /* See if the terminal needs to be closed. */ Lisp_Object tail, frame1; int delete = 1; + struct tty_output *tty = FRAME_TTY (f); + + /* delete_tty will call us recursively, so better kill the + frame now. */ + f->output_data.nothing = 0; + /* See if the terminal needs to be closed. */ FOR_EACH_FRAME (tail, frame1) { - if (!FRAME_LIVE_P (XFRAME (frame1)) && - FRAME_TERMCAP_P (XFRAME (frame1)) && - FRAME_TTY (XFRAME (frame1)) == FRAME_TTY (f)) + if (frame1 != frame + && FRAME_LIVE_P (XFRAME (frame1)) + && FRAME_TERMCAP_P (XFRAME (frame1)) + && FRAME_TTY (XFRAME (frame1)) == FRAME_TTY (f)) { delete = 0; break; } } if (delete) - delete_tty (FRAME_TTY (f)); + delete_tty (tty); } - - f->output_data.nothing = 0; + else + { + f->output_data.nothing = 0; + } /* If we've deleted the last_nonminibuf_frame, then try to find another one. */ diff -r db645482d6bc -r d4e6a050c9b1 src/keyboard.c --- a/src/keyboard.c Sun Dec 28 22:28:52 2003 +0000 +++ b/src/keyboard.c Mon Dec 29 07:16:26 2003 +0000 @@ -10433,7 +10433,7 @@ #ifndef DOS_NT /* this causes startup screen to be restored and messes with the mouse */ - reset_all_sys_modes (); + reset_sys_modes (CURTTY ()); #endif #ifdef SIGIO @@ -10461,17 +10461,17 @@ flow_control = !NILP (flow); if (NILP (meta)) - FRAME_TTY (SELECTED_FRAME ())->meta_key = 0; + CURTTY ()->meta_key = 0; else if (EQ (meta, Qt)) - FRAME_TTY (SELECTED_FRAME ())->meta_key = 1; + CURTTY ()->meta_key = 1; else - FRAME_TTY (SELECTED_FRAME ())->meta_key = 2; + CURTTY ()->meta_key = 2; if (!NILP (quit)) /* Don't let this value be out of range. */ - quit_char = XINT (quit) & (FRAME_TTY (SELECTED_FRAME ())->meta_key ? 0377 : 0177); + quit_char = XINT (quit) & (CURTTY ()->meta_key ? 0377 : 0177); #ifndef DOS_NT - init_all_sys_modes (); + init_sys_modes (CURTTY ()); #endif #ifdef POLL_FOR_INPUT diff -r db645482d6bc -r d4e6a050c9b1 src/lisp.h --- a/src/lisp.h Sun Dec 28 22:28:52 2003 +0000 +++ b/src/lisp.h Mon Dec 29 07:16:26 2003 +0000 @@ -2942,8 +2942,6 @@ /* defined in sysdep.c */ extern void stuff_char P_ ((char c)); extern void init_sigio P_ ((int)); -extern void request_sigio P_ ((void)); -extern void unrequest_sigio P_ ((void)); extern void sys_subshell P_ ((void)); extern void sys_suspend P_ ((void)); extern void discard_tty_input P_ ((void)); @@ -2957,7 +2955,6 @@ extern void setup_pty P_ ((int)); extern int set_window_size P_ ((int, int, int)); extern void create_process P_ ((Lisp_Object, char **, Lisp_Object)); -extern void init_baud_rate P_ ((void)); extern int emacs_open P_ ((const char *, int, int)); extern int emacs_close P_ ((int)); extern int emacs_read P_ ((int, char *, unsigned int)); diff -r db645482d6bc -r d4e6a050c9b1 src/msdos.c --- a/src/msdos.c Sun Dec 28 22:28:52 2003 +0000 +++ b/src/msdos.c Mon Dec 29 07:16:26 2003 +0000 @@ -4858,7 +4858,7 @@ char *badfunc; { fprintf (stderr, "%s not yet implemented\r\n", badfunc); - reset_sys_modes (); + reset_all_sys_modes (); exit (1); } diff -r db645482d6bc -r d4e6a050c9b1 src/sysdep.c --- a/src/sysdep.c Sun Dec 28 22:28:52 2003 +0000 +++ b/src/sysdep.c Mon Dec 29 07:16:26 2003 +0000 @@ -184,6 +184,7 @@ #include "termopts.h" #include "dispextern.h" #include "process.h" +#include "cm.h" /* for reset_sys_modes */ #ifdef WINDOWSNT #include @@ -330,7 +331,7 @@ #endif /* SIGTSTP */ void -init_baud_rate () +init_baud_rate (struct tty_output *tty) { if (noninteractive) emacs_ospeed = 0; @@ -345,7 +346,7 @@ #ifdef VMS struct sensemode sg; - SYS$QIOW (0, fileno (TTY_INPUT (CURTTY())), IO$_SENSEMODE, &sg, 0, 0, + SYS$QIOW (0, fileno (TTY_INPUT (tty)), IO$_SENSEMODE, &sg, 0, 0, &sg.class, 12, 0, 0, 0, 0 ); emacs_ospeed = sg.xmit_baud; #else /* not VMS */ @@ -353,7 +354,7 @@ struct termios sg; sg.c_cflag = B9600; - tcgetattr (fileno (TTY_INPUT (CURTTY())), &sg); + tcgetattr (fileno (TTY_INPUT (tty)), &sg); emacs_ospeed = cfgetospeed (&sg); #if defined (USE_GETOBAUD) && defined (getobaud) /* m88k-motorola-sysv3 needs this (ghazi@noc.rutgers.edu) 9/1/94. */ @@ -366,16 +367,16 @@ sg.c_cflag = B9600; #ifdef HAVE_TCATTR - tcgetattr (fileno (TTY_INPUT (CURTTY())), &sg); + tcgetattr (fileno (TTY_INPUT (tty)), &sg); #else - ioctl (fileno (TTY_INPUT (CURTTY())), TCGETA, &sg); + ioctl (fileno (TTY_INPUT (tty)), TCGETA, &sg); #endif emacs_ospeed = sg.c_cflag & CBAUD; #else /* neither VMS nor TERMIOS nor TERMIO */ struct sgttyb sg; sg.sg_ospeed = B9600; - if (ioctl (fileno (TTY_INPUT (CURTTY())), TIOCGETP, &sg) < 0) + if (ioctl (fileno (TTY_INPUT (tty)), TIOCGETP, &sg) < 0) abort (); emacs_ospeed = sg.sg_ospeed; #endif /* not HAVE_TERMIO */ @@ -649,7 +650,7 @@ #ifdef BSD4_1 if (interrupt_input) - reset_sigio (); + reset_sigio (0); #endif /* BSD4_1 */ #ifdef RTU { @@ -915,6 +916,7 @@ int fd; { #ifdef FASYNC + /* XXX What if we get called with more than one fds? */ old_fcntl_flags = fcntl (fd, F_GETFL, 0) & ~FASYNC; fcntl (fd, F_SETFL, old_fcntl_flags | FASYNC); #endif @@ -922,9 +924,10 @@ } void -reset_sigio () +reset_sigio (fd) + int fd; { - unrequest_sigio (); + fcntl (fd, F_SETFL, old_fcntl_flags); } #ifdef FASYNC /* F_SETFL does not imply existence of FASYNC */ @@ -938,13 +941,13 @@ #ifdef SIGWINCH sigunblock (sigmask (SIGWINCH)); #endif - fcntl (fileno (TTY_INPUT (CURTTY())), F_SETFL, old_fcntl_flags | FASYNC); + sigunblock (sigmask (SIGIO)); interrupts_deferred = 0; } void -unrequest_sigio () +unrequest_sigio (void) { if (read_socket_hook) return; @@ -952,7 +955,7 @@ #ifdef SIGWINCH sigblock (sigmask (SIGWINCH)); #endif - fcntl (fileno (TTY_INPUT (CURTTY())), F_SETFL, old_fcntl_flags); + sigblock (sigmask (SIGIO)); interrupts_deferred = 1; } @@ -967,19 +970,21 @@ if (read_socket_hook) return; - ioctl (fileno (TTY_INPUT (CURTTY())), FIOASYNC, &on); + /* XXX CURTTY() is bogus here. */ + ioctl (fileno (TTY_INPUT (CURTTY ())), FIOASYNC, &on); interrupts_deferred = 0; } void -unrequest_sigio () +unrequest_sigio (struct tty_output *tty) { int off = 0; if (read_socket_hook) return; - ioctl (fileno (TTY_INPUT (CURTTY())), FIOASYNC, &off); + /* XXX CURTTY() is bogus here. */ + ioctl (fileno (TTY_INPUT (CURTTY ())), FIOASYNC, &off); interrupts_deferred = 1; } @@ -1000,7 +1005,7 @@ sigemptyset (&st); sigaddset (&st, SIGIO); - ioctl (fileno (TTY_INPUT (CURTTY())), FIOASYNC, &on); + ioctl (0, FIOASYNC, &on); /* XXX This fails for multiple ttys. */ interrupts_deferred = 0; sigprocmask (SIG_UNBLOCK, &st, (sigset_t *)0); } @@ -1013,7 +1018,7 @@ if (read_socket_hook) return; - ioctl (fileno (TTY_INPUT (CURTTY())), FIOASYNC, &off); + ioctl (0, FIOASYNC, &off); /* XXX This fails for multiple ttys. */ interrupts_deferred = 1; } @@ -1728,7 +1733,7 @@ struct sensemode tty; - SYS$QIOW (0, fileno (TTY_INPUT (CURTTY())), IO$_SENSEMODE, &tty, 0, 0, + SYS$QIOW (0, fileno (TTY_INPUT (tty_out)), IO$_SENSEMODE, &tty, 0, 0, &tty.class, 12, 0, 0, 0, 0); *widthp = tty.scr_wid; *heightp = tty.scr_len; @@ -1795,14 +1800,12 @@ } } -/* Prepare the terminal for exiting Emacs; move the cursor to the +/* Prepare the terminal for closing it; move the cursor to the bottom of the frame, turn off interrupt-driven I/O, etc. */ void reset_sys_modes (tty_out) struct tty_output *tty_out; { - struct frame *sf; - if (noninteractive) { fflush (stdout); @@ -1822,11 +1825,9 @@ ) return; #endif - sf = SELECTED_FRAME (); - cursor_to (FRAME_LINES (sf) - 1, 0); - clear_end_of_line (FRAME_COLS (sf)); - /* clear_end_of_line may move the cursor */ - cursor_to (FRAME_LINES (sf) - 1, 0); + 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); #if defined (IBMR2AIX) && defined (AIXHFT) { /* HFT devices normally use ^J as a LF/CR. We forced it to @@ -1852,7 +1853,7 @@ #ifdef F_SETOWN /* F_SETFL does not imply existence of F_SETOWN */ if (interrupt_input) { - reset_sigio (); + reset_sigio (tty_out); fcntl (fileno (TTY_INPUT (tty_out)), F_SETOWN, old_fcntl_owner); } #endif /* F_SETOWN */ @@ -1864,7 +1865,7 @@ #endif /* F_SETFL */ #ifdef BSD4_1 if (interrupt_input) - reset_sigio (); + reset_sigio (tty_out); #endif /* BSD4_1 */ if (tty_out->old_tty) @@ -2170,7 +2171,8 @@ request_sigio (); } -reset_sigio () +reset_sigio (fd) + int fd; { unrequest_sigio (); } @@ -2720,12 +2722,13 @@ } void -reset_sigio () +reset_sigio (fd) + int fd; { if (noninteractive) return; lmode = ~LINTRUP & lmode; - ioctl (0, TIOCLSET, &lmode); + ioctl (fd, TIOCLSET, &lmode); } void @@ -3173,7 +3176,7 @@ #undef abort sys_abort () { - reset_sys_modes (); + reset_all_sys_modes (); LIB$SIGNAL (SS$_DEBUG); } #endif /* abort */ diff -r db645482d6bc -r d4e6a050c9b1 src/term.c --- a/src/term.c Sun Dec 28 22:28:52 2003 +0000 +++ b/src/term.c Mon Dec 29 07:16:26 2003 +0000 @@ -651,8 +651,6 @@ clear_end_of_line (first_unused_hpos) int first_unused_hpos; { - register int i; - struct frame *f = (updating_frame ? updating_frame : XFRAME (selected_frame)); struct tty_output *tty; @@ -663,8 +661,13 @@ return; } - tty = FRAME_TTY (f); - + tty_clear_end_of_line (FRAME_TTY (f), first_unused_hpos); +} + +void +tty_clear_end_of_line (struct tty_output *tty, int first_unused_hpos) +{ + register int i; /* Detect the case where we are called from reset_sys_modes and the costs have never been calculated. Do nothing. */ if (! tty->costs_set) @@ -683,8 +686,8 @@ /* Do not write in last row last col with Auto-wrap on. */ if (AutoWrap (tty) - && curY (tty) == FRAME_LINES (f) - 1 - && first_unused_hpos == FRAME_COLS (f)) + && curY (tty) == FrameRows (tty) - 1 + && first_unused_hpos == FrameCols (tty)) first_unused_hpos--; for (i = curX (tty); i < first_unused_hpos; i++) @@ -2124,9 +2127,7 @@ struct tty_output * -term_init (name, terminal_type) - char *name; - char *terminal_type; +term_init (Lisp_Object frame, char *name, char *terminal_type) { char *area; char **address = &area; @@ -2134,20 +2135,16 @@ int buffer_size = 4096; register char *p; int status; - struct frame *sf = XFRAME (selected_frame); - + struct frame *f = XFRAME (frame); struct tty_output *tty; tty = get_named_tty (name); if (tty) { - /* Return the previously initialized terminal, except if it is the dummy - terminal created for the initial frame. */ + /* Return the previously initialized terminal, except if it is + the dummy terminal created for the initial frame. */ if (tty->type) return tty; - - /* In the latter case, initialize top_frame to the current terminal. */ - tty->top_frame = selected_frame; } else { @@ -2160,21 +2157,25 @@ if (! tty->Wcm) tty->Wcm = (struct cm *) xmalloc (sizeof (struct cm)); + /* Make sure the frame is live; if an error happens, it must be + deleted. */ + f->output_method = output_termcap; + f->output_data.tty = tty; + if (name) { int fd; - FILE *f; + FILE *file; fd = emacs_open (name, O_RDWR, 0); if (fd < 0) { - tty_list = tty->next; - xfree (tty); + delete_tty (tty); error ("Could not open file: %s", name); } - f = fdopen (fd, "w+"); + file = fdopen (fd, "w+"); TTY_NAME (tty) = xstrdup (name); - TTY_INPUT (tty) = f; - TTY_OUTPUT (tty) = f; + TTY_INPUT (tty) = file; + TTY_OUTPUT (tty) = file; } else { @@ -2185,8 +2186,6 @@ TTY_TYPE (tty) = xstrdup (terminal_type); - init_sys_modes (tty); - #ifdef WINDOWSNT initialize_w32_display (); @@ -2194,9 +2193,9 @@ area = (char *) xmalloc (2044); - FrameRows = FRAME_LINES (sf); - FrameCols = FRAME_COLS (sf); - specified_window = FRAME_LINES (sf); + FrameRows = FRAME_LINES (f); + FrameCols = FRAME_COLS (f); + specified_window = FRAME_LINES (f); delete_in_insert_mode = 1; @@ -2213,8 +2212,8 @@ baud_rate = 19200; - FRAME_CAN_HAVE_SCROLL_BARS (sf) = 0; - FRAME_VERTICAL_SCROLL_BAR_TYPE (sf) = vertical_scroll_bar_none; + FRAME_CAN_HAVE_SCROLL_BARS (f) = 0; + FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none; TN_max_colors = 16; /* Required to be non-zero for tty-display-color-p */ return tty; @@ -2229,6 +2228,7 @@ #ifdef TERMINFO if (name) { + xfree (buffer); delete_tty (tty); error ("Cannot open terminfo database file"); } @@ -2237,6 +2237,7 @@ #else if (name) { + xfree (buffer); delete_tty (tty); error ("Cannot open termcap database file"); } @@ -2249,12 +2250,13 @@ #ifdef TERMINFO if (name) { + xfree (buffer); delete_tty (tty); error ("Terminal type %s is not defined", terminal_type); } else fatal ("Terminal type %s is not defined.\n\ -If that is not the actual type of terminal you have,\n \ +If that is not the actual type of terminal you have,\n\ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\ `setenv TERM ...') to specify the correct type. It may be necessary\n\ to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.", @@ -2262,12 +2264,13 @@ #else if (name) { + xfree (buffer); delete_tty (tty); error ("Terminal type %s is not defined", terminal_type); } else fatal ("Terminal type %s is not defined.\n\ -If that is not the actual type of terminal you have,\n \ +If that is not the actual type of terminal you have,\n\ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\ `setenv TERM ...') to specify the correct type. It may be necessary\n\ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", @@ -2401,21 +2404,29 @@ { int height, width; get_tty_size (tty, &width, &height); - FRAME_COLS (sf) = width; - FRAME_LINES (sf) = height; + FrameCols (tty) = width; + FrameRows (tty) = height; } - if (FRAME_COLS (sf) <= 0) - SET_FRAME_COLS (sf, tgetnum ("co")); - else - /* Keep width and external_width consistent */ - SET_FRAME_COLS (sf, FRAME_COLS (sf)); - if (FRAME_LINES (sf) <= 0) - FRAME_LINES (sf) = tgetnum ("li"); - - if (FRAME_LINES (sf) < 3 || FRAME_COLS (sf) < 3) - fatal ("Screen size %dx%d is too small", - FRAME_LINES (sf), FRAME_COLS (sf)); + if (FrameCols (tty) <= 0) + FrameCols (tty) = tgetnum ("co"); + if (FrameRows (tty) <= 0) + FrameRows (tty) = tgetnum ("li"); + + if (FrameRows (tty) < 3 || FrameCols (tty) < 3) + { + if (initialized) + { + delete_tty (tty); + error ("Screen size %dx%d is too small", + FrameCols (tty), FrameRows (tty)); + } + else + { + fatal ("Screen size %dx%d is too small", + FrameCols (tty), FrameRows (tty)); + } + } #if 0 /* This is not used anywhere. */ TTY_MIN_PADDING_SPEED (tty) = tgetnum ("pb"); @@ -2541,15 +2552,14 @@ } } - FrameRows (tty) = FRAME_LINES (sf); - FrameCols (tty) = FRAME_COLS (sf); - tty->specified_window = FRAME_LINES (sf); + tty->specified_window = FrameRows (tty); if (Wcm_init (tty) == -1) /* can't do cursor motion */ if (name) { delete_tty (tty); - error ("Terminal type \"%s\" is not powerful enough to run Emacs"); + error ("Terminal type \"%s\" is not powerful enough to run Emacs", + terminal_type); } else { #ifdef VMS @@ -2562,15 +2572,15 @@ #else /* not VMS */ # ifdef TERMINFO fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\ -It lacks the ability to position the cursor.\n \ -If that is not the actual type of terminal you have,\n \ +It lacks the ability to position the cursor.\n\ +If that is not the actual type of terminal you have,\n\ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\ `setenv TERM ...') to specify the correct type. It may be necessary\n\ to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.", terminal_type); # else /* TERMCAP */ fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\ -It lacks the ability to position the cursor.\n \ +It lacks the ability to position the cursor.\n\ If that is not the actual type of terminal you have,\n\ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\ `setenv TERM ...') to specify the correct type. It may be necessary\n\ @@ -2580,8 +2590,7 @@ #endif /*VMS */ } - if (FRAME_LINES (sf) <= 0 - || FRAME_COLS (sf) <= 0) + if (FrameRows (tty) <= 0 || FrameCols (tty) <= 0) { if (name) { @@ -2619,20 +2628,29 @@ TTY_FAST_CLEAR_END_OF_LINE (tty) = tty->TS_clr_line != 0; - init_baud_rate (); + init_baud_rate (tty); if (read_socket_hook) /* Baudrate is somewhat meaningless in this case */ baud_rate = 9600; - FRAME_CAN_HAVE_SCROLL_BARS (sf) = 0; - FRAME_VERTICAL_SCROLL_BAR_TYPE (sf) = vertical_scroll_bar_none; -#endif /* WINDOWSNT */ - - xfree (buffer); - + FRAME_CAN_HAVE_SCROLL_BARS (f) = 0; + FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none; + + /* Don't do this. I think termcap may still need the buffer. */ + /* xfree (buffer); */ + + tty->top_frame = frame; + + tty->foreground_pixel = FACE_TTY_DEFAULT_FG_COLOR; + tty->background_pixel = FACE_TTY_DEFAULT_BG_COLOR; + + /* Init system terminal modes (RAW or CBREAK, etc.). */ + init_sys_modes (tty); + tty_set_terminal_modes (tty); return tty; +#endif /* WINDOWSNT */ } /* VARARGS 1 */ @@ -2670,11 +2688,20 @@ Fprovide (intern ("multi-tty"), Qnil); } +static int deleting_tty = 0; + void delete_tty (struct tty_output *tty) { Lisp_Object tail, frame; - + + if (deleting_tty) + /* We get a recursive call when we delete the last frame on this + tty. */ + return; + + deleting_tty = 1; + if (tty == tty_list) tty_list = tty->next; else @@ -2687,7 +2714,8 @@ /* This should not happen. */ abort (); - p->next = p->next->next; + p->next = tty->next; + tty->next = 0; } FOR_EACH_FRAME (tail, frame) @@ -2700,46 +2728,31 @@ } } - /* This hangs. */ - /* reset_sys_modes (tty); if (tty->name) xfree (tty->name); if (tty->type) xfree (tty->type); - */ + if (tty->input) fclose (tty->input); if (tty->output) fclose (tty->output); if (tty->termscript) fclose (tty->termscript); - - tty->input = 0; - tty->output = 0; - tty->termscript = 0; - /* if (tty->old_tty) - { - memset (tty->old_tty, 'Z', sizeof (struct emacs_tty)); - tty->old_tty = 0; - } - - - /* xfree (tty->old_tty); - - if (tty->Wcm) - { - bzero (tty->Wcm, sizeof (struct cm)); - } + xfree (tty->old_tty); + +#if 0 /* XXX There is a dangling reference somewhere into this. */ + if (tty->Wcm) xfree (tty->Wcm); +#endif bzero (tty, sizeof (struct tty_output)); - xfree (tty); - */ + deleting_tty = 0; }