diff src/buffer.c @ 114:8619ce7e4c50 r20-1b9

Import from CVS: tag r20-1b9
author cvs
date Mon, 13 Aug 2007 09:21:54 +0200
parents fe104dbd9147
children 9f59509498e1
line wrap: on
line diff
--- a/src/buffer.c	Mon Aug 13 09:20:50 2007 +0200
+++ b/src/buffer.c	Mon Aug 13 09:21:54 2007 +0200
@@ -986,6 +986,8 @@
 	{
 	  int count = specpdl_depth ();
 	  /* lock_file() and unlock_file() currently use current_buffer */
+	  /* #### - dmoore, what if lock_file or unlock_file kill
+	     the current buffer? */
 	  record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
 	  set_buffer_internal (buf);
 	  if (!already && !NILP (flag))
@@ -1306,14 +1308,14 @@
      to kill the buffer.  This must be done after the questions
      since anything can happen within yes-or-no-p.  */
 
+  /* Might have been deleted during the last question above */
+  if (!BUFFER_LIVE_P (b))
+    return Qnil;
+
   /* Don't kill the minibuffer now current.  */
   if (EQ (buf, XWINDOW (minibuf_window)->buffer))
     return Qnil;
 
-  /* Might have been deleted during the last question above */
-  if (!BUFFER_LIVE_P (b))
-    return Qnil;
-
   /* When we kill a base buffer, kill all its indirect buffers.
      We do it at this stage so nothing terrible happens if they
      ask questions or their hooks get errors.  */
@@ -1342,8 +1344,23 @@
   /* Now there is no question: we can kill the buffer.  */
 
 #ifdef CLASH_DETECTION
-  /* Unlock this buffer's file, if it is locked.  */
+  /* Unlock this buffer's file, if it is locked.  unlock_buffer
+     can both GC and kill the current buffer, and wreak general
+     havok by running lisp code. */
+  GCPRO1 (buf);
   unlock_buffer (b);
+  UNGCPRO;
+  b = XBUFFER (buf);
+
+  if (!BUFFER_LIVE_P (b))
+    return Qnil;
+
+  if (b == current_buffer)
+    {
+      Fset_buffer (Fother_buffer (buf, Qnil, Qnil));
+      if (b == current_buffer)
+	return Qnil;
+    }
 #endif /* CLASH_DETECTION */
 
   {