aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMartin Rudalics2012-06-18 09:20:19 +0200
committerMartin Rudalics2012-06-18 09:20:19 +0200
commitb7e8d081674c24b19c5ee39892a72aef25c1dfcc (patch)
treef53f81a0692d7e47235db17bfb51cf6ef2bfd895 /src
parent7ea2b33947b401d506d10bf47721278a2b174410 (diff)
downloademacs-b7e8d081674c24b19c5ee39892a72aef25c1dfcc.tar.gz
emacs-b7e8d081674c24b19c5ee39892a72aef25c1dfcc.zip
Handle cases where buffer gets killed while running Fkill_buffer (Bug#11665).
* buffer.c (Fkill_buffer): Don't throw an error when the buffer gets killed during executing of this function (Bug#11665). Try to always return Qt when the buffer has been actually killed. (Vkill_buffer_query_functions): In doc-string say that functions run by this hook should not change the current buffer.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog8
-rw-r--r--src/buffer.c75
2 files changed, 51 insertions, 32 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index de472ab51dd..9a239de5b99 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,11 @@
12012-06-18 Martin Rudalics <rudalics@gmx.at>
2
3 * buffer.c (Fkill_buffer): Don't throw an error when the buffer
4 gets killed during executing of this function (Bug#11665). Try
5 to always return Qt when the buffer has been actually killed.
6 (Vkill_buffer_query_functions): In doc-string say that functions
7 run by this hook should not change the current buffer.
8
12012-06-18 Paul Eggert <eggert@cs.ucla.edu> 92012-06-18 Paul Eggert <eggert@cs.ucla.edu>
2 10
3 Fix recently-introduced process.c problems found by static checking. 11 Fix recently-introduced process.c problems found by static checking.
diff --git a/src/buffer.c b/src/buffer.c
index c8cbaa25698..e501c9b73cc 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1434,24 +1434,26 @@ No argument or nil as argument means do this for the current buffer. */)
1434 DEFVAR_LISP ("kill-buffer-hook", ..., "\ 1434 DEFVAR_LISP ("kill-buffer-hook", ..., "\
1435Hook to be run (by `run-hooks', which see) when a buffer is killed.\n\ 1435Hook to be run (by `run-hooks', which see) when a buffer is killed.\n\
1436The buffer being killed will be current while the hook is running.\n\ 1436The buffer being killed will be current while the hook is running.\n\
1437See `kill-buffer'." 1437
1438 */ 1438Functions run by this hook are supposed to not change the current
1439buffer. See `kill-buffer'."
1440*/
1439DEFUN ("kill-buffer", Fkill_buffer, Skill_buffer, 0, 1, "bKill buffer: ", 1441DEFUN ("kill-buffer", Fkill_buffer, Skill_buffer, 0, 1, "bKill buffer: ",
1440 doc: /* Kill buffer BUFFER-OR-NAME. 1442 doc: /* Kill the buffer specified by BUFFER-OR-NAME.
1441The argument may be a buffer or the name of an existing buffer. 1443The argument may be a buffer or the name of an existing buffer.
1442Argument nil or omitted means kill the current buffer. Return t if the 1444Argument nil or omitted means kill the current buffer. Return t if the
1443buffer is actually killed, nil otherwise. 1445buffer is actually killed, nil otherwise.
1444 1446
1445This function calls `replace-buffer-in-windows' for cleaning up all 1447The functions in `kill-buffer-query-functions' are called with the
1446windows currently displaying the buffer to be killed. The functions in 1448buffer to be killed as the current buffer. If any of them returns nil,
1447`kill-buffer-query-functions' are called with the buffer to be killed as 1449the buffer is not killed. The hook `kill-buffer-hook' is run before the
1448the current buffer. If any of them returns nil, the buffer is not 1450buffer is actually killed. The buffer being killed will be current
1449killed. The hook `kill-buffer-hook' is run before the buffer is 1451while the hook is running. Functions called by any of these hooks are
1450actually killed. The buffer being killed will be current while the hook 1452supposed to not change the current buffer.
1451is running.
1452 1453
1453Any processes that have this buffer as the `process-buffer' are killed 1454Any processes that have this buffer as the `process-buffer' are killed
1454with SIGHUP. */) 1455with SIGHUP. This function calls `replace-buffer-in-windows' for
1456cleaning up all windows currently displaying the buffer to be killed. */)
1455 (Lisp_Object buffer_or_name) 1457 (Lisp_Object buffer_or_name)
1456{ 1458{
1457 Lisp_Object buffer; 1459 Lisp_Object buffer;
@@ -1505,6 +1507,10 @@ with SIGHUP. */)
1505 unbind_to (count, Qnil); 1507 unbind_to (count, Qnil);
1506 } 1508 }
1507 1509
1510 /* If the hooks have killed the buffer, exit now. */
1511 if (NILP (BVAR (b, name)))
1512 return Qt;
1513
1508 /* We have no more questions to ask. Verify that it is valid 1514 /* We have no more questions to ask. Verify that it is valid
1509 to kill the buffer. This must be done after the questions 1515 to kill the buffer. This must be done after the questions
1510 since anything can happen within do_yes_or_no_p. */ 1516 since anything can happen within do_yes_or_no_p. */
@@ -1513,9 +1519,6 @@ with SIGHUP. */)
1513 if (EQ (buffer, XWINDOW (minibuf_window)->buffer)) 1519 if (EQ (buffer, XWINDOW (minibuf_window)->buffer))
1514 return Qnil; 1520 return Qnil;
1515 1521
1516 if (NILP (BVAR (b, name)))
1517 return Qnil;
1518
1519 /* When we kill a base buffer, kill all its indirect buffers. 1522 /* When we kill a base buffer, kill all its indirect buffers.
1520 We do it at this stage so nothing terrible happens if they 1523 We do it at this stage so nothing terrible happens if they
1521 ask questions or their hooks get errors. */ 1524 ask questions or their hooks get errors. */
@@ -1536,6 +1539,10 @@ with SIGHUP. */)
1536 } 1539 }
1537 1540
1538 UNGCPRO; 1541 UNGCPRO;
1542
1543 /* Exit if we now have killed the base buffer (Bug#11665). */
1544 if (NILP (BVAR (b, name)))
1545 return Qt;
1539 } 1546 }
1540 1547
1541 /* Run replace_buffer_in_windows before making another buffer current 1548 /* Run replace_buffer_in_windows before making another buffer current
@@ -1544,9 +1551,12 @@ with SIGHUP. */)
1544 buffer. (Bug#10114) */ 1551 buffer. (Bug#10114) */
1545 replace_buffer_in_windows (buffer); 1552 replace_buffer_in_windows (buffer);
1546 1553
1547 /* Make this buffer not be current. 1554 /* Exit if replacing the buffer in windows has killed our buffer. */
1548 In the process, notice if this is the sole visible buffer 1555 if (NILP (BVAR (b, name)))
1549 and give up if so. */ 1556 return Qt;
1557
1558 /* Make this buffer not be current. Exit if it is the sole visible
1559 buffer. */
1550 if (b == current_buffer) 1560 if (b == current_buffer)
1551 { 1561 {
1552 tem = Fother_buffer (buffer, Qnil, Qnil); 1562 tem = Fother_buffer (buffer, Qnil, Qnil);
@@ -1555,15 +1565,12 @@ with SIGHUP. */)
1555 return Qnil; 1565 return Qnil;
1556 } 1566 }
1557 1567
1558 /* Notice if the buffer to kill is the sole visible buffer 1568 /* If the buffer now current is shown in the minibuffer and our buffer
1559 when we're currently in the mini-buffer, and give up if so. */ 1569 is the sole other buffer give up. */
1560 XSETBUFFER (tem, current_buffer); 1570 XSETBUFFER (tem, current_buffer);
1561 if (EQ (tem, XWINDOW (minibuf_window)->buffer)) 1571 if (EQ (tem, XWINDOW (minibuf_window)->buffer)
1562 { 1572 && EQ (buffer, Fother_buffer (buffer, Qnil, Qnil)))
1563 tem = Fother_buffer (buffer, Qnil, Qnil); 1573 return Qnil;
1564 if (EQ (buffer, tem))
1565 return Qnil;
1566 }
1567 1574
1568 /* Now there is no question: we can kill the buffer. */ 1575 /* Now there is no question: we can kill the buffer. */
1569 1576
@@ -1576,11 +1583,10 @@ with SIGHUP. */)
1576 kill_buffer_processes (buffer); 1583 kill_buffer_processes (buffer);
1577 UNGCPRO; 1584 UNGCPRO;
1578 1585
1579 /* Killing buffer processes may run sentinels which may 1586 /* Killing buffer processes may run sentinels which may have killed
1580 have called kill-buffer. */ 1587 our buffer. */
1581
1582 if (NILP (BVAR (b, name))) 1588 if (NILP (BVAR (b, name)))
1583 return Qnil; 1589 return Qt;
1584 1590
1585 /* These may run Lisp code and into infinite loops (if someone 1591 /* These may run Lisp code and into infinite loops (if someone
1586 insisted on circular lists) so allow quitting here. */ 1592 insisted on circular lists) so allow quitting here. */
@@ -1592,8 +1598,7 @@ with SIGHUP. */)
1592 Vinhibit_quit = Qt; 1598 Vinhibit_quit = Qt;
1593 /* Remove the buffer from the list of all buffers. */ 1599 /* Remove the buffer from the list of all buffers. */
1594 Vbuffer_alist = Fdelq (Frassq (buffer, Vbuffer_alist), Vbuffer_alist); 1600 Vbuffer_alist = Fdelq (Frassq (buffer, Vbuffer_alist), Vbuffer_alist);
1595 /* If replace_buffer_in_windows didn't do its job correctly fix that 1601 /* If replace_buffer_in_windows didn't do its job fix that now. */
1596 now. */
1597 replace_buffer_in_windows_safely (buffer); 1602 replace_buffer_in_windows_safely (buffer);
1598 Vinhibit_quit = tem; 1603 Vinhibit_quit = tem;
1599 1604
@@ -1611,6 +1616,10 @@ with SIGHUP. */)
1611 internal_delete_file (BVAR (b, auto_save_file_name)); 1616 internal_delete_file (BVAR (b, auto_save_file_name));
1612 } 1617 }
1613 1618
1619 /* Deleting an auto-save file could have killed our buffer. */
1620 if (NILP (BVAR (b, name)))
1621 return Qt;
1622
1614 if (b->base_buffer) 1623 if (b->base_buffer)
1615 { 1624 {
1616 /* Unchain all markers that belong to this indirect buffer. 1625 /* Unchain all markers that belong to this indirect buffer.
@@ -5991,7 +6000,9 @@ Use Custom to set this variable and update the display." */);
5991 DEFVAR_LISP ("kill-buffer-query-functions", Vkill_buffer_query_functions, 6000 DEFVAR_LISP ("kill-buffer-query-functions", Vkill_buffer_query_functions,
5992 doc: /* List of functions called with no args to query before killing a buffer. 6001 doc: /* List of functions called with no args to query before killing a buffer.
5993The buffer being killed will be current while the functions are running. 6002The buffer being killed will be current while the functions are running.
5994If any of them returns nil, the buffer is not killed. */); 6003
6004If any of them returns nil, the buffer is not killed. Functions run by
6005this hook are supposed to not change the current buffer. */);
5995 Vkill_buffer_query_functions = Qnil; 6006 Vkill_buffer_query_functions = Qnil;
5996 6007
5997 DEFVAR_LISP ("change-major-mode-hook", Vchange_major_mode_hook, 6008 DEFVAR_LISP ("change-major-mode-hook", Vchange_major_mode_hook,