Mercurial > vim
comparison src/buffer.c @ 13720:7d2039b2ecc8 v8.0.1732
patch 8.0.1732: crash when terminal API call deletes the buffer
commit https://github.com/vim/vim/commit/a997b45c7e350ea5b378ca0c52ed3d4cc610975c
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue Apr 17 23:24:06 2018 +0200
patch 8.0.1732: crash when terminal API call deletes the buffer
Problem: Crash when terminal API call deletes the buffer.
Solution: Lock the buffer while calling a function. (closes https://github.com/vim/vim/issues/2813)
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Tue, 17 Apr 2018 23:30:07 +0200 |
parents | cec5137d5332 |
children | 3be5e8306a3e |
comparison
equal
deleted
inserted
replaced
13719:fb1a9741c1c5 | 13720:7d2039b2ecc8 |
---|---|
415 | 415 |
416 if (!HASHITEM_EMPTY(hi)) | 416 if (!HASHITEM_EMPTY(hi)) |
417 hash_remove(&buf_hashtab, hi); | 417 hash_remove(&buf_hashtab, hi); |
418 } | 418 } |
419 | 419 |
420 static char *e_buflocked = N_("E937: Attempt to delete a buffer that is in use"); | |
421 | |
420 /* | 422 /* |
421 * Close the link to a buffer. | 423 * Close the link to a buffer. |
422 * "action" is used when there is no longer a window for the buffer. | 424 * "action" is used when there is no longer a window for the buffer. |
423 * It can be: | 425 * It can be: |
424 * 0 buffer becomes hidden | 426 * 0 buffer becomes hidden |
474 if (bt_terminal(buf) && (buf->b_nwindows == 1 || del_buf)) | 476 if (bt_terminal(buf) && (buf->b_nwindows == 1 || del_buf)) |
475 { | 477 { |
476 if (term_job_running(buf->b_term)) | 478 if (term_job_running(buf->b_term)) |
477 { | 479 { |
478 if (wipe_buf || unload_buf) | 480 if (wipe_buf || unload_buf) |
481 { | |
482 if (buf->b_locked) | |
483 { | |
484 EMSG(_(e_buflocked)); | |
485 return; | |
486 } | |
479 /* Wiping out or unloading a terminal buffer kills the job. */ | 487 /* Wiping out or unloading a terminal buffer kills the job. */ |
480 free_terminal(buf); | 488 free_terminal(buf); |
489 } | |
481 else | 490 else |
482 { | 491 { |
483 /* The job keeps running, hide the buffer. */ | 492 /* The job keeps running, hide the buffer. */ |
484 del_buf = FALSE; | 493 del_buf = FALSE; |
485 unload_buf = FALSE; | 494 unload_buf = FALSE; |
497 | 506 |
498 /* Disallow deleting the buffer when it is locked (already being closed or | 507 /* Disallow deleting the buffer when it is locked (already being closed or |
499 * halfway a command that relies on it). Unloading is allowed. */ | 508 * halfway a command that relies on it). Unloading is allowed. */ |
500 if (buf->b_locked > 0 && (del_buf || wipe_buf)) | 509 if (buf->b_locked > 0 && (del_buf || wipe_buf)) |
501 { | 510 { |
502 EMSG(_("E937: Attempt to delete a buffer that is in use")); | 511 EMSG(_(e_buflocked)); |
503 return; | 512 return; |
504 } | 513 } |
505 | 514 |
506 /* check no autocommands closed the window */ | 515 /* check no autocommands closed the window */ |
507 if (win != NULL && win_valid_any_tab(win)) | 516 if (win != NULL && win_valid_any_tab(win)) |
1353 */ | 1362 */ |
1354 if (unload) | 1363 if (unload) |
1355 { | 1364 { |
1356 int forward; | 1365 int forward; |
1357 bufref_T bufref; | 1366 bufref_T bufref; |
1367 | |
1368 if (buf->b_locked) | |
1369 { | |
1370 EMSG(_(e_buflocked)); | |
1371 return FAIL; | |
1372 } | |
1358 | 1373 |
1359 set_bufref(&bufref, buf); | 1374 set_bufref(&bufref, buf); |
1360 | 1375 |
1361 /* When unloading or deleting a buffer that's already unloaded and | 1376 /* When unloading or deleting a buffer that's already unloaded and |
1362 * unlisted: fail silently. */ | 1377 * unlisted: fail silently. */ |