bug#78899: 30.1; garbage inserted in the terminal buffer when quitting Emacs

Vincent Lefevre <[email protected]>
Newsgroups gmane.emacs.bugs
Message-ID <[email protected]>
On 2026-08-16 08:18:57 +0300, Eli Zaretskii wrote:
> > First, some hunks fail for lisp/term/xterm.el and lisp/xt-mouse.el,
> > but that's easily fixable since the failures only come from
> > unchanged lines that have been modified in the repository.
> > 
> > But when compiling, I get the following error:
> > 
> >   error: ‘inhibit_lisp_code’ undeclared
> > 
> > This symbol was removed in 855ad6d870852144221a15d04f4b31969689bffb.
> 
> Please always show complete compilation error messages.
> 
> Chrystal ball says that you need to add to src/lisp.h a line like
> this:
> 
>   extern Lisp_Object inhibit_lisp_code;

I no longer get any issue with the resulting patch (attached),
except the following errors that appear:

xterm--read-string: Wrong type argument: sequencep, 99
xterm--read-string: Wrong type argument: sequencep, 27

-- 
Vincent Lefèvre <[email protected]> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / Pascaline project (LIP, ENS-Lyon)
emacs-new2.patch (text/plain, 21.8 KB)
diff --git a/lisp/term/xterm.el b/lisp/term/xterm.el
index 60a992a7e7b..8238f55694c 100644
--- a/lisp/term/xterm.el
+++ b/lisp/term/xterm.el
@@ -769,9 +769,10 @@ xterm-standard-colors
 
 (defun xterm--report-background-handler ()
   ;; The reply should be: \e ] 11 ; rgb: NUMBER1 / NUMBER2 / NUMBER3 \e \\
-  (let ((str (xterm--read-string ?\e ?\\)))
-    (when (string-match
-           "rgb:\\([a-f0-9]+\\)/\\([a-f0-9]+\\)/\\([a-f0-9]+\\)" str)
+  (let ((str (xterm--read-string "\e\\")))
+    (when (and str
+               (string-match
+                "rgb:\\([a-f0-9]+\\)/\\([a-f0-9]+\\)/\\([a-f0-9]+\\)" str))
       (set-terminal-parameter
        nil 'xterm--background-color
        (list (string-to-number (match-string 1 str) 16)
@@ -791,14 +792,10 @@ xterm--report-foreground-handler
 
 (defun xterm--version-handler ()
   ;; The reply should be: \e [ > NUMBER1 ; NUMBER2 ; NUMBER3 c
-  ;; If the timeout is completely removed for read-event, this
-  ;; might hang for terminals that pretend to be xterm, but don't
-  ;; respond to this escape sequence.  RMS' opinion was to remove
-  ;; it completely.  That might be right, but let's first try to
-  ;; see if by using a longer timeout we get rid of most issues.
-  (let ((str (xterm--read-string ?c)))
+  (let ((str (xterm--read-string "c")))
     ;; Since xterm-280, the terminal type (NUMBER1) is now 41 instead of 0.
-    (when (string-match "\\([0-9]+\\);\\([0-9]+\\);[01]" str)
+    (when (and str
+               (string-match "\\([0-9]+\\);\\([0-9]+\\);[01]" str))
       (let ((version (string-to-number (match-string 2 str))))
         (when (and (> version 2000)
                    (or (equal (match-string 1 str) "1")
@@ -858,6 +855,22 @@ xterm--primary-da-handler
       ;; https://github.com/contour-terminal/vt-extensions/blob/master/clipboard-extension.md
       (xterm--init-activate-set-selection))))
 
+(defun xterm--name-and-version-handler ()
+  ;; The reply should be: \e [ > NUMBER1 ; NUMBER2 ; NUMBER3 c
+  ;; If the timeout is completely removed for read-event, this
+  ;; might hang for terminals that pretend to be xterm, but don't
+  ;; respond to this escape sequence.  RMS' opinion was to remove
+  ;; it completely.  That might be right, but let's first try to
+  ;; see if by using a longer timeout we get rid of most issues.
+  (let ((str (xterm--read-string "\e\\")))
+    (and str
+         (not xterm-mouse-mode-called)
+         ;; Only automatically enable xterm mouse on terminals
+         ;; confirmed to still support all critical editing
+         ;; workflows (bug#74833).
+         (string-match-p xterm--auto-xt-mouse-allowed-names str)
+         (xterm-mouse-mode 1))))
+
 (defvar xterm-query-timeout 2
   "Seconds to wait for an answer from the terminal.
 Can be nil to mean \"no timeout\".")
@@ -865,100 +878,42 @@ xterm-query-timeout
 (defvar xterm-query-redisplay-timeout 0.2
   "Seconds to wait before allowing redisplay during terminal query." )
 
-(defun xterm--read-event-for-query ()
+(defun xterm--read-event-for-query (end-time)
   "Like `read-event', but inhibit redisplay.
 
 By not redisplaying right away for xterm queries, we can avoid
 unsightly flashing during initialization.  Give up and redisplay
 anyway if we've been waiting a little while."
-  (let ((start-time (current-time)))
+  (let* ((timeout (float-time (time-subtract end-time (current-time))))
+         (first-timeout (min xterm-query-redisplay-timeout timeout))
+         (second-timeout (- timeout first-timeout)))
     (or (let ((inhibit-redisplay t))
-          (read-event nil nil xterm-query-redisplay-timeout))
-        (read-event nil nil
-                    (and xterm-query-timeout
-			 (max 0 (float-time
-				 (time-subtract
-				  xterm-query-timeout
-				  (time-since start-time)))))))))
-
-(defun xterm--read-string (term1 &optional term2)
-  "Read a string with terminating characters.
-This uses `xterm--read-event-for-query' internally."
-  (let ((str "")
-        chr last)
-    (while (and (setq last chr
-                      chr (xterm--read-event-for-query))
-                (if term2
-                    (not (and (equal last term1) (equal chr term2)))
-                  (not (equal chr term1))))
-      (setq str (concat str (string chr))))
-    (if term2
-        (substring str 0 -1)
-      str)))
-
-(defun xterm--query (query handlers &optional no-async)
+          (read-event nil nil (max 0 first-timeout)))
+        (read-event nil nil (max 0 second-timeout)))))
+
+(defun xterm--query (query handlers)
   "Send QUERY string to the terminal and watch for a response.
 HANDLERS is an alist with elements of the form (STRING . FUNCTION).
 We run the first FUNCTION whose STRING matches the input events."
-  ;; We used to query synchronously, but the need to use `discard-input' is
-  ;; rather annoying (bug#6758).  Maybe we could always use the asynchronous
-  ;; approach, but it's less tested.
-  ;; FIXME: Merge the two branches.
-  (let ((register
-         (lambda (handlers)
-           (dolist (handler handlers)
-             (define-key input-decode-map (car handler)
-               (lambda (&optional _prompt)
-                 ;; Unregister the handler, since we don't expect
-                 ;; further answers.
-                 (dolist (handler handlers)
-                   (define-key input-decode-map (car handler) nil))
-                 (funcall (cdr handler))
-                 []))))))
-    (if (and (or (null xterm-query-timeout) (input-pending-p))
-             (not no-async))
-        (progn
-          (funcall register handlers)
-          (send-string-to-terminal query))
-      ;; Pending input can be mistakenly returned by the calls to
-      ;; read-event below: discard it.
-      (discard-input)
-      (send-string-to-terminal query)
-      (while handlers
-        (let ((handler (pop handlers))
-              (i 0))
-          (while (and (< i (length (car handler)))
-                      (let ((evt (xterm--read-event-for-query)))
-                        (if (and (null evt) (= i 0) (not no-async))
-                            ;; Timeout on the first event: fallback on async.
-                            (progn
-                              (funcall register (cons handler handlers))
-                              (setq handlers nil)
-                              nil)
-                          (or (eq evt (aref (car handler) i))
-                              (progn (if evt (push evt unread-command-events))
-                                     nil)))))
-            (setq i (1+ i)))
-          (if (= i (length (car handler)))
-              (progn (setq handlers nil)
-                     (funcall (cdr handler)))
-            (while (> i 0)
-              (push (aref (car handler) (setq i (1- i)))
-                    unread-command-events))))))))
-
-(defun xterm--query-name-and-version ()
-  "Get the terminal name and version string (XTVERSION)."
-  ;; Reduce query timeout time. The default value causes a noticeable
-  ;; startup delay on terminals that ignore the query.
-  (let ((xterm-query-timeout 0.1))
-    (catch 'result
-      (xterm--query
-       "\e[>0q"
-       `(("\eP>|" . ,(lambda ()
-                       ;; The reply should be: \e P > | STRING \e \\
-                       (let ((str (xterm--read-string ?\e ?\\)))
-                         (throw 'result str))))))
-      nil)))
+  (let (unregister-functions)
+    (dolist (handler handlers)
+      (let* ((binding
+              (lambda (&optional _prompt)
+                ;; Unregister the handlers, since we don't expect
+                ;; further answers.
+                (mapc #'funcall unregister-functions)
+                (funcall (cdr handler))
+                []))
+             (unregister
+              (lambda ()
+                (when (eq (lookup-key input-decode-map (car handler))
+                          binding)
+                  (define-key input-decode-map (car handler) nil)))))
+        (define-key input-decode-map (car handler) binding)
+        (push unregister unregister-functions)))
+    (send-string-to-terminal query)
+    (run-with-timer xterm-query-timeout nil
+                    (lambda () (mapc #'funcall unregister-functions)))))
 
 (defun xterm--push-map (map basemap)
   ;; Use inheritance to let the main keymaps override those defaults.
@@ -1032,16 +987,9 @@ xterm--init
       ;; for initial frame.
       (xterm--maybe-update-default-face (selected-frame))))
 
-  (when (and (not xterm-mouse-mode-called)
-             ;; Only automatically enable xterm mouse on terminals
-             ;; confirmed to still support all critical editing
-             ;; workflows (bug#74833).
-             (or (string-match-p xterm--auto-xt-mouse-allowed-types
-                                 (tty-type (selected-frame)))
-                 (and-let* ((name-and-version (xterm--query-name-and-version)))
-                   (string-match-p xterm--auto-xt-mouse-allowed-names
-                                   name-and-version))))
-    (xterm-mouse-mode 1))
+  (when (not xterm-mouse-mode-called)
+    (xterm--query "\e[>0q"
+                  '(("\eP>|" . xterm--name-and-version-handler))))
   ;; Unconditionally enable bracketed paste mode: terminals that don't
   ;; support it just ignore the sequence.
   (xterm--init-bracketed-paste-mode)
@@ -1130,6 +1078,33 @@ xterm--selection-char
     ('CLIPBOARD "c")
     (_ (error "Invalid selection type: %S" type))))
 
+(defun xterm--read-string (sequence &optional unread-all-events)
+  "Read input until we see SEQUENCE.  Return string of the input characters
+before its appearance, or nil if we hit a timeout.  Non-characters are
+stored in unread-command-events.  If UNREAD-ALL-EVENTS is non-nil, all
+events are stored there."
+  (setq sequence (nreverse (append sequence nil)))
+  (let ((end-time (time-add (current-time) xterm-query-timeout))
+        (n (length sequence))
+        events chars ret)
+    (unwind-protect
+        (catch 'failure
+          (while (not (equal (take n chars) sequence))
+            (let ((event (xterm--read-event-for-query end-time)))
+              (if event
+                  (push event events)
+                (throw 'failure nil))
+              (when (characterp event)
+                (push event chars))))
+          (setq ret (concat (nreverse (nthcdr n chars)))))
+      (dolist (event events)
+        (cond ((eq event (car sequence))
+               (pop sequence))
+              ((or (not (characterp event))
+                   (not (stringp ret))
+                   unread-all-events)
+               (push event unread-command-events)))))))
+
 (cl-defmethod gui-backend-get-selection
     (type data-type
      &context (window-system nil)
@@ -1141,27 +1116,16 @@ gui-backend-get-selection
                (eql nil)))
   (unless (eq data-type 'STRING)
     (error "Unsupported data type %S" data-type))
-  (let ((query (concat "\e]52;" (xterm--selection-char type) ";")))
-    (with-temp-buffer
+  (with-temp-buffer
+    (let* ((query (concat "\e]52;" (xterm--selection-char type) ";")))
       (set-buffer-multibyte nil)
-      (xterm--query
-       ;; Use ST as query terminator to get ST as reply terminator (bug#36879).
-       (concat query "?\e\\")
-       (list (cons query
-                   (lambda ()
-                     ;; Read data up to the string terminator, ST.
-                     (let (char last)
-                       (while (and (setq char (read-char
-                                               nil nil
-                                               xterm-query-timeout))
-                                   (not (and (eq char ?\\)
-                                             (eq last ?\e))))
-                         (when last
-                           (insert last))
-                         (setq last char))))))
-       'no-async)
-      (base64-decode-region (point-min) (point-max))
-      (decode-coding-region (point-min) (point-max) 'utf-8-unix t))))
+      (send-string-to-terminal (concat query "?\e\\"))
+      (xterm--read-string query t)
+      (let ((str (xterm--read-string "\e\\")))
+        (when str
+          (insert str)
+          (base64-decode-region (point-min) (point-max))
+          (decode-coding-region (point-min) (point-max) 'utf-8-unix t))))))
 
 (cl-defmethod gui-backend-set-selection
     (type data
diff --git a/lisp/xt-mouse.el b/lisp/xt-mouse.el
index b93d914380f..834323f43c4 100644
--- a/lisp/xt-mouse.el
+++ b/lisp/xt-mouse.el
@@ -387,6 +387,9 @@ xterm-mouse-mode-called
   "If `xterm-mouse-mode' has been called already.
 This can be used to detect if xterm-mouse-mode was explicitly set.")
 
+(defvar xterm-mouse--terminals (make-hash-table :test 'eq :weakness 'key)
+  "Hash table of cleanups to be performed when xterm-mouse-mode is disabled.")
+
 ;;;###autoload
 (define-minor-mode xterm-mouse-mode
   "Toggle XTerm mouse mode.
@@ -507,6 +510,7 @@ xterm-mouse--tracking-sequence
 
 (defun turn-on-xterm-mouse-tracking-on-terminal (&optional terminal)
   "Enable xterm mouse tracking on TERMINAL."
+  (setq terminal (or terminal (frame-terminal)))
   (when (and xterm-mouse-mode (eq t (terminal-live-p terminal))
 	     ;; Avoid the initial terminal which is not a termcap device.
              (not (frame-initial-p terminal)))
@@ -523,7 +527,8 @@ turn-on-xterm-mouse-tracking-on-terminal
         (define-key input-decode-map "\e[M" 'xterm-mouse-translate)
         (define-key input-decode-map "\e[<" 'xterm-mouse-translate-extended))
       (let ((enable (xterm-mouse-tracking-enable-sequence))
-            (disable (xterm-mouse-tracking-disable-sequence)))
+            (disable (xterm-mouse-tracking-disable-sequence))
+            (sync (lambda () (xterm-mouse--sync terminal))))
         (condition-case err
             (send-string-to-terminal enable terminal)
           ;; FIXME: This should use a dedicated error signal.
@@ -531,12 +536,27 @@ turn-on-xterm-mouse-tracking-on-terminal
                             "Terminal is currently suspended")
                      nil ; The sequence will be sent upon resume.
                    (signal err))))
-        (push enable (terminal-parameter nil 'tty-mode-set-strings))
-        (push disable (terminal-parameter nil 'tty-mode-reset-strings))
+        (push enable (terminal-parameter terminal 'tty-mode-set-strings))
+        (push sync (terminal-parameter terminal 'tty-mode-reset-strings))
+        (push disable (terminal-parameter terminal 'tty-mode-reset-strings))
+        (puthash terminal (list enable disable sync) xterm-mouse--terminals)
         (set-terminal-parameter terminal 'xterm-mouse-mode t)
         (set-terminal-parameter terminal 'xterm-mouse-utf-8
                                 xterm-mouse-utf-8)))))
 
+(declare-function xterm--read-string "xterm" (sequence &optional unread-all-events))
+
+(defun xterm-mouse--sync (terminal)
+  "Ensure that the TERMINAL is in a synchronized state, but obey
+xterm-query-timeout.
+
+When the sequence to disable mouse tracking has been sent and this
+function returns successfully, no further mouse events should be
+produced."
+  (send-string-to-terminal "\e[0c" terminal)
+  (xterm--read-string "\e[?" t)
+  (xterm--read-string "c"))
+
 (defun turn-off-xterm-mouse-tracking-on-terminal (terminal)
   "Disable xterm mouse tracking on TERMINAL."
   ;; Only send the disable command to those terminals to which we've already
@@ -549,19 +569,23 @@ turn-off-xterm-mouse-tracking-on-terminal
     ;; to send it too few times (or to fail to let xterm-mouse events
     ;; pass by untranslated).
     (condition-case err
-        (send-string-to-terminal xterm-mouse-tracking-disable-sequence
-                                 terminal)
+        (progn
+          (send-string-to-terminal xterm-mouse-tracking-disable-sequence
+                                   terminal)
+          (xterm-mouse--sync terminal))
       ;; FIXME: This should use a dedicated error signal.
       (error (if (equal (error-slot-value err 1)
                         "Terminal is currently suspended")
                  nil
                (signal err))))
-    (setf (terminal-parameter nil 'tty-mode-set-strings)
-          (remq xterm-mouse-tracking-enable-sequence
-                (terminal-parameter nil 'tty-mode-set-strings)))
-    (setf (terminal-parameter nil 'tty-mode-reset-strings)
-          (remq xterm-mouse-tracking-disable-sequence
-                (terminal-parameter nil 'tty-mode-reset-strings)))
+    (dolist (el (gethash terminal xterm-mouse--terminals))
+      (setf (terminal-parameter terminal 'tty-mode-set-strings)
+            (remq el
+                  (terminal-parameter terminal 'tty-mode-set-strings)))
+      (setf (terminal-parameter terminal 'tty-mode-reset-strings)
+            (remq el
+                  (terminal-parameter terminal 'tty-mode-reset-strings))))
+    (remhash terminal xterm-mouse--terminals)
     (set-terminal-parameter terminal 'xterm-mouse-mode nil)))
 
 (provide 'xt-mouse)
diff --git a/src/dispnew.c b/src/dispnew.c
index dd799c62d02..ecd38e084e2 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -3456,8 +3456,8 @@ frames_in_reverse_z_order (struct frame *f, bool visible_only)
   struct frame *root = root_frame (f);
   Lisp_Object frames = frames_with_root (root, visible_only);
   frames = CALLN (Fsort, frames, QClessp, Qframe__z_order_lessp);
-  eassert (FRAMEP (XCAR (frames)));
-  eassert (XFRAME (XCAR (frames)) == root);
+  eassert (NILP (frames) || FRAMEP (XCAR (frames)));
+  eassert (NILP (frames) || XFRAME (XCAR (frames)) == root);
   return frames;
 }
 
@@ -3517,7 +3517,7 @@ is_tty_root_frame_with_visible_child (struct frame *f)
   if (!is_tty_root_frame (f))
     return false;
   Lisp_Object z_order = frames_in_reverse_z_order (f, true);
-  return CONSP (XCDR (z_order));
+  return CONSP (z_order) && CONSP (XCDR (z_order));
 }
 
 /* Return the index of the first enabled row in MATRIX, or -1 if there
diff --git a/src/emacs.c b/src/emacs.c
index 95e0c170435..e2a712d651d 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -460,6 +460,8 @@ terminate_due_to_signal (int sig, int backtrace_limit)
 	      Fkill_emacs (make_fixnum (sig), Qnil);
 	    }
 
+	  /* Prevent running of Lisp code from now on.  */
+	  inhibit_lisp_code = Qt;
           shut_down_emacs (sig, Qnil);
           emacs_backtrace (backtrace_limit);
         }
@@ -3148,6 +3150,7 @@ shut_down_emacs (int sig, Lisp_Object stuff)
   fflush (stdout);
   reset_all_sys_modes ();
 #endif
+  inhibit_lisp_code = Qt;
 
   stuff_buffered_input (stuff);
 
diff --git a/src/eval.c b/src/eval.c
index 9d47f04f92a..8029555f2d4 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -3247,6 +3247,8 @@ safe_eval (Lisp_Object sexp)
   return safe_calln (Qeval, sexp, Qt);
 }
 
+Lisp_Object inhibit_lisp_code;
+
 /* Apply a C subroutine SUBR to the NUMARGS evaluated arguments in ARG_VECTOR
    and return the result of evaluation.  */
 
@@ -4619,6 +4621,9 @@ syms_of_eval (void)
   staticpro (&list_of_t);
   list_of_t = list1 (Qt);
 
+  inhibit_lisp_code = Qnil;
+  staticpro (&inhibit_lisp_code);
+
   defsubr (&Sor);
   defsubr (&Sand);
   defsubr (&Sif);
diff --git a/src/keyboard.c b/src/keyboard.c
index 1129fd3b58c..94df32ec68c 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -12628,7 +12628,10 @@ handle_interrupt (bool in_signal_handler)
 	  fflush (stdout);
 	}
 
+      Lisp_Object old_inhibit_lisp_code = inhibit_lisp_code;
+      inhibit_lisp_code = Qt;
       reset_all_sys_modes ();
+      inhibit_lisp_code = old_inhibit_lisp_code;
 
 #ifdef SIGTSTP
 /*
diff --git a/src/lisp.h b/src/lisp.h
index de94b2fa9d1..81e61b20d2f 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4769,6 +4769,7 @@ intern_c_string (const char *str)
 extern Lisp_Object Vautoload_queue;
 extern Lisp_Object Vrun_hooks;
 extern Lisp_Object Vsignaling_function;
+extern Lisp_Object inhibit_lisp_code;
 extern bool signal_quit_p (Lisp_Object);
 
 /* To run a normal hook, use the appropriate function from the list below.
diff --git a/src/term.c b/src/term.c
index 7e05f5b5139..91673b57d51 100644
--- a/src/term.c
+++ b/src/term.c
@@ -194,6 +194,10 @@ tty_send_additional_strings (struct terminal *terminal, Lisp_Object sym)
           if (tty->termscript)
 	    fwrite (SDATA (string), 1, sbytes, tty->termscript);
         }
+      else if (NILP (inhibit_lisp_code) && FUNCTIONP (string))
+	{
+	  safe_calln (string);
+	}
     }
 }
 
@@ -2469,14 +2473,16 @@ DEFUN ("suspend-tty", Fsuspend_tty, Ssuspend_tty, 0, 1, 0,
 
   if (f)
     {
-      /* First run `suspend-tty-functions' and then clean up the tty
-	 state because `suspend-tty-functions' might need to change
-	 the tty state.  */
+      /* The Emacs server uses `suspend-tty-functions' to perform the
+	 actual suspension of secondary terminals.  Therefore, we must
+	 run them after resetting the terminal state.  */
       Lisp_Object term;
       XSETTERMINAL (term, t);
-      CALLN (Frun_hook_with_args, Qsuspend_tty_functions, term);
 
       reset_sys_modes (t->display_info.tty);
+
+      CALLN (Frun_hook_with_args, Qsuspend_tty_functions, term);
+
       delete_keyboard_wait_descriptor (fileno (f));
 
 #ifndef MSDOS
@@ -4951,6 +4957,8 @@ vfatal (const char *str, va_list ap)
 maybe_fatal (bool must_succeed, struct terminal *terminal,
 	     const char *str1, const char *str2, ...)
 {
+  Lisp_Object old_inhibit_lisp_code = inhibit_lisp_code;
+  inhibit_lisp_code = Qt;
   va_list ap;
   va_start (ap, str2);
 
@@ -4965,6 +4973,8 @@ maybe_fatal (bool must_succeed, struct terminal *terminal,
     vfatal (str2, ap);
   else
     verror (str1, ap);
+
+  inhibit_lisp_code = old_inhibit_lisp_code;
 }
 
 void
diff --git a/src/terminal.c b/src/terminal.c
index f3a90740d8e..0ee7d21658f 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -412,10 +412,15 @@ DEFUN ("delete-terminal", Fdelete_terminal, Sdelete_terminal, 0, 2, 0,
   else
     safe_calln (Qrun_hook_with_args, Qdelete_terminal_functions, terminal);
 
+  Lisp_Object old_inhibit_lisp_code = inhibit_lisp_code;
+  if (EQ (force, Qnoelisp))
+    inhibit_lisp_code = Qt;
   if (t->delete_terminal_hook)
     (*t->delete_terminal_hook) (t);
   else
     delete_terminal (t);
+  if (EQ (force, Qnoelisp))
+    inhibit_lisp_code = old_inhibit_lisp_code;
 
   return Qnil;
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.