Mercurial > emacs
changeset 82987:1682917e56b4
Major bugfixes and slight enhancements.
src/dispextern.h (get_tty_size, tabs_safe_p, init_baud_rate): Update
prototypes.
src/dispnew.c (window_change_signal): Update call to get_tty_size.
src/frame.c (Fmake_terminal_frame): Ditto.
src/keyboard.c (Fsuspend_emacs): Ditto.
src/sysdep.c: Eliminate tty_outputs, wherever possible. (The
exceptions are init_sys_modes and reset_sys_modes, which need access
to tty-local parameters).
(init_baud_rate): Change tty_output parameter to a simple file descriptor.
(narrow_foreground_group, widen_foreground_group): Ditto.
(tabs_safe_p, get_tty_size): Ditto.
(init_sys_modes): Update narrow_foreground_group invocation.
(reset_sys_modes): Update widen_foreground_group invocation.
(request_sigio)[!FASYNC && STRIDE]: Fix function signature.
src/term.c (delete_tty): Only close output file handle if it is
different from input. Re-enable freeing of Wcm.
(term_init): Update get_tty_size, tabs_safe_p and init_baud_rate
invocations.
lib-src/emacsclient.c (here): Renamed to frame.
(longopts): Change --here to --frame. The -h short option may be
confused with --help.
(decode_options, print_help_and_exit): Update to reflect above changes.
(main): Ditto.
lisp/server.el (server-start): Fix frame-live-p call syntax.
(server-process-filter): Handle 'emacsclient -f' without file
arguments. Don't return any values to emacsclient when 'emacsclient
-f -e'.
(server-switch-buffer): Prevent infinite recursion when there are no
files to edit.
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-27
author | Karoly Lorentey <lorentey@elte.hu> |
---|---|
date | Tue, 30 Dec 2003 19:27:57 +0000 |
parents | 02a346f99eaf |
children | f82e3a6f5ccb |
files | README.multi-tty lib-src/emacsclient.c lisp/server.el src/dispextern.h src/dispnew.c src/frame.c src/keyboard.c src/sysdep.c src/term.c |
diffstat | 9 files changed, 85 insertions(+), 75 deletions(-) [+] |
line wrap: on
line diff
--- a/README.multi-tty Tue Dec 30 17:51:52 2003 +0000 +++ b/README.multi-tty Tue Dec 30 19:27:57 2003 +0000 @@ -39,7 +39,7 @@ then start up the emacs server (src/emacs, M-x server-start), and then (from a shell prompt on another terminal) start emacsclient with - lib-src/emacsclient -h /optional/file/names... + lib-src/emacsclient -f /optional/file/names... You'll hopefully have two fully working, independent frames on separate terminals. (This seems to be very useful, emacsclient starts @@ -213,13 +213,7 @@ (Seems to be working OK.) -THINGS TO DO ------------- - -** Understand Emacs's low-level input system. It seems - complicated. :-) - -** Fix mysterious memory corruption error with tty deletion. To +-- Fix mysterious memory corruption error with tty deletion. To trigger it, try the following shell command: while true; do TERM=no-such-terminal-definition emacsclient -h; done @@ -230,17 +224,23 @@ Why were these vars collected into a struct before multi-tty support?) - The bug does not seem to happen if the error occurs before terminal - initialization or if I comment out all xfree()s in delete_frame. - Update: yes it does, although it is much rarer. Or maybe it's - another bug. + (Done. Whew. It turned out that the problem had nothing to do + with hypothetical external references to Wcm, or any other + tty_output component; it was simply that delete_tty closed the + filehandles of secondary ttys twice, resulting in fclose doubly + free()ing memory. Utterly trivial matter. I love the C's memory + management, it puts hair on your chest.) - Idea: Some of these errors may have been caused by having more - file handles than FD_SETSIZE. +THINGS TO DO +------------ + +** Understand Emacs's low-level input system (it seems complicated) :-) + and maybe rewrite multi-tty input in terms of MULTIKBOARD. ** Find out why does Emacs abort when it wants to close its controlling tty. Hint: chan_process[] array. Hey, maybe - noninterrupt-IO would work, too? + noninterrupt-IO would work, too? Update: no, there is no process + for stdin/out. ** Support raw secondary terminals. (Note that SIGIO works only on the controlling terminal.) Hint: extend read_input_waiting() for @@ -252,9 +252,21 @@ ** Issue with SIGIO: it needs to be disabled during redisplay. See if fcntl() kernel behaviour could be emulated by emacsclient. +** Get rid of the accessor macros in termchar.h, or define macros for + all members. + ** Make parts of struct tty_output accessible from Lisp. The device name and the type is sufficient. +** server.el: There are issues with saving files in buffers of closed + clients. Try editing a file with emacsclient -f, and (without + saving it) do a delete-frame. The frame is closed without + question, and a surprising confirmation prompt appears in another + frame. + +** emacsclient.el, server.el: Handle eval or file open errors when + doing -f. + ** Export delete_tty to the Lisp environment, for emacsclient. ** Make sure C-g goes to the right frame. This is hard, as SIGINT @@ -283,6 +295,6 @@ ** Fix DOS support (I can't do this myself). - +** Do a grep on XXX and ?? for more issues. ;;; arch-tag: 8da1619e-2e79-41a8-9ac9-a0485daad17d
--- a/lib-src/emacsclient.c Tue Dec 30 17:51:52 2003 +0000 +++ b/lib-src/emacsclient.c Tue Dec 30 19:27:57 2003 +0000 @@ -118,7 +118,7 @@ char *display = NULL; /* Nonzero means open a new Emacs frame on the current terminal. */ -int here = 0; +int frame = 0; /* If non-NULL, the name of an editor to fallback to if the server is not running. --alternate-editor. */ @@ -135,7 +135,7 @@ { "eval", no_argument, NULL, 'e' }, { "help", no_argument, NULL, 'H' }, { "version", no_argument, NULL, 'V' }, - { "here", no_argument, NULL, 'h' }, + { "frame", no_argument, NULL, 'f' }, { "alternate-editor", required_argument, NULL, 'a' }, { "socket-name", required_argument, NULL, 's' }, { "display", required_argument, NULL, 'd' }, @@ -153,7 +153,7 @@ while (1) { int opt = getopt_long (argc, argv, - "VHnea:s:d:h", longopts, 0); + "VHnea:s:d:f", longopts, 0); if (opt == EOF) break; @@ -192,8 +192,8 @@ exit (0); break; - case 'h': - here = 1; + case 'f': + frame = 1; break; case 'H': @@ -207,7 +207,7 @@ } } - if (here) { + if (frame) { nowait = 0; display = 0; } @@ -225,7 +225,7 @@ The following OPTIONS are accepted:\n\ -V, --version Just print a version info and return\n\ -H, --help Print this usage information message\n\ --h, --here Open a new Emacs frame on the current terminal\n\ +-f, --frame Open a new Emacs frame on the current terminal\n\ -n, --no-wait Don't wait for the server to return\n\ -e, --eval Evaluate the FILE arguments as ELisp expressions\n\ -d, --display=DISPLAY Visit the file in the given display\n\ @@ -876,7 +876,7 @@ /* Process options. */ decode_options (argc, argv); - if ((argc - optind < 1) && !eval && !here) + if ((argc - optind < 1) && !eval && !frame) { fprintf (stderr, "%s: file name or argument required\n", progname); fprintf (stderr, "Try `%s --help' for more information\n", progname); @@ -1048,7 +1048,7 @@ fprintf (out, " "); } - if (here) + if (frame) { if (! init_signals ()) { @@ -1108,7 +1108,7 @@ } else { - if (!here) + if (!frame) { while ((str = fgets (string, BUFSIZ, stdin))) { @@ -1128,7 +1128,7 @@ return 0; } - if (here) + if (frame) { if (! pty_conversation (out)) {
--- a/lisp/server.el Tue Dec 30 17:51:52 2003 +0000 +++ b/lisp/server.el Tue Dec 30 19:27:57 2003 +0000 @@ -271,7 +271,7 @@ (while server-frames (let ((frame (cadar server-frames))) (setq server-frames (cdr server-frames)) - (when frame-live-p frame (delete-frame frame 'force)))) + (when (frame-live-p frame) (delete-frame frame 'force)))) (unless leave-dead (if server-process (server-log (message "Restarting server"))) @@ -314,7 +314,7 @@ (coding-system (and default-enable-multibyte-characters (or file-name-coding-system default-file-name-coding-system))) - client nowait eval + client nowait eval newframe (files nil) (lineno 1) (columnno 0)) @@ -336,6 +336,7 @@ (setq request ""))))) ;; Open a new frame at the client. ARG is the name of the pseudo tty. ((and (equal "-pty" arg) (string-match "\\([^ ]*\\) \\([^ ]*\\) " request)) + (setq newframe t) (let ((pty (server-unquote-arg (match-string 1 request))) (type (server-unquote-arg (match-string 2 request)))) (setq request (substring request (match-end 0))) @@ -364,7 +365,7 @@ (if eval (condition-case err (let ((v (eval (car (read-from-string arg))))) - (when v + (when (and (not newframe v)) (with-temp-buffer (let ((standard-output (current-buffer))) (pp v) @@ -382,7 +383,7 @@ (server-visit-files files client nowait) (run-hooks 'post-command-hook)) ;; CLIENT is now a list (CLIENTNUM BUFFERS...) - (if (null (cdr client)) + (if (and (not newframe) (null (cdr client))) ;; This client is empty; get rid of it immediately. (progn (let ((frame (assq (car client) server-frames))) @@ -607,7 +608,8 @@ ;; since we've already effectively done that. (if (null next-buffer) (if server-clients - (server-switch-buffer (nth 1 (car server-clients)) killed-one) + (let ((buffer (nth 1 (car server-clients)))) + (and buffer (server-switch-buffer buffer killed-one))) (unless (or killed-one (window-dedicated-p (selected-window))) (switch-to-buffer (other-buffer)) (message "No server buffers remain to edit")))
--- a/src/dispextern.h Tue Dec 30 17:51:52 2003 +0000 +++ b/src/dispextern.h Tue Dec 30 19:27:57 2003 +0000 @@ -2562,11 +2562,11 @@ /* Defined in sysdep.c */ -void get_tty_size P_ ((struct tty_output *, int *, int *)); +void get_tty_size P_ ((int, int *, int *)); void request_sigio P_ ((void)); void unrequest_sigio P_ ((void)); -int tabs_safe_p P_ ((struct tty_output *)); -void init_baud_rate P_ ((struct tty_output *)); +int tabs_safe_p P_ ((int)); +void init_baud_rate P_ ((int)); void init_sigio P_ ((int)); /* Defined in xfaces.c */
--- a/src/dispnew.c Tue Dec 30 17:51:52 2003 +0000 +++ b/src/dispnew.c Tue Dec 30 19:27:57 2003 +0000 @@ -5927,7 +5927,7 @@ if (! tty->term_initted) continue; - get_tty_size (tty, &width, &height); + get_tty_size (fileno (TTY_INPUT (tty)), &width, &height); { Lisp_Object tail, frame;
--- a/src/frame.c Tue Dec 30 17:51:52 2003 +0000 +++ b/src/frame.c Tue Dec 30 19:27:57 2003 +0000 @@ -656,7 +656,7 @@ { int width, height; - get_tty_size (FRAME_TTY (f), &width, &height); + get_tty_size (fileno (TTY_INPUT (FRAME_TTY (f))), &width, &height); change_frame_size (f, height, width, 0, 0, 0); }
--- a/src/keyboard.c Tue Dec 30 17:51:52 2003 +0000 +++ b/src/keyboard.c Tue Dec 30 19:27:57 2003 +0000 @@ -10127,7 +10127,7 @@ call1 (Vrun_hooks, intern ("suspend-hook")); GCPRO1 (stuffstring); - get_tty_size (CURTTY (), &old_width, &old_height); + get_tty_size (fileno (TTY_INPUT (CURTTY ())), &old_width, &old_height); reset_all_sys_modes (); /* sys_suspend can get an error if it tries to fork a subshell and the system resources aren't available for that. */ @@ -10143,7 +10143,7 @@ /* Check if terminal/window size has changed. Note that this is not useful when we are running directly with a window system; but suspend should be disabled in that case. */ - get_tty_size (CURTTY (), &width, &height); + get_tty_size (fileno (TTY_INPUT (CURTTY ())), &width, &height); if (width != old_width || height != old_height) change_frame_size (SELECTED_FRAME (), height, width, 0, 0, 0);
--- a/src/sysdep.c Tue Dec 30 17:51:52 2003 +0000 +++ b/src/sysdep.c Tue Dec 30 19:27:57 2003 +0000 @@ -309,10 +309,13 @@ #endif /* not WINDOWSNT */ } + #ifdef SIGTSTP /* Arrange for character C to be read as the next input from - the terminal. */ + the terminal. + XXX What if we have multiple ttys? +*/ void stuff_char (char c) @@ -331,7 +334,7 @@ #endif /* SIGTSTP */ void -init_baud_rate (struct tty_output *tty) +init_baud_rate (int fd) { if (noninteractive) emacs_ospeed = 0; @@ -346,7 +349,7 @@ #ifdef VMS struct sensemode sg; - SYS$QIOW (0, fileno (TTY_INPUT (tty)), IO$_SENSEMODE, &sg, 0, 0, + SYS$QIOW (0, fd, IO$_SENSEMODE, &sg, 0, 0, &sg.class, 12, 0, 0, 0, 0 ); emacs_ospeed = sg.xmit_baud; #else /* not VMS */ @@ -354,7 +357,7 @@ struct termios sg; sg.c_cflag = B9600; - tcgetattr (fileno (TTY_INPUT (tty)), &sg); + tcgetattr (fd, &sg); emacs_ospeed = cfgetospeed (&sg); #if defined (USE_GETOBAUD) && defined (getobaud) /* m88k-motorola-sysv3 needs this (ghazi@noc.rutgers.edu) 9/1/94. */ @@ -367,16 +370,16 @@ sg.c_cflag = B9600; #ifdef HAVE_TCATTR - tcgetattr (fileno (TTY_INPUT (tty)), &sg); + tcgetattr (fd, &sg); #else - ioctl (fileno (TTY_INPUT (tty)), TCGETA, &sg); + ioctl (fd, 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 (tty)), TIOCGETP, &sg) < 0) + if (ioctl (fd, TIOCGETP, &sg) < 0) abort (); emacs_ospeed = sg.sg_ospeed; #endif /* not HAVE_TERMIO */ @@ -392,6 +395,7 @@ baud_rate = 1200; } + /*ARGSUSED*/ void set_exclusive_use (fd) @@ -976,7 +980,7 @@ } void -unrequest_sigio (struct tty_output *tty) +unrequest_sigio () { int off = 0; @@ -1078,23 +1082,23 @@ group, redirect the TTY to point to our own process group. We need to be in our own process group to receive SIGIO properly. */ void -narrow_foreground_group (struct tty_output *tty) +narrow_foreground_group (int fd) { int me = getpid (); setpgrp (0, inherited_pgroup); /* XXX This only works on the controlling tty. */ if (inherited_pgroup != me) - EMACS_SET_TTY_PGRP (fileno (TTY_INPUT (tty)), &me); + EMACS_SET_TTY_PGRP (fd, &me); setpgrp (0, me); } /* Set the tty to our original foreground group. */ void -widen_foreground_group (struct tty_output *tty) +widen_foreground_group (int fd) { if (inherited_pgroup != getpid ()) - EMACS_SET_TTY_PGRP (fileno (TTY_INPUT (tty)), &inherited_pgroup); + EMACS_SET_TTY_PGRP (fd, &inherited_pgroup); setpgrp (0, inherited_pgroup); } @@ -1289,11 +1293,9 @@ void init_all_sys_modes (void) { - struct tty_output *tty = tty_list; - while (tty) { + struct tty_output *tty; + for (tty = tty_list; tty; tty = tty->next) init_sys_modes (tty); - tty = tty->next; - } } void @@ -1358,7 +1360,7 @@ #ifdef BSD_PGRPS if (! read_socket_hook && EQ (Vwindow_system, Qnil)) - narrow_foreground_group (tty_out); + narrow_foreground_group (fileno (TTY_INPUT (tty_out))); #endif #ifdef HAVE_WINDOW_SYSTEM @@ -1683,11 +1685,11 @@ At the time this is called, init_sys_modes has not been done yet. */ int -tabs_safe_p (struct tty_output *tty) +tabs_safe_p (int fd) { struct emacs_tty etty; - EMACS_GET_TTY (fileno (TTY_INPUT (tty)), &etty); + EMACS_GET_TTY (fd, &etty); return EMACS_TTY_TABS_OK (&etty); } @@ -1696,9 +1698,7 @@ We store 0 if there's no valid information. */ void -get_tty_size (tty_out, widthp, heightp) - struct tty_output *tty_out; - int *widthp, *heightp; +get_tty_size (int fd, int *widthp, int *heightp) { #ifdef TIOCGWINSZ @@ -1706,7 +1706,7 @@ /* BSD-style. */ struct winsize size; - if (ioctl (fileno (TTY_INPUT (tty_out)), TIOCGWINSZ, &size) == -1) + if (ioctl (fd, TIOCGWINSZ, &size) == -1) *widthp = *heightp = 0; else { @@ -1720,7 +1720,7 @@ /* SunOS - style. */ struct ttysize size; - if (ioctl (fileno (TTY_INPUT (tty_out)), TIOCGSIZE, &size) == -1) + if (ioctl (fd, TIOCGSIZE, &size) == -1) *widthp = *heightp = 0; else { @@ -1733,7 +1733,7 @@ struct sensemode tty; - SYS$QIOW (0, fileno (TTY_INPUT (tty_out)), IO$_SENSEMODE, &tty, 0, 0, + SYS$QIOW (0, fd, IO$_SENSEMODE, &tty, 0, 0, &tty.class, 12, 0, 0, 0, 0); *widthp = tty.scr_wid; *heightp = tty.scr_len; @@ -1793,11 +1793,9 @@ void reset_all_sys_modes (void) { - struct tty_output *tty = tty_list; - while (tty) { + struct tty_output *tty; + for (tty = tty_list; tty; tty = tty->next) reset_sys_modes (tty); - tty = tty->next; - } } /* Prepare the terminal for closing it; move the cursor to the @@ -1889,7 +1887,7 @@ #endif #ifdef BSD_PGRPS - widen_foreground_group (tty_out); + widen_foreground_group (fileno (TTY_INPUT (tty_out))); #endif }
--- a/src/term.c Tue Dec 30 17:51:52 2003 +0000 +++ b/src/term.c Tue Dec 30 19:27:57 2003 +0000 @@ -2403,7 +2403,7 @@ /* Get frame size from system, or else from termcap. */ { int height, width; - get_tty_size (tty, &width, &height); + get_tty_size (fileno (TTY_INPUT (tty)), &width, &height); FrameCols (tty) = width; FrameRows (tty) = height; } @@ -2609,7 +2609,7 @@ && tty->TS_end_standout_mode && !strcmp (tty->TS_standout_mode, tty->TS_end_standout_mode)); - UseTabs (tty) = tabs_safe_p (tty) && TabWidth (tty) == 8; + UseTabs (tty) = tabs_safe_p (fileno (TTY_INPUT (tty))) && TabWidth (tty) == 8; TTY_SCROLL_REGION_OK (tty) = (tty->Wcm->cm_abs @@ -2628,7 +2628,7 @@ TTY_FAST_CLEAR_END_OF_LINE (tty) = tty->TS_clr_line != 0; - init_baud_rate (tty); + init_baud_rate (fileno (TTY_INPUT (tty))); if (read_socket_hook) /* Baudrate is somewhat meaningless in this case */ baud_rate = 9600; @@ -2737,7 +2737,7 @@ if (tty->input) fclose (tty->input); - if (tty->output) + if (tty->output && tty->output != tty->input) fclose (tty->output); if (tty->termscript) fclose (tty->termscript); @@ -2745,10 +2745,8 @@ if (tty->old_tty) 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);