1
0
forked from aniani/vim

patch 8.2.1970: it is easy to make mistakes when cleaning up swap files

Problem:    It is easy to make mistakes when cleaning up swap files after the
            system crashed.
Solution:   Warn for the process still running after recovery.  Do not
            automatically delete a swap file created on another system.
            (David Fries, closes #7273)
This commit is contained in:
Bram Moolenaar
2020-11-09 21:04:17 +01:00
parent ea696852e7
commit f883508e36
3 changed files with 77 additions and 3 deletions

View File

@@ -1690,7 +1690,17 @@ ml_recover(int checkext)
}
else
msg(_("Recovery completed. Buffer contents equals file contents."));
msg_puts(_("\nYou may want to delete the .swp file now.\n\n"));
msg_puts(_("\nYou may want to delete the .swp file now."));
#if defined(UNIX) || defined(MSWIN)
if (mch_process_running(char_to_long(b0p->b0_pid)))
{
// Warn there could be an active Vim on the same file, the user may
// want to kill it.
msg_puts(_("\nNote: process STILL RUNNING: "));
msg_outnum(char_to_long(b0p->b0_pid));
}
#endif
msg_puts("\n\n");
cmdline_row = msg_row;
}
#ifdef FEAT_CRYPT
@@ -2230,14 +2240,30 @@ swapfile_unchanged(char_u *fname)
ret = FALSE;
#if defined(UNIX) || defined(MSWIN)
// Host name must be known and must equal the current host name, otherwise
// comparing pid is meaningless.
if (*(b0.b0_hname) == NUL)
{
ret = FALSE;
}
else
{
char_u hostname[B0_HNAME_SIZE];
mch_get_host_name(hostname, B0_HNAME_SIZE);
hostname[B0_HNAME_SIZE - 1] = NUL;
if (STRICMP(b0.b0_hname, hostname) != 0)
ret = FALSE;
}
// process must be known and not be running
pid = char_to_long(b0.b0_pid);
if (pid == 0L || mch_process_running(pid))
ret = FALSE;
#endif
// TODO: Should we check if the swap file was created on the current
// system? And the current user?
// We do not check the user, it should be irrelevant for whether the swap
// file is still useful.
close(fd);
return ret;

View File

@@ -403,4 +403,50 @@ func Test_swap_symlink()
call delete('Xswapdir', 'rf')
endfunc
func Test_swap_auto_delete()
" Create a valid swapfile by editing a file with a special extension.
split Xtest.scr
call setline(1, ['one', 'two', 'three'])
write " file is written, not modified
write " write again to make sure the swapfile is created
" read the swapfile as a Blob
let swapfile_name = swapname('%')
let swapfile_bytes = readfile(swapfile_name, 'B')
" Forget about the file, recreate the swap file, then edit it again. The
" swap file should be automatically deleted.
bwipe!
" change the process ID to avoid the "still running" warning
let swapfile_bytes[24] = 0x99
call writefile(swapfile_bytes, swapfile_name)
edit Xtest.scr
" will end up using the same swap file after deleting the existing one
call assert_equal(swapfile_name, swapname('%'))
bwipe!
" create the swap file again, but change the host name so that it won't be
" deleted
autocmd! SwapExists
augroup test_swap_recover_ext
autocmd!
autocmd SwapExists * let v:swapchoice = 'e'
augroup END
" change the host name
let swapfile_bytes[28 + 40] = 0x89
call writefile(swapfile_bytes, swapfile_name)
edit Xtest.scr
call assert_equal(1, filereadable(swapfile_name))
" will use another same swap file name
call assert_notequal(swapfile_name, swapname('%'))
bwipe!
call delete('Xtest.scr')
call delete(swapfile_name)
augroup test_swap_recover_ext
autocmd!
augroup END
augroup! test_swap_recover_ext
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1970,
/**/
1969,
/**/