diff options
author | Po Lu <luangruo@yahoo.com> | 2022-07-13 20:16:21 +0800 |
---|---|---|
committer | Po Lu <luangruo@yahoo.com> | 2022-07-13 20:16:45 +0800 |
commit | 9f6d8486b46ce4d2dfaba9a59ccc349359688878 (patch) | |
tree | 74eea6f26d065a198106af2d26d7e46a57a58f1b | |
parent | ad4ccd4d907a6741668d3c7ba1385485315ee6e1 (diff) | |
download | emacs-9f6d8486b46ce4d2dfaba9a59ccc349359688878.tar.gz |
Fix recursive calls of x_connection_closed leading to dead terminal
* src/xterm.c (x_connection_closed): Return if called again for
the current display.
(x_io_error_quitter): Fix attributes. (bug#56528)
-rw-r--r-- | src/xterm.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/src/xterm.c b/src/xterm.c index fa54d5c9e28..284a08769a1 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -23301,7 +23301,7 @@ static char *error_msg; /* Handle the loss of connection to display DPY. ERROR_MESSAGE is the text of an error message that lead to the connection loss. */ -static AVOID +static void x_connection_closed (Display *dpy, const char *error_message, bool ioerror) { struct x_display_info *dpyinfo; @@ -23313,6 +23313,15 @@ x_connection_closed (Display *dpy, const char *error_message, bool ioerror) Lisp_Object minibuf_frame, tmp; struct x_failable_request *failable; struct x_error_message_stack *stack; + static Display *current_display; + + /* Prevent recursive calls of this function for the same display. + This is because destroying a frame might still cause an IO error + in some cases. (bug#56528) */ + if (current_display == dpy) + return; + + current_display = dpy; dpyinfo = x_display_info_for_display (dpy); error_msg = alloca (strlen (error_message) + 1); @@ -23519,6 +23528,7 @@ For details, see etc/PROBLEMS.\n", /* Here, we absolutely have to use a non-local exit (e.g. signal, throw, longjmp), because returning from this function would get us back into Xlib's code which will directly call `exit'. */ + current_display = NULL; error ("%s", error_msg); } @@ -23623,7 +23633,7 @@ x_error_quitter (Display *display, XErrorEvent *event) It kills all frames on the display that we lost touch with. If that was the only one, it prints an error message and kills Emacs. */ -static _Noreturn ATTRIBUTE_COLD int +static int NO_INLINE x_io_error_quitter (Display *display) { char buf[256]; @@ -23631,6 +23641,8 @@ x_io_error_quitter (Display *display) snprintf (buf, sizeof buf, "Connection lost to X server '%s'", DisplayString (display)); x_connection_closed (display, buf, true); + + return 0; } |