diff options
| author | Karoly Lorentey | 2006-05-20 12:20:41 +0000 |
|---|---|---|
| committer | Karoly Lorentey | 2006-05-20 12:20:41 +0000 |
| commit | a98f16179037d21357c817701c5181ac37fec0a2 (patch) | |
| tree | 6057eb2ba02d9f55d2be2d61f4bb04956e0fb3f0 /src | |
| parent | 4a6657585e59c464789c2039241b0c3a74d16199 (diff) | |
| download | emacs-a98f16179037d21357c817701c5181ac37fec0a2.tar.gz emacs-a98f16179037d21357c817701c5181ac37fec0a2.zip | |
Fix crashes in `delete-terminal' caused by recursive calls or X displays with live frames.
* src/termhooks.h (terminal) <deleted>: New member.
* src/term.c (delete_tty): Use it.
(deleting_tty): Remove old variable.
* src/terminal.c (delete_terminal): Use terminal->deleted.
* src/xterm.c (x_delete_terminal): Use terminal->deleted. Delete all
frames on the display explicitly.
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-562
Diffstat (limited to 'src')
| -rw-r--r-- | src/term.c | 12 | ||||
| -rw-r--r-- | src/termhooks.h | 6 | ||||
| -rw-r--r-- | src/terminal.c | 8 | ||||
| -rw-r--r-- | src/xterm.c | 18 |
4 files changed, 35 insertions, 9 deletions
diff --git a/src/term.c b/src/term.c index 00900ae96f4..3076e8939f1 100644 --- a/src/term.c +++ b/src/term.c | |||
| @@ -2970,9 +2970,6 @@ fatal (str, arg1, arg2) | |||
| 2970 | 2970 | ||
| 2971 | 2971 | ||
| 2972 | 2972 | ||
| 2973 | static int deleting_tty = 0; | ||
| 2974 | |||
| 2975 | |||
| 2976 | /* Delete the given tty terminal, closing all frames on it. */ | 2973 | /* Delete the given tty terminal, closing all frames on it. */ |
| 2977 | 2974 | ||
| 2978 | static void | 2975 | static void |
| @@ -2983,9 +2980,9 @@ delete_tty (struct terminal *terminal) | |||
| 2983 | char *tty_name; | 2980 | char *tty_name; |
| 2984 | int last_terminal; | 2981 | int last_terminal; |
| 2985 | 2982 | ||
| 2986 | if (deleting_tty) | 2983 | /* Protect against recursive calls. Fdelete_frame calls us back |
| 2987 | /* We get a recursive call when we delete the last frame on this | 2984 | when we delete our last frame. */ |
| 2988 | terminal. */ | 2985 | if (terminal->deleted) |
| 2989 | return; | 2986 | return; |
| 2990 | 2987 | ||
| 2991 | if (terminal->type != output_termcap) | 2988 | if (terminal->type != output_termcap) |
| @@ -3022,7 +3019,8 @@ delete_tty (struct terminal *terminal) | |||
| 3022 | tty->next = 0; | 3019 | tty->next = 0; |
| 3023 | } | 3020 | } |
| 3024 | 3021 | ||
| 3025 | deleting_tty = 1; | 3022 | /* We must not throw any errors below this line. */ |
| 3023 | terminal->deleted = 1; | ||
| 3026 | 3024 | ||
| 3027 | FOR_EACH_FRAME (tail, frame) | 3025 | FOR_EACH_FRAME (tail, frame) |
| 3028 | { | 3026 | { |
diff --git a/src/termhooks.h b/src/termhooks.h index 8937a709f85..46fb0c453f5 100644 --- a/src/termhooks.h +++ b/src/termhooks.h | |||
| @@ -299,7 +299,11 @@ struct terminal | |||
| 299 | 299 | ||
| 300 | /* The number of frames that are on this terminal. */ | 300 | /* The number of frames that are on this terminal. */ |
| 301 | int reference_count; | 301 | int reference_count; |
| 302 | 302 | ||
| 303 | /* Nonzero while deleting this terminal. Used to protect against | ||
| 304 | recursive calls to delete_terminal_hook. */ | ||
| 305 | int deleted; | ||
| 306 | |||
| 303 | /* The type of the terminal device. */ | 307 | /* The type of the terminal device. */ |
| 304 | enum output_method type; | 308 | enum output_method type; |
| 305 | 309 | ||
diff --git a/src/terminal.c b/src/terminal.c index fa6a0a4f51e..db75e16b6cf 100644 --- a/src/terminal.c +++ b/src/terminal.c | |||
| @@ -277,7 +277,13 @@ delete_terminal (struct terminal *terminal) | |||
| 277 | { | 277 | { |
| 278 | struct terminal **tp; | 278 | struct terminal **tp; |
| 279 | Lisp_Object tail, frame; | 279 | Lisp_Object tail, frame; |
| 280 | 280 | ||
| 281 | /* Protect against recursive calls. Fdelete_frame calls us back | ||
| 282 | when we delete our last frame. */ | ||
| 283 | if (terminal->deleted) | ||
| 284 | return; | ||
| 285 | terminal->deleted = 1; | ||
| 286 | |||
| 281 | /* Check for and close live frames that are still on this | 287 | /* Check for and close live frames that are still on this |
| 282 | terminal. */ | 288 | terminal. */ |
| 283 | FOR_EACH_FRAME (tail, frame) | 289 | FOR_EACH_FRAME (tail, frame) |
diff --git a/src/xterm.c b/src/xterm.c index 2070c65d76a..04242f2af3b 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -10837,6 +10837,24 @@ x_delete_terminal (struct terminal *terminal) | |||
| 10837 | { | 10837 | { |
| 10838 | struct x_display_info *dpyinfo = terminal->display_info.x; | 10838 | struct x_display_info *dpyinfo = terminal->display_info.x; |
| 10839 | int i; | 10839 | int i; |
| 10840 | Lisp_Object tail, frame; | ||
| 10841 | |||
| 10842 | /* Protect against recursive calls. Fdelete_frame calls us back | ||
| 10843 | when we delete our last frame. */ | ||
| 10844 | if (terminal->deleted) | ||
| 10845 | return; | ||
| 10846 | terminal->deleted = 1; | ||
| 10847 | |||
| 10848 | /* Check for and close live frames that are still on this | ||
| 10849 | terminal. */ | ||
| 10850 | FOR_EACH_FRAME (tail, frame) | ||
| 10851 | { | ||
| 10852 | struct frame *f = XFRAME (frame); | ||
| 10853 | if (FRAME_LIVE_P (f) && f->terminal == terminal) | ||
| 10854 | { | ||
| 10855 | Fdelete_frame (frame, Qt); | ||
| 10856 | } | ||
| 10857 | } | ||
| 10840 | 10858 | ||
| 10841 | BLOCK_INPUT; | 10859 | BLOCK_INPUT; |
| 10842 | /* Free the fonts in the font table. */ | 10860 | /* Free the fonts in the font table. */ |