aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Rudalics2026-01-11 10:22:54 +0100
committerMartin Rudalics2026-01-11 10:22:54 +0100
commit38092d879b747b829fb80328925c3f282d8936e9 (patch)
tree1f46d564a966e822ee7c8b9baeb992221f883b70
parent1bc8e61df480cbf45e401baf2e81a62093e6d2a2 (diff)
downloademacs-38092d879b747b829fb80328925c3f282d8936e9.tar.gz
emacs-38092d879b747b829fb80328925c3f282d8936e9.zip
Fix crash where dead frame remains on list of live frames (Bug#80120)
* src/fns.c (delq_no_quit): New function. * src/lisp.h: Extern delq_no_quit. * src/frame.c (delete_frame): Call delq_no_quit to remove frame from Vframe_list uninterruptedly (Bug#80120).
-rw-r--r--src/fns.c25
-rw-r--r--src/frame.c4
-rw-r--r--src/lisp.h1
3 files changed, 27 insertions, 3 deletions
diff --git a/src/fns.c b/src/fns.c
index 3604e633f8d..5c30d950cff 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -2104,6 +2104,31 @@ argument. */)
2104 return list; 2104 return list;
2105} 2105}
2106 2106
2107/* Like Fdelq but do not report errors and neither quit nor process
2108 signals. Use only on objects known to be non-circular lists. */
2109Lisp_Object
2110delq_no_quit (Lisp_Object elt, Lisp_Object list)
2111{
2112 Lisp_Object prev = Qnil, tail = list;
2113
2114 for (; !NILP (tail); tail = XCDR (tail))
2115 {
2116 Lisp_Object tem = XCAR (tail);
2117
2118 if (EQ (elt, tem))
2119 {
2120 if (NILP (prev))
2121 list = XCDR (tail);
2122 else
2123 Fsetcdr (prev, XCDR (tail));
2124 }
2125 else
2126 prev = tail;
2127 }
2128
2129 return list;
2130}
2131
2107DEFUN ("delete", Fdelete, Sdelete, 2, 2, 0, 2132DEFUN ("delete", Fdelete, Sdelete, 2, 2, 0,
2108 doc: /* Delete members of SEQ which are `equal' to ELT, and return the result. 2133 doc: /* Delete members of SEQ which are `equal' to ELT, and return the result.
2109SEQ must be a sequence (i.e. a list, a vector, or a string). 2134SEQ must be a sequence (i.e. a list, a vector, or a string).
diff --git a/src/frame.c b/src/frame.c
index a03be0cd52f..5d38f015130 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -2778,9 +2778,7 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
2778 delete_all_child_windows (f->root_window); 2778 delete_all_child_windows (f->root_window);
2779 fset_root_window (f, Qnil); 2779 fset_root_window (f, Qnil);
2780 2780
2781 block_input (); 2781 Vframe_list = delq_no_quit (frame, Vframe_list);
2782 Vframe_list = Fdelq (frame, Vframe_list);
2783 unblock_input ();
2784 SET_FRAME_VISIBLE (f, false); 2782 SET_FRAME_VISIBLE (f, false);
2785 2783
2786 /* Allow the vector of menu bar contents to be freed in the next 2784 /* Allow the vector of menu bar contents to be freed in the next
diff --git a/src/lisp.h b/src/lisp.h
index 49f7c1c9782..68d1226b2ee 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4284,6 +4284,7 @@ extern Lisp_Object nconc2 (Lisp_Object, Lisp_Object);
4284extern Lisp_Object assq_no_quit (Lisp_Object, Lisp_Object); 4284extern Lisp_Object assq_no_quit (Lisp_Object, Lisp_Object);
4285extern Lisp_Object assq_no_signal (Lisp_Object, Lisp_Object); 4285extern Lisp_Object assq_no_signal (Lisp_Object, Lisp_Object);
4286extern Lisp_Object assoc_no_quit (Lisp_Object, Lisp_Object); 4286extern Lisp_Object assoc_no_quit (Lisp_Object, Lisp_Object);
4287extern Lisp_Object delq_no_quit (Lisp_Object, Lisp_Object);
4287extern ptrdiff_t string_char_to_byte (Lisp_Object, ptrdiff_t); 4288extern ptrdiff_t string_char_to_byte (Lisp_Object, ptrdiff_t);
4288extern ptrdiff_t string_byte_to_char (Lisp_Object, ptrdiff_t); 4289extern ptrdiff_t string_byte_to_char (Lisp_Object, ptrdiff_t);
4289extern Lisp_Object string_to_multibyte (Lisp_Object); 4290extern Lisp_Object string_to_multibyte (Lisp_Object);