comparison src/term.c @ 83525:b2e7507b55c6

Fix C-x 5 2 on the controlling tty; fix some possible crash conditions and a memory leak. * src/frame.c (make_terminal_frame): Don't create frames on a terminal that is being deleted. * src/xfns.c (Fx_create_frame, x_create_tip_frame): Ditto. * src/keyboard.c (tty_read_avail_input): Don't read from a terminal that is being deleted. * src/term.c (get_named_tty): Abort if tty name is NULL. Simplify accordingly. * src/term.c (Ftty_type): Return nil if terminal is not on a tty instead of throwing an error. Doc update. * src/term.c (init_tty): Set name before calling `get_named_tty'. * src/term.c (delete_tty): Let delete_terminal delete the frames. Plug memory leak caused by tty->name. Remove reference to `deleting_tty'. * src/term.c (syms_of_term) <Vsuspend_tty_functions, Vresume_tty_functions>: Doc update. * src/termhooks.h (terminal) <name>: Explain why identifying terminals by name is a bad idea. * src/terminal.c (delete_terminal): Doc update. * src/xterm.c (XTread_socket): Disable loop on all X displays. * src/xterm.c (x_delete_display): Doc update to reflect changes in delete_terminal. * src/xterm.c (x_delete_terminal): Don't set terminal->deleted and let delete_terminal delete the frames on the terminal. * src/xterm.h (x_display_info) <terminal>: Move member earlier in the struct. git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-565
author Karoly Lorentey <lorentey@elte.hu>
date Sat, 20 May 2006 17:12:43 +0000
parents a5d712e6585a
children c71725faff1a
comparison
equal deleted inserted replaced
83524:673d62ad74b5 83525:b2e7507b55c6
2027 } 2027 }
2028 2028
2029 return t; 2029 return t;
2030 } 2030 }
2031 2031
2032 /* Return the active termcap device that uses the tty device with the 2032 /* Return an active termcap device that uses the tty device with the
2033 given name. If NAME is NULL, return the device corresponding to 2033 given name.
2034 our controlling terminal.
2035 2034
2036 This function ignores suspended devices. 2035 This function ignores suspended devices.
2037 2036
2038 Returns NULL if the named terminal device is not opened. */ 2037 Returns NULL if the named terminal device is not opened. */
2039 2038
2041 get_named_tty (name) 2040 get_named_tty (name)
2042 char *name; 2041 char *name;
2043 { 2042 {
2044 struct terminal *t; 2043 struct terminal *t;
2045 2044
2046 for (t = terminal_list; t; t = t->next_terminal) { 2045 if (!name)
2047 if (t->type == output_termcap 2046 abort ();
2048 && ((t->display_info.tty->name == 0 && name == 0) 2047
2049 || (name && t->display_info.tty->name 2048 for (t = terminal_list; t; t = t->next_terminal)
2050 && !strcmp (t->display_info.tty->name, name))) 2049 {
2051 && TERMINAL_ACTIVE_P (t)) 2050 if (t->type == output_termcap
2052 return t; 2051 && !strcmp (t->display_info.tty->name, name)
2053 }; 2052 && TERMINAL_ACTIVE_P (t))
2053 return t;
2054 }
2054 2055
2055 return 0; 2056 return 0;
2056 } 2057 }
2057 2058
2058 2059
2059 DEFUN ("tty-type", Ftty_type, Stty_type, 0, 1, 0, 2060 DEFUN ("tty-type", Ftty_type, Stty_type, 0, 1, 0,
2060 doc: /* Return the type of the tty device that TERMINAL uses. 2061 doc: /* Return the type of the tty device that TERMINAL uses.
2062 Returns nil if TERMINAL is not on a tty device.
2061 2063
2062 TERMINAL can be a terminal id, a frame or nil (meaning the selected 2064 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2063 frame's terminal). */) 2065 frame's terminal). */)
2064 (terminal) 2066 (terminal)
2065 Lisp_Object terminal; 2067 Lisp_Object terminal;
2066 { 2068 {
2067 struct terminal *t = get_terminal (terminal, 1); 2069 struct terminal *t = get_terminal (terminal, 1);
2068 2070
2069 if (t->type != output_termcap) 2071 if (t->type != output_termcap)
2070 error ("Terminal %d is not a termcap terminal", t->id); 2072 return Qnil;
2071 2073
2072 if (t->display_info.tty->type) 2074 if (t->display_info.tty->type)
2073 return build_string (t->display_info.tty->type); 2075 return build_string (t->display_info.tty->type);
2074 else 2076 else
2075 return Qnil; 2077 return Qnil;
2076 } 2078 }
2386 static void maybe_fatal(); 2388 static void maybe_fatal();
2387 2389
2388 /* Create a termcap display on the tty device with the given name and 2390 /* Create a termcap display on the tty device with the given name and
2389 type. 2391 type.
2390 2392
2391 If NAME is NULL, then use the controlling tty, i.e., stdin/stdout. 2393 If NAME is NULL, then use the controlling tty, i.e., "/dev/tty".
2392 Otherwise NAME should be a path to the tty device file, 2394 Otherwise NAME should be a path to the tty device file,
2393 e.g. "/dev/pts/7". 2395 e.g. "/dev/pts/7".
2394 2396
2395 TERMINAL_TYPE is the termcap type of the device, e.g. "vt100". 2397 TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
2396 2398
2412 if (!terminal_type) 2414 if (!terminal_type)
2413 maybe_fatal (must_succeed, 0, 0, 2415 maybe_fatal (must_succeed, 0, 0,
2414 "Unknown terminal type", 2416 "Unknown terminal type",
2415 "Unknown terminal type"); 2417 "Unknown terminal type");
2416 2418
2419 if (name == NULL)
2420 name = "/dev/tty";
2421 if (!strcmp (name, "/dev/tty"))
2422 ctty = 1;
2423
2417 /* If we already have a terminal on the given device, use that. If 2424 /* If we already have a terminal on the given device, use that. If
2418 all such terminals are suspended, create a new one instead. */ 2425 all such terminals are suspended, create a new one instead. */
2419 /* XXX Perhaps this should be made explicit by having init_tty 2426 /* XXX Perhaps this should be made explicit by having init_tty
2420 always create a new terminal and separating terminal and frame 2427 always create a new terminal and separating terminal and frame
2421 creation on Lisp level. */ 2428 creation on Lisp level. */
2436 tty->Wcm = (struct cm *) xmalloc (sizeof (struct cm)); 2443 tty->Wcm = (struct cm *) xmalloc (sizeof (struct cm));
2437 Wcm_clear (tty); 2444 Wcm_clear (tty);
2438 2445
2439 set_tty_hooks (terminal); 2446 set_tty_hooks (terminal);
2440 2447
2441 if (name == NULL)
2442 name = "/dev/tty";
2443 if (!strcmp (name, "/dev/tty"))
2444 ctty = 1;
2445
2446 { 2448 {
2447 int fd; 2449 int fd;
2448 FILE *file; 2450 FILE *file;
2449 2451
2450 #ifdef O_IGNORE_CTTY 2452 #ifdef O_IGNORE_CTTY
2975 static void 2977 static void
2976 delete_tty (struct terminal *terminal) 2978 delete_tty (struct terminal *terminal)
2977 { 2979 {
2978 struct tty_display_info *tty; 2980 struct tty_display_info *tty;
2979 Lisp_Object tail, frame; 2981 Lisp_Object tail, frame;
2980 char *tty_name;
2981 int last_terminal; 2982 int last_terminal;
2982 2983
2983 /* Protect against recursive calls. Fdelete_frame calls us back 2984 /* Protect against recursive calls. Fdelete_frame in
2984 when we delete our last frame. */ 2985 delete_terminal calls us back when it deletes our last frame. */
2985 if (terminal->deleted) 2986 if (terminal->deleted)
2986 return; 2987 return;
2987 2988
2988 if (terminal->type != output_termcap) 2989 if (terminal->type != output_termcap)
2989 abort (); 2990 abort ();
3017 3018
3018 p->next = tty->next; 3019 p->next = tty->next;
3019 tty->next = 0; 3020 tty->next = 0;
3020 } 3021 }
3021 3022
3022 /* We must not throw any errors below this line. */
3023 terminal->deleted = 1;
3024
3025 FOR_EACH_FRAME (tail, frame)
3026 {
3027 struct frame *f = XFRAME (frame);
3028 if (FRAME_TERMCAP_P (f) && FRAME_LIVE_P (f) && FRAME_TTY (f) == tty)
3029 {
3030 Fdelete_frame (frame, Qt);
3031 }
3032 }
3033
3034 /* reset_sys_modes needs a valid device, so this call needs to be 3023 /* reset_sys_modes needs a valid device, so this call needs to be
3035 before delete_terminal. */ 3024 before delete_terminal. */
3036 reset_sys_modes (tty); 3025 reset_sys_modes (tty);
3037 3026
3038 delete_terminal (terminal); 3027 delete_terminal (terminal);
3039 3028
3040 tty_name = tty->name; 3029 if (tty->name)
3030 xfree (tty->name);
3031
3041 if (tty->type) 3032 if (tty->type)
3042 xfree (tty->type); 3033 xfree (tty->type);
3043 3034
3044 if (tty->input) 3035 if (tty->input)
3045 { 3036 {
3058 if (tty->Wcm) 3049 if (tty->Wcm)
3059 xfree (tty->Wcm); 3050 xfree (tty->Wcm);
3060 3051
3061 bzero (tty, sizeof (struct tty_display_info)); 3052 bzero (tty, sizeof (struct tty_display_info));
3062 xfree (tty); 3053 xfree (tty);
3063 deleting_tty = 0;
3064 } 3054 }
3065 3055
3066 3056
3067 3057
3068 /* Mark the pointers in the tty_display_info objects. 3058 /* Mark the pointers in the tty_display_info objects.
3094 system_uses_terminfo = 0; 3084 system_uses_terminfo = 0;
3095 #endif 3085 #endif
3096 3086
3097 DEFVAR_LISP ("suspend-tty-functions", &Vsuspend_tty_functions, 3087 DEFVAR_LISP ("suspend-tty-functions", &Vsuspend_tty_functions,
3098 doc: /* Functions to be run after suspending a tty. 3088 doc: /* Functions to be run after suspending a tty.
3099 The functions are run with one argument, the name of the tty to be suspended. 3089 The functions are run with one argument, the terminal id to be suspended.
3100 See `suspend-tty'. */); 3090 See `suspend-tty'. */);
3101 Vsuspend_tty_functions = Qnil; 3091 Vsuspend_tty_functions = Qnil;
3102 3092
3103 3093
3104 DEFVAR_LISP ("resume-tty-functions", &Vresume_tty_functions, 3094 DEFVAR_LISP ("resume-tty-functions", &Vresume_tty_functions,
3105 doc: /* Functions to be run after resuming a tty. 3095 doc: /* Functions to be run after resuming a tty.
3106 The functions are run with one argument, the name of the tty that was revived. 3096 The functions are run with one argument, the terminal id that was revived.
3107 See `resume-tty'. */); 3097 See `resume-tty'. */);
3108 Vresume_tty_functions = Qnil; 3098 Vresume_tty_functions = Qnil;
3109 3099
3110 DEFVAR_BOOL ("visible-cursor", &visible_cursor, 3100 DEFVAR_BOOL ("visible-cursor", &visible_cursor,
3111 doc: /* Non-nil means to make the cursor very visible. 3101 doc: /* Non-nil means to make the cursor very visible.